功能全覽:自動格式化的魔法
學完你能做什麼
- 了解外掛的 8 大核心功能
- 知道哪些場景適合用這個外掛
- 明白外掛的邊界在哪裡(不能做什麼)
你現在的困境
外掛資訊
本外掛全名為 @franlol/opencode-md-table-formatter,以下簡稱"表格格式化外掛"。
AI 生成的 Markdown 表格經常是這樣的:
| 名稱 | 描述 | 狀態 |
|--- | --- | ---|
| **使用者管理** | 管理系統使用者 | ✅ 完成 |
| API | 介面文件 | 🚧 進行中 |列寬參差不齊,看著難受。手動調整?每次 AI 生成新表格都要調一遍,太累了。
什麼時候用這一招
- AI 生成了 Markdown 表格,你想讓它更整齊
- 你開啟了 OpenCode 的隱藏模式(Concealment Mode),表格對齊總是出問題
- 你懶得手動調整表格列寬
核心思路
這個外掛的工作原理很簡單:
AI 生成文字 → 外掛檢測表格 → 驗證結構 → 格式化 → 返回美化後的文字它掛載在 OpenCode 的 experimental.text.complete 鉤子上,AI 每次生成完文字,外掛就自動處理。你不需要手動觸發,全程無感。
8 大核心功能
1. 自動表格格式化
外掛會自動檢測 AI 生成文字中的 Markdown 表格,統一列寬,讓表格整齊美觀。
格式化前:
| 名稱 | 描述 | 狀態 |
|--- | --- | ---|
| **使用者管理** | 管理系統使用者 | ✅ 完成 |
| API | 介面文件 | 🚧 進行中 |格式化後:
| 名稱 | 描述 | 狀態 |
|--- | --- | ---|
| **使用者管理** | 管理系統使用者 | ✅ 完成 |
| API | 介面文件 | 🚧 進行中 |觸發條件
外掛掛載在 experimental.text.complete 鉤子上,AI 生成文字完成後自動觸發,無需手動操作。
2. 隱藏模式相容
OpenCode 預設開啟隱藏模式(Concealment Mode),會隱藏 Markdown 符號(如 **、*、~~)。
普通的表格格式化工具不考慮這一點,計算寬度時會把 ** 也算進去,導致對齊錯位。
這個外掛專門為隱藏模式最佳化:
- 計算寬度時,剝離
**粗體**、*斜體*、~~刪除線~~等符號 - 輸出時保留原始 Markdown 語法
- 最終效果:隱藏模式下表格完美對齊
技術細節:寬度計算邏輯
// 剝離 Markdown 符號(用於寬度計算)
visualText = visualText
.replace(/\*\*\*(.+?)\*\*\*/g, "$1") // ***粗斜體*** → 文字
.replace(/\*\*(.+?)\*\*/g, "$1") // **粗體** → 粗體
.replace(/\*(.+?)\*/g, "$1") // *斜體* → 斜體
.replace(/~~(.+?)~~/g, "$1") // ~~刪除線~~ → 刪除線原始碼位置:index.ts:181-185
3. 對齊支援
支援 Markdown 表格的三種對齊方式:
| 語法 | 對齊方式 | 效果 |
|---|---|---|
--- 或 :--- | 左對齊 | 文字靠左(兩種語法效果相同) |
:---: | 居中 | 文字居中 |
---: | 右對齊 | 文字靠右 |
範例:
| 左對齊 | 居中 | 右對齊 |
|--- | --- | ---|
| 文字 | 文字 | 文字 |格式化後,每列會按指定方式對齊,分隔行會根據對齊方式重新生成。
4. 巢狀 Markdown 處理
表格儲存格裡可能有巢狀的 Markdown 語法,比如 ***粗斜體***。
外掛使用多輪正則演算法,從外到內逐層剝離:
***粗斜體*** → **粗斜體** → *粗斜體* → 粗斜體這樣即使巢狀多層,寬度計算也是準確的。
5. 程式碼保護
行內程式碼(用反引號包裹)裡的 Markdown 符號應該保持原樣,不被剝離。
比如 `**bold**`,使用者看到的就是 **bold** 這 8 個字元,而不是 bold 這 4 個字元。
外掛會先提取程式碼內容,剝離其他部分的 Markdown 符號後,再把程式碼內容放回去。
技術細節:程式碼保護邏輯
// 第 1 步:提取並保護行內程式碼
const codeBlocks: string[] = []
let textWithPlaceholders = text.replace(/`(.+?)`/g, (match, content) => {
codeBlocks.push(content)
return `\x00CODE${codeBlocks.length - 1}\x00`
})
// 第 2 步:剝離非程式碼部分的 Markdown 符號
// ...
// 第 3 步:恢復行內程式碼內容
visualText = visualText.replace(/\x00CODE(\d+)\x00/g, (match, index) => {
return codeBlocks[parseInt(index)]
})原始碼位置:index.ts:168-193
6. 邊界情況處理
外掛能正確處理各種邊界情況:
| 場景 | 處理方式 |
|---|---|
| Emoji 表情 | 使用 Bun.stringWidth 正確計算顯示寬度 |
| Unicode 字元 | 中文、日文等寬字元正確對齊 |
| 空儲存格 | 填充空格到最小寬度(3 字元) |
| 超長內容 | 正常處理,不截斷 |
7. 靜默操作
外掛在後台靜默執行:
- 無日誌輸出:不會在控制台列印任何資訊
- 錯誤不中斷:即使格式化失敗,也不會影響 AI 的正常輸出
如果格式化過程中出錯,外掛會保留原文,並在末尾新增一條 HTML 註解:
<!-- table formatting failed: [錯誤資訊] -->8. 驗證回饋
外掛會驗證表格結構是否有效。無效的表格不會被格式化,而是保留原樣,並新增提示:
<!-- table not formatted: invalid structure -->有效表格的要求:
- 至少 2 行(含分隔行)
- 所有行的列數一致
- 必須有分隔行(格式:
|---|---|)
外掛的邊界
不支援的場景
- HTML 表格:只處理 Markdown 管線表格(
| ... |) - 多行儲存格:含
<br>標籤的儲存格不支援 - 無分隔行表格:必須有
|---|---|分隔行 - 無表頭表格:必須有表頭行
檢查點
完成本課後,你應該能回答:
- [ ] 外掛是如何自動觸發的?(答:
experimental.text.complete鉤子) - [ ] 為什麼需要"隱藏模式相容"?(答:隱藏模式會隱藏 Markdown 符號,影響寬度計算)
- [ ] 行內程式碼裡的 Markdown 符號會被剝離嗎?(答:不會,程式碼內的 Markdown 符號會被完整保留)
- [ ] 無效表格會怎麼處理?(答:保留原樣,新增錯誤註解)
本課小結
| 功能 | 說明 |
|---|---|
| 自動格式化 | AI 生成完文字自動觸發,無需手動操作 |
| 隱藏模式相容 | 正確計算 Markdown 符號隱藏後的顯示寬度 |
| 對齊支援 | 左對齊、居中、右對齊 |
| 巢狀 Markdown | 多輪正則剝離,支援巢狀語法 |
| 程式碼保護 | 行內程式碼中的符號保持原樣 |
| 邊界情況 | Emoji、Unicode、空儲存格、超長內容 |
| 靜默操作 | 無日無日誌,錯誤不中斷 |
| 驗證回饋 | 無效表格新增錯誤註解 |
下一課預告
下一課我們深入 隱藏模式原理。
你會學到:
- OpenCode 隱藏模式的工作原理
- 外掛如何正確計算顯示寬度
Bun.stringWidth的作用
附錄:原始碼參考
點擊展開查看原始碼位置
更新時間:2026-01-26
| 功能 | 檔案路徑 | 行號 |
|---|---|---|
| 外掛入口 | index.ts | 9-23 |
| 表格檢測 | index.ts | 58-61 |
| 表格驗證 | index.ts | 70-88 |
| 寬度計算(隱藏模式) | index.ts | 161-196 |
| 對齊方式解析 | index.ts | 141-149 |
| 程式碼保護 | index.ts | 168-173 |
關鍵常量:
colWidths[col] = 3:列最小寬度為 3 字元(index.ts:115)
關鍵函數:
formatMarkdownTables():主處理函數,格式化文字中的所有表格getStringWidth():計算字串顯示顯示寬度,剝離 Markdown 符號isValidTable():驗證表格結構是否有效