SSkilltecabyclaudinhocode
Enviar skill
← Voltar para o catálogo

lazy-english-reader

Documentos

Use when the user wants to process a whole book file (PDF, EPUB, MOBI, DOCX, or TXT) into any of — a full Chinese translation, chapter-by-chapter intensive reading notes (第一人称中文复述 + 嵌入式精译 + 编辑解读), an Obsidian reading vault, or cross-chapter theme notes. Trigger even when the user only mentions one of these (translation, reading notes, vault, 主题归纳) — the skill treats them as three independent produ

1estrelas
Ver no GitHub ↗Autor: designserviceLicença: NOASSERTION

Lazy English Reader Skill

整书学习工作流。它把 PDF/EPUB/MOBI/DOCX/TXT 拆成三个独立可选的产物:全本翻译章节精读主题归纳,外加 Obsidian vault 集成。三个产物可单独跑也可组合跑。

本 skill 是 agent-agnostic 的。文档里出现的 ReadWriteBashAgentAskUserQuestion 等名称只是能力示例;非 Claude Code 环境映射到等价工具即可。

起点参考

三个产物

全本翻译章节精读主题归纳
目的整本中译,备查主动学习与吸收全书读完后的横向抽取
工具Calibre + Pandoc + 并行 workerextract_book.py + 笔记编排扫描章节笔记 + Obsidian 双链
产物epub / pdf / docx / md每章一份 markdown:第一人称叙事 + 嵌入式精译 + 编辑解读方法论、人物、概念等主题笔记
依赖ebook-convert pandoc仅 Python 解析库章节精读完成后的章节笔记

核心原则:single source of truth — 全本翻译和章节精读必须按同一份切分对齐

这是 skill 最重要的设计原则。 因为全本翻译和章节精读会互相 wikilink(章节精读里的"原文 → 中译"链接、全本翻译入口里的"→ 精读笔记"链接),两条线的章节划分必须 1:1 对齐——同章号、同文件名、同粒度。

权威是 .chapter_map.json,在 Phase 3 生成:

{
  "chapters": [
    {"num": 0, "filename": "第00章_引言_Foreword_Introduction",
     "anchors": []},
    {"num": 1, "filename": "第01章_谁建了金字塔_Who_Built_the_Pyramids",
     "anchors": ["序言 I", "PREFACE I", "MIKE LEFEVRE"]},
    ...
  ]
}
  • 章节精读 用 chapter_map 决定写哪些章节笔记,文件名直接取 chapters[i].filename
  • 全本翻译 的 postprocess 用 --chapter-map 参数驱动切分,文件名也用 chapters[i].filename
  • 结果:00_全本中译/第04章_耕地谋生_Working_the_Land.md01_章节精读/第04章_耕地谋生_Working_the_Land.md 同名只是不同文件夹

反 pattern(不要做)

  • ❌ 章节精读按"工种类别"切 29 篇,全本翻译按 EPUB 自带 chapter 切 14 篇——映射不上
  • ❌ 全本翻译按 markdown 标题 # ## 切——翻译过程会把 section 标题降级为段落,导致前言被堆成一个巨型文件
  • ❌ "两条线粒度不一致没关系"——必然导致 cross-link 错位

为什么 chapter_map 是权威:它在 EPUB 解出的英文纯文本上用 ALL-CAPS 启发式建立,翻译之前就确定。翻译过程对它不可见,所以不会污染。

工作流总览

Phase 0  收集参数(交互)
Phase 1  环境检查 + vault 准备
Phase 2  全本翻译启动(如选)→ 后台跑
Phase 3  章节结构提取结构 → 生成 MOC + 章节地图
Phase 4  章节循环(前台,按用户节奏)
Phase 5  主题归纳(章节精读全部完成后)
Phase 6  全本翻译完成后挂进 vault
Phase 7  最终报告

Agent 能力映射

执行时只需要:读写文件、运行 shell、搜索文件、向用户收集参数、必要时并行或后台处理 chunk。若平台没有并行 worker,全本翻译可以顺序执行,只是更慢;若没有结构化提问工具,就先让用户提供配置,再写入 .lazy-english-reader.json

{baseDir} 表示这个 skill 的安装目录——Claude Code 下通常是 ~/.claude/skills/lazy-english-reader/,其他 agent 请替换成本地实际路径。详细的能力名 → 平台工具映射见 references/agent_adapter.md

Phase 0 — 收集参数

