关于 lovstudio-any2pdf
将 Markdown 文件排版并转换为 PDF 的技能,面向需要制作正式文档的用户。支持中日韩文字、代码块、表格、图片和多种封面与版式选项。
主要功能
- 01将 Markdown 转为 PDF
- 02处理中日韩混排与代码块
- 03排版表格、图片和提示框
- 04生成目录、书签和封面
- 05支持水印与多种主题
适用场景
- 01将技术报告导出为正式 PDF
- 02制作含中日韩文字的文档
- 03为文档添加封面、目录或水印
- 04处理含表格、图片和公式的 Markdown
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ lovstudio/ skills --skill lovstudio-any2pdf安装后在 Claude Code 中输入/lovstudio-any2pdf确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
CHANGELOG.mdREADME.mdcases/cases.jsonissue-regressions.mdreferences/themes.mdscripts/md2pdf.py详细介绍
any2pdf — 将 Markdown 转换为专业 PDF
这项技能使用 Python 的 reportlab 库,将任意 Markdown 文件转换为出版级质量的 PDF。它通过对真实中文技术报告进行大量迭代开发,解决了许多简单的 MD→PDF 转换器容易处理错误的棘手问题。
适用场景
- 用户想将
.md→.pdf - 用户有一份 Markdown 报告/文档,并希望获得专业排版
- 文档包含与拉丁文字混排的 CJK 字符(中文/日文/韩文)
- 文档包含围栏代码块、Markdown 表格或嵌套列表
- 文档包含本地/远程图片、Obsidian 提示框、表情符号或数学公式
- 用户想为 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(中日韩文字正文)和 Menlo(代码);Linux 上自动回退
- 中日韩文字包装器:
_font_wrap()将中日韩字符序列包装在<font>标签中,以自动切换字体 - 混合文本渲染器:
_draw_mixed()处理画布上的中日韩文字与拉丁文字混排(封面、页眉、页脚) - 代码块处理器:
esc_code()在 reportlab Paragraph 中保留缩进、行内对齐和换行 - 智能表格宽度:根据内容长度按比例设置列宽,最小宽度为 18mm
- 书签系统:
ChapterMarkflowable 可创建 PDF 侧边栏书签和命名锚点 - 标题预处理器:
_preprocess_md()将# Part## Chapter这类合并标题拆分为单独的行 - 图片处理器:本地、相对路径、
file://和远程 Markdown 图片都会缩放至正文框架内;出错时显示备用文本 - 提示框渲染器:Obsidian 风格的
> [!NOTE]区块会渲染为带主题样式的方框提示 - 公式渲染器:显示公式可使用可选的 matplotlib mathtext 图片,并在无法使用时回退到带样式的文本
- Emoji 回退:有可用的缓存 Twemoji PNG 时使用它们渲染 Emoji,否则回退到本地 Emoji 字体
来之不易的经验
中日韩字符渲染为 □
reportlab 的 Paragraph 只使用 ParagraphStyle 中设置的字体。如果 fontName="Mono",但
文本中含有中文,字符就会渲染为 □。解决方法:对所有可能包含中日韩文字的文本始终应用 _font_wrap(),
包括代码块。
代码块丢失换行
reportlab 会将 \n 视为空白字符。解决方法:esc_code() 会将 \n 转换为 <br/>,并
将所有空格转换为 ,在应用 _font_wrap() 前保留缩进和行内对齐。
中日韩文字与拉丁文字的自动换行
reportlab 默认只在空格处断行,导致出现“Claude\nCode”这类难看的断行。解决方法:在正文和项目符号样式上设置 wordWrap='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 表格或图片引用。
配置参考
大多数选项也可以在文件顶部采用 YAML 风格的 frontmatter 设置。显式 CLI 参数优先于 frontmatter 值。
| 参数 | Frontmatter 键 | 默认值 | 描述 |
|---|---|---|---|
--input | — | (required) | Markdown 文件路径 |
--output | — | output.pdf | 输出 PDF 路径 |
--title | title | 来自第一个 H1 | 封面上的文档标题 |
--subtitle | subtitle | "" | 副标题文本 |
--author | author | "" | 作者姓名 |
--date | date | 今天 | 日期字符串 |
--version | version | "" | 封面上的版本字符串 |
--watermark | watermark | "" | 水印文本(空 = 无) |
--theme | theme | warm-academic | 配色主题名称 |
--theme-file | — | "" | 自定义主题 JSON 文件路径 |
--cover | cover | true | 生成封面 |
--toc | toc | true | 生成目录 |
--page-size | page-size | A4 | 页面尺寸(A4 或 Letter) |
--frontispiece | frontispiece | "" | 封面之后的整页图片 |
--banner | banner | 内置的 assets/backcover-banner.jpg | 封底横幅图片(传入 none 可禁用) |
--header-title | header-title | "" | 页眉中的报告标题 |
--footer-left | footer-left | 作者 | 页脚中的品牌/作者 |
--stats-line | stats-line | "" | 封面上的统计信息 |
--stats-line2 | stats-line2 | "" | 第二行统计信息 |
--edition-line | edition-line | "" | 封面底部的版本信息 |
--disclaimer | disclaimer | "" | 封底免责声明 |
--copyright | copyright | "" | 封底版权信息 |
--code-max-lines | code-max-lines | 30 | 每个代码块的最大行数 |
--image-cover | image-cover | false | 将卷首插图用作满版封面(第 1 页),文字封面移至第 2 页 |
--heading-top-spacer | heading-top-spacer | 5 | H1/H2 章节标题前的顶部间距,单位为 mm |
--wm-size | wm-size | 自动(半页宽) | 水印字号;自动缩放,使文本宽度约为页面宽度的 50% |
--wm-opacity | wm-opacity | 0.1 | 水印不透明度(0.0–1.0) |
--wm-angle | wm-angle | 35 | 水印旋转角度,单位为度 |
--wm-spacing-x | wm-spacing-x | 9999 | 水印水平间距,单位为 pt(≥2000 = 每页居中显示一个) |
--wm-spacing-y | 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 排版 + 点线 TOC 引导符,适合内容为王的学术/技术文档。
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 article 类没有内置封面;如有需要,可使用 LaTeX 代码片段配合
--include-before-body) - 不支持扉页/封底(请使用 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
# Optional formula rendering:
pip install matplotlib --break-system-packages
推荐的 Ubuntu/Debian 字体:
sudo apt install fonts-dejavu-core fonts-liberation fonts-freefont-ttf fonts-noto fonts-noto-cjk fonts-noto-color-emoji