Communitygithub.com

jasonadu/my-skills

將英文 PDF 技術書籍轉換為逐段中英對照的離線 HTML 閱讀版,支援圖片 base64 內嵌與可折疊目錄導航。

my-skills 是什麼?

此技能專為處理英文技術 PDF(如手冊、教科書)而設計,將其轉換為每章一個獨立 HTML 檔案的雙語閱讀版本。每個 HTML 檔案採用 UTF-8 編碼,圖片壓縮後以 base64 內嵌,確保可離線開啟。核心功能包括:按段落完整翻譯原文、保留程式碼區塊的英文原文、中文段落以淺藍色背景和左側色條區分、每頁翻譯完成後標註原始 PDF 頁碼。技能支援 PyMuPDF 提取書籤結構以生成章節目錄,並通過固定左側欄提供可折疊的導航。用戶可透過右下角的 🌐 按鈕在「僅英文、僅中文、中英對照」三種顯示模式間循環切換,且狀態會透過 localStorage 跨頁面保持。此技能適用於 Claude Code、Cursor 等平台,工作流程包含從 PDF 提取文本與圖片、壓圖轉 base64、逐段翻譯、生成構建腳本等步驟,並提供完整的異常處理機制,例如處理 JPEG2000 或 RGBA 圖片格式、避免 f-string 中的花括號衝突等。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/jasonadu/my-skills/tree/HEAD/bilingual-reading

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

雙語閱讀(Bilingual Reading)

概述

把一本英文技術 PDF 變成逐段中英對照的離線 HTML 閱讀版:每章一個自包含 HTML(UTF-8、圖片 base64 內嵌、單檔案可離線開啟),左側固定可折疊目錄, 右下角 🌐 懸浮按鈕在「僅英文 / 僅中文 / 中英對照」間循環,翻頁後保持。

觸發與輸入

  • 輸入:英文版 PDF(本地路徑或 URL,先下載到本地)。
  • 輸出:index.html + 前置/結語頁 + chapter-NN.html(一章一檔案), 最終打包 zip 交付。
  • 若 PDF 帶書籤(get_toc()),章節結構以書籤為準並先與用戶確認, 用戶確認「不拆分」後再批量生產。

核心規則(不可違反)

  1. 原文逐段全譯,不做概要/合併。
  2. 一章一檔案,不拆章;章內按原書頁順序逐段排版。
  3. 程式碼區塊(<pre><code>)保留英文不翻譯;含花括號的程式碼不寫進 f-string。
  4. 中文段落淺藍底 + 左側 4px 色條,與英文段區分;列表項中文同規格。
  5. 圖片壓縮後 base64 內嵌;每譯完原書一頁後,單獨加一行頁碼標記 (page_mark(pdf_page))顯示原 PDF 頁碼。
  6. 檔案名稱小寫連字號(chapter-01.html、front-matter.html)。
  7. 目錄條目按書籤層級(l2/l3)生成;上下章連結串聯,首尾章置灰。

工作流程總覽

① 定頁範圍 → ② 抽文字 → ③ 抽圖片 → ④ 壓圖轉 base64
→ ⑤ 讀原文翻譯 → ⑥ 寫 build_chN.py → ⑦ 補花括號 → ⑧ 執行生成
→ ⑨ 串聯導航 → 驗證 → 交付

先做樣板章(通常 ch1)給用戶驗收樣式,確認後沉澱/複用 book_theme.py 再連續批量生產,中途無需再確認。前置/結語頁與 index.html 最後統一收尾。

步驟詳解

① 定頁範圍

輸入:全書 TOC / 章號。用 PyMuPDF 讀書籤:

import fitz
doc = fitz.open("book.pdf")
toc = doc.get_toc()          # [[level, title, page_1based], ...]

按 1-based 頁碼換算為 PyMuPDF 0-based 區間。書籤頁碼與物理頁常有偏移, 以書籤為準;向用戶列出章節劃分並確認後再開工。

② 抽文字

text = "".join(doc[p].get_text("text", sort=True) for p in range(start0, end0+1))
open("chN_raw.txt", "w", encoding="utf-8").write(text)

sort=True 保證閱讀順序,多欄不混淆。每章寫 chN_raw.txt 存原文。

③ 抽圖片

用 scripts/extract_assets.py:

python3 extract_assets.py book.pdf <start_page_1based> <end_page_1based> --out assets
  • page.get_images(full=True) 按 xref 去重 → extract_image(xref)。
  • jpx(JPEG2000)、RGBA、P 模式統一轉 RGB 再存 JPEG(瀏覽器相容)。

④ 壓圖轉 base64

同上一步一併完成(腳本內建):PIL 開啟;寬 >800px 等比縮到 800(LANCZOS); JPEG q≈68 重存;base64 寫 assets/figN-M.txt。單圖壓到 30~80KB。

⑤ 讀原文並翻譯

  • 分段 Read chN_raw.txt(每次 500~600 行),逐段翻譯,並記錄圖註對應 (書中的圖,如烏鴉圖示,轉成對應文字「筆記」)。
  • 程式碼段跳過翻譯;表格轉 HTML table;清單類內容也逐條翻譯不合併。

⑥ 寫建構腳本

build_chN.py 頂部 from book_theme import P, LI, CODE, INLINE, H, img_b64, page_mark, page, 正文寫在 f-string body 裡。f-string 內 P()/LI() 必須寫成 {P(...)} 才會求值; 程式碼區塊抽成普通字串變數 CODE_X = '''...''' 再用 + CODE_X 拼接。 完整範本見 scripts/book_theme.py 檔案頭 docstring。

⑦ 後處理補花括號

python3 scripts/fix_braces.py build_chN.py

遍歷行:以 P('/LI(' 開頭的行首補 {,向後找第一個以 ) 結尾的行尾補 }。 不處理 img_b64(/page( 呼叫行,避免誤把 } 加到末尾 page() 行。

⑧ 執行生成

python3 build_chN.py     # 腳本列印檔案名稱與 KB 數即成功

⑨ 串聯導航

prev/next 按章號填(ch1 prev=front-matter.html,末章 next=None), 首尾章用 disabled 佔位(page() 內已處理)。

收尾

  • front-matter.html、closing.html(含/不含推薦書目,先與用戶約定)、 index.html 總入口(連結全部章節)。
  • 用 python3 -m zipfile -c bilingual_reading.zip *.html 打包,交付 zip。

分支與異常處理

觸發條件處理方式
圖為 jpx / RGBA / P 模式extract_assets.py 統一 convert 為 RGB 再存 JPEG
f-string 裡含程式碼區塊花括號(JSON dict)不寫在 f-string 裡;抽成 CODE_X = '''...''' 再 + CODE_X 拼接
{<P( 誤寫sed 's/{<P(/{P(/g' 修正
批量補 } 誤加到末尾 page() 行fix_braces.py 已避免;仍出現則手動刪除該行尾多餘的 }
用戶要求「先看效果再繼續」只做樣板章,暫停等回饋
用戶要求「程式碼不翻譯」所有 <pre><code> 保留英文原文(預設即如此)
更多排查項見 references/troubleshooting.md

資源索引

  • scripts/book_theme.py — 核心共享模組:CSS/JS/頁面骨架 + P、LI、CODE、 INLINE、H、img_b64、page_mark、page 函式。改樣式只改這裡。
  • scripts/extract_assets.py — 步驟 ③④:抽圖、壓縮、轉 base64 寫 assets/。
  • scripts/fix_braces.py — 步驟 ⑦:批次補 f-string 花括號。
  • references/style-guide.md — 樣式與互動規範細節(配色、佈局、元件、驗收對照)。
  • references/troubleshooting.md — 問題排查表與可複用經驗。

驗收清單

  • 樣板章樣式經用戶確認(中文淺藍底、列表項中文同規格、頁碼標記存在)
  • 原文逐段全譯、程式碼區塊未翻譯、圖片 base64 內嵌可離線開啟
  • 每章 HTML 可獨立開啟,目錄可折疊,錨點跳轉正常
  • 🌐 按鈕三態循環,翻頁後保持(localStorage)
  • 上下章連結串聯正確,首尾章按鈕置灰
  • 全部檔案 UTF-8、檔案名稱小寫連字號,zip 打包交付

相關技能