返回博客
6 分钟阅读
MarkdownToImage

保留代码高亮的 Markdown 转 PDF:怎么让语法色不丢

怎么把 Markdown 转 PDF 不丢代码高亮。为什么大部分工具会剥色、三件必须对齐的事、适合打印的主题选择,以及逐个工具的比较。

保留代码高亮的 Markdown 转 PDF:怎么让语法色不丢

快速结论

Markdown 转成 PDF 后还能不能保留语法高亮,关键不在 Markdown 文件本身,而在整条渲染链路。代码围栏要标明语言,渲染器要真正执行语法高亮,PDF 导出还要保留背景色、字体和换行设置。

如果只处理一份文档,最省事的办法是打开 MarkdownToImage 的 Markdown 转 PDF 工具:粘贴或上传 Markdown,先检查预览,再选择主题、字体和文档宽度,最后导出。需要自动化或精细控制时,再考虑 md-to-pdf、VS Code Markdown PDF 或 Pandoc。

为什么语法颜色会丢失

大多数问题都能稳定复现。先检查下面三项:

  1. 代码围栏没有声明语言。 只有三个反引号的代码块只是预格式化文本。请在开头写上 javascriptpythonbash 或最接近的受支持语言。
  2. 导出时没有启用背景图形。 语法主题通常同时依赖文字颜色和代码块背景。浏览器或 Chromium 导出可能保留彩色词元,却把背景去掉。
  3. 预览和 PDF 使用了不同设置。 渲染器、主题、字体、页面宽度或打印样式表只要有一项不同,颜色和换行就可能变化。先用一个小样例比较预览与 PDF,再处理长文档。

与其笼统地说“PDF 会让代码褪色”,不如检查导出前到底渲染出了什么。PDF 完全可以保存彩色文字,问题通常发生在写入 PDF 之前。

导出前先用这个小片段测试

把下面代码放进同一份文档,先导出一次:

const palette = ["cyan", "amber", "coral"];

function renderStatus(format) {
  return `${format}: ${palette.length} colors`;
}

console.log(renderStatus("PDF"));

在预览和 PDF 中分别检查五点:关键字颜色、字符串颜色、代码块背景、等宽字体,以及模板字符串那一行的换行方式。任何一项不一致,都应该先修正主题或导出设置,再继续处理正式文档。

Markdown 代码高亮在 PDF 转换流程中得到保留

四种可靠的导出方式

MarkdownToImage /markdown-to-pdf

网页版通过服务端 Chromium 生成 PDF,支持带语法高亮的代码块、KaTeX 公式、Mermaid 图表、表格、嵌入图片和任务列表。预览就是最重要的检查基准:先设置主题、字体和文档宽度,再导出并比较上面的测试代码。

目前免费导出会带水印;登录免费账户后总共有 5 次免水印导出。价格与额度以后可能调整,如果要把它放进长期流程,请先查看当前转换页面

适合场景:不想安装本地工具,又希望快速得到排版完整的 PDF。

md-to-pdf CLI

md-to-pdf 使用 Marked 解析 Markdown、highlight.js 处理代码高亮,再通过 Puppeteer/Chromium 生成 PDF。默认高亮主题是 GitHub,也可以显式指定其他主题。

md-to-pdf input.md --highlight-style github --pdf-options '{ "printBackground": true }'

需要在脚本或 CI 中重复构建同一文档时,CLI 更合适。如果使用带背景色的深色主题,要保留 printBackground。不要直接处理不可信的 Markdown;该工具的官方说明也明确建议先做安全过滤。

VS Code Markdown PDF

Markdown PDF 扩展 使用基于 Chromium 的浏览器导出,并通过 highlight.js 处理代码围栏。语法高亮默认开启,主题由 markdown-pdf.highlightStyle 单独控制。

"markdown-pdf.highlightStyle": "github.css"

修改设置后,再导出一次测试代码。扩展当前使用 highlight.js v11,旧主题文件名可能已经更名或移除;遇到问题时应选择现有主题,而不是默认老名称仍然有效。

Pandoc

Pandoc 使用 Skylighting 高亮带语言标识的代码围栏。当前 Pandoc 推荐 --syntax-highlighting,旧的 --highlight-style 写法已经弃用。

pandoc input.md -o output.pdf --syntax-highlighting=pygments

Pandoc 还提供 katetangozenburnbreezeDark 等内置样式,也支持自定义 JSON .theme 文件。如果你的流程已经包含 Pandoc 模板、引用或 LaTeX 排版,它通常是最合适的选择。字体与分页仍会受到 PDF 引擎和模板影响,需要单独测试。

浏览器打印:先验证,不要想当然

把已经渲染好的 Markdown 页面直接“打印为 PDF”有时也能保留高亮,但结果完全取决于页面的 print CSS。有些站点会保留颜色和背景,有些则会为了纸张输出简化所有样式。请在打印对话框中启用背景图形,检查分页,再比较测试代码。

如果页面本身已经显示正确,浏览器打印很方便;但除非你同时控制 HTML、CSS、浏览器版本和打印设置,否则它不算稳定的自动化构建方式。

导出前检查清单

  • 每个代码围栏都写明语言。
  • 可能打印的文档优先选择浅色、高对比度主题。
  • 主题依赖背景色时,启用背景图形。
  • 使用确定存在的等宽字体,并在导出环境中确认字体可用。
  • 按最终 A4 或 Letter 页面宽度检查长行,不要套用屏幕上的换行结果。
  • 长报告导出前,先运行上面的 JavaScript 小样例。
  • 用户或外部系统提交的 Markdown 必须先过滤,再交给本地转换器。
  • 最终 PDF 至少打开检查一次:颜色、可选中文字、链接、图片和分页都要正常。

需要更完整的横向比较,可以阅读 Markdown 转 PDF 的五种方法。要建立可重复执行的流程,请继续看 使用 CLI、Pandoc 和 CI 批量转换

常见问题

为什么预览里有颜色,PDF 中却变成普通文字?

先确认已启用背景图形,再检查导出是否使用了与预览相同的主题和渲染器。页面的打印样式表也可能覆盖词元颜色。

适合打印的 PDF 应该选什么主题?

可以先用 GitHub 或其他浅色主题。它们通常在彩色和灰度打印中都更容易阅读。深色主题更适合屏幕 PDF,但分享前必须检查背景和对比度。

能保留行号吗?

只有渲染器或主题主动添加行号时才可以。标准 Markdown 代码围栏本身没有行号。想得到稳定结果,应使用自己能控制的 CLI 或样式表,并按最终页面宽度测试。

批量转换会不会丢失高亮?

不会必然丢失。可以使用基于 Chromium 的 CLI 保持 Web 风格高亮,也可以给 Pandoc 显式指定语法主题。在 CI 中固定工具版本和主题,避免未来构建结果悄悄变化。

现在就试一次

打开 MarkdownToImage 的 Markdown 转 PDF 工具,粘贴本文的小段 JavaScript,然后导出一份 PDF。把预览和文件并排比较;确认颜色、背景、字体和换行一致后,再换成你的正式文档。

Markdown To Image | 保留代码高亮的 Markdown 转 PDF:怎么让语法色不丢 | MarkdownToImage