21
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Markdownから楽してフォーマット変換する方法

Last updated at Posted at 2016-07-05

O'Reilly Atlasの簡易版みたいな仕組みで製品マニュアルを作って欲しいと言われました。
マニュアル作成にはAsciidoctorを使いたいのでAsciiDoc形式で記述することが決まったのですが、Markdown形式のほうが慣れてて楽とのことだったので、Markdown形式からAsciiDoc形式へ変換しなければならなくなりました。
pandocを使えば余裕!と思っていたのですが、意図した通りの変換ができませんでした。

調べたこと

pandocを使うならHaskellを勉強して直せばいいんだろうけども、時間がないのでPythonのMarkdownパーサーライブラリ使って変換プログラム作れないかな?と思って調べてみました。

表でまとめると以下の通り。

評価項目 Python-Markdown Misaka Mistune
URL https://github.com/waylan/Python-Markdown https://github.com/FSX/misaka https://github.com/lepture/mistune
ライセンス BSD MIT BSD
実装 python python + C python
対応バージョン Python 2.7, 3.3+ and PyPy Python 2.7, 3.2+ and PyPy 2.6 Python 2.6+, Python 3.3+ and PyPy
出力のカスタム ×
備考 Hoedownに依存

Python-Markdownは出力をカスタムできないのでパス。Misakaは枯れてて良さそうなんだけども、Hoedownに依存している点が微妙だからパス。

消去法でMistuneに決定したので、これを使って実装してみます。

簡単な使いかた

インストール

Python2.6以上で動くそうなので、2.7.11で動作確認しました。

pip install mistune

簡単ですね!

MarkdownからHTMLへ変換

以下のMarkdown形式のファイルとHTML変換用のソースを用意しました。ほぼ公式のBasic Usageに書いてある内容と一緒です。

test.md
# サンプルドキュメント
## 第XX章
### 第XXX節
convert.py
import mistune

with open('test.md', 'r') as test_file:
    markdown = mistune.Markdown()
    print markdown(test_file.read())

で、実行します。

python convert.py

すると、出力結果は以下のようになりました。

output
<h1>サンプルドキュメント</h1>
<h2>第XX章</h2>
<h3>第XXX節</h3>

部分的に適用されているので、HTMLの定義などは別でテンプレートを用意しておいて、Bodyの内容だけを書き換えるような感じで作れば良さそうです。

Markdownから自由な形式へ変換

さて本題です。

mistuneはRendererクラスを継承して、出力したい項目(メソッド)をオーバーライドすればよいそうです。
今回は見出しタグをAsciiDoc形式のセクションに置き換えたいので、以下のように作りました。

custom_render.py
import mistune

class CustomRenderer(mistune.Renderer):
    def header(self, text, level, raw=None):
        section = '=' * level
        return '{0} {1}\n'.format(section, text)

if __name__ == '__main__':
    custom_renderer = CustomRenderer()
    with open('test.md', 'r') as test_file:
        markdown = mistune.Markdown(renderer=custom_renderer)
        print markdown(test_file.read())

実行します。

python custom_render.py

以下のような結果になりました。

output
= サンプルドキュメント
== 第XX章
=== 第XXX節

想定していた結果が得られました!

あとは、必要な構文からメソッドをオーバーライドしていって、出力形式を整えればフォーマット変換ができますね。

21
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?