MyST-Parserの振る舞いを、よりGFMっぽくする。
強行突破する
conf.py
にこれを書くとどうにかできるっぽい。
def setup(app):
# すでに定義している場合は、returnより前にこの2行を足す。
from myst_parser.mdit_to_docutils.base import DocutilsRenderer
DocutilsRenderer.render_softbreak = DocutilsRenderer.render_hardbreak
前提
- Sphinx
- MyST-Parser
- ドキュメントをMarkdownで書く
目的
このようなMarkdownソースがあったとする。
我々はネコである。
名前はまだない。
これをHTMLビルドするときに、ニュアンスとしてoutpu-1
ではなくoutput-2
を出力したい。
<p>我々はネコである。
名前はまだない。</p>
<p>我々はネコである。<br>
名前はまだない。</p>
オプションでの解決...ができない
MyST-Parserの動作設定はこのページの項目が指定できる。
ここでmyst_gfm_only
をTrue
に指定すると、内部で動作するMarkdown-itのパーサーがGitHub Flavors Markdown(GFM)の規格に従ったプリセット [1] [2] で動くようになる。
が、この設定をしても目的が達成できない。
これは、規格と実装に乖離があり、GitHub各所での振る舞いである「文中に改行があったら、そのまま<br>
とする」という動作がが、Soft line breakには定義されていないため。
関連
強行突破の解説メモ
Markdown(Commonmark)での改行には"soft line break"と"hard line break"があり、大雑把に次のようになっている。
- "hard line break": 文書構造として「ここが改行である」ことが明示された状態。
- 行末に
\
があると、こちらと解釈される。 - HTMLレンダリング時は、
<br />
に変換される。
- 行末に
- "soft line break": ソースコード上に改行コードがあるだけの状態。
- HTMLレンダリング時は、改行コードのまま。
MyST-Parserはビルドの過程でMarkdown -> Doctree -> HTMLと変換するのだが、
Markdownをパースする部分はDoctreeRenderer
が担当している。
内部では、"soft line break"と"hard line break"を検知した時の振る舞いとしてrender_softbreak
,render_hardbreak
がそれぞれ定義されており、前述の規格に従った動作をする。
GitHub上におけるGFMの動作は"soft line break"を検知した際に"hard line break"と同じ動作をするようになっている。
そのため、DoctreeRenderer
の挙動を強制的に上書きしてしまうことで、問答無用で<br />
を差し込めるようになる。
余談
この「"soft line breaks"を勝手に"hard line breaks"とする」仕様があるので、正直なところ実装としてのGFMは好きじゃないです。
「ソースとしての可読性調整」と「文体の調整」は別物であってほしい。