# 轉換管線

本頁說明 `transToHTML()` 把 Markdown 轉成 HTML 時依序執行的步驟，以及這個順序為何會影響輸出。

## 函式簽名

```javascript
transToHTML(body = "", path = "", target = "_blank", standard = false)
```

| 參數 | 意義 |
|---|---|
| `body` | Markdown 原文；三個元件呼叫時都會在前後補 `\n` |
| `path` | hashtag 連結前綴，空字串時不轉換 hashtag |
| `target` | hashtag 連結的開啟方式；只有 `"_blank"` 會保留，其他值一律輸出 `_self` |
| `standard` | `true` 時略過擴充語法，見 [標準模式](/standard-mode) |

## 步驟

| 階段 | 動作 |
|---|---|
| 1. 跳脫預處理 | `\!`、`` \` ``、`\#`、`\*`、`\_`、`\~`、`\^`、`\=`、`\<`、`\>`、`\[`、`\]`、`\(`、`\)` 換成 `@excl@` 等內部佔位字串；`$` 換成 `@dollar@`；不換行空白（U+00A0）統一為一般空白 |
| 2. 語法轉換 | 依下表順序呼叫 16 個 `set*` 函式 |
| 3. 佔位符還原 | 反覆把 `{{tag-uuid}}` 換回對應 HTML，直到字串中不再有佔位符（巢狀片段需要多輪） |
| 4. 區塊空白整理 | 移除 `h1`～`h6`、`table`、`ol`、`ul`、`pre`、`blockquote`、`details`、`hr`、`label` 開頭與結尾兩側的換行 |
| 5. 跳脫還原 | 佔位字串換成 HTML entity（`&excl;`、`&num;`、`&ast;` 等）；一個或多個連續空行換成一個 `<br>` |

## 語法轉換順序

| 順序 | 函式 | 處理內容 | 為何排在這裡 |
|---|---|---|---|
| 1 | `setPreCode` | fenced code block、Mermaid | 先隔離，內部語法才不會被誤判 |
| 2 | `setCode` | 行內 code | 需在字型格式之前隔離 |
| 3 | `setMedia` | 圖片（含尺寸、對齊）、`.mp4`／`.mov` 影片 | `![]()` 與連結 `[]()` 相似，必須先比對 |
| 4 | `setMediaDefault` | 圖片、影片（無尺寸） | 標準模式的圖片處理 |
| 5 | `setLink` | 連結、YouTube／Vimeo 嵌入、自動網址、Email | |
| 6 | `setLinkStandard` | 連結、自動網址、Email（無嵌入） | 標準模式的連結處理 |
| 7 | `setFont` | 粗體、斜體、刪除線、標記、上下標 | |
| 8 | `setFontStandard` | 粗體、斜體、刪除線 | 標準模式的字型處理 |
| 9 | `setHeading` | `#` 標題、setext 標題、表格儲存格內標題 | 需在列表之前（列表項目可含 `#`） |
| 10 | `setHr` | `---`、`***` | 需在表格之前，避免 `---` 被當成表格分隔列 |
| 11 | `setTable` | 表格 | |
| 12 | `setBlockquote` | 引用、GitHub 樣式提示框 | |
| 13 | `setBlockquoteStandard` | 引用（無提示框） | 標準模式的引用處理 |
| 14 | `setList` | 有序／無序列表、checkbox | |
| 15 | `setTabCode` | 縮排程式碼區塊 | 最後處理，避免與巢狀列表衝突 |
| 16 | `setHashtag` | `#tag` 連結 | 最後一個文字轉換 |

擴充模式（`standard: false`）會同時執行標準版函式，但擴充版已先把語法換成佔位符，標準版不會再比對到同一段。

## 佔位符機制

`replaceWithUUID()` 把轉換結果的 `outerHTML` 存進 `elementUUIDMap`，原文改成 `{{tag-32位亂數}}`。後續步驟的 regex 不會比對到佔位符，所以程式碼區塊內的 `**` 不會變成粗體。

`elementUUIDMap` 是模組層級的 `Map`，從不清除；長時間連續渲染時，舊片段會一直留在記憶體中。

## 已知限制（v1.11.6）

| 現象 | 原因 |
|---|---|
| 內文中的 `$` 會輸出成 `@dollar@` | 步驟 1 把 `$` 換成 `@dollar@`，但步驟 5 的還原表誤把 `@excl@` 對到 `&dollar;`，`@dollar@` 從未被還原 |
| 原始 HTML 原樣輸出 | 管線不做 sanitize，見 [安全性](/security) |
