Pandoc 的新 Typst 模板
速览
Pandoc 近日发布了新的 Typst 模板,旨在简化从 Markdown 到 Typst 的文档转换流程。该模板允许用户利用 Typst 强大的排版能力生成精美文档。这一更新为偏好 Typst 的用户提供了更便捷的跨格式文档处理方案。
AI 深度解读
为 Pandoc 打造全新的 Typst 模板:从 v0.11 到 v0.13 的演进与重构
背景
去年夏天,作者深入研究了 Typst(当时版本为 v0.11)与 Pandoc 的结合,旨在构建一套灵活且可复用的工作流,将 Markdown 格式的文章排版为 PDF。当时,作者设计了一个针对 Typst 的 Pandoc 模板,该模板在版式和排版方面表现出色,并曾在 Hacker News 上分享过相关经验。
然而,时间快进到 2025 年春季,在这期间,Typst 已升级至 v0.13 版本,Pandoc 也至少进行了三次重大更新(当前版本为 v3.6.4)。由于底层逻辑的变化,作者之前的模板已无法正常工作。造成这一现状的原因主要有两点:一是 Pandoc 自带的 Typst 输出模板发生了变化,其对调用方式的假设不同;二是自 v0.12 版本以来,Typst 的核心逻辑发生了重大变革。
鉴于此,作者在近期教授研究生课程的过程中,着手重建了这一工作流。新的模板体系不仅解决了兼容性问题,还通过分离 Pandoc 的逻辑与 Typst 的逻辑,提高了长期使用的稳健性。
核心内容
工作流的重构与调用方式
新的模板体系基于 Pandoc 默认的 Typst 输出模板。值得注意的是,Pandoc 默认的 Typst 模板本身在格式化方面功能极简,其核心作用是作为桥梁,导入一个真正的 Typst 模板(即专门为 Typst 编写,而非为 Pandoc 编写)。
调用方式如下:
pandoc file.md -o file.pdf -V template=article.typ --pdf-engine=typst
这里的关键在于 -V template=article.typ 参数。这并非直接让 Pandoc 使用其内置模板,而是向 Pandoc 传递一个变量。Pandoc 内部的 template.typst 会检测该变量是否被设置,若被设置,则导入名为 article.typ 的外部模板。这种语法虽然初看有些令人困惑,但它有效地将 Pandoc 的逻辑与 Typst 的逻辑分离开来,从长远来看更加稳健。
为了清晰起见,完整的命令可以拆解为:
pandoc article.md \
-f markdown --wrap=none \
-t pdf --pdf-engine=typst \
-V template=article.typ \
-o article.pdf
模板的设计哲学
新开发的 Typst 模板假设用户以上述方式运行命令,并负责从 Markdown 源文件中收集 Pandoc 所能识别的所有元数据。作者假设 Markdown 文件头部包含标准的元数据块(如标题、作者、日期等)。
该模板旨在承担大量的排版工作,但用户可以根据需求禁用部分功能。以下是模板各部分的详细解析:
-
元数据映射(Content-to-string mapping): 这部分代码直接借鉴自 Pandoc 的极简 Typst 模板。其作用是将多部分元数据(如作者姓名、电子邮件等)组装成字符串,使其在 Typst 中可用。
-
配置设置(Conf setup): 为模板设置默认值,包括来自文档元数据的变量,以及页面尺寸、格式、基础字体和编号选项等样板内容。
-
页眉与页脚(Running heads and footers): 这是第一个主要的自定义部分。模板支持左右页面对称排版(如书籍格式)。
- 如果文档区分左右页,页眉和页脚将分别对齐左侧和右侧,并可选地包含不同内容。
- 如果不关心左右页区分,可以将第 41 行的边距设置为相同值(即“内侧”和“外侧”边距一致),并将左右页的页眉设置为相同内容。
- 页眉/页脚的内容基于当前页码是奇数还是偶数来决定。用户也可以根据偏好将对齐方式设置为居中。
-
文本基础属性: 利用 Typst 对 OpenType 字体选项的支持,启用连字(ligatures)、旧式数字(old-style figures)等功能。
-
特定元素样式(第 110 行起): 定义了块引用、代码块、图片及标题、脚注的样式。虽然代码量不大,但注重细节,视觉效果优于默认设置。
-
标题层级样式(第 143 行起): 定义了三个层级的标题,并提供了风格差异。这些格式设置略显华丽,旨在展示 Typst 的能力,并方便后续调整样式。
-
标签化章节(第 170 行起): 设置了两个带标签的章节:引言(Epigraphs)和参考文献(References)。
- 例如,参考文献部分使用了悬挂缩进(hanging indent)。
- 这些章节通过 Markdown 中的特定语法调用,Pandoc 会将其识别并转换为 Typst 的“标签”(Label),类似于 HTML 中给 div 添加 ID。
- 示例 Markdown 语法:
::: {#epigraph} It was the best of times... ::: - 用户可以为内容中的任何标签自定义样式。
-
特定文本正则匹配(第 185 行起): 要求 Typst 对特定文本片段进行样式处理。
- 例如,使用正则表达式匹配日期后跟随的“CE”,并将其设置为小型大写字母(smallcaps)。
- 另一处样式处理针对 URL。用户可以添加更多此类规则。
-
文档布局(第 192 行起): 这是文档的实际布局部分。作者保持了简洁,但可以通过编写更多 Typst 代码来使其更加复杂。
- 标题/元数据显示块:包含标题、作者、日期和摘要,周围留有额外的垂直空间,并用一条线与正文分隔。
- 正文显示:设置段落样式为两端对齐(justified)且首行缩进。这些设置在正文部分定义,以避免标题块也应用首行缩进和两端对齐。
- 附注(Colophon):最后包含一段简短的附注,致谢 Typst 和 Pandoc。
关键要点
- 版本兼容性危机:Pandoc(v3.6.4)和 Typst(v0.13)的多次重大更新导致旧版模板失效,特别是 Pandoc 默认输出模板逻辑的变化和 Typst 核心逻辑的重构。
- 逻辑分离架构:新工作流通过
-V template=...参数,让 Pandoc 导入外部 Typst 模板,实现了 Pandoc 逻辑与 Typst 排版逻辑的解耦,提高了系统的长期稳健性。 - 元数据自动化:模板能够自动从 Markdown 头部的元数据块中提取标题、作者、日期等信息,并处理多部分元数据(如作者列表)的字符串组装。
- 高级排版功能:
- 支持复杂的页眉页脚逻辑,区分左右页(奇偶页)并支持对称对齐。
- 支持 OpenType 字体特性(连字、旧式数字)。
- 支持通过正则表达式自动格式化特定文本(如日期后的“CE”、URL)。
- 灵活的标签系统:利用 Pandoc 的
::: {#label}语法,允许用户在内容中插入自定义标签,并在 Typst 模板中为这些标签定义独特的样式(如悬挂缩进的参考文献)。 - 代码优化:相比去年的版本,新模板代码更简洁、组织更有序,部分得益于 Typst 引擎本身的智能化提升以及作者对文档理解的加深。
意义与影响
这一工作流的重建不仅解决了技术兼容性问题,更代表了 Markdown 到 PDF 排版工作流的一种最佳实践演进。
首先,它证明了 Pandoc 作为内容转换引擎 与 Typst 作为排版引擎 分离架构的优势。通过 -V 参数传递模板路径,使得排版逻辑完全由 Typst 掌控,避免了 Pandoc 模板语法与 Typ
