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
は、上手く生成できています。大きな差はないと思いますが・・・。
記法が間違っている?
そもそも、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
犯人
ということで、この場合、怪しいのは明らかに「・」(中点)でしょう。 こいつを「/」に置き換えてみます。
graph TD A[クライアント] -- リクエスト --> B[プロキシサーバー] B -- リクエスト --> C((ICAPサーバー)) C -- リクエスト --> D(変更/検査/ブロック) D -- レスポンス --> C C -- レスポンス --> B B -- レスポンス --> A
問題なく表示されました。
今度は、「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」で埋め尽くされてしまいました。アイコン的にそろそろ爆発しそうで怖いです。