rustdoc中でmermaidを使って図を書く

2 min read読了の目安(約2000字

mermaidはテキストベースでフローチャート図などを書くためのJavaScriptライブラリです。
mermaid-header-image
(mermaid公式ページより)これは例えばGitLabでは標準でMarkdown処理系に組み込まれており、次の様にMarkdown中に記述するとその位置に図を出してくれます。

```mermaid
graph TD;
  A-->B;
  A-->C;
  B-->D;
  C-->D;
```

gitlab-mermaid-image

この記事ではmermaidをrustdoc中で使う方法についてまとめます。

Aquamarine crate

結論から先に書くと、aquamarineというcrateが存在し、これを使って次の様にAttributeを書くと使えます:

#[cfg_attr(doc, aquamarine::aquamarine)]
/// ```mermaid
/// graph LR
///     s([Source]) --> a[[aquamarine]]
///     r[[rustdoc]] --> f([Docs w/ Mermaid!])
///     subgraph rustc[Rust Compiler]
///     a -. inject mermaid.js .-> r
///     end
/// ```
pub fn example() {}

aquamarine-image
(aquamarineのREADMEより)

ここで#[cfg_attr(cond, attr)]条件付きコンパイルの文法で、条件condの時だけ#[attr]と同じ様に振る舞います。rustdocでコンパイルするとき、条件docが設定されるため:

#[aquamarine::aquamarine]
/// ```mermaid
/// graph LR
///     s([Source]) --> a[[aquamarine]]
///     r[[rustdoc]] --> f([Docs w/ Mermaid!])
///     subgraph rustc[Rust Compiler]
///     a -. inject mermaid.js .-> r
///     end
/// ```
pub fn example() {}

つまりドキュメントのビルド時だけこのようにAttributeが展開されるわけです。
このaquamarine::aquamarineはproc-macroで、ドキュメント句(///から始まる部分、#[doc = "..."]として関数のAttributeとしてproc-macro側に渡される)を解析してその中のmermaid部分だけを抜き出してmermaid APIが読める形に変換します。mermaid APIはページロード時に<div class="mermaid">なHTML要素を置き換えるJavaScriptなので、これでrustdocの生成したHTMLをブラウザで開いたらMarkdown内のmermaidにしたがって図が描画されます。