关于 lov-any2pdf
lov-any2pdf 是将 Markdown 文档排版为 PDF 的 Skill,支持中日韩文字及多种复杂内容。它提供多种主题,并可设置封面、目录和水印。
主要功能
- 01Markdown 转 PDF
- 02中日韩与拉丁文字混排
- 03表格、代码、图片与标注
- 04主题、封面与目录
- 05书签与公式渲染
适用场景
- 01排版中文技术报告
- 02转换含表格和代码的 Markdown
- 03为 PDF 添加封面和目录
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ lovstudio/ any2pdf --skill lov-any2pdf安装后在 Claude Code 中输入/lov-any2pdf确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
skill.yamlreferences/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) 海洋 — 青绿色调,清新自然
━━━ 🖼 扉页图片(封面之后的全页插图) ━━━
1) 跳过
2) 我提供本地图片路径
3) AI 根据内容自动生成一张
━━━ 💧 水印 ━━━
1) 不加
2) 自定义文字(如 "DRAFT"、"内部资料")
━━━ 📇 封底物料(名片/二维码/品牌) ━━━
1) 跳过
2) 我提供图片
3) 纯文字信息
示例回复:"a, 扉页跳过, 水印:仅供学习参考, 封底图片:/path/qr.png"
直接说人话就行,不用记编号 😄
将用户选择映射到 CLI 参数
| 选择 | CLI 参数 |
|---|---|
| 设计风格 a-j | --theme,值取自下表 |
| 本地扉页 | --frontispiece <path> |
| AI 生成扉页 | 先生成图片,然后使用 --frontispiece /tmp/frontispiece.png |
| 水印文字 | --watermark "文字" |
| 封底图片 | --banner <path> |
| 封底文字 | --disclaimer "声明" 和/或 --copyright "© 信息" |
主题名称映射
| 选择 | --theme 值 | 灵感来源 |
|---|---|---|
| a) 暖学术 | warm-academic | Skill Publisher 设计系统 |
| 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 | — |
处理 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 的 Paragraph 中保留缩进和换行 - 智能表格宽度:根据内容长度按比例设置列宽,并设定 18mm 的最小宽度
- 书签系统:
ChapterMark流式组件会创建 PDF 侧边栏书签和命名锚点 - 标题预处理器:
_preprocess_md()将# Part## Chapter这类合并标题拆分为独立行 - 图片处理器:本地、相对路径、
file://和远程 Markdown 图片会缩放至正文区域;发生错误时显示备用文本 - 提示框渲染器:Obsidian 风格的
> [!NOTE]区块会渲染为带主题样式的框状提示 - 公式渲染器:显示公式可使用可选的 matplotlib mathtext 图片;也可回退为带样式的文本
- 表情符号回退:有可用的缓存 Twemoji PNG 时使用它们渲染表情符号,否则回退到本地表情符号字体
经验教训
CJK 字符显示为 □
reportlab 的 Paragraph 只使用 ParagraphStyle 中的字体。如果 fontName="Mono",但
文本包含中文,中文就会显示为 □。修复方法:始终对所有可能包含 CJK 的文本应用 _font_wrap(),包括代码块。
代码块丢失换行
reportlab 会将 \n 视为空白字符。修复方法:esc_code() 会将 \n 转换为 <br/>,并将
所有空格转换为 ,以便在应用 _font_wrap() 前保留缩进和行内对齐。
CJK/拉丁文字换行
reportlab 默认只在空格处换行,导致出现 "Claude\nCode" 这样的难看断行。
修复方法:在正文和项目符号样式中设置 wordWrap='CJK',以允许在 CJK 字符边界处换行。
Canvas 中含 CJK 的文本(封面/页脚)
使用拉丁字体的 drawString() / drawCentredString() 无法显示 年/月/日 等字符。
修复方法:对所有包含用户内容的 canvas 文本(日期、统计数据、免责声明)使用 _draw_mixed()。
配置参考
大多数选项也可以在文件顶部的 YAML 风格 frontmatter 中设置。显式 CLI 参数优先于 frontmatter 值。
| 参数 | Frontmatter 键 | 默认值 | 描述 |
|---|---|---|---|
--input | — | (必填) | 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 | "" | 封底横幅图片 |
--header-title | header-title | "" | 页眉中的报告标题 |
--footer-left | footer-left | author | 页脚中的品牌/作者 |
--stats-line | stats-line | "" | 封面上的统计信息 |
--stats-line2 | stats-line2 | "" | 第二行统计信息 |
--edition-line | edition-line | "" | 封面底部的版本信息 |
--disclaimer | disclaimer | "" | 封底免责声明 |
--copyright | copyright | "" | 封底版权信息 |
--code-max-lines | code-max-lines | 30 | 每个代码块的最大行数 |
主题
可用主题:warm-academic、nord-frost、github-light、solarized-light、
paper-classic、ocean-breeze。
每个主题定义:页面背景、墨色、强调色、淡化文本、边框、代码背景和水印色调。
依赖项
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
运行时上下文(共享)
运行前读取本 Skill 包的 skill.yaml,由宿主提供 skill-runtime/v1 上下文。字段解析顺序为:当前请求、项目上下文、个人 Preferences、品牌 Profile、通用默认值。
- 只使用 Manifest 声明的字段;Profile 保存公开品牌事实,Preferences 保存个人工作偏好。
- 缺少
required: true字段时,按 Manifest 的问题配置向用户提出一个聚焦问题;用户明确同意后再保存回答。 - 报错提供可复制的
context_id、字段路径与来源,诊断内容避开秘密、完整私人路径和原始配置。