Communitygithub.com

jasonadu/my-skills

英文PDF(技術書、チュートリアル、マニュアル等)を、段落ごとに日英対訳表示し、画像はBase64埋め込み、左側に折りたたみ可能な目次ナビゲーションを備えたマルチファイルHTMLリーディング版に変換します。

my-skills とは?

このスキルは、英語の技術PDFを、段落ごとに日本語と英語を対比表示するHTMLリーディング版に変換します。各章が自己完結したHTMLファイル(UTF-8、画像はBase64埋め込みでオフラインでも開ける)として生成され、左側に固定された折りたたみ可能な目次、右下の🌐ボタンで「英語のみ / 日本語のみ / 日英対訳」を切り替え可能です。元のPDFのページ番号も保持されます。主なワークフローは、ページ範囲の決定、テキスト抽出、画像抽出・圧縮・Base64変換、逐段落の翻訳、ビルドスクリプトの生成と実行、ナビゲーションリンクの連結、そして最終的なZIPパッケージ化です。コードブロックは翻訳せず原文のまま保持し、日本語段落は薄い青背景と左側の色線で区別されます。まずサンプル章を生成してユーザーの承認を得た後、残りの章を連続生成します。Claude CodeやCursorなどのAIエージェント環境で利用でき、技術書の多言語学習やレビューに非常に役立ちます。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/jasonadu/my-skills/tree/HEAD/bilingual-reading

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

日英対訳リーディング(Bilingual Reading)

概要

英語の技術PDFを、段落ごとに日英対訳表示するオフライン対応HTMLリーディング版に変換します。各章は自己完結したHTML(UTF-8、画像はBase64埋め込み、単一ファイルでオフラインでも開ける)として生成され、左側に固定された折りたたみ可能な目次、右下の🌐フローティングボタンで「英語のみ / 日本語のみ / 日英対訳」を切り替えられ、ページ遷移後も状態を保持します。

トリガーと入力

  • 入力:英語版PDF(ローカルパスまたはURL。最初にローカルにダウンロード)。
  • 出力:index.html + 前書き/後書きページ + chapter-NN.html(各章1ファイル)。最終的にZIPファイルで納品。
  • PDFにブックマーク(get_toc())がある場合、章構成はブックマークを基準とし、事前にユーザーと確認します。ユーザーが「分割しない」と確認した後、一括生成を行います。

中核ルール(厳守)

  1. 原文は段落ごとに完全翻訳し、要約や結合は行いません。
  2. 各章を1ファイルとし、章を分割しません。章内は元の本のページ順に段落を配置します。
  3. コードブロック(<pre><code>)は英語のまま保持し翻訳しません。中括弧を含むコードはf-string内に記述しません。
  4. 日本語段落は薄い青色の背景+左側に4pxの色線を付け、英語段落と区別します。リスト項目の日本語も同様のスタイルを適用します。
  5. 画像は圧縮後Base64で埋め込みます。元の本の1ページを翻訳し終えるごとに、ページ区切りマーク(page_mark(pdf_page))を1行追加し、元の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を超える場合は等比で800pxに縮小(LANCZOS);JPEG品質q≈68で再保存;Base64でassets/figN-M.txtに書き出します。1枚あたり30〜80KBに圧縮。

⑤ 原文読み取り・翻訳

  • 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数を表示すれば成功

⑨ ナビゲーション連結

前/次の章へのリンクを章番号に従って設定(ch1の前はfront-matter.html、最終章の次は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は独立して開け、目次は折りたたみ可能、アンカージャンプが正常に動作する
  • 🌐 ボタンの3状態切り替えが動作し、ページ遷移後も状態を保持する(localStorage)
  • 前後の章へのリンクが正しく連結され、最初と最後の章のボタンはグレーアウトしている
  • 全ファイルがUTF-8、ファイル名は小文字ハイフン区切り、ZIP圧縮で納品されている

関連スキル