Mermaid 圖表
建構器透過兩階段處理支援 Mermaid 圖表:remark 外掛在建構時準備標記,客戶端渲染器則產生 SVG。
Remark 外掛
Section titled “Remark 外掛”remark-mermaid 外掛(由 docs-theme npm 套件提供)在 Astro 建構期間執行。它使用 unist-util-visit 尋找 lang === 'mermaid' 的圍欄程式碼區塊,並將其替換為 HTML:
visit(tree, 'code', (node, index, parent) => { if (node.lang !== 'mermaid' || index === undefined || !parent) return;
const escaped = node.value .replace(/&/g, '&') .replace(/</g, '<') .replace(/>/g, '>') .replace(/"/g, '"');
parent.children[index] = { type: 'html', value: `<div class="mermaid-container" data-mermaid-src="${escaped}"> <pre class="mermaid">${node.value}</pre> </div>`, };});關鍵細節:
| 方面 | 值 |
|---|---|
| 匹配的節點類型 | lang === 'mermaid' 的 code 節點 |
| HTML 實體跳脫 | &、<、>、" — 防止 data-mermaid-src 中的屬性注入 |
| 輸出結構 | <div class="mermaid-container"> 搭配 data-mermaid-src 屬性存放跳脫後的原始碼 |
| 備用內容 | <pre class="mermaid"> 搭配原始原始碼(在 JS 渲染前可見) |
src/scripts/placeholder-dom.ts 中的 renderMermaidDiagrams() 函式負責在瀏覽器中產生 SVG。
Mermaid 匯入
Section titled “Mermaid 匯入”Mermaid 從 CDN 按需載入——並非打包在內:
const mermaid = (await import('https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs')).default;mermaid.initialize({ startOnLoad: false, theme: 'default', securityLevel: 'loose', themeVariables: { primaryColor: '#ffffff', primaryBorderColor: '#cccccc', background: '#ffffff', mainBkg: '#ffffff', secondBkg: '#ffffff', tertiaryColor: '#ffffff', },});startOnLoad: false 防止 Mermaid 自動掃描頁面。securityLevel: 'loose' 允許圖表中的點擊事件和連結。
對於每個 .mermaid-container 元素:
- 從
data-mermaid-src讀取原始圖表原始碼 - 對原始碼執行佔位符替換(見下方)
- 清除容器並移除任何
data-processed屬性 - 呼叫
mermaid.render()使用隨機 ID 產生 SVG - 在渲染的
<svg>元素上設定backgroundColor: 'white'
圖表中的佔位符替換
Section titled “圖表中的佔位符替換”在渲染之前,圖表原始碼會通過 DOM 遍歷器使用的相同 substituteText() 函式進行處理(遍歷器機制請參閱佔位符系統):
const template = container.getAttribute('data-mermaid-src') || '';const substituted = substituteText(template, values);這意味著像 xCUSTOMER_ASNx 這樣的佔位符符記可以在 Mermaid 圖表定義中使用。當使用者在表單中更改值時,placeholder-change 事件會觸發所有圖表使用更新後的值進行完整重新渲染。
如果 mermaid.render() 拋出錯誤(例如,因為圖表原始碼中的語法錯誤),catch 區塊會直接在容器中顯示錯誤:
} catch (e) { container.textContent = `Diagram error: ${e}`;}這使得撰寫錯誤可見,而不會破壞頁面的其餘部分。
圖表在兩種情況下會重新渲染:
| 觸發條件 | 事件 | 發生什麼 |
|---|---|---|
| 佔位符值變更 | placeholder-change | handleChange() 使用新值呼叫 renderMermaidDiagrams() |
| Astro 頁面導航 | astro:page-load | init() 為新頁面呼叫 renderMermaidDiagrams() |
使用 mermaid 語言標籤撰寫標準的圍欄程式碼區塊:
```mermaidflowchart LR A[Customer ASN: xCUSTOMER_ASNx] --> B[F5 XC ASN: xF5_XC_ASNx]```remark 外掛在建構時將其轉換為容器 div。客戶端會將其渲染為替換了佔位符值的 SVG。