Mermaid 渲染陷阱

Obsidian / GitHub / 任何 Markdown 渲染器內嵌的 Mermaid,對 node label 的特殊字元特別敏感。Vincent vault 2026-05-02 在建 Boris Cherny 工作流地圖 時連續踩了三個坑,把規則記下永久避免。

🔥 黃金法則

node label 第一個字元(或前幾個字元)只要看起來像「Markdown 語法符號」就會出事。

最安全的做法:node label 含任何特殊字元時一律加引號。

✅ NodeA["1) 任何文字 / 含 / @ # 等"]
✅ NodeB["/loop 5m"]
✅ NodeC["3. 含 backslash \ 也安全"]

❌ NodeA[1) 任何文字]              ← 1) 被當 ordered list
❌ NodeA[1. 任何文字]              ← 1. 被當 ordered list
❌ NodeB[/loop 5m]                ← [/ 被當 parallelogram 起手
❌ NodeC[* bullet 內容]            ← * 被當 unordered list

坑 #1:數字. 開頭被當 Ordered List

觸發

flowchart LR
    I1[1. 第一步]
    I2[2. 第二步]

錯誤訊息

Unsupported markdown: list

整個 node 被替換成「Unsupported markdown: list」字樣,但 mermaid 引擎不會 abort——其他 node 還是會渲染。容易誤以為只是某個 node 的 bug

原因

Mermaid 內建支援部分 Markdown(粗體、斜體、清單),node label 看到 1. 2. 等開頭會試圖解析成 ordered list 但失敗(label 容器太小),於是顯示 “Unsupported markdown: list”。

修法

方法範例
✅ 加引號I1["1. 第一步"]
✅ 用括號I1["1) 第一步"] ← 但只有引號內才安全
✅ 用全形編號I1[① 第一步]
✅ 改文字I1[Step 1: 第一步]
❌ 換句點I1[1) 第一步]1) 也會被當 list!

重點

1)1. 等同——都觸發 ordered list 解析。連 1 .(中間有空格)也可能觸發。不是換掉句點就沒事,要加引號


坑 #2:/ 開頭被當 Parallelogram Shape

觸發

flowchart LR
    PR[/commit-push-pr]
    LP[/loop /schedule]

錯誤訊息(不一定報錯)

可能渲染成奇怪的平行四邊形 shape,或解析失敗顯示 syntax error。

原因

Mermaid 的 node shape 語法:

語法shape
[text]矩形
(text)圓角
((text))圓形
[/text/]平行四邊形(右斜)
[\text\]平行四邊形(左斜)
[/text\] / [\text/]梯形

[/text] 開頭被當成 parallelogram 起手,期待 /] 結尾,找不到就出錯。

修法

✅ PR["/commit-push-pr"]           ← 加引號最安全
✅ PR[/commit-push-pr]         ← HTML entity
✅ PR("/commit-push-pr")           ← 用圓角 shape 避開

坑 #3:Parse error: Expecting SQE, got PE

觸發

flowchart LR
    A[1) text]    ← 同坑 #1,但錯誤訊息不同(看版本)

錯誤訊息

Error parsing Mermaid diagram!
Parse error on line N:
... A[1) ...
-----^
Expecting 'SQE', 'TAGEND', 'UNICODE_TEXT', 'TEXT', 'TAGSTART', got 'PE'

解碼

縮寫意思
SQESquare End — ]
PEParen End — )
TAGENDHTML tag 結束 — >
TAGSTARTHTML tag 開始 — <
UNICODE_TEXT任意 Unicode 文字

→ Parser 在 [ 之後期待文字、HTML tag 或 ],結果遇到 )因為 1) 被當成 list 結尾的 )

修法

跟坑 #1 一樣:加引號


其他可能的坑(注意但不一定踩過)

開頭符號要小心

符號風險
1. 1) 1*ordered list
- * + unordered list
> blockquote
# ## heading
| (pipe)在 edge label 內會跟 |text| 衝突
/parallelogram shape
\trapezoid shape
(round shape
[nested square
<HTML tag start

→ 看到任何上面的符號開頭,直接加引號

<br/> 是少數安全例外

✅ A[第一行<br/>第二行]              ← <br/> 在 label 內安全
✅ A["第一行<br/>第二行"]             ← 加引號也行(建議)

但其他 HTML tag(<b><i><span> 等)行為不一致——某些版本當 HTML render,某些當 text。保險起見也加引號

subgraph 標題

✅ subgraph imm["立刻可做"]            ← 引號正確
✅ subgraph imm[立刻可做]              ← 純中文也 OK
❌ subgraph imm[1. 第一階段]           ← 一樣會踩坑 #1

Edge label

A -->|"含 / 跟 :"| B                  ← edge label 也建議引號

Vincent vault 在 Boris Cherny 工作流地圖 的踩坑紀錄

時間node 範例修法
2026-05-02 第一輪坑 #2PR[/commit-push-pr]PR["/commit-push-pr"]
2026-05-02 第二輪坑 #1I1[1. 設 env var]1) (錯! 還是 list)
2026-05-02 第三輪坑 #1 + #3I1[1) 設 env var]I1["1) 設 env var"] ← 真的對了

→ **三輪才修對的根本原因:以為換符號就好,沒理解問題是「mermaid 在 label 開頭做 markdown 解析」。**正解只有一個:加引號


SOP — 寫 Mermaid 的人類規則

  1. node label 一律用引號A["text"] 永遠對;A[text] 只有純中英文時才對
  2. subgraph title 一律用引號subgraph X["title"]
  3. edge label 含特殊字元時加引號A -->|"text"| B
  4. ✅ 寫完每張 mermaid 在 Obsidian 預覽渲染一次,看到「Unsupported markdown」/「Parse error」立即修
  5. ❌ 不要相信「換個符號就好」直覺——看到 markdown-like 開頭,直接加引號

wiki-lint 的 future enhancement 建議

wiki-lint 可以加一個 mermaid 健檢:

# Pseudocode
for mermaid_block in vault:
    for node_label in extract_node_labels(block):
        if node_label.startswith(('1.', '1)', '/', '\\', '* ', '- ', '+ ', '> ', '# ')):
            if not (node_label.startswith('"') and node_label.endswith('"')):
                warn(f"node label may trigger mermaid markdown parsing: {node_label}")

→ 提早抓出,不用渲染才發現。


相關概念

強連結

推斷連結(LLM 認為相關,待確認)

  • wiki-compile ?? — 編譯 wiki 時若產生 mermaid 圖也要套這規則
  • wiki-repair ?? — 可加 auto-quote 修補規則

深入閱讀

← 回到 wiki