Mermaidのノードテキストで「・」「#」「*」は使えない罠

Mermaidにはまっている(二重の意味で)

Mermaid記法について

Mermaid記法は、テキストベースの構文でグラフや図を作成するツール・記法です。 以前の記事でも紹介したとおり、Mermaid記法は、ごく簡単により広い環境で利用することができます。

最近、このMermaid記法を知ってからはまっていて、いちいち図を作成したりフロー図を作成する手間が省けるので公私で便利に活用しています。

フローチャートガントチャートなどは、直感的で分かりやすいですよね。しかし、手作業でツールを使って作成するのは大変な作業です。

Mermaid記法は、テキストベースで直感的に図表を作成でき、知識も不要なのでとても便利です。ただ、今日はちょっとした罠にはまってしまいました。

何が間違っている?

graph TD
A[クライアント] -- リクエスト --> B[プロキシサーバー]
B -- リクエスト --> C((ICAPサーバー))
C -- リクエスト --> D(変更・検査・ブロック)
D -- レスポンス --> C
C -- レスポンス --> B
B -- レスポンス --> A

いつも通り、Mermaidでフローチャートを書こうとしたところ、コードにエラーがあると指摘されました。

エラーメッセージは以下の通りです。

Lexical error on line 4. Unrecognized text.
...C -- リクエスト --> D(変更・検査・ブロック)D -- レスポンス
----------------------^

同じような内容の

graph TD
A[クライアント] -- リクエスト --> B[プロキシサーバー]
B -- リクエスト --> C((ICAPサーバー))
C -- レスポンス --> B
B -- レスポンス --> A

は、上手く生成できています。大きな差はないと思いますが・・・。

似たような2つのコード

でも片方では上手くいかない

記法が間違っている?

そもそも、Mermaidの知識が浅いため、まずは自分の記法が間違っている可能性があると疑いました。

今回は、ICAPサーバー、プロキシサーバー、クライアントの関係について図示したいものです。 図には、それぞれの要素があり、クライアント、プロキシサーバー、ICAPサーバーが線で繋がっている様子を表現します。

Mermaid記法ではより深いこともできますが、このチャートは非常に簡単です。利用している要素は以下のとおりです。

要素 記法 説明
ノード A, B, C ダイヤモンドや四角形、円形などで表現される要素
ノード形状 ( ( ) ), [ ], {{ }} ノードの形状をカスタマイズすることができる
エッジ -- ノードとノードを結ぶ線
方向 graph TD, graph LR, graph TB graph TD で下向き、graph LR で右向き、graph TB で上向き

※ ( ( ) ) は本来空白は不要ですが、はてなブログの忌まわしい機能で引用扱いとされる上にエスケープ文字も無いようなので空白で回避しています。以降読み替えてください。ごめんなさい。

今回は、各ノード同士がグラフTD方向にリクエストもしくはレスポンスのエッジで結ばれています。具体的には、ノードA(クライアント、四角形)、ノードB(プロキシサーバー、四角形)、ノードC(ICAPサーバー、丸形)、ノードD(変更・検査・ブロック、四角形)があります。

仮に描画がうまくいっていたとしても、「変更・検査・ブロック」をノードとして表現していることについては、今考えると意味が分からないのですが、今回は見逃してください。

さて、これを踏まえると、極々簡単な記法であることが分かるのですが、この短い記法の間で、エラーが出てしまっています。

Lexical error on line 4. Unrecognized text.
...C -- リクエスト --> D(変更・検査・ブロック)D -- レスポンス
----------------------^

 

エラーコードを確認すると、4行目のノードDのテキスト部分でエラーが発生していることが分かります。

ただ、このテキストはその上の「B -- リクエスト --> C( (ICAPサーバー) )」と大きく変わっていません。

その「B -- リクエスト --> C( (ICAPサーバー) )」を含む図は正しく表現されているので、どこが問題かが分かりません。Mermaidは日本語を扱うことができるわけです。 (どこまで想定されていてサポートされているかは置いておいて)

切り分けのために、試しにエラー箇所のノードDのtextを別の文字列に置き換えてみます。(Mermaidのノード名は空欄にできないため) 今回は、ノードDの名称を「test」に変更してみます。

graph TD
A[クライアント] -- リクエスト --> B[プロキシサーバー]
B -- リクエスト --> C((ICAPサーバー))
C -- リクエスト --> D(test)
D -- レスポンス --> C
C -- レスポンス --> B
B -- レスポンス --> A

"test"ノードだとOK

犯人

ということで、この場合、怪しいのは明らかに「・」(中点)でしょう。 こいつを「/」に置き換えてみます。

graph TD
A[クライアント] -- リクエスト --> B[プロキシサーバー]
B -- リクエスト --> C((ICAPサーバー))
C -- リクエスト --> D(変更/検査/ブロック)
D -- レスポンス --> C
C -- レスポンス --> B
B -- レスポンス --> A

変更/検査/ブロック ノードだとOK

問題なく表示されました。

今度は、「ICAPサーバー」ノードに中点を入れてみましょう。これまでに問題ないことが証明されているノードです。

graph TD
A[クライアント] -- リクエスト --> B[プロキシサーバー]
B -- リクエスト --> C((ICAP・サーバー))
C -- レスポンス --> B
B -- レスポンス --> A

同じくエラーが出る

同じエラーが出ました。

結論

結論として、Mermaid記法では、ノード要素のテキストに「・」(中点)を入れると問題が発生することが分かりました。

Mermaidの詳細な仕様は、無学な僕には理解できませんが、JavaScriptのライブラリであるため、依存するパーサーによってはサポートされていない対象である、Unicodeの「・」も解釈に問題が生じているのだと思いました。

また、同じように「#」や「*」でも同様にエラーが発生するため、解釈的にはこのような記号は多くあると思われます。

対策としてはやはり、こういったときには、全角文字は使わないに限りますね。Mermaidに関する情報があまりないため、調べるのに苦戦しました。という備忘録でした。

余談

最近は、ブロック管理がしやすいため、ブログ記事を下書きするのにNotionを利用しています。そしてこのNotionもMermaid記法をサポートしています。

Notionはコードの記載と表示、どちらも同時にできて最高に便利なんですが、この記事のために誤ったMermaid記法を列記していたら、Notionの画面が「Syntax Error」で埋め尽くされてしまいました。アイコン的にそろそろ爆発しそうで怖いです。

爆弾アイコンやめろ