Re: Markdownにmetaタグを入れる

つい最近、こんな記事が出ていました。
kamekokamekame.net

いいですね、コミュニティ。さっと拡張を書いてくれる人に優しさを感じます (自画自賛)。

markdown の拡張子は?

さて、この記事では source-read イベントをフックして md_prolog を実現しました。
でも、このコード、よく読むとイベントハンドラで filename.endswith('.md') とか決め打ちしていますね。
これでよいのでしょうか?

適当にぐぐってみると、こんなやりとりが見つかります。
superuser.com
.markdown とか .mkd とか、いろいろ使ってる人がいるんですね。
先ほどのコードは完璧ではありません。

Sphinx における markdown の拡張子

Sphinx では source_parsers の設定で、Markdown パーサを有効にすることが多いですよね*1
source_parsers は conf.py にこんな感じで定義します。

from recommonmark.parser import CommonMarkParser

source_parsers = {
    '.md': CommonMarkParser,
}

source_suffix = ['.rst', '.md']

source_parsers 変数に「拡張子」と「パーサクラス」のペアを列挙します。
そして、source_suffix に対象となる拡張子のリストを並べます。


ここの設定を工夫することで、好みの拡張子を割り当てることができます。

任意の拡張子を考慮した md_prolog

さて、このように Sphinx では任意の拡張子を Markdown 文書として扱うことができます。
これに対して、冒頭の記事で紹介されているコードは対応できていません。
拡張子がハードコードされているため、設定によっては正しく動きません。

これに対応するには次のようなコードを書きます。

from recommonmark.parser import CommonMarkParser

def on_source_read(app, docname, source):
    extensions = tuple([ext in (ext, parser) in app.config.source_parsers.items()
                        if parser is CommonMarkParser])

    filename = app.env.doc2path(docname)
    if filename.endswith(extensions):
        source[0] = app.config.md_prolog + "\n\n" + source[0]

このコードでは source_parsers の値を元に CommonMarkParser が処理する拡張子のファイルかどうかを判定しています。
ちょっとわかりづらいコードになっていますが、これは無事に動くはずです。

いまやほとんどの人は .md を使っているような気もするのですが、つい .markdown を使いたいひとや .mkd 派の貴方はこのコードを使ってみると良いでしょう。

*1:API を使って足すこともできるのですが、recommonmark は使っていません