Skip to content

功能全覽:自動格式化的魔法

學完你能做什麼

  • 了解外掛的 8 大核心功能
  • 知道哪些場景適合用這個外掛
  • 明白外掛的邊界在哪裡(不能做什麼)

你現在的困境

外掛資訊

本外掛全名為 @franlol/opencode-md-table-formatter,以下簡稱"表格格式化外掛"。

AI 生成的 Markdown 表格經常是這樣的:

markdown
| 名稱 | 描述 | 狀態 |
|--- | --- | ---|
| **使用者管理** | 管理系統使用者 | ✅ 完成 |
| API | 介面文件 | 🚧 進行中 |

列寬參差不齊,看著難受。手動調整?每次 AI 生成新表格都要調一遍,太累了。

什麼時候用這一招

  • AI 生成了 Markdown 表格,你想讓它更整齊
  • 你開啟了 OpenCode 的隱藏模式(Concealment Mode),表格對齊總是出問題
  • 你懶得手動調整表格列寬

核心思路

這個外掛的工作原理很簡單:

AI 生成文字 → 外掛檢測表格 → 驗證結構 → 格式化 → 返回美化後的文字

它掛載在 OpenCode 的 experimental.text.complete 鉤子上,AI 每次生成完文字,外掛就自動處理。你不需要手動觸發,全程無感。

8 大核心功能

1. 自動表格格式化

外掛會自動檢測 AI 生成文字中的 Markdown 表格,統一列寬,讓表格整齊美觀。

格式化前

markdown
| 名稱 | 描述 | 狀態 |
|--- | --- | ---|
| **使用者管理** | 管理系統使用者 | ✅ 完成 |
| API | 介面文件 | 🚧 進行中 |

格式化後

markdown
| 名稱         | 描述         | 狀態       |
|--- | --- | ---|
| **使用者管理** | 管理系統使用者 | ✅ 完成    |
| API          | 介面文件     | 🚧 進行中  |

觸發條件

外掛掛載在 experimental.text.complete 鉤子上,AI 生成文字完成後自動觸發,無需手動操作。

2. 隱藏模式相容

OpenCode 預設開啟隱藏模式(Concealment Mode),會隱藏 Markdown 符號(如 ***~~)。

普通的表格格式化工具不考慮這一點,計算寬度時會把 ** 也算進去,導致對齊錯位。

這個外掛專門為隱藏模式最佳化:

  • 計算寬度時,剝離 **粗體***斜體*~~刪除線~~ 等符號
  • 輸出時保留原始 Markdown 語法
  • 最終效果:隱藏模式下表格完美對齊
技術細節:寬度計算邏輯
typescript
// 剝離 Markdown 符號(用於寬度計算)
visualText = visualText
  .replace(/\*\*\*(.+?)\*\*\*/g, "$1") // ***粗斜體*** → 文字
  .replace(/\*\*(.+?)\*\*/g, "$1")     // **粗體** → 粗體
  .replace(/\*(.+?)\*/g, "$1")         // *斜體* → 斜體
  .replace(/~~(.+?)~~/g, "$1")         // ~~刪除線~~ → 刪除線

原始碼位置:index.ts:181-185

3. 對齊支援

支援 Markdown 表格的三種對齊方式:

語法對齊方式效果
---:---左對齊文字靠左(兩種語法效果相同)
:---:居中文字居中
---:右對齊文字靠右

範例

markdown
| 左對齊 | 居中 | 右對齊 |
|--- | --- | ---|
| 文字 | 文字 | 文字 |

格式化後,每列會按指定方式對齊,分隔行會根據對齊方式重新生成。

4. 巢狀 Markdown 處理

表格儲存格裡可能有巢狀的 Markdown 語法,比如 ***粗斜體***

外掛使用多輪正則演算法,從外到內逐層剝離:

***粗斜體*** → **粗斜體** → *粗斜體* → 粗斜體

這樣即使巢狀多層,寬度計算也是準確的。

5. 程式碼保護

行內程式碼(用反引號包裹)裡的 Markdown 符號應該保持原樣,不被剝離。

比如 `**bold**`,使用者看到的就是 **bold** 這 8 個字元,而不是 bold 這 4 個字元。

外掛會先提取程式碼內容,剝離其他部分的 Markdown 符號後,再把程式碼內容放回去。

技術細節:程式碼保護邏輯
typescript
// 第 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 註解:

markdown
<!-- table formatting failed: [錯誤資訊] -->

8. 驗證回饋

外掛會驗證表格結構是否有效。無效的表格不會被格式化,而是保留原樣,並新增提示:

markdown
<!-- 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.ts9-23
表格檢測index.ts58-61
表格驗證index.ts70-88
寬度計算(隱藏模式)index.ts161-196
對齊方式解析index.ts141-149
程式碼保護index.ts168-173

關鍵常量

  • colWidths[col] = 3:列最小寬度為 3 字元(index.ts:115

關鍵函數

  • formatMarkdownTables():主處理函數,格式化文字中的所有表格
  • getStringWidth():計算字串顯示顯示寬度,剝離 Markdown 符號
  • isValidTable():驗證表格結構是否有效