Mermaid 作為 markdown 的流程圖繪製解決方案大大增加了 markdown 的實用性。對於繪圖苦手的我來說 Mermaid 簡直是一大救星。因此在開始自己搭建 hexo 部落格之後,我第一件事也是確認 Mermaid 是否可用。

後來選上 shoka 這套主題不單是它漂亮的佈景,還有豐富的內建 markdwon 語法支援。其中當然包括了今天的主角 Mermaid

在一切搭建都接近完成後,我依依確認功能是否完備時發現 Mermaid 無法正確顯示流程圖。無論怎麼修改 _config.yml 的配置,其永遠都是死死地顯示純文字的格式。

```mermaid
graph LR
    A[Square Rect] -- Link text --> B((Circle))
    A --> C(Round Rect)
    B --> D{Rhombus}
    C --> D
```
```mermaid
sequenceDiagram
    loop Daily query
        Alice->>Bob: Hello Bob, how are you?
        alt is sick
            Bob->>Alice: Not so good :(
        else is well
            Bob->>Alice: Feeling fresh like a daisy
        end
        opt Extra response
            Bob->>Alice: Thanks for asking
        end
    end
```

爬了很久的文,找了很多文章。

一開始以為應該是 dependency 不正確,或是 css style 沒有載入之類的。
嘗試了諸多方法依然無解。偏偏官方文檔完全沒有多加說明。

就在窮盡所有方法之後,決定去爬 mode_modules 中的 source code。
(就乖乖的 console.log 看看吧!)

幸好這個 Plugin 的 code 不長,很快就定位到了實際運作的位置

hexo-renderer-multi-markdown-it/lib/renderer/markdown-it-mermaid
md.renderer.rules.fence = (tokens, idx, options, env, self) => {
    const token = tokens[idx]
    const code = token.content.trim()
    if (token.info === 'mermaid') {
        var firstLine = code.split(/\n/)[0].trim()
        if (firstLine.match(/^graph (?:TB|BT|RL|LR|TD);?$/)) {
            firstLine = ' graph'
        } else {
            firstLine = ''
        }
        return mermaidChart(code, config, firstLine)
    }
    return defaultRenderer(tokens, idx, options, env, self)
}

經過各種的 console.log 之後,終於發現原因!

原因在於 markdown-it 在針對文章 parse token 時,將 marmaid 的 token.info 定義為 mermaid2 。因此 if condition 一定比對失敗。


知道了問題點就好辦了,接下來我只需要決定如何修理即可。

有兩種我比較喜歡的修改方式:

  1. if (token.info === 'mermaid') 改成 if (token.info === 'mermaid2') ,未來在用的時候統一使用 mermaid2
  2. if (token.info === 'mermaid') 改成 if (token.info.includes('mermaid')) ,未來只要 type 有關鍵字 mermaid 即可自動 parse 出 graph。 我也不用管是 mermaid 還是 mermaid2

最終我選擇了第二種方案。

這兩種方案其實殊途同歸,唯一的問題在於未來在重新佈局時一定要記得手動修改 node_modules 裡的這段 code.