md-pdf-report

Other

Convert Markdown research reports / fact-checks / scheme proposals into styled PDFs with native CJK (Chinese) font support. Markdown is the single source of truth; PDF is generated FROM the Markdown. Triggers on "做个 PDF 报告", "转成 PDF", "调研报告", "fact-check 报告", "方案 PDF", "scheme 报告", "给我 PDF", "PDF 版本", or any long-form analytical content that needs to be both editable (MD) and viewable/shareable (PDF).

Install

openclaw skills install md-pdf-report

md-pdf-report · Markdown 双产物报告(PDF + MD)

MD 是事实源,PDF 是交付物。 同一份内容,两个产物:

  • .md — 可二次编辑、可分发给其他 Agent
  • .pdf — 打开即看、可分享给他人

(详见下一节"🚨 必做最后一步")

核心用户偏好(Jialin): 调研类内容要同时产出 PDF(方便看/分享)和 MD(方便二次编辑或分发给其他 Agent)。MD 是单一事实源,不要写两份。


何时使用

触发用法
"做个 PDF 报告" / "转成 PDF" / "给我 PDF 版本"→ 本 skill
"调研报告"、"fact-check 报告"、"方案 PDF"→ 本 skill
长文分析(> 1 页 A4)需要可编辑源文件→ 本 skill
用户说"以后经常用" 类长文输出→ 本 skill

不适用:

  • 简历、一页纸、产品白皮书、品牌文档 → 用 kami
  • PPT/slides → 用 kami 的 slides 路径
  • 简短消息/通知 → 直接发文字
  • 不需要 PDF,只要 MD → 直接写 .md,不调用本 skill

快速开始

# 1. 选模板(首次使用)
cp ~/.hermes/skills/md-pdf-report/templates/research-report.md ~/my-report.md
# 或 fact-check.md, scheme.md

# 2. 编辑内容(用任何 MD 编辑器)

# 3. 生成 PDF
python3 -m md2pdf ~/my-report.md

# 4. 交付(飞书/Telegram)
# 在对话中:MEDIA:/Users/you/my-report.pdf

Python 用法:

from md2pdf import md_to_pdf
md_to_pdf("report.md")                    # 同名 .pdf
md_to_pdf("report.md", "out.pdf")         # 自定义输出
md_to_pdf("report.md", keep_html=True)    # 保留 .html(调试用)

工作流

Step 1 — 写 Markdown(事实源)

用标准 GitHub-flavored Markdown 写。支持的语法:

  • 标题(#, ##, ###)、列表、表格
  • 加粗斜体行内代码、代码块
  • 链接 [文字](url)
  • 引用 >、分隔线 ---

特殊区块(用 <div> 实现,已在 CSS 中预定义):

Class用途样式
<div class="callout">重要提示、警示、关键结论红色边框 + 浅红背景
<div class="note">注释、补充信息、免责声明灰色边框 + 浅灰背景
<div class="warn">警告黄色边框 + 浅黄背景

示例:

<div class="callout">

**重要:** 这是一段红色 callout 文字。Testing mixed CJK + English.

</div>

模板起点: templates/research-report.mdtemplates/fact-check.mdtemplates/scheme.md

Step 2 — 转换为 PDF

python3 -m md2pdf /path/to/report.md            # 基本用法
python3 -m md2pdf report.md -o final.pdf         # 自定义输出
python3 -m md2pdf report.md --keep-html          # 保留中间 HTML(调试)

Step 3 — 交付

飞书/Telegram 对话框中,PDF 通过 MEDIA: 前缀上传:

MEDIA:/absolute/path/to/report.pdf

飞书/Telegram 会自动作为附件投递。


关键技术细节

⚠️ Pitfall #1: macOS .ttc 字体不可用

苹果系统 .ttc 字体文件(PingFang.ttc、STHeiti Medium.ttc)用 PostScript outlines, reportlab 和 weasyprint 都无法加载

解决:.ttf 字体文件:

字体用途路径
STXIHEI正文…/10e7a462a671950b802274fad767b566ff8457d1…/STXIHEI.ttf
STHEITI标题…/53fe5be564086fefc7523ccd0a31200acf92e0e5…/STHEITI.ttf
Kai注释/引用…/6331c5916c361af1b83fb8b8b76ef2eece20c8eb…/Kai.ttf

完整路径、验证脚本、失败模式references/macos-cjk-fonts.md

⚠️ Pitfall #2: weasyprint 缺 C 库

brew install pango
export DYLD_FALLBACK_LIBRARY_PATH=/opt/homebrew/lib

md2pdf.pybootstrap_macos() 在导入时自动设置。设 MD2PDF_NO_BOOTSTRAP=1 可关闭。

详细步骤、验证方法、Linux 替代references/weasyprint-bootstrap.md

⚠️ Pitfall #3: HTML 标签在 reportlab 表格里需要 Paragraph 包裹

如果混用 reportlab 路径(罕见,本 skill 默认 weasyprint),<b> <br/>Table 单元格中不会自动渲染,必须把字符串用 Paragraph() 包一层。

⚠️ Pitfall #4: PDF 文件大小

weasyprint 默认嵌入全字体(2-3MB/页)。研究类报告 < 15 页通常无需优化。 超过 15 页或需要邮件发送时,参考 references/pdf-engine-comparison.md 的优化章节。


引擎选择

md2pdf.py 默认使用 weasyprint(最佳平衡点)。三种引擎详细对比、迁移路径见 references/pdf-engine-comparison.md

简要决策:

场景推荐引擎
研究报告、fact-check、方案weasyprint(默认)
程序化生成、极致文件大小reportlab
学术级排版、纯 MD + 公式pandoc + tectonic

文件结构

~/.hermes/skills/md-pdf-report/
├── SKILL.md                    # 本文件
├── scripts/
│   └── md2pdf.py              # 主转换模块(也可作 CLI: python3 -m md2pdf)
├── templates/
│   ├── research-report.md     # 调研报告模板
│   ├── fact-check.md          # 事实核查模板
│   └── scheme.md              # 方案/计划模板
├── references/
│   ├── macos-cjk-fonts.md     # 中文字体路径与陷阱
│   ├── weasyprint-bootstrap.md # C 库安装与环境变量
│   └── pdf-engine-comparison.md # weasyprint vs reportlab vs pandoc
└── examples/
    ├── Mike_Lynch_FactCheck.md  # 真实案例(7页 PDF)
    └── test_report.md           # 最小测试用例

软链到 PATH(可选):

ln -s ~/.hermes/skills/md-pdf-report/md2pdf.py ~/.local/bin/md2pdf
chmod +x ~/.local/bin/md2pdf
# 然后直接用: md2pdf report.md

自定义 CSS

from md2pdf import md_to_pdf, DEFAULT_CSS

# 追加自定义规则
custom_css = DEFAULT_CSS + """
h1 { color: #B91C1C; }  /* 改标题为红 */
table th { background: #0F172A; }  /* 表头更深 */
"""

md_to_pdf("report.md", css=custom_css)

验证清单(生成 PDF 后必做)

  • 中文渲染正常(不是方块、不是问号)
  • 表格不被截断
  • 代码块/引用样式正确
  • callout/note/warn 区块显示正确
  • 页码/页脚正常
  • 链接可点击(导出后 hover 试一下)
  • 文件大小 < 5MB

快速验证命令:

pdfinfo report.pdf | grep Pages           # 检查页数
pdftotext report.pdf - | head -50         # 检查中文渲染

维护

  • macOS 系统升级后字体路径可能变find /System/Library/AssetsV2 -name "STXIHEI.ttf" 重新确认
  • PDF 突然乱码 → 90% 是字体路径失效,重新 find
  • 导出报 cannot load library 'libgobject' → pango 没装好或 DYLD_FALLBACK_LIBRARY_PATH 没设
  • weasyprint 版本更新 → 关注 changelog