日別アーカイブ: 2020年7月20日

CommonMark文書をcmarkでXML形式にする

CommonMark[1]処理系のリファレンス実装であるcmark[2]は、その抽象構文木(AST)をXMLとして出力できます。さらに、このASTの文書型定義(DTD)も存在します。公開されていて、身近でミニマルなDTD、また文書のASTとして学習にも有用です。cmarkのインストール、DTDについての詳細は割愛します。

次のようなCommonMark文書があるとします。

# 見出しレベル1

CommonMarkにはDTDがある。

## 見出しレベル2

docutilsにもDTDがある。

これをcmarkでXML出力すると、次のようになります(xml:space="preserve"プロパティを省略して表示しています)。

<document>
<heading level="1"><text>見出しレベル1</text></heading>
<paragraph><text>CommonMarkにはDTDがある。</text></paragraph>
<heading level="2"><text>見出しレベル2</text></heading>
<paragraph><text>docutilsにもDTDがある。</text></paragraph>
</document>

CommonMarkのDTDの一部を抜き出すと、次のようになっています(表示を省略した箇所は「…」のように記述しています)。

<!ENTITY % block
         'block_quote|list|code_block|paragraph|heading|thematic_break|html_block|custom_block'>
<!ENTITY % inline
         'text|softbreak|linebreak|code|emph|strong|link|image|html_inline|custom_inline'>
...
<!ELEMENT paragraph (%inline;)*>

<!ELEMENT heading (%inline;)*>
<!ATTLIST heading
          level (1|2|3|4|5|6) #REQUIRED>
...
<!ELEMENT text (#PCDATA)>

CommonMarkの処理系を実装するときに厄介な、ある記法の途中での他の記法の割り込み処理などは変換後のASTには登場しませんから平和な見た目です。さて、このCommonMarkのDTDですが、コメントや見た目の調整のための改行を含めても90行程度。さらにこのXMLは変換前はCommonMark文書ですから、おおよそどんな見た目の記述がこの構造になるかの対応付けも整理をつけやすいのではないでしょうか。「<html_block>」や「<custom_block>」(あるいはこれらのインラインマークアップ)について真面目に考えるならもう少し難しくなりますが、CommonMark文書のASTとしての文書型定義は相当にシンプルです。


こんな記事[3]を見つけました。Markdownからの変換としては多くはLaTeX、近頃はCSS組版などがありますが、ASTをXMLで出力できるならこういったアプローチも可能ですね。目的によってはMarkdownを変換したXHTMLから更に変形するよりも単純な記述で求めるPDF出力を得られるでしょう。
ところで、アンテナハウス製品には最近のフォントも組版できるXSL-FOプロセッサー、Antenna House Formatterがあります。次回、CommonMarkのASTをFOに変換したものをAH Formatterで出力してみる予定です。


参考資料

  1. [1]https://commonmark.org/
  2. [2]https://github.com/commonmark/cmark
  3. [3] Markdown + XSL → PDF


Antenna House Formatter

DITA/XML Service Antenna House


関連記事