一次问完以下参数。在 Claude Code 里可用 AskUserQuestion;其他 agent 可用自然语言追问、表单、配置文件或等价的用户输入机制。

  1. 书的路径(必填)
  2. 跑哪些产物:只做全本翻译 / 只做章节精读 / 全本翻译 + 章节精读(推荐,主题归纳会在章节精读完成后自动跑) / 只重跑主题归纳
  3. 目标语言:默认 zh
  4. Obsidian vault 路径:默认 ~/Documents/Obsidian/Vault
  5. 书的笔记目录名:按 <原书主标题>-<作者姓> 命名规则推断。规则:
    • 用原书主标题(去掉副标题如 : Researching, Interviewing, Writing,去掉冠词 The/A,但 The 是书名核心一部分时保留)
    • - 连接作者姓(last name 或中文姓)
    • 原书是英文 → 用英文(Moby-Dick-MelvilleWar-and-Peace-Tolstoy
    • 原书是中文 → 用中文(活着-余华人类简史-Harari
    • 多字标题用下划线或保留空格替成 -Brothers-Karamazov-Dostoyevsky
  6. 章节笔记体量(不卡死,给 AI 一个参考量级):
    • 单人章节(一篇前言 / 一位采访对象):1500–2500 字中文
    • 多人章节(3–6 位口述者):3000–6000 字中文
    • 巨型多人章节(10+ 位口述者,如 某口述史经典的13 人):主推 5–6 位主角,其他人在编辑解读里整合,不要硬把每个人拉成同等长度
    • 跟原书章节差不多长(用户想要逐句中文复述):选这个时跳过"嵌入式精译",整章直接当翻译做
  7. 全本翻译并行度:默认 8

把参数写入 <vault>/书库/<book_dir>/.lazy-english-reader.json 作为本次 run 的配置档。兼容旧项目时,如果只发现 .book-workflow.json,先读取旧文件,再在下次保存时迁移到新文件名。

Phase 1 — 环境检查 + vault 准备

python3 --version
which ebook-convert pandoc   # 全本翻译才需要
python3 -m pip install -r {baseDir}/requirements.txt

vault 骨架(仅 vault 不存在时建,不要覆盖用户已有内容):

<vault>/
├── CLAUDE.md            ← 用 templates/vault_CLAUDE.md(AI context file)
├── index.md             ← 用 templates/vault_index.md
├── 书库/
│   └── <book_dir>/
│       ├── CLAUDE.md    ← 用 templates/book_CLAUDE.md(AI context file)
│       ├── index.md     ← 用 templates/book_index.md
│       ├── 00_全本中译/
│       ├── 01_章节精读/
│       └── 02_主题笔记/
└── 主题/

重要:vault 根不要自动建 日记/灵感/项目/ 之类,除非用户明确要做综合性第二大脑。本 skill 默认 vault 是读书笔记专用。

Phase 2 — 全本翻译启动(后台)

如果用户选了全本翻译:

mkdir -p <vault>/书库/<book_dir>/00_全本中译/
cd <vault>/书库/<book_dir>/00_全本中译/
python3 {baseDir}/scripts/convert.py "<book_path>" --olang "<target_lang>"

之后按全本翻译的 7 步流程(与原 translate-book 一致):discover chunks → build glossary → parallel worker translate → merge meta per batch → verify → translate title → merge_and_build。

全本翻译可以后台跑。Claude Code 可用 Bash run_in_background=true;其他环境用后台 shell、任务队列或独立 worker。用户同时要全本翻译和章节精读时,先启动全本翻译再进 Phase 3——这样翻译在后台跑的同时用户可以读章节精读。

注:78+ chunks 时建议让全本翻译跑独立长任务,不要在主对话里逐个创建 worker —— 会爆 context。可考虑:

  1. 写一个独立 shell 脚本调用 claude CLI 顺序翻译,后台 nohup 起
  2. 或让一个 dispatching worker 内部并行

启动同时必须写 HANDOFF.md(防止"翻译跑完没人接")

后台翻译可能跑 30 min – 2 小时,期间主对话可能完全结束、用户关电脑、几小时后才回来。启动翻译的同一刻必须立刻做两件事:

1. 写 <vault>/书库/<book_dir>/HANDOFF.md,内容样板:

# 全本翻译后台任务

- **PID**:`<pid>`(也写到 `/tmp/<book_dir>-translate/translate.pid`)
- **日志**:`/tmp/<book_dir>-translate/translate.log`
- **temp 目录**:`/tmp/<book_dir>-translate/<book_filename>_temp/`
- **预计时间**:30 min – 2 小时
- **完成标记**:当 `<temp_dir>/_DONE` 文件出现时,翻译完成

## 翻译完成后必须运行(Phase 6)

```bash
python3 ~/.claude/skills/lazy-english-reader/scripts/postprocess_book.py \
  "<temp_dir>" \
  "<vault>/书库/<book_dir>/00_全本中译" \
  --title "<中文书名>" \
  --author "<作者>"

进度检查(任何时候都能跑)

tail -3 <log_path>
ls <temp_dir>/output_chunk*.md 2>/dev/null | wc -l   # 已完成的 chunk 数
test -f <temp_dir>/_DONE && echo "✅ 翻译完成,可以跑 postprocess" || echo "⏳ 还在跑"

**2. 让后台脚本在结束时 `touch <temp_dir>/_DONE`**——`scripts/convert.py` 或 `merge_and_build.py` 的最后一行加上 `Path(temp_dir / "_DONE").touch()`。这是主对话 / 用户检查是否完成的唯一可靠信号(不要用日志最后一行匹配,会被部分写入糊弄)。

**3. 重入检查**:每次用户重新触发 `lazy-english-reader`,主对话第一件事是检查 `HANDOFF.md` 是否存在、`_DONE` 是否出现——出现就直接跳到 Phase 6。

具体术语表 / merge / build 细节见原 [translate-book SKILL.md](https://github.com/deusyu/translate-book/blob/main/SKILL.md)。

## Phase 3 — 提取章节结构

```bash
python3 {baseDir}/scripts/extract_book.py "<book_path>" \
    -o "<vault>/书库/<book_dir>/.extracted.json"

读 JSON 输出,做章节分组:

  • PDF:优先用 PDF 自带 outline (fitz.open(...).get_toc())。如果没 outline,再用 metadata + 目录页 fallback
  • EPUB/MOBI:默认按 EPUB 自带的 chapter 划分。但要做 anthology 检测——见下
  • TXT:按章节标记或固定行数

EPUB anthology 检测(口述史 / 短篇集 / 散文集必做)

很多书 EPUB 文件里的 "chapter" 其实是编辑分组,真正的读单元更细。典型例子:

  • 某口述史经典:某 EPUB chapter 内含 13 位工人独白,每位工人才是真正的读单元
  • 散文集:一个 EPUB chapter 包含多篇散文
  • 短篇集:一个 EPUB chapter = 一本子集,下面才是单篇

检测

# Phase 3 提取完后,对 EPUB / MOBI 检查每个 chapter 的内部结构
for chapter in extracted_chapters:
    body = chapter['text']
    # 找全大写或 markdown-style 内嵌标题
    allcaps_sections = re.findall(r'^[A-Z][A-Z0-9 ,\'\-]{4,}$', body, re.MULTILINE)
    bold_sections = re.findall(r'^\*\*[A-Z][^*]+\*\*$', body, re.MULTILINE)
    if len(allcaps_sections) + len(bold_sections) >= 3:
        # 这个 EPUB chapter 是 anthology,按内部 section 重切
        flag_for_resplit(chapter)

处理:检测到 anthology 后,章节笔记单元改成 section(或 worker / 篇)而不是 EPUB chapter。文件命名仍按阅读顺序数字前缀 第NN章_<slug>.md,但"章"现在指的是真正的读单元——可能比 EPUB 自带的 chapter 多很多(某口述史经典 EPUB 有 ~9 个 chapter,重切后有 29 个真正的读单元 / section)。

这件事章节精读和全本翻译都要按同一份结构走 —— 见上面的「核心原则」。 重切后产出 .chapter_map.json章节精读用它写笔记,全本翻译 postprocess 用它切中译,两条线产出的 markdown 同名。

生成 .chapter_map.json

# Phase 3 末尾
chapter_map = {
    "chapters": [
        {"num": i, "filename": f"第{i:02d}章_{中文slug}_{english_slug}",
         "anchors": [list_of_anchor_strings_for_this_chapter]}
        for i, ch in enumerate(real_reading_units)
    ]
}
Path(book_dir / '.chapter_map.json').write_text(json.dumps(chapter_map, ensure_ascii=False, indent=2))

anchors 是什么:每章起点的「候选字符串列表」,按优先级排序——脚本对每个候选在合并 markdown 里找 H1/H2 标题,第一个找到的就是该章起始行。工人英文名 / 篇章作者英文名是最稳的锚点(翻译会保留)。section 中文标题(如 "前言" "引言")可以作为备选,但常被翻译降级为段落,作可选 anchor 但不要只放这一个。

产出 01_章节精读/00_章节地图.md

# 章节地图 — <书名>

| # | 章节 | 英文标题 | 页 | 状态 | 链接 |
|---|------|---------|----|------|------|

Como adicionar

/plugin marketplace add designservice/lazy-english-reader.skill

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Comentários · Nenhum comentário

Entre para comentar. Entrar

  • Ainda não há comentários. Seja o primeiro.