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 不長,很快就定位到了實際運作的位置
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 一定比對失敗。
知道了問題點就好辦了,接下來我只需要決定如何修理即可。
有兩種我比較喜歡的修改方式:
- 將
if (token.info === 'mermaid')
改成if (token.info === 'mermaid2')
,未來在用的時候統一使用mermaid2
- 將
if (token.info === 'mermaid')
改成if (token.info.includes('mermaid'))
,未來只要 type 有關鍵字 mermaid 即可自動 parse 出 graph。 我也不用管是mermaid
還是mermaid2
。
最終我選擇了第二種方案。
這兩種方案其實殊途同歸,唯一的問題在於未來在重新佈局時一定要記得手動修改 node_modules
裡的這段 code.