pdf-text-recoverlisted
Install: claude install-skill kau10082/pdf-text-recover
# pdf-text-recover — PDF 文字層確定性修復 Skill
## 定位與核心心法
修復「有文字層、但解碼壞掉」的 PDF——不是 OCR 工具,是**字型法醫**。
- **缺 ToUnicode ≠ 不可還原**:那只是缺「code→Unicode 的現成對照表」。
`/Encoding /Differences` 給出 code→glyph 名稱,內嵌字型 charset 給出字型
自己的命名,兩者常足以確定性重建全部對照。OCR/vision 是最後手段。
- **OCR 是驗證者,不是裁判**:用來替假說投票、對撞,不用來直接產出文字;
OCR 與修復結果的差異一律人工裁決,不可自動採信 OCR。
- **驗證訊號自檢**:任何檢查啟用前,先確認它會對已知錯誤回報失敗。
不會失敗的檢查等於沒有檢查(恆真式最危險——「看起來有效」,實為零資訊)。
- **只修壞的,不動好的**:有 ToUnicode 的字型(含 CJK 層)原樣保留,禁止一併重寫。
## 前置檢查(動手前必跑,依序)
```
1. 列出所有字型:哪些有 ToUnicode?哪些沒有?
2. 沒有的字型:是否有 /Encoding /Differences?內嵌字型 charset 是語意名稱
(如 A、hyphen)還是匿名編號(如 gidNNNNN)?
3. 同一 BaseFont 是否存在多個子集實例(不同 xref)?
→ 若是,禁止使用單一全域對照表(各實例編碼互不相通)。
4. 驗證訊號自檢:準備採用的每個檢查,會對已知錯誤回報失敗嗎?
5. 不在 /Differences 內的 code → 依 PDF 規範回落 base encoding
(通常 WinAnsiEncoding),不視為未解字元。
6. 建表用「整行 OCR + 位置對齊投票」,禁用單字元 OCR。
7. 必須有第二條獨立驗證路徑(結構規律/語意合理性/已知引用比對),
與 OCR 投票對撞,收斂才可下結論。
8. 輸出前:連字正規化、U+FFFD 計數必須為 0、修復腳本重跑位元級相同。
```
## 三個已知的坑(實案驗證過,錯誤假設 → 正解)
1. **「一個字型 = 一套編碼」是錯的。**
排版軟體(如 Illustrator)會把同一個 BaseFont 切成多個子集實例(實案:
同一字型 7 個實例),各帶一套 `/Differences`——同一個 code 在不同實例
代表不同字母。症狀陰險:內文 90% 正常、只有表格/標題/罕用頁亂碼,
極易被當雜訊放過。**對照表必須以「字型實例(xref)」為單位建立。**
2. **API 回傳的 "gid" 可能不是真 glyph id。**
對 Type1/CFF simple font,PyMuPDF `get_texttrace` 回傳的其實是 char code,
而 CFF charset 索引也等於 code——用兩者做一致性檢查會得到**恆真式**
(實案:回報 89.3% 完美匹配,實為零資訊)。凡驗證訊號,先餵已知錯誤
確認它會叫,才可採信(前置檢查第 4 條)。
3. **漏掉 base encoding 回落會製造假的「未解字元」。**
不在 `/Differences` 的 code 依規範回落 WinAnsiEncoding;補上這條後,
實案殘餘的 20 個 sen