みなさん、ドキュメントを書いていますでしょうか?
私は最近はAtomのmarkdown-preview-enhancedを使ってドキュメントを書いています。
markdown-preview-enhancedの記事は以下のものがわかり易いと思います。
- 【ドキュメントが書きたくなる】Markdownライブプレビュー + インライン数式/UML/図表 + 綺麗にPDF/Wordエクスポートまで
- Atom Markdown Preview Enhancedで業務に関する全てのドキュメントを書くためのTips
mermaid.jsやPlantUMLをリアルタイムに確認しながらドキュメント書けるので、とにかくドキュメントを早く書けます。
ただ辛い部分もあって、ある程度長いドキュメントになってくるとページ分けをしたくなってきます。
やはりある程度、分量があるドキュメントはSphinxのように章分けしてくれるツールのほうが読みやすいです。
ですので、markdown-preview-enhanced
で書いたマークダウンをSphinx
にそのまま取り込めるsphinxcontrib-pandoc-markdownというSphinxフィルターを作りました。
sphinxcontrib-pandoc-markdown
インストールはpipで簡単に行なえます。
$ pip install -U sphinxcontrib-pandoc-markdown
conf.py
に以下の記述を追加します。
from sphinxcontrib.pandoc_markdown import MarkdownParser
source_suffix = ['.rst', '.md']
source_parsers = {
'.md': MarkdownParser,
}
これでSphinxで.md
ファイルを読み込み可能になります。
依存ソフトウェア
markdown-preview-enhanced
という名前の通りpandocに依存しています、依存ソフトウェアは以下の通りです。
- pandoc
- Graphviz (viz機能を使う場合)
- PlantUML (UML機能を使う場合)
- mermaid-cli (JavaScript以外の出力を場合)
実装済みのmarkdown-preview-enhanced
機能
CodeChunkやスライド能は実装していません。
Sphinx独自の機能
markdown-preview-enhanced
に実装されている機能の他にSphinx
固有の記法も実装しています。
reStructuredTextの埋め込み
recommonmark
と同様にeval_rst
でreStructuredText
を埋め込むことができます。
`` ` eval_rst
* This is a bulleted list.
* It has two items, the second
item uses two lines.
`` `
これでマークダウンで書きながら、reStructuredText
できめ細かい制御を行うという書き方もできます。
ノート、警告、参照
`` `note
This is note.
`` `
`` `warning
This is warning.
`` `
`` `seealso
This is seealso
`` `
TODO
`` `todo
This is todo.
`` `
TODOリスト
`` `todolist
`` `
TODOを使用するにはconf.py
に以下の記述を追加してください。
extensions += ['sphinx.ext.todo']
todo_include_todos=True
pull-quote、highlights
`` `pull-quote
This is pull-quote
`` `
`` `highlights
This is highlights
`` `
epigraph
`` `epigraph
考えるな、感じろ ”Don't think. Feel!”
-- 映画「ドラゴン怒りの鉄拳」より
`` `
mermaid.js
`` `mermaid
graph TD;
A-->B;
A-->C;
B-->D;
C-->D;
`` `
注意
mermaid.jsの現バージョン(7.0.0)ではCssの設定の関係で画面が半透明になる問題があります。
すでにイシューは投げられていますが、次バージョンあたりで修正されると思います。
現状ではpng形式で出力した方がよいでしょう。
mermaid.jsを使用するには、Sphinx拡張のsphinxcontrib-mermaidをインストールする必要があります。
$ pip install sphinxcontrib-mermaid
また、pngやsvgなどの出力形式に対応したい場合はmermaid-cliが必要です。
$ npm install -g mermaid-cli
conf.py
に以下の記述を追加してください。
extensions += ['sphinxcontrib.mermaid']
mermaid_output_format = "png"
Graphviz
Graphvizはグラフ構造をテキストベースで記述できるツールです。
`` `viz
digraph G {
subgraph cluster_0 {
style=filled;
color=lightgrey;
node [style=filled,color=white];
a0 -> a1 -> a2 -> a3;
label = "process #1";
}
subgraph cluster_1 {
node [style=filled];
b0 -> b1 -> b2 -> b3;
label = "process #2";
color=blue
}
start -> a0;
start -> b0;
a1 -> b3;
b2 -> a3;
a3 -> a0;
a3 -> end;
b3 -> end;
start [shape=Mdiamond];
end [shape=Msquare];
}
`` `
Graphvizを使用するには、conf.py
に以下のコードを追加する必要があります。
extensions += ['sphinx.ext.graphviz']
Wavedrom
`` `wavedrom
{ assign:[
["out",
["|",
["&", ["~", "a"], "b"],
["&", ["~", "b"], "a"]
]
]
]}
`` `
Wavedromを使用するには、Sphinx拡張のsphinxcontrib-wavedromをインストールする必要があります。
$ pip install sphinxcontrib-wavedrom
conf.py
に以下の記述を追加してください。
extensions += ['sphinxcontrib.wavedrom']
技術解説
ここはQiitaなので技術解説をします。
とはいえ、pandoc
が難しい事をほとんどやってくれているので難しい事はほとんどありません。
処理の流れ
マークダウン -> プリプロセス -> pandocフィルタ -> reStructuredText -> ポストプロセス
プリプロセス
@import
記法をプリプロセス部分で置き換えします、多分、本家の処理もプリプロセスで処理していると思います。
pandocフィルタ
pandocでマークダウンからreStructuredText
に変換しているのですが、フィルタを作成して画像のキャプションを除去しています。
フィルタは以下の通りです。
from pandocfilters import toJSONFilter, Image
def remove_caption_filter(key, value, format_, meta):
if key == 'Image':
"""
markdown:
![alt](path "title")
json:
[[u'', [], []], [{u'c': u'alt', u't': u'Str'}], [u'path', u'fig:title']]
"""
try:
alt = value[1][0].get("c")
except IndexError:
alt = None
value[1] = []
if alt:
value[2][1] = u"fig:{}".format(alt)
return Image(*value)
if __name__ == "__main__":
toJSONFilter(remove_caption_filter)
ポストプロセス
変換されたreStructuredText
をパースしてコードブロックの置換処理をします。
こんなコードを
.. codeblock:: note
This is Note.
こんなふうに変換しているだけです。
.. note::
This is Note.
reStructuredText
はルールが単純なのでパースしやすいですね。
まとめ
markdown-preview-enhanced
はマークダウン
->HTML
と直接変換なのに対して、こちらはマークダウン
->reStructuredText
->HTML
としているので、どうしてもdocutils
の仕様にひっぱられたりします。
何か問題や欲しい機能がありましたら、GitHubのイシューに投げてください。