直接用 markdown-pdf 会失败,因其自2021年停更,依赖的 phantomjs 在 Node 16+ 下无法编译,且不支持 @media print、中文字体渲染,导致字体重叠、页眉错位、代码截断;推荐用 marked + puppeteer 自定义 HTML 模板生成 PDF。

为什么直接用 markdown-pdf 会失败
因为 markdown-pdf 模块自 2021 年后已停止维护,其依赖的 phantomjs 在 Node 16+ 环境下根本无法编译安装,运行时大概率报错 Error: Cannot find module 'phantomjs' 或 node-gyp rebuild 失败。它也不支持现代 CSS @media print 规则和中文字体渲染,默认输出的 PDF 经常字体重叠、页眉错位、代码块截断。
用 puppeteer + 自定义 HTML 模板才是可行路径
核心思路是:不依赖任何 Markdown 转 PDF 的“黑盒”工具,而是把 Markdown 渲染成带样式的 HTML(用 marked),再用 puppeteer 打印为 PDF。这样能完全控制字体、页边距、页码、目录结构等讲义必需元素。
- 安装必须的包:
npm install marked puppeteer(puppeteer会自动下载 Chromium,首次运行较慢) - 准备一个最小 HTML 模板(如
template.html),内嵌@media print样式,指定font-family: "Noto Sans CJK SC", sans-serif避免中文方块 - 用
marked的renderer选项处理标题层级,为<h1></h1>~<h3></h3>自动添加id,后续可生成目录锚点 - 调用
puppeteer.launch({ headless: true })后,用page.setContent(html, { waitUntil: 'networkidle0' })加载内容,再执行page.pdf(),务必传入{ format: 'A4', printBackground: true, margin: { top: '20mm', bottom: '20mm', left: '15mm', right: '15mm' } }
VSCode 中一键触发的关键是 Task + 自定义脚本
VSCode 本身不提供“当前 Markdown 转 PDF”按钮,但可通过配置 .vscode/tasks.json 把转换逻辑绑定到快捷键(如 Ctrl+Shift+P → “Tasks: Run Task”)。
ZenHeart zenlink 与 zenlink-mcp 为 OpenClaw,涵盖安装、MCP 注册、钩子接线、入站轮询及升级维护。
- 在项目根目录建
scripts/md2pdf.js,读取process.argv[2](即当前打开的 .md 文件路径),用fs.readFileSync读内容,经marked渲染,套入模板,输出同名 .pdf -
tasks.json中定义 task:"command": "node", "args": ["${workspaceFolder}/scripts/md2pdf.js", "${file}"],并设"group": "build"方便快速调用 - 注意路径问题:
${file}是绝对路径,但marked不处理图片相对路径;需在渲染前用正则把替换为, './assets/xxx.png')}) - 如果讲义含数学公式,别用
marked默认 renderer,改用marked.use({ extensions: [ { name: 'katex', renderer: ... }] })配合katex库预渲染
中文页眉页脚和目录必须手动注入
puppeteer.pdf() 不支持自动生成目录或页眉页脚,必须在 HTML 模板里写死或用 page.evaluate() 注入 DOM。
- 页眉用
@page { @top-center { content: "《算法导论》讲义"; } }无效(Chromium 不支持),正确做法是在模板中固定位置放<header class="pdf-header">...</header>,配合position: fixed; top: 0 - 目录需先用正则提取所有
<h2 id="xxx">标题</h2>,拼成 HTML 字符串插入模板指定位置;否则 PDF 里只有正文,没有导航 - 生成的 PDF 文件默认无书签(outline),要启用需额外调用
page.pdf({ ... })后,用pdf-lib库打开该文件,手动添加 outline 条目——这步容易被跳过,结果 PDF 在 Acrobat 里无法点击跳转
真正卡住人的从来不是“能不能转”,而是字体 fallback 是否完整、页边距是否适配打印、目录链接是否指向正确 offset —— 这些细节没处理,PDF 就只是个能看的快照,不是可交付的讲义。


















