关于 lovstudio:any2pdf
将 Markdown 文档排版并转换为 PDF 的技能,面向需要制作专业报告或包含中日韩文字的文档作者。它使用 Python 的 reportlab,并提供多种主题、目录和封面设置,也可在特定情况下改用 pandoc 与 XeLaTeX。
主要功能
- 01Markdown 转高质量 PDF
- 02支持中日韩与拉丁文字混排
- 03处理代码块、表格和嵌套列表
- 04提供封面、目录、水印及主题选项
- 05支持 pandoc 与 XeLaTeX 回退
适用场景
- 01将技术报告导出为 PDF
- 02排版含 CJK 字符和代码的文档
- 03为报告添加封面、目录或水印
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ lovstudio/ skills --skill lovstudio:any2pdf安装后在 Claude Code 中输入/lovstudio:any2pdf确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
CHANGELOG.mdREADME.mdcases/cases.jsonreferences/themes.mdscripts/md2pdf.py详细介绍
any2pdf——将 Markdown 转换为专业 PDF
此技能使用 Python 的 reportlab 库将任意 Markdown 文件转换为出版级 PDF。它通过大量真实中文技术报告的迭代开发而成,解决了若干朴素的 MD→PDF 转换器容易出错的难题。
何时使用
- 用户想将
.md→.pdf - 用户有 Markdown 报告/文档,并希望获得专业排版
- 文档包含 CJK 字符(中文/日文/韩文),并与拉丁文本混排
- 文档包含围栏代码块、Markdown 表格或嵌套列表
- 用户希望在 PDF 中添加封面、目录或水印
快速开始
python md2pdf/scripts/md2pdf.py \
--input report.md \
--output report.pdf \
--title "My Report" \
--author "Author Name" \
--theme warm-academic
除 --input 外,所有参数均为可选参数——系统会应用合理的默认值。
转换前选项(必需)
重要:运行转换前,必须使用 AskUserQuestion 工具提出这些问题。不要将选项作为纯文本列出——请使用该工具,让用户获得恰当的交互式提示。请在一次 AskUserQuestion 调用中询问所有选项。
使用以下模板调用 AskUserQuestion。语气应友好、简洁——像设计助手,而不是配置表单:
开始转 PDF!先帮你确认几个选项 👇
━━━ 📐 设计风格 ━━━
a) 暖学术 — 陶土色调,温润典雅,适合人文/社科报告
b) 经典论文 — 棕色调,灵感源自 LaTeX classicthesis,适合学术论文
c) Tufte — 极简留白,深红点缀,适合数据叙事/技术写作
d) 期刊蓝 — 藏蓝严谨,灵感源自 IEEE,适合正式发表风格
e) 精装书 — 咖啡色调,书卷气,适合长篇专著/技术书
f) 中国红 — 朱红配暖纸,适合中文正式报告/白皮书
g) 水墨 — 纯灰黑,素雅克制,适合文学/设计类内容
h) GitHub — 蓝白极简,程序员熟悉的风格
i) Nord 冰霜 — 蓝灰北欧风,清爽现代
j) 海洋 — 青绿色调,清新自然
k) LaTeX 清爽 — pandoc+XeLaTeX 原生排版,无封面无装饰,干净学术风(需装 pandoc+texlive)
l) 咨询深蓝 — 深海军蓝色块 + 白底 + 大写左对齐标题,麦肯锡 / BCG / Deloitte 研究报告风格
━━━ 🖼 扉页图片(封面之后的全页插图) ━━━
1) 跳过
2) 我提供本地图片路径
3) AI 根据内容自动生成一张
━━━ 💧 水印 ━━━
1) 不加
2) 自定义文字(如 "DRAFT"、"内部资料")
可选调整:字号(默认52)、透明度(0-1)、角度(默认35°)、间距
━━━ 📇 封底物料(名片/二维码/品牌) ━━━
1) 跳过
2) 我提供图片
3) 纯文字信息
示例回复:"a, 扉页跳过, 水印:仅供学习参考, 封底图片:/path/qr.png"
直接说人话就行,不用记编号 😄
将用户选择映射为 CLI 参数
| 选择 | CLI 参数 |
|---|---|
| 设计风格 a-k | --theme,取值见下表(k 使用 pandoc 引擎) |
| 本地扉页 | --frontispiece <path> |
| AI 扉页 | 先生成图像,再使用 --frontispiece /tmp/frontispiece.png |
| 水印文字 | --watermark "文字" |
| 水印样式 | --wm-size 30 --wm-opacity 0.1 --wm-angle 45(均为可选) |
| 图片作为封面 | --image-cover true(需要 --frontispiece) |
| 封底图片 | --banner <path> |
| 封底文字 | --disclaimer "声明" 和/或 --copyright "© 信息" |
主题名称映射
| 选择 | --theme 值 | 灵感来源 |
|---|---|---|
| a) 暖学术 | warm-academic | Lovstudio 设计系统 |
| b) 经典论文 | classic-thesis | LaTeX classicthesis |
| c) Tufte | tufte | Edward Tufte 的书籍 |
| d) 期刊蓝 | ieee-journal | IEEE 期刊格式 |
| e) 精装书 | elegant-book | LaTeX ElegantBook |
| f) 中国红 | chinese-red | 中国正式文件 |
| g) 水墨 | ink-wash | 水墨画 / 水墨画风格 |
| h) GitHub | github-light | GitHub Markdown 风格 |
| i) Nord | nord-frost | Nord 配色方案 |
| j) 海洋 | ocean-breeze | — |
| k) LaTeX 清爽 | latex-clean | pandoc+XeLaTeX 原生排版,无封面 |
| l) 咨询深蓝 | consulting-navy | McKinsey / BCG / Deloitte 深度研究报告 |
处理 AI 生成的扉页
如果用户选择 AI 生成:阅读文档标题和首段,使用图像生成工具创建与所选设计风格相符的主题插图,展示给用户审批,然后通过 --frontispiece /path/to/image.png 传入
架构
Markdown → Preprocess (split merged headings) → Parse (code-fence-aware) → Story (reportlab flowables) → PDF build
主要组件:
- 字体系统:macOS 上使用 Palatino(拉丁正文)、Songti SC(CJK 正文)、Menlo(代码);Linux 上自动回退
- CJK 包装器:
_font_wrap()将 CJK 字符段包装在<font>标签中,以便自动切换字体 - 混合文本渲染器:
_draw_mixed()在画布上处理 CJK/拉丁混合文本(封面、页眉、页脚) - 代码块处理器:
esc_code()在 reportlab 段落中保留缩进和换行 - 智能表格宽度:根据内容长度按比例设置列宽,最小宽度为 18mm
- 书签系统:
ChapterMarkflowable 创建 PDF 侧边栏书签和命名锚点 - 标题预处理器:
_preprocess_md()将# Part## Chapter这样的合并标题拆分为单独行
来之不易的经验
CJK 字符显示为 □
reportlab 的 Paragraph 仅使用 ParagraphStyle 中指定的字体。如果 fontName="Mono",但文本包含中文,中文就会显示为 □。解决方法:始终对所有可能包含 CJK 的文本应用 _font_wrap(),包括代码块。
代码块丢失换行
reportlab 会将 \n 视为空白字符。修复:esc_code() 会将 \n 转换为 <br/>,并将行首空格转换为 ,且在 _font_wrap() 之前应用。
CJK/拉丁文单词换行
reportlab 默认只在空格处换行,导致出现“Claude\nCode”这类不自然的断行。修复:在正文和项目符号样式上设置 wordWrap='CJK',允许在 CJK 字符边界处换行。
含 CJK 字符的画布文本(封面/页脚)
使用拉丁字体的 drawString() / drawCentredString() 无法呈现年/月/日等字符。
修复:对画布上所有用户内容文本(日期、统计数据、免责声明)使用 _draw_mixed()。
图片被静默跳过(相对路径)
Markdown 文件中的  过去会被跳过,且没有任何警告,因为图片路径是相对于当前工作目录而不是 Markdown 文件所在目录解析的。修复:main() 现在会将 input_dir(.md 文件所在目录)传递给构建器,图片处理程序会据此解析相对路径。现在找不到图片时,也会向 stderr 输出 WARN: image not found: ...,而不是静默跳过。
多行图片引用(pandoc --wrap=auto)
将 pandoc 的输出传入 md2pdf 时,pandoc 默认的 --wrap=auto(72 列)会把较长的  拆分到多行,从而导致单行图片正则表达式无法匹配。修复:_preprocess_md() 现在会在解析前将多行图片引用合并为一行(代码围栏之外)。
**管道处理提示:**如果要通过 pandoc 将 HTML 转换为 Markdown,请使用
pandoc --wrap=none input.html -o output.md,避免图片和表格因换行而出现解析问题。
输入格式
此技能仅接受 Markdown 文件作为输入。如果输入是 HTML、DOCX 或其他格式,请先将其转换为 Markdown(例如使用 pandoc --wrap=none)。
Markdown 中嵌入的 HTML 块会作为文本传递——调用 md2pdf 前,请先将图表、复杂表格等视觉内容预处理为普通 Markdown 表格或图片引用。
配置参考
| 参数 | 默认值 | 说明 |
|---|---|---|
--input | (必填) | Markdown 文件路径 |
--output | output.pdf | 输出 PDF 路径 |
--title | 取自第一个 H1 | 封面上的文档标题 |
--subtitle | "" | 副标题文本 |
--author | "" | 作者姓名 |
--date | 今天 | 日期字符串 |
--version | "" | 封面上的版本字符串 |
--watermark | "" | 水印文本(空值 = 无) |
--theme | warm-academic | 配色主题名称 |
--theme-file | "" | 自定义主题 JSON 文件路径 |
--cover | true | 生成封面 |
--toc | true | 生成目录 |
--page-size | A4 | 页面大小(A4 或 Letter) |
--frontispiece | "" | 封面后的整页图片 |
--banner | 打包的 assets/backcover-banner.jpg | 封底横幅图片(传入 none 可禁用) |
--header-title | "" | 页眉中的报告标题 |
--footer-left | 作者 | 页脚中的品牌/作者 |
--stats-line | "" | 封面上的统计信息 |
--stats-line2 | "" | 第二行统计信息 |
--edition-line | "" | 封面底部的版本说明 |
--disclaimer | "" | 封底免责声明 |
--copyright | "" | 封底版权信息 |
--code-max-lines | 30 | 每个代码块的最大行数 |
--image-cover | false | 将扉页图片用作满版封面(第 1 页),文字封面移至第 2 页 |
--heading-top-spacer | 5 | H1/H2 章节标题前的顶部间距(mm) |
--wm-size | 自动(页面宽度的一半) | 水印字体大小;自动缩放,使文本宽度约为页面宽度的 50% |
--wm-opacity | 0.1 | 水印不透明度(0.0–1.0) |
--wm-angle | 35 | 水印旋转角度(度) |
--wm-spacing-x | 9999 | 水印水平间距(pt)(≥2000 = 每页居中显示一个) |
--wm-spacing-y | 9999 | 水印垂直间距(pt)(≥2000 = 每页居中显示一个) |
主题
可用主题:warm-academic、nord-frost、github-light、solarized-light、
paper-classic、ocean-breeze、consulting-navy。
每个主题定义:页面背景、文字颜色、强调色、淡化文字、边框、代码背景、水印色调。
回退方案:pandoc + XeLaTeX
当 reportlab 失败时(例如,宽表格或复杂表格导致表格宽度计算陷入无限循环), 回退到 pandoc 和 XeLaTeX。这样可以生成高质量的 CJK PDF,并妥善处理表格。
何时使用 pandoc 引擎
- 用户选择了
latex-clean主题(k)——pandoc 是主要引擎,而非回退方案 - 文档包含许多宽的多列表格(reportlab 的表格布局可能会卡住)
- 文档需要 LaTeX 级别的排版效果(两端对齐、断词)
- reportlab md2pdf.py 处理输入时卡住或崩溃
基本命令
pandoc input.md -o output.pdf \
--pdf-engine=xelatex \
-V CJKmainfont="Songti SC" -V mainfont="Palatino" -V monofont="Menlo" \
-V geometry:margin=2.5cm -V fontsize=11pt \
--toc -V toc-title="目录" -V documentclass=article
添加水印 + 页眉/页脚
pandoc input.md -o output.pdf \
--pdf-engine=xelatex \
-V CJKmainfont="Songti SC" -V mainfont="Palatino" -V monofont="Menlo" \
-V geometry:margin=2.5cm -V fontsize=11pt \
-V colorlinks=true -V linkcolor=red -V toccolor=red -V urlcolor=red \
--toc -V toc-title="目录" -V documentclass=article \
-V header-includes='
\usepackage{fancyhdr}
\pagestyle{fancy}
\fancyhf{}
\fancyhead[L]{\small 页眉左侧文字}
\fancyhead[R]{\small 页眉右侧文字}
\fancyfoot[C]{\thepage}
\usepackage{draftwatermark}
\SetWatermarkText{水印文字}
\SetWatermarkScale{0.5}
\SetWatermarkColor[gray]{0.9}
'
Pandoc 主题预设
每个预设都定义了一组完整的 pandoc -V 标志。使用上方“添加水印 + 页眉/页脚”
中的完整命令,并根据预设替换颜色/链接标志。
| 主题 | linkcolor | toccolor | urlcolor | 水印颜色 | 备注 |
|---|---|---|---|---|---|
| chinese-red | red | red | red | [gray]{0.9} | 朱红正式,适合政企报告、白皮书 |
| warm-academic | brown | brown | brown | [gray]{0.9} | 陶土色调,温润学术风 |
| classic-thesis | brown | brown | brown | [gray]{0.85} | 灵感来自 LaTeX classicthesis |
| ieee-journal | blue | blue | blue | [gray]{0.9} | 藏蓝严谨,期刊风格 |
| github-light | blue | blue | blue | [gray]{0.92} | 极简蓝白,程序员友好 |
| ink-wash | black | black | black | [gray]{0.92} | 水墨素雅,文学/设计类 |
| nord-frost | teal | teal | teal | [gray]{0.9} | 北欧冰霜蓝灰 |
| consulting-navy | blue | blue | blue | [gray]{0.88} | 咨询深蓝,研究报告风 |
chinese-red 完整示例(本次一滕项目实际使用)
pandoc input.md -o output.pdf \
--pdf-engine=xelatex \
-V CJKmainfont="Songti SC" -V mainfont="Palatino" -V monofont="Menlo" \
-V geometry:margin=2.5cm -V fontsize=11pt \
-V colorlinks=true -V linkcolor=red -V toccolor=red -V urlcolor=red \
--toc -V toc-title="目录" -V documentclass=article \
-V header-includes='
\usepackage{fancyhdr}
\pagestyle{fancy}
\fancyhf{}
\fancyhead[L]{\small 报告标题 | 品牌名}
\fancyhead[R]{\small 商业机密}
\fancyfoot[C]{\thepage}
\usepackage{draftwatermark}
\SetWatermarkText{商业机密}
\SetWatermarkScale{0.5}
\SetWatermarkColor[gray]{0.9}
'
latex-clean 完整示例(最简洁的 LaTeX 学术风格)
选择 latex-clean 时,跳过 reportlab,直接使用 pandoc 生成。特点:无封面、无扉页、
无装饰色块,采用纯 LaTeX 排版 + 点线目录引导符,适合内容为王的学术/技术文档。
pandoc input.md -o output.pdf \
--pdf-engine=xelatex \
-V CJKmainfont="Songti SC" -V mainfont="Palatino" -V monofont="Menlo" \
-V geometry:margin=2.5cm -V fontsize=11pt \
-V colorlinks=true -V linkcolor=brown -V toccolor=brown -V urlcolor=brown \
--toc -V toc-title="目录" -V documentclass=article
如需添加页眉、页脚或水印,请参考上方“添加水印 + 页眉/页脚”,并追加 -V header-includes。
已知限制(pandoc 回退方案)
- 没有封面(pandoc 文章类没有内置封面——如有需要,可使用
--include-before-body和 LaTeX 片段) - 不支持扉页/封底(这些请使用 md2pdf.py)
→★☆符号在 Palatino 中可能会触发警告——它们通过 CJK 字体回退机制渲染,可放心忽略- ASCII 艺术图会渲染为代码块(与 md2pdf.py 相同)
依赖项(pandoc 回退方案)
需要 pandoc 和带有 XeLaTeX 的 TeX 发行版:
brew install pandoc
brew install --cask mactex-no-gui # 或 basictex
依赖项
pip install reportlab --break-system-packages