独自構文のテキストから、各種のダイアグラムを生成できるMermaidという便利なライブラリがありますが、現時点ではHugoでサポートされていません。
このため通常、
- 独自のショートコードを作成する
- 言語としてmermaidを指定したコードブロックを使用し、mermaidで
language-mermaid
クラスの要素を変換対象として指定する
などの実装が多かったと思うのですが、公式サイトを調べていたところv0.93.0からサポートされたcodeブロックに対するレンダーフックを用いた例が載っており、よりスマートに実装できそうでした。
ここでは公式サイトのレンダーフックを用いたMermaidの組み込み方法を説明します。
レンダーフックの追加
codeブロックに対するレンダーフックを定義するには、
layouts/_default/_markup/render-codeblock-言語名.html
というファイルを作成します。今回ファイル名を、
layouts/_default/_markup/render-codeblock-mermaid.html
とすることで、
```mermaid
flowchart LR
Start --> Stop
```
というような、言語にmermaidを指定したコードブロックに対してレンダーフックが起動します。レンダーフックの内容は以下の通りです。
<div class="mermaid">
{{- .Inner | safeHTML }}
</div>
{{ .Page.Store.Set "hasMermaid" true }}
<div class="mermaid">
でコードブロックの内容を囲む- Mermaidの記述があることを表す
hasMermaid
フラグをtrueにする
テンプレートの修正
テンプレートについては、
- layouts/_default/baseof.html
- layouts/_default/single.html
など、Mermaidのコンテンツを表示したいテンプレートへ以下の内容を追加します。私の場合、通常エントリでのみ表記できれば良いためsingle.htmlへ追加しました。
{{ if .Page.Store.Get "hasMermaid" }}
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
<script>
mermaid.initialize({ startOnLoad: true });
</script>
{{ end }}
このコードはhasMermaid
フラグがtrueの場合のみ、MermaidのJavascscript読み込みと初期化を行います。これにより、Mermaidの記述がないページではコードが展開されずムダな処理を抑止できるわけです。
上記処理をテンプレートへ追記する場合の注意点としては、.Content
が出現する箇所より下へ書く必要があるということです。Hugoでは.Content
が実行(評価)されるまではレンダーフックは処理されないためです。