Python で Github Flavored Markdown をレンダリングする

前回の補足的な内容

python の Markdown ライブラリ自体は Github Flavored Markdown(GFM) をサポートしていない。

>>> import markdown
>>> markdown.markdown("```python\ndef hello():\n    print('hello')\n```")
u"<p><code>python\ndef hello():\n    print('hello')</code></p>"

python の Markdown ライブラリは拡張可能になっている。Markdown ライブラリの拡張ライブラリとして py-gfm を使うと gfm も扱えるようになる。

>>> import markdown
>>> markdown.markdown("```python\ndef hello():\n    print('hello')\n```", extensions=['gfm'])
u'<pre class="highlight"><code class="language-python">def hello():\n    print(\'hello\')</code></pre>'

さて、これで python であることを認識してくれたわけではあるけれど、シンタックスハイライトが効いていない。しかし、前回のエントリで MoinMoin に Markdown + py-gfm を組み込んだときはシンタックスハイライトがついていた。なんで?

これが気になっていろいろソース読んだりしたのだけど、答えは MoinMoin が pygments に依存しているから。pygments をインストールする前後で Markdown ライブラリは動きが変わる。

$ pip install pygments
>>> import markdown
>>> markdown.markdown("```python\ndef hello():\n    print('hello')\n```", extensions=['gfm'])
u'<div class="highlight"><pre><span class="k">def</span> <span class="nf">hello</span><span class="p">():</span>\n    <span class="k">print</span><span class="p">(</span><span class="s">&#39;hello&#39;</span><span class="p">)</span>\n</pre></div>'
>

pygments をインストールしたらシンタックスハイライトがついた。

実は Markdown のほうにこんなコードがあった。

try:
    from pygments import highlight
    from pygments.lexers import get_lexer_by_name, guess_lexer, TextLexer
    from pygments.formatters import HtmlFormatter
    pygments = True
except ImportError:
    pygments = False

https://github.com/waylan/Python-Markdown/blob/2.4-final/markdown/extensions/codehilite.py#L26-L32

わかりにくい挙動だと思う。markdown 関数の第二引数で extensions=['pygment'] みたいに渡すようにすればいいのに。せっかく拡張を作れるにしたのになぜこういう結合をさせるのか理解に苦しむ。

まあともあれ、Markdown + py-gfm + pygments で良い感じに GFM がレンダリングできるので使うと良いと思います。