概要
fenced_code
拡張機能とcodehilite
拡張機能の特徴について。
fenced_code
拡張機能を使用したシンタックスハイライトのフレームワーク。
マークダウンで<pre>
タグにクラス属性とID属性を付与する。
attr_list
拡張機能と組み合わせてマークダウンから<code>
タグにキー/バリューを付与する。
codehilite
拡張機能を追加し、Pygmentsツールからシンタックスハイライトを使用する。
注意
ここでは一部の拡張機能について実装しているので、Python-Markdownのインストールから全体的な拡張機能の実装は以下の記事をご参照ください。
実行環境 |
---|
Windows Subsystem for Linux |
Python 3.6.9 |
pip 9.0.1 |
jupyter notebook |
使用ライブラリ | ライセンス |
---|---|
Markdown==3.3.6 | BSD |
Pygments==2.11.2 | BSD |
fenced_code
拡張機能とcodehilite
拡張機能の使い方についてそれぞれ簡単に実装します。
詳しくは後の方で実装するということで、まずはfenced_code
拡張機能を追加すると、3つのバッククォート(```)やチルダ(~~~)で文字列を囲むことによって<pre><code>
としてHTMLに変換されます。
import markdown
md = markdown.Markdown(extensions=['fenced_code',])
text = """
```
source code
```
"""
html = md.convert(text)
print(html)
"""
<pre><code>source code
</code></pre>
"""
次にcodehilite
拡張機能です。
codehilite
拡張機能を使用するには、fenced_code
拡張機能と合わせて使います。
md = markdown.Markdown(
extensions=[
'fenced_code',
'codehilite',
]
)
マークダウンの書式自体は変わりませんが出力結果が異なります。
出力結果は<div class="codehilite"><pre>...
というHTMLに変換されます。
text = """
```
source code
```
"""
html = md.convert(text)
print(html)
"""
<div class="codehilite"><pre><span></span><code>source code
</code></pre></div>
"""
通常のfeced_code
拡張機能で囲ったHTMLの結果と違い、codehilite
拡張機能ではPygmentsエンジンを使う為のHTMLの結果として出力されます。
補足
PygmentsはPythonに適したシンタックスハイライト(構文強調)です。
構成設定のextension_configs
の内容を変えることで手間無くコードブロック内のテーマカラーの変更や行番号などを設置することができる。
codehilite
拡張機能はPygmentsに依存しているので、外部のシンタックスハイライト(Prism.jsやhighlightjs)を使用する場合はfenced_code
拡張機能だけを追加するようにします。
fenced_code
拡張機能についてです。
1行目のバッククォートの後に波括弧を使ってコードブロック内の言語の設定、そしてクラス属性の場合はドット(.)、ID属性の場合はシャープ(#)を使って要素を渡すことができます。
注意
最初の文字列がソースコード内の言語として読み込まれる({ .言語 .class-name #id-name })。
md = markdown.Markdown(extensions=['fenced_code',])
text = """
```{ .lang .class-name #id-name }
source code
```
"""
html = md.convert(text)
print(html)
"""
<pre id="id-name" class="class-name"><code class="language-lang">source code
</code></pre>
"""
<code>
タグにキーとバリューを設定したい場合は拡張機能のattr_list
を追加します。
md = markdown.Markdown(extensions=['fenced_code', 'attr_list']) # 属性リスト拡張機能の追加
# キー&バリューであるtitleを追記
text = """
```{ .lang .class-name #id-name title="Source Code" }
source code
```
"""
html = md.convert(text)
print(html)
"""
<pre id="id-name" class="class-name"><code class="language-lang" title="Source Code">source code
</code></pre>
"""
fenced_code
拡張機能でソースコードを強調表示させ、さらにシンタックスハイライトさせるには「Prism.js」や「highlightjs」といったフレームワークが必要です。
以下はPrism.jsによってシンタックスハイライトしたソースコードの例です。
md = markdown.Markdown(extensions=['fenced_code', 'attr_list']) # 属性リスト拡張機能の追加
# キー&バリューであるtitleを追記
text = """
```{ .python }
def markdown_to_html(text, extensions=['fenced_code', 'codehilite'])
import markdown
html = markdown.markdown(text, extensions=extensions)
return html
```
```{ .python .line-numbers title="Python Code" }
def markdown_to_html(text, extensions=['fenced_code', 'codehilite'])
import markdown
html = markdown.markdown(text, extensions=extensions)
return html
```
"""
html = md.convert(text)
print(html)
"""
<pre><code class="language-python">def markdown_to_html(text, extensions=['fenced_code', 'codehilite'])
import markdown
html = markdown.markdown(text, extensions=extensions)
return html
</code></pre>
<pre class="line-numbers"><code class="language-python" title="Python Code">def markdown_to_html(text, extensions=['fenced_code', 'codehilite'])
import markdown
html = markdown.markdown(text, extensions=extensions)
return html
</code></pre>
"""
codehilite
拡張機能です。
codehilite
拡張機能では、Pygmentsというツールを使ってコードブロック内のコードをシンタックスハイライトします。
そのためには、別途Pygmentsをpipでインストールします。
pip install Pygments
extensions
にはfenced_code
拡張機能を追加した上でcodehilite
拡張機能を追加します。
構成設定のextension_configs
パラメータに何も設定しないと以下のように動作します。
md = markdown.Markdown(extensions=['fenced_code', 'codehilite'])
text = """
```
def markdown_to_html(text, extensions=['fenced_code', 'codehilite'])
import markdown
html = markdown.markdown(text, extensions=extensions)
return html
```
"""
html = md.convert(text)
print(html)
"""
<div class="codehilite"><pre><span></span><code><span class="k">def</span> <span class="nf">markdown_to_html</span><span class="p">(</span><span class="n">text</span><span class="p">,</span> <span class="n">extensions</span><span class="o">=</span><span class="p">[</span><span class="s1">'fenced_code'</span><span class="p">,</span> <span class="s1">'codehilite'</span><span class="p">])</span>
<span class="kn">import</span> <span class="nn">markdown</span>
<span class="n">html</span> <span class="o">=</span> <span class="n">markdown</span><span class="o">.</span><span class="n">markdown</span><span class="p">(</span><span class="n">text</span><span class="p">,</span> <span class="n">extensions</span><span class="o">=</span><span class="n">extensions</span><span class="p">)</span>
<span class="k">return</span> <span class="n">html</span>
</code></pre></div>
"""
上記のHTMLをWebサイトで表示した場合のイメージは以下のようになります。
Pygmentsツールにあるシンタックスハイライトを使用する最も簡単だと思われる設定は以下です。
# extension_configsパラメータに渡す辞書
config = {
'codehilite':{
'noclasses': True,
}
}
# extension_configsパラメータの設定
md = markdown.Markdown(extensions=['fenced_code', 'codehilite'], extension_configs=config)
text = """
```
def markdown_to_html(text, extensions=['fenced_code', 'codehilite'])
import markdown
html = markdown.markdown(text, extensions=extensions)
return html
```
"""
html = md.convert(text)
print(html)
"""
<div class="codehilite" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><code><span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">markdown_to_html</span>(text, extensions<span style="color: #666666">=</span>[<span style="color: #BA2121">'fenced_code'</span>, <span style="color: #BA2121">'codehilite'</span>])
<span style="color: #008000; font-weight: bold">import</span> <span style="color: #0000FF; font-weight: bold">markdown</span>
html <span style="color: #666666">=</span> markdown<span style="color: #666666">.</span>markdown(text, extensions<span style="color: #666666">=</span>extensions)
<span style="color: #008000; font-weight: bold">return</span> html
</code></pre></div>
"""
上記のHTMLをWebサイトで表示した場合のイメージは以下のようになります。
さらに簡易的にシンタックスハイライトさせる方法は、バッククォート3つの後に波括弧を使って記述します。
補足
attr_list
拡張機能とは関係なく動作します。
md = markdown.Markdown(extensions=['fenced_code', 'codehilite'])
text = """
```{ noclasses=True}
def markdown_to_html(text, extensions=['fenced_code', 'codehilite'])
import markdown
html = markdown.markdown(text, extensions=extensions)
return html
```
"""
html = md.convert(text)
print(html)
"""
<div class="codehilite" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><code><span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">markdown_to_html</span>(text, extensions<span style="color: #666666">=</span>[<span style="color: #BA2121">'fenced_code'</span>, <span style="color: #BA2121">'codehilite'</span>])
<span style="color: #008000; font-weight: bold">import</span> <span style="color: #0000FF; font-weight: bold">markdown</span>
html <span style="color: #666666">=</span> markdown<span style="color: #666666">.</span>markdown(text, extensions<span style="color: #666666">=</span>extensions)
<span style="color: #008000; font-weight: bold">return</span> html
</code></pre></div>
"""
codehilite
拡張機能ではextension_configs
によって構成設定の初期値を定めるか、マークダウンの波括弧を使用して構成設定を操作するかで柔軟にシンタックスハイライトすることができます。
以下はcodehilite
拡張機能の構成設定の一部です。
Key | Value |
---|---|
linenums | デフォルト=False、行番号を付与するか |
guess_lang | デフォルト=True、自動で言語を構文強調させるか |
css_class | デフォルト='css_class.perldoc' |
pygments_style | デフォルト='defaul'、シンタックスハイライトのテーマを設定する。Pygments-Style一覧 |
noclasses | デフォルト=False、CSSを使う場合はFalse。Trueだとpygments_styleどおりのスタイルになる |
use_pygments | デフォルト=True |
lang_prefic | デフォルト='language-' |
その他はPygmentsのオプションをご参照下さい。
最後にマークダウンからシンタックスハイライトのテーマをそれぞれ設定してみます。
md = markdown.Markdown(extensions=['fenced_code', 'codehilite'])
text = """
- default
```{ noclasses=True pygments_style='default'}
def markdown_to_html(text, extensions=['fenced_code', 'codehilite'])
import markdown
html = markdown.markdown(text, extensions=extensions)
return html
```
- monokai
```{ hl_lines="2" noclasses=True pygments_style='monokai'}
def markdown_to_html(text, extensions=['fenced_code', 'codehilite'])
import markdown
html = markdown.markdown(text, extensions=extensions)
return html
```
- solarized-light
```{ hl_lines="4 5" noclasses=True pygments_style='solarized-light'}
def markdown_to_html(text, extensions=['fenced_code', 'codehilite'])
import markdown
html = markdown.markdown(text, extensions=extensions)
return html
```
"""
html = md.convert(text)
print(html)
"""
<ul>
<li>default</li>
</ul>
<div class="codehilite" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><code><span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">markdown_to_html</span>(text, extensions<span style="color: #666666">=</span>[<span style="color: #BA2121">'fenced_code'</span>, <span style="color: #BA2121">'codehilite'</span>])
<span style="color: #008000; font-weight: bold">import</span> <span style="color: #0000FF; font-weight: bold">markdown</span>
html <span style="color: #666666">=</span> markdown<span style="color: #666666">.</span>markdown(text, extensions<span style="color: #666666">=</span>extensions)
<span style="color: #008000; font-weight: bold">return</span> html
</code></pre></div>
<ul>
<li>monokai</li>
</ul>
<div class="codehilite" style="background: #272822"><pre style="line-height: 125%;"><span></span><code><span style="color: #66d9ef">def</span> <span style="color: #a6e22e">markdown_to_html</span><span style="color: #f8f8f2">(text,</span> <span style="color: #f8f8f2">extensions</span><span style="color: #f92672">=</span><span style="color: #f8f8f2">[</span><span style="color: #e6db74">'fenced_code'</span><span style="color: #f8f8f2">,</span> <span style="color: #e6db74">'codehilite'</span><span style="color: #f8f8f2">])</span>
<span style="background-color: #49483e"> <span style="color: #f92672">import</span> <span style="color: #f8f8f2">markdown</span>
</span>
<span style="color: #f8f8f2">html</span> <span style="color: #f92672">=</span> <span style="color: #f8f8f2">markdown</span><span style="color: #f92672">.</span><span style="color: #f8f8f2">markdown(text,</span> <span style="color: #f8f8f2">extensions</span><span style="color: #f92672">=</span><span style="color: #f8f8f2">extensions)</span>
<span style="color: #66d9ef">return</span> <span style="color: #f8f8f2">html</span>
</code></pre></div>
<ul>
<li>solarized-light</li>
</ul>
<div class="codehilite" style="background: #fdf6e3"><pre style="line-height: 125%;"><span></span><code><span style="color: #859900">def</span> <span style="color: #268bd2">markdown_to_html</span><span style="color: #657b83">(text,</span> <span style="color: #657b83">extensions</span><span style="color: #93a1a1">=</span><span style="color: #657b83">[</span><span style="color: #2aa198">'fenced_code'</span><span style="color: #657b83">,</span> <span style="color: #2aa198">'codehilite'</span><span style="color: #657b83">])</span>
<span style="color: #cb4b16">import</span> <span style="color: #268bd2">markdown</span>
<span style="background-color: #eee8d5"> <span style="color: #657b83">html</span> <span style="color: #93a1a1">=</span> <span style="color: #657b83">markdown</span><span style="color: #93a1a1">.</span><span style="color: #657b83">markdown(text,</span> <span style="color: #657b83">extensions</span><span style="color: #93a1a1">=</span><span style="color: #657b83">extensions)</span>
</span><span style="background-color: #eee8d5"> <span style="color: #859900">return</span> <span style="color: #657b83">html</span>
</span></code></pre></div>
"""
上記のHTMLをWebサイトで表示した場合のイメージは以下のようになります。
PygmentsのCSSファイルを取得したい場合は、ターミナル上でコマンドを打ちます。
$ pygmentize -S default -f html -a .codehilite > default.css
するとカレントディレクトリに「default.css」がダウンロードされているはずです。
詳しくは【Python】Python-Markdownで拡張機能を追加する(その2)の中で説明しています。
それでは以上となります。
最後までご覧いただきありがとうございました。