wmy2981/skills

scanned-pdf-to-epub

>- 将扫描版 PDF 书籍(? 识别由 Claude 视觉子代理(Sonnet 模型)逐页读图完成,CLI 脚本负责 拆页渲染、标记检查、批次合并、按章节切分打? 扫描书转 epub / 把这本书做成 epub / 扫描件转可读格式 / 图片 PDF 生成目录"时,务? 即使对方没有明确说出"skill"或"epub"字样。

First seen Aug 8, 2026

Installation

$ npx skills add wmy2981/skills --skill scanned-pdf-to-epub

Summary

将扫描版 PDF 书籍(内页全为图片、无文字层)转换为带完整导航目录、可点击跳转的可读 EPUB。 识别由 Claude 视觉子代理(Sonnet 模型)逐页读图完成,CLI 脚本负责 拆页渲染、标记检查、批次合并、按章节切分打包、EPUB 校验。当用户提到"扫描 PDF 转电子书 / PDF 转 EPUB /…

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from wmy2981/skills · top by installs.

npx skills add wmy2981/skills

Browse all from wmy2981/skills

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 1
License LICENSE
Default branch main
Open issues 3
Status Active

Skill metadata

Parsed from SKILL.md frontmatter.

More metadata
skill_version
1.0.3

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 14,876 B
  • docs SUMMARY.md 567 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 36 installs

SKILL.md

PDF → EPUB(扫描书转换工作流)

何时使用

  • 输入是一本 PDF 书籍,内页全是扫描图片、没有文字层(用 PyMuPDF 提取不出文本,或全是空白)。
  • 目标产物是一本干净、带完整导航目录、目录可点击跳转的 EPUB。
  • 中间产物可以是 Markdown。
  • 本 skill 面向通用流程:任何页数的纯文字中文书籍,不针对某一本书特化。

本 skill 不适用于:有文字层的数字原生 PDF(直接用提取工具即可);漫画书(图为主,本流程去除插图)。

核心原则:职责边界

环节 承担方 理由
拆页渲染、标记检查、批次合并、分章、打包、校验 CLI 脚本scripts/ 确定性、可复现、可重跑
识图、错别字校对、版权页判定、锚点转标题 Agent(Claude 子代理 / 主代理) 需要视觉与语义判断,不写脚本
全流程编排与规范 SKILL.md 承载流程与严谨规则

模型约定:识图子代理必须使用 Sonnet 模型;不要使用外部 API。主代理校对由当前会话模型完成。

不要为识图或校对环节编写脚本——那部分是 Agent 的灵活任务,脚本只覆盖五个确定性命令:extractcheck-markersmerge-batchesmd-to-epubverify

工作流总览

1. extract (CLI)        PDF → 每页一张图 page_0001.png...
2. 子代理识图 (Agent)    每子代理一批 → batch_001.md(纯文本行 + 锚点)
3. 批次标记检查 (CLI)    check-markers 检查各 batch 标记 → 有误重跑、无误通过
4. 批次合并 (CLI)        merge-batches 按序合并 → draft.md
5. 草稿标记复查 (CLI)    check-markers 复查 draft.md 标记
6. 主代理校对 (Agent)    修正错别字(不改原文)→ 锚点转 h 标题 → book.md
7. md-to-epub (CLI)     book.md → 按 h 标题切分章节 → 生成导航目录 → book.epub
8. verify (CLI)          校验 EPUB 结构、目录跳转、无残留

依赖

  • Python 3.10+,pymupdf(渲染 PDF 页为图,import fitzimport pymupdf
  • pandoc(Markdown → EPUB,含导航目录)。安装顺序:

1. 系统 CLI pandoc(winget install JohnMacFarlane.Pandoc / brew install pandoc) 2. 或 pip install pypandoc-binary(捆绑 pandoc 二进制,无需单独安装) 3. 兜底:pip install ebooklib(纯 Python 打包,目录同样生成)

  • 脚本自动探测上述任一可用路径。

启动前先检查:python scripts/extract.py --check 会报告缺哪些依赖。

工作目录布局

在临时目录内新建一个项目文件夹 book/,全部产物放其中:

book/
├── pages/            # 1. 拆页图片 page_0001.png...
├── raws/             # 2. 子代理识图输出 batch_001.md...
├── draft.md          # 3-5. 批次合并 + 标记检查后的草稿(仍含 PAGE/CH/__ 标记)
├── book.md           # 6. 校对优化后的全文(干净层级化 Markdown)
└── book.epub         # 7. 最终产物

1. extract:拆页渲染(CLI)

python scripts/extract.py <input.pdf> -o book/pages [--dpi 300]
  • 每页渲染为一张 PNG,文件名按原书页码顺序 page0001.pngpage0002.png……(从 1 起连续编号,忽略 PDF 内部无关页面偏移)。
  • 默认 300 DPI,足以支撑中文小字识别;输出时打印总页数,供调度子代理参考。
  • 结束后核对 pages/ 图片数量 == PDF 页数。

2. 子代理识图(Sonnet 子代理):逐页转纯文本行 + 锚点

分派规则

  • 模型:本阶段识图一律使用 Sonnet 模型子代理(Sonnet 具备本环境识图能力),严禁使用外部 API 或其他模型;主代理校对由当前会话模型完成。
  • 每个子代理负责连续 10 张图片:子代理 #1 负责 page0001page0010,#2 负责 page0011page0020……批次严格按页码顺序分派。
  • 批次边界:第 k 个子代理负责 page{(k-1)10+1:04d}page{k10:04d};最后一批不足 10 页则只处理实际存在的页。
  • 并发由主代理自行决定:一次可同时调度多个子代理,各自负责不同批次,批次间不重叠、顺序不乱。并发数与批次划分由主代理按页数规模、成本与运行环境权衡,不设固定上限。
  • 每子代理一个文件:子代理把自己负责的整批页内容写入同一个文件 batch{k:03d}.md(命名规范见 references/subagentprompt.md),文件内每页(含空白页、无正文页)均以 <!-- PAGE XXXX --> 注释定位(空页只写标记不写内容)。失败重跑以批次为单位。

子代理提示词模板(引用 references/subagent_prompt.md)

调度每个子代理时,直接使用 references/subagentprompt.md 中的提示词模板:把 {N}{起始页}{结束页}{批次序号}{pagesdir}{raws_dir} 替换为实际值后作为子代理任务传入(识别必须用 Sonnet 模型)。该文件是提示词的唯一正式来源,本小节不再内嵌模板正文。 调度子代理时,仅可替换模板中 {占位符} 标记的内容,模板其余部分必须原样保留,禁止增删或修改。

子代理严格输出约束(要点)

子代理的唯一输出规范以 references/subagent_prompt.md 的提示词模板为准,要点归纳如下;完整条款见模板与下方「锚点规范」「内容保留 / 去除规则」:

  • 输出纯文本行:原文一个自然段 = Markdown 一行,段落间空行;不使用列表、表格、代码块等结构标记。
  • 跨页段落:一个自然段被分页截断时,上一页行尾与下一页行首各写 __ 连接标记(两部分间不放空行),校对时合并为一段。
  • 禁止:任何解释、说明、思考过程、结论、"这是第 X 页"之类元评论;禁止页眉页脚文字;禁止对图片的描述性旁白。
  • 每子代理一个文件 batch{k:03d}.md严格按 pageXXXX.png 文件名的数字顺序逐页读取,整批页内容顺序写入同一文件;每页(含空页)以 <!-- PAGE XXXX --> 定位(XXXX 严格等于该图片文件名的页码:读 page_0005.png<!-- PAGE 0005 -->)。
  • 遇到章节标题时,插入层级前缀式锚点(见下),正文段落里不重复标题文字;层级如实反映原书结构,不主观合并或拆分。
  • 保留:前言、后记(标题用锚点标注层级)、各章节章号/大标题、正文段落;原书目录页照常识别。
  • 去除:页眉、页脚、插图、二维码/条形码/水印等无关标识。
  • 遇到疑似版权页(整页版权声明模式:ISBN / 版权年份 / 出版信息 / 印次号)时,整页内容以单个锚点 <!-- COPYRIGHT_CANDIDATE --> 起始,交由主代理终审。
  • 完成后汇报:顺利则只返回一句话说明已写入的文件名;遇阻断或不确定点(图片无法读取、内容严重残缺、规则无法判断)如实反馈主代理,不自行臆断、跳过或编造内容。

锚点规范(层级前缀式)

每遇到一个标题,插入一行注释,CH 后的数字表示层级:

<!-- CH1: 第二部 江湖 -->

<!-- CH2: 第1章 初入师门 -->

<!-- CH3: 第一节 拜师 -->
  • CH1 = 全书最高级标题:有部/卷则部/卷为 CH1、章为 CH2、节为 CH3;无部/卷的书,章直接为 CH1(保证顶级章节转成 h1,pandoc 才能按章切分,否则全书挤成单一文件)。
  • 标题文本只出现在锚点中,正文段落不重复标题。
  • 锚点为独立注释行,前后以空行与正文隔开;锚点之间是正文(段落,一个自然段 = 一行)。
  • 规则:遇到一个新标题就按其层级插入对应锚点;层级如实反映原书结构,不要主观合并或拆分。

内容保留 / 去除规则

内容 处理
✅ 保留 前言、后记 作为正文保留(标题用锚点标注层级)
✅ 保留 各章节章号/大标题 插入锚点,作为分章依据
✅ 保留 正文段落 每段一行,段落间空行
❌ 去除 页眉、页脚 直接丢弃,不写入
❌ 去除 插图(含示意图、照片) 直接丢弃,不写入(本 skill 面向纯文字书籍)
❌ 去除 版权页(整页版权声明) <!-- COPYRIGHT_CANDIDATE --> 标记,主代理终审
❌ 去除 无关标识(二维码、条形码、水印、页码) 直接丢弃
⚠️ 特殊 原书目录页 子代理照常识别正文,但主代理校对阶段会据此提取章节结构并整体丢弃(不进入最终 EPUB,避免与导航目录重复)

3. 批次标记检查:check-markers(CLI)

全部批次子代理完成后,用脚本逐个检查 raws/ 下的 batch_XXX.md

python scripts/check_markers.py book/raws/*.md

脚本输出每个文件的标记清单与问题:

  • PAGE:列出全部页码;检查顺序递增、无缺号、无重复。
  • CH:列出全部 <!-- CHn: 标题 --> 及行号;检查层级是否跳级(作警告)。
  • :列出全部行尾/行首 及行号;检查跨页切口是否成对。

判定:无问题 → 通过;有问题(PAGE 缺失/乱序、__ 不成对)→ 单独重派该批次子代理,重跑后复检,直至通过;不重跑全书。若同一批次多次失败,可临时缩小该批次页数(如拆为 5 页)再试,或暂停交由用户处理。

4. 批次合并:merge-batches(CLI)

python scripts/merge_batches.py book/raws -o book/draft.md

按批次序号顺序合并所有 batch_XXX.mddraft.md保留各批内的 PAGE/CH/ 标记(供校对定位、跨批次 切口衔接);合并时校验批次序号连续(1..K 无缺)。合并后规范化行距:任意两个相邻非空行之间恰好 1 个空行(跨页 __ 切口连接的行除外,保持切口两部分紧密相连),无连续空行堆积、无缺失空行。

5. 草稿标记复查:check-markers(CLI)

python scripts/check_markers.py book/draft.md

合并后对整本草稿复查一次标记:全书画页码连续(无跨批次缺页)、__ 切口在批次边界正确成对、CH 层级全本连续。复查通过后再进入校对。

6. 主代理校对:错别字修正 + 转标题(Agent)

这是 Agent 的灵活任务,不写脚本。基于 draft.md 执行:

  1. 分块通读:按批次分批通读 draft.md,每块在上下文内完整读完。页数多也不爆上下文。主要修正识别出来的错别字,不改变原文、不增删句子。
  2. 标记转换

- 删除 <!-- PAGE XXXX --> 页定位注释——空白页/无意义页仅含该注释,删除后自然无痕。 - 去掉跨页行尾/行首的 __ 连接标记并把两部分合成为一段。 - 将 <!-- CH1 --> / CH2 / CH3 / CH4 分别转为 # / ## / ### / #### Markdown 标题(以此类推);删除已无用的锚点注释与 COPYRIGHT_CANDIDATE 标记。

  1. 目录页处理:原书目录页仅用于核对章节标题与层级,核对完毕后从正文中移除
  2. 版权页终审:逐个确认 COPYRIGHT_CANDIDATE 标记的页——确为版权声明则删除;误标(如书名页、献辞页)则保留为正文。
  3. 最终检查:全文无空锚点、无连续空行堆积、无未清除的页眉页脚特征、无 <!-- PAGE 残留、无 __ 残留;h 标题层级连续无跳级。此时产出 book.md,是干净的层级化 Markdown,h1=全书最高级标题(有部/卷则为部/卷,无则为章),h2、h3 依层级递减。

7. md-to-epub:分章与打包(CLI)

python scripts/md_to_epub.py book/book.md -o book/book.epub \
  --title "书名" --author "作者" --lang zh [--cover book/pages/page_0001.png]

脚本行为:

  • 切分:以 h1 为顶级章节切分正文;h2/h3 作为子级保留在章节内。
  • 导航目录:生成 EPUB 导航(NCX 与 nav.xhtml),目录条目与正文 h1/h2 标题一一对应(h3 及以下为章内层级,不进目录),支持点击跳转。
  • 封面(可选):--cover <图片> 指定封面图(PNG/JPG)。实际流程通常用拆页得到的 page_0001.png(原书封面页),也可由用户提供其他图片;pandoc 路径用 --epub-cover-image,ebooklib 路径用 EpubImagecover-image 属性,两条路径均生成封面。
  • 打包:优先调用 pandoc(Markdown → EPUB);若 pandoc 缺失,回退用 ebooklib 手工组包(目录同样生成)。两种路径都保证阅读顺序与原书一致、已去除的内容不出现。
  • 输出 book.epub

8. verify:校验(CLI)

python scripts/verify.py book/book.epub

脚本检查并完整打印校验报告到终端

  • EPUB 结构合法:content.opf / manifest / spine 完整一致。
  • 导航目录存在,且每条目录条目在正文中都有对应标题(条目数 ≈ 正文 h1/h2 标题数;封面等非正文页除外)。
  • 目录锚点目标可解析(点击可跳转)。
  • 正文字段抽查:无 <!-- CH 锚点注释残留、无 COPYRIGHT_CANDIDATE、无 <!-- PAGE 页定位注释残留、无 __ 连接标记残留。

校验失败时脚本给出具体条目,修复后重跑 md-to-epubverify 直至通过。

常见问题

  • 某批次识别失败 / 子代理超时:用 check-markers 检查确认问题,单独重跑该批次子代理(batch_XXX),不重跑全书。
  • 正文出现公式/表格(罕见):本 skill 面向纯文字书籍(如小说),子代理不使用结构标记;若某页含公式表格等非常规内容,如实转录为文字段落,主代理校对时人工核对。
  • 某本书需要保留插图:偏离通用默认,需用户单独确认,并放弃"去除插图"规则。