markdownの拡張記法の現状

Kibelaは次のようにいくつかmarkdownを拡張しています。

そして、今後もそういう拡張は増えていくと思われます。

PlantUML

KibelaのPlantUML記法はこういうやつです。

    ```plantuml
    Bob -> Alice : hello
    Alice -> Bob : Go Away
    ```

GitLabも同じ構文でPlantUMLをサポートしていますね。

PlantUML & GitLab - GitLab Documentation

crowiも最近PlantUML記法をサポートしはじめましたね。構文はKibelaとおなじです。

Support PlantUML by sotarok · Pull Request #231 · crowi/crowi · GitHub

esa.io もUML記法という名前でPlantUMLをサポートしていて、こちらは plantuml ではなく uml というキーワードです。

ReleaseNotes/2016/10/22/UML記法に対応しました - docs.esa.io

問題としては、fenced code blocksでいいの?といいうところです。「markdownとして解釈されずにコードを表示する」というfenced code blocksのセマンティクスを完全に無視していますからね。

具体的な弊害としても、PlantUMLそのもののソースコードをsyntax highlightを効かせて埋め込むことができないというものがあります。

MathJax / TeX

こちらは様々なmarkdown処理系が思いおもいに拡張していて、 だいたい Math in MarkDown · cben/mathdown Wiki · GitHub にまとまっています。

CommonMarkでも2014年くらいから議論されていますが進捗は芳しくなさそうです。

MathJax extension for LaTeX equations - Extensions - CommonMark Discussion

ざっくりまとめると、fenced code blocksを使うスタイルと $$ ... $$\( ... \) などの独自記法を定義するスタイルがあります。

fenced code blocksの問題はPlantUMLとおなじです。つまり、セマンティクスを無視していいのかという一貫性の問題と、syntax highlightとの衝突の問題です。 もっとも、TeX記法に関していうと math キーワードを使う事が多いようなので、TeX (LaTeX) とのsyntax highlightの衝突はそれほど問題ではありません。

独自記法は大きな問題です。 $$ はshellやPerlのpidを示す特殊変数なので、普通に文中に出現する可能性があります。また、markdownは \ をメタ文字として扱っているので、 \(\[ というトークンはmarkdown parserレベルで ([ にしてしまいます。つまり、真面目にやるならmarkdown parser自体を拡張するか、markdown parserに与える前に処理をする必要があります。これらはいずれにしても実装コストが高いので避けたいところです。github/cmarkのtable拡張 をみても、パーサの拡張はわりとしんどい感じがします。

R Markdown

R Markdown というものがあって、ツールとしてはJupiter Notebookみたいなものだと認識していますが、markdown中にRを書けて実行もできるというものです。

構文がちょっとおもしろくて、fenced code blocksなんですが明らかに拡張だなとわかります。

    ```{r}
     1 + 1
    ```

RだけじゃなくPythonやbashなどもいけるようですね。

{r INCLUDE = FALSE} のように、code blockに対して引数を与えることもできるようです。

個人的には、この構文はわりと使いやすいようにみえます。つまり

  • fenced code blocksの拡張だがそれほどセマンティクスを侵害していないようにみえる(主観)
  • foo に対する {foo} で「実行」を示すので、syntax highlightと衝突しない
  • fenced code blocksの中はmarkdownの干渉をうけないのでmarkdown parserの拡張が不要

もちろんデメリットもあって

  • インライン記法がないことで、文中にLaTeXで数式を書きたいというニーズにこたえられない
  • Kibelaに限って考えるとしても、これまでやってきた拡張と互換性がない
  • CommonMarkとしてのコンセンサスはない

という感じです。CommonMark的にどうかというのは気持ちの問題なので無視してもいいですが、他のデメリットもそこそこ大きいんですよね。

Generic Directives /Plugins in CommonMark

汎用的な拡張記法の提案で、CommonMarkで議論中のものです。

Generic directives/plugins syntax - Extensions - CommonMark Discussion

ざっとしか眺めてませんが、あまり芳しくなさそうです。スレ主の提案はこんな感じです。

::: name [inline-content] {key=val}
contents, which are sometimes further block elements
:::

悪くなさそうにみえますが、2014年の議論でいままとまっていないということは…。

あまりまとまりはないですが、とりあえず現状のメモでした。

See Also

gfx.hatenablog.com