| name | bluebook-pdf-builder |
| description | 把蓝皮书/白皮书/行业报告的 Markdown 渲染成正式 PDF,封面整页铺图,每个一级标题生成与封面同款配色的独立分隔页,每个二级标题单独起一页。当用户想把蓝皮书、白皮书、研究报告、行业报告、咨询报告的 markdown 转成 PDF,或者提到"把蓝皮书/白皮书做成 PDF"、"加上章节分隔页"、"每个章节单独一页"、"配合封面生成 PDF"时,使用此 skill。即使用户只说"把这份报告导出成 PDF",只要是一份带封面图、有多级标题的正式文档,也应触发。 |
蓝皮书 PDF 生成器
把一份蓝皮书/白皮书的 Markdown 文件渲染成正式出版的 PDF:
- 封面:整页使用用户提供的封面图(通常由
bluebook-cover-generator 生成)
- 每个一级标题(H1):生成独立分隔页,深色渐变背景 + 金色装饰,配色从封面自动采样,保证视觉统一
- 每个二级标题(H2):强制另起一页
- 正文:宋体衬线、表格/代码块/引用块都有定制样式
前置条件
脚本依赖四个组件,绝大多数 macOS 环境已具备。首次调用前快速检查:
which pandoc python3 && \
python3 -c "import fitz; print('pymupdf ok')" && \
DYLD_FALLBACK_LIBRARY_PATH=/opt/homebrew/lib python3 -c "import weasyprint; print('weasyprint ok')" && \
echo "deps OK" || echo "deps missing"
注意:weasyprint 在 macOS 上依赖 homebrew 的 glib/pango 系统库,直接 import 会报 libgobject 找不到。必须像上面那样设置 DYLD_FALLBACK_LIBRARY_PATH=/opt/homebrew/lib——脚本内部调用 weasyprint 时已经这么做了,所以这只是用来检查环境是否就绪。
若缺失,按需安装:
| 依赖 | 安装 | 用途 |
|---|
| pandoc | brew install pandoc | Markdown → HTML |
| weasyprint (Python 包) | pip install weasyprint | HTML → PDF |
| glib + pango (macOS 系统库) | brew install glib pango | weasyprint 的渲染后端 |
| PyMuPDF (Python 包) | pip install pymupdf | 从封面采样颜色 + 读页数 |
确认输入
触发此 skill 时,必须先拿到两样东西——少了任何一个都不能开始:
- Markdown 文件路径:蓝皮书的正文。确认它用
# 第一章 ... / ## 节标题 的标准 markdown 标题层级。
- 封面图片路径:PNG/JPG,通常和 markdown 在同一目录。尺寸建议接近 A4 比例(1:1.414),由
bluebook-cover-generator 生成的封面开箱即用。
可选信息(用户没给就用默认值,不要追问):
- 书名:分隔页底部左侧的标识。默认"蓝皮书"。
- 底部标签:分隔页底部右侧,如年份/系列名。默认与书名相同。
如果用户只给了 markdown 没给封面图,先在文件同级目录找同名 -封面.png/cover.png/-cover.png;找不到就问用户要,不要在没有封面的情况下开始——封面图的颜色采样是整个分隔页配色的基础。
调用
一切就绪后,一条命令完成全部渲染:
python3 "$SKILL_DIR/scripts/bluebook_pdf.py" "<markdown路径>" "<封面图路径>" \
--output "<输出PDF路径>" \
--book-title "<书名>" \
--footer-tag "<底部标签>"
参数说明:
--output:不传则默认与 markdown 同名 .pdf
--book-title:分隔页左下角书名(默认"蓝皮书")
--footer-tag:分隔页右下角标签,如 FDE · 2026(默认与书名相同)
--no-divider:不生成 H1 分隔页,只做封面 + H2 分页正文
--keep-html:保留中间 HTML 文件(便于调试样式)
脚本会打印 5 步进度,最后报告 PDF 路径、页数、大小。把这三项告诉用户即可。
工作原理(用户改样式时才需要看)
脚本做了四件事,理解了才好回答用户的修改需求:
1. 封面颜色采样:用 PyMuPDF 把封面图读成像素阵列,采样三组颜色——背景渐变两端(取顶部/底部各 1/6 区域的中位数)、强调色(金色:高 R、中 G、低 B 的像素中位数)、文字色(最亮的浅色像素中位数)。分隔页的背景、装饰线、文字全部基于这三组颜色生成,所以无论封面是 blueGold、blackGold 还是 green 模板,分隔页都能自动呼应。如果用户说"分隔页配色不对",通常是封面图颜色采样受装饰元素干扰——可以让用户检查封面,或用 --keep-html 看采到的具体色值。
2. Markdown 预处理:中文作者常在 blockquote(> 引用)后面紧跟 # 标题 而不留空行,pandoc 会把标题吞进引用块。脚本检测到 H1/H2 紧跟非空行时自动补空行。如果用户的 markdown 里 H1 被渲染成了正文文字(不是大标题),就是这个原因,脚本已自动修复。
3. H1 分隔页生成 + 章首导语提取:把每个 H1 文本拆成三段——kicker(如"第一章")、主标题、副标题(破折号后的部分)。分隔页用绝对定位的三层结构:顶部 kicker + 金色短线、中部主标题 + 副标题 + 金色横线、底部页脚,大量留白,与蓝皮书封面的版式节奏一致。
章首导语:许多蓝皮书在 H1 和第一个 H2 之间会写一小段「核心结论」或开篇导引文字。脚本会自动提取这段内容(split_lede),渲染到分隔页主标题下方(.hero-lede),而不是让它单独占一个正文页——这样章节首屏信息更完整,也避免了「只有一小段话的无标题单页」。导语支持两种形态:
- 引语式(
> 核心结论:…,渲染成半透明深底 + 金色左竖线的 callout)
- 段落式(普通开篇段落,直接以浅色文字显示)
若整章没有 H2(如「作者简介」「执行摘要」很短时),不拆分,整体当正文处理。
4. 排版细节:正文用 Songti SC 衬线、1.85 行高、两端对齐;H2 标题有金色下划线;表格深蓝表头 + 斑马纹;代码块深色底;引用块(核心结论/小结)金色左边框 + 浅蓝底。
完成检查
脚本跑完后,向用户报告 PDF 的绝对路径、页数、文件大小。无需额外验证——脚本内部已经通过 PyMuPDF 读了页数。
如果用户对样式有具体修改需求(字号、配色、留白等),用 --keep-html 重新生成保留中间 HTML,直接改 HTML 里的 <style> 再手动用 weasyprint 渲染即可,不必反复改脚本。