claude-howto 文档双引擎发布指南:用 build_epub.py 与 build_website.py 将 Markdown 一键生成 EPUB 电子书与静态网站
【免费下载链接】claude-howtoA visual, example-driven guide to Claude Code — from basic concepts to advanced agents, with copy-paste templates that bring immediate value.项目地址: https://gitcode.com/GitHub_Trending/cl/claude-howto
本文面向想把自己或团队维护的 Claude Code 教程、Agent 使用手册发布为可分发产物的开发者,系统讲解 claude-howto 仓库中 scripts/README.md 定义的两套文档生成器:EPUB 构建脚本 build_epub.py 与静态网站构建脚本 build_website.py。读完你将掌握:如何在纯本地环境(无需外网)把多语言 Markdown 教程构建成含封面、目录、Mermaid 图表的 EPUB,以及如何生成一个移动端友好、零 CDN 依赖、可直接部署 GitHub Pages 的静态站点,并理解两套脚本背后的章节编排、链接改写与资产自托管实现原理。
一、先看整体:两个生成器、一份内容源
claude-howto 仓库把教程文档以 Markdown 形式组织为01-slash-commands、02-memory、03-skills到10-cli等分章节目录(内容脉络可参见 CATALOG.md 与 INDEX.md)。scripts/目录下的两个生成器负责把它们变成可分发格式:
- EPUB Builder:把 Markdown 构建为单本 EPUB 电子书;
- Static Website Builder:把同一批 Markdown 渲染为多页静态网站。
两者共享同一个核心设计理念:Markdown 是唯一事实来源(single source of truth)。每次编辑.md文件后,只需重新运行对应脚本即可重新生成产物,网站与电子书之间不存在内容重复副本,因此永远不会出现"一处改了另一处没改"的同步问题。
二、EPUB Builder:一键产出可分发电子书
2.1 功能特性总览
build_epub.py 的功能清单(源码 docstring 与 scripts/README.md 一致确认):
- 按目录结构组织章节:
01-slash-commands、02-memory等文件夹会被整理为电子书的分篇/分章; - Mermaid 图本地渲染为 PNG:通过本机
mmdcCLI 完成,全程无需网络; - 相同图表只渲染一次:命中缓存则跳过,重复出现的 Mermaid 代码块共享同一份图片资源;
- 自动生成封面图:使用项目 Logo
claude-howto-logo.png生成封面; - 内部链接改写:Markdown 内部链接被转换为 EPUB 章内引用(
chap_XX.xhtml); - 严格错误模式:只要有任何一张 Mermaid 图渲染失败,构建直接失败并报错,避免产出残缺文件。
2.2 环境要求与快速开始
运行该脚本需要三样东西:
| 依赖 | 说明 |
|---|---|
| Python 3.10+ | 脚本最低解释器版本,见 pyproject.toml 中requires-python |
| uv | 推荐的 Python 包管理器与脚本运行器,用于解析 PEP 723 内联依赖 |
mmdc(Mermaid CLI) | 用于渲染 Mermaid 图,通过npm install -g @mermaid-js/mermaid-cli安装到PATH |
最简运行方式(uv 会自动读取脚本头部的 PEP 723 内联依赖元数据并在隔离环境中安装,无需手动建 venv):
uv run scripts/build_epub.py脚本第一行#!/usr/bin/env -S uv run --script说明它也可被当作可执行脚本直接运行;直接python scripts/build_epub.py同样可行(前提是ebooklib、markdown、beautifulsoup4、pillow已安装)。
2.3 命令行参数详解
完整参数与 scripts/README.md 及 build_epub.py 的 main() 中 argparse 定义一致:
usage: build_epub.py [-h] [--root ROOT] [--output OUTPUT] [--verbose] [--mmdc-path MMDC_PATH] [--lang {en,vi,zh,ja}] [--puppeteer-config PUPPETEER_CONFIG]| 参数 | 默认值 | 作用 |
|---|---|---|
--root, -r | 仓库根目录 | 扫描 Markdown 的源目录(源码通过Path(__file__).parent.parent定位仓库根) |
--output, -o | claude-howto-guide.epub | 输出 EPUB 路径 |
--verbose, -v | 关闭 | 开启 DEBUG 级日志(setup_logging中level = logging.DEBUG if verbose else logging.INFO) |
--mmdc-path | mmdc(PATH 查找) | 指定mmdc可执行文件路径,用于不在 PATH 的场景 |
--lang {en,vi,zh,ja} | en | 构建语言版本:vi输出到vi/源目录、zh对应zh/、ja对应ja/ |
--puppeteer-config | 无 | 传给mmdc -p的 Puppeteer 配置 JSON,常用于 CI/容器传--no-sandbox |
2.4 常用构建示例
# 输出详细构建日志 uv run scripts/build_epub.py --verbose # 自定义输出位置 uv run scripts/build_epub.py --output ~/Desktop/claude-guide.epub # 构建越南语翻译版 uv run scripts/build_epub.py --lang vi # mmdc 不在 PATH 时显式指定 uv run scripts/build_epub.py --mmdc-path ./node_modules/.bin/mmdc从源码看(main()),--lang背后是一张语言映射表:不同语言使用各自的源目录(en→仓库根、vi→vi/、zh→zh/、ja→ja/)、各自的默认输出文件名(claude-howto-guide-vi.epub等)和各自的多语言标题/副标题元数据(定义在EPUBConfig中,例如中文标题"Claude Code 使用指南"、副标题"一个周末掌握 Claude Code")。
2.5 产物内容
构建成功后会在仓库根目录生成claude-howto-guide.epub,其中包含:
- 带项目 Logo 的封面图;
- 带嵌套分节的目录(文件夹被组织为
epub.Section分组,顶层文档独立成章); - 全部 Markdown 内容转换后的 EPUB 兼容 HTML(启用了
tables、fenced_code、codehilite、toc四个 markdown 扩展); - Mermaid 图以 PNG 形式内嵌。
2.6 源码级原理拆解
依赖管理:PEP 723 内联元数据
脚本头部直接声明运行时依赖(build_epub.py 第 1-4 行),uv run据此自动构建隔离环境:
#!/usr/bin/env -S uv run --script # /// script # dependencies = ["ebooklib", "markdown", "beautifulsoup4", "pillow"] # ///| 依赖 | 用途 |
|---|---|
ebooklib | EPUB 文件生成与打包 |
markdown | Markdown → HTML 转换 |
beautifulsoup4 | HTML 解析、链接与图片改写 |
pillow | 封面图合成 |
构建流水线:从校验到写盘
从 build_epub_async() 可以看到完整执行顺序:validate_inputs(校验源目录存在、输出目录可写、仓库内至少存在一个.md文件,缺 Logo 仅告警不中断)→ 初始化epub.EpubBook与元数据 →create_cover_image生成封面 →ChapterCollector.collect_all_chapters依据 get_chapter_order() 的固定章节顺序(README → LEARNING-ROADMAP → QUICK_REFERENCE → claude_concepts_guide → 01~09 目录 → resources)单趟收集章节并建立path_to_chapter路径映射 → 提取并渲染全部去重后的 Mermaid 图 → 逐章执行 Markdown→HTML 转换 → 组装 TOC 与 spine → 写出.epub文件。
Mermaid 渲染:本地 mmdc + 双重去重
MermaidRenderer 在临时目录中写入.mmd源码、调用mmdc -i diagram.mmd -o diagram.png -b white(-b white强制白底),每次调用带 60 秒超时,超时或非零退出码都会抛出MermaidRenderError。去重发生在两个层面:渲染前由 extract_all_mermaid_blocks 用set去掉重复代码块;渲染结果又缓存在state.mermaid_cache中(以代码内容为 key),保证每个唯一图只调用一次mmdc。
值得注意的细节是 sanitize_mermaid:Mermaid 的 markdown-in-nodes 特性会把节点标签里的编号列表(如["1. Item"])误解析,脚本通过正则把[1.转义为[1\.规避该问题。对应单测见 test_sanitize_mermaid_numbered_list。
链接与图片改写
md_to_html的处理顺序是先替换 Mermaid 代码块为图片引用,再做 Markdown 渲染,再通过 BeautifulSoup 处理<picture>包裹与.svg图片(内嵌为 EPUB 图像资源而非<object>),最后 convert_internal_links 把指向仓库内.md的相对链接解析到对应chap_XX.xhtml,并保留#anchor片段。锚点分割逻辑兼容三种路径形态(纯目录、目录+/、目录+/README.md)以最大化命中率。
封面生成
create_cover_image 用 Pillow 在(600, 900)的画布上绘制标题、副标题与 Logo;字体采用跨平台候选列表(macOS Arial Bold、Linux DejaVuSans、Windows arialbd)逐一尝试加载,全部失败则回退默认字体;Logo 缺失时自动降级为纯文字封面——这与 README 故障排查一节"Missing logo"的说明互相印证。
三、Static Website Builder:Markdown 直出的零 CDN 静态站
3.1 功能特性总览
build_website.py 用与 EPUB 构建完全相同的 Markdown 源渲染出美观、移动友好的静态网站:
- 一源一页:每个 Markdown 源对应一个 HTML 页面,内部
.md链接被改写为站内页面地址; - 仓库文件直达源码:指向模板、脚本、JSON 等非 Markdown 文件的引用会被改写为仓库 blob 链接,读者可一键跳到 GitHub 源码;
- Mermaid 客户端渲染:通过站内自托管的
mermaid.min.js渲染,运行时无 CDN; - Tailwind CSS 静态编译:使用 Tailwind 独立 CLI(Go 二进制,无需 Node.js),编译产物随站点托管,提供响应式布局、侧边栏导航、页内 TOC、暗色模式切换与上一篇/下一篇导航;
- 字体自托管:Inter + JetBrains Mono 字体文件与 CSS 一并打包,页面加载不产生任何第三方请求;
- 章节顺序与 EPUB 对齐:镜像电子书课程顺序(
01-~10-目录加顶层文档); - 纯静态可托管:产物可直接部署到 GitHub Pages 等任何静态托管。
3.2 快速开始与本地预览
# 构建英文站到 ./site/ uv run scripts/build_website.py # 本地预览 python -m http.server --directory site 8080 # 然后浏览器打开 http://localhost:80803.3 命令行参数详解
与 build_website.py 的 main() 一致:
usage: build_website.py [-h] [--root ROOT] [--output OUTPUT] [--lang {en,vi,zh,ja,uk}] [--repo-url REPO_URL] [--branch BRANCH] [--verbose]| 参数 | 默认值 | 作用 |
|---|---|---|
--root, -r | 仓库根目录 | 源文档根目录 |
--output, -o | <repo>/site | 输出目录(非英文版默认site-<lang>,如site-vi) |
--lang {en,vi,zh,ja,uk} | en | 构建语言;站内构建器比 EPUB 多支持乌克兰语uk(源目录为uk/) |
--repo-url | luongnv89/claude-howto | 生成 blob 链接用的仓库地址 |
--branch | main | blob 链接使用的分支 |
--verbose, -v | 关闭 | 开启调试日志 |
3.4 GitHub Pages 部署
仓库自带 Pages 工作流:每次向main推送且任一.md或生成器文件发生变更时自动构建站点,并通过actions/deploy-pages发布。只需在仓库设置中启用 GitHub Pages,并将发布来源(Source)选为GitHub Actions即可生效。
3.5 架构与模板组织
build_website.py 复用了 EPUB 构建器的章节排序逻辑(文件头的注释与 CHAPTER_ORDER 均可佐证,其中10-cli、CATALOG、INDEX、STYLE_GUIDE 等是网站独有的扩展章节),HTML 模板位于 scripts/website_templates/:
- page.html.j2:Jinja2 单页模板,含侧边栏导航、页内 TOC、上/下篇翻页;
- tailwind.config.js 与 tailwind.input.css:Tailwind 独立 CLI 的配置与入口 CSS;CLI 会扫描构建出的 HTML,仅产出实际用到的工具类到
site/assets/tailwind.css; - site.css:站点自定义样式与 Pygments 高亮主题。
Tailwind CLI 二进制、Mermaid 包与字体文件在首次构建时下载,并缓存到scripts/.vendor-cache/(已被 gitignore),具体逻辑见 vendor_assets.py:fetch_mermaid固定拉取 Mermaid v10 的 UMD 包,fetch_fonts下载 Google Fonts CSS 后把其中的fonts.gstatic.comURL 改写为相对路径files/…再落地,build_tailwind_css固定 Tailwindv3.4.19(因为模板使用 v3 风格运行时配置)执行--minify编译。最终构建顺序为:先渲染全部 HTML,最后跑 Tailwind 扫描,确保样式类被完整收集。
3.6 源码级原理:链接改写与锚点一致性
链接改写是网站构建最精细的部分。_rewrite_anchor 对每个<a>的规则是:
- 跳过外部链接(
http/https/mailto/tel)与纯锚点#…; - 解析相对路径到仓库内,先查
source_to_url映射(命中说明目标是站内页面,改写为相对 URL 并保留锚点); - 未命中则视为仓库普通文件,改写为
<repo_url>/blob/<branch>/<path>并附加target="_blank"与rel="noopener noreferrer"。
资产(img/source)会被改写并复制到assets/下对应目录,同时自动补loading="lazy"。
锚点一致性是容易被忽视但非常关键的实现细节:页面标题的id不是由python-markdown的toc扩展随机生成,而是由 heading_to_anchor 用与 check_cross_references.py 完全相同的算法(先剔除 emoji 等 Unicode 变体字符,再小写化、非字母数字转-)计算——这样 pre-commit 校验通过的#anchor引用在最终站点上也必然能正确跳转。test_build_website.py 中大量 fixture 覆盖了<picture>标签、内部.md链接、非 Markdown 仓库文件、Mermaid 代码块等场景的改写正确性。此外_disambiguate_url处理了 macOS/Windows 大小写不敏感文件系统的冲突问题(如INDEX.html与index.html),保证构建在不同平台上结果一致。
四、工程质量:测试、lint 与静态检查
scripts/目录还提供了围绕两个生成器及文档校验的质量工具链:
- 测试套件:scripts/tests/ 下 test_build_epub.py 与 test_build_website.py 通过 fixture 构造最小项目结构(含临时生成的 PNG Logo、章节目录与 Mermaid 块),验证输入校验、章节收集、HTML 转义、渲染去重、mmdc 异常(找不到、失败、超时)等路径;另有 test_check_cross_references.py 与 test_check_markdown_rendering.py 守护文档交叉引用与渲染质量;
- 运行测试:
uv一条命令即可,无需预先安装开发依赖:
uv run --with pytest --with pytest-asyncio \ --with ebooklib --with markdown --with beautifulsoup4 \ --with pillow \ pytest scripts/tests/ -v或走传统开发环境:uv venv创建虚拟环境 →uv pip install -r requirements-dev.txt→pytest scripts/tests/ -v(requirements-dev.txt额外引入pytest-cov、pre-commit、ruff、bandit、mypy等代码质量工具,核心依赖见 requirements.txt)。
- 工程配置:scripts/pyproject.toml 集中管理 pytest 选项(
testpaths、asyncio_mode = "auto")、Ruff(大量启用PL、PTH、PERF等严格规则)与 Bandit/Mypy 配置,约束脚本质量与类型正确性。
五、常见问题排查(Troubleshooting)
构建报mmdc not found:安装 Mermaid CLI(npm install -g @mermaid-js/mermaid-cli),若二进制不在PATH上则改用--mmdc-path显式指定。另外需要注意:内置 Chromium 没有可用的 arm64 版本,因此在 arm64 机器上应改到 CI 中构建 EPUB——.github/workflows/test.yml中的build-epub任务会覆盖每一种语言版本。
mmdc在 CI 或容器中失败:Chromium 需要免沙箱配置。把{"args":["--no-sandbox","--disable-setuid-sandbox"]}写入一个 JSON 文件,再通过--puppeteer-config传入即可:
echo '{"args":["--no-sandbox","--disable-setuid-sandbox"]}' > /tmp/puppeteer.json uv run scripts/build_epub.py --puppeteer-config /tmp/puppeteer.json缺少 Logo:当根目录找不到claude-howto-logo.png时,脚本不会中断,而是生成纯文字封面(源码中仅记录 warning,见 validate_inputs 与 create_cover_image)。
六、内容到产物的推荐工作流
综合两个生成器,推荐的内容发布闭环为:
- 编辑任一
.md教程文件(这是唯一需要人工维护的内容); - 运行仓库自带校验(如
scripts/tests/中的交叉引用与渲染检查)保证文档质量; - 本地预览网站:
uv run scripts/build_website.py后python -m http.server --directory site 8080; - 需要电子书时执行
uv run scripts/build_epub.py(多语言版加--lang zh/vi/ja); - 推送
main分支触发 GitHub Pages 工作流自动发布新版站点,EPUB 则由 CI 的build-epub任务兜底产出。
整套方案的技术要点可归结为一句话:用脚本而非人工维护分发产物,把 Markdown 作为唯一事实来源,同时把渲染、样式、字体、图表全部收敛到本地与仓库内,从而同时获得电子书与网站的"一次编写、多处发布"体验。需要深入实现细节时,可从 scripts/README.md 出发,对照 build_epub.py、build_website.py 与 vendor_assets.py 逐行阅读。
【免费下载链接】claude-howtoA visual, example-driven guide to Claude Code — from basic concepts to advanced agents, with copy-paste templates that bring immediate value.项目地址: https://gitcode.com/GitHub_Trending/cl/claude-howto
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考