PreTeXt:以XML为核心的结构化写作与多格式出版系统 早几年我给别人推荐写作工具一般就两条路要么无脑 Markdown渲染 PDF 时再套 Pandoc要么请作者直接学 LaTeX一步到位但学习曲线劝退好多人。直到我在一个开源教材项目里遇到 PreTeXt 之后我对“文本排版引擎”的认知被修正了一次。先说结论PreTeXt 不是一个类似 Word 那样的编辑软件也不是单纯把 Markdown 变成 PDF 的转换器。它是一个以 XML 为核心的写作和出版系统覆盖“内容结构编写 → 自动化转换 → HTML/PDF/EPUB 多格式出版”的完整链路。很多技术文章把它叫“文本排版引擎”严格来说它更像“排版流水线上的指挥系统”底下真正干排版重活的其实还是 LaTeX/XeLaTeX 或 HTMLCSS。但正是因为它在内容和版面之间加了一层语义结构才让写书、写长文档这类本来很容易翻车的项目变得可控、可维护、可以多人协作。这套体系特别适合谁我认为是这几类人准备和维护开源教材/技术手册的团队、经常出结构化报告或习题集的内容团队、以及所有对“同一份内容要同时输出网页版和印刷版”有执念的人。如果你只是临时打印一封两页的说明信别用它杀鸡不用牛刀。1. 它不是又一个 LaTeX 平替而是一套“结构→版面”的发布管线1.1 一句话先认识 PreTeXtPreTeXt 的历史可以追溯到十几年前最初它服务于美国数学协会资助的开源数学教材项目比如著名的 Abstract Algebra: Theory and Applications 以及 Precalculus 等。它的设计起点非常朴素一群数学老师想写教科书写完不仅想印成书还希望学生能在网页上免费阅读同一套内容最好还能导成电子书。按传统做法这需要同一份内容在 LaTeX 和 HTML 里各维护一份更新一个小节要改两三个地方很快就会精神崩溃。PreTeXt 的思路是让作者只维护一份以语义标记为核心的 XML 源文件然后所有输出格式都从这份源文件自动生成。这个思路听起来很像 Pandoc其实深度完全不同。Pandoc 做的是通用格式转换你把 Markdown 丢进去能出来 LaTeX、docx、epub但它不会理解“这是一个 exercise”“这是一段 hint”“这是交叉引用一个 example”这类语义PreTeXt 的 XML 词汇表是专门为图书级内容设计的它“认识”书稿里的章节、引理、习题、解答、示例、术语表并能基于这些语义在不同输出格式里自动排版。所以本质上PreTeXt 是一套“结构写作格式 转换工具链”再往下去调用真正的排版引擎完成视觉呈现。1.2 同一份 ptx 源码最终会走三条不同的技术通道为了理解它为什么被称为排版引擎我们需要看一下它输出端的真实结构。以我目前使用的版本为例PreTeXt 对同一份.ptx源文件会执行不同的转换任务目标格式中间链路背后真正干排版活的部件适用场景PDF电子稿/印刷稿XML → 书籍级 LaTeXXeLaTeX/LuaLaTeX出版级打印、线下阅读HTML多页/单页XML → HTML5 自定义 CSS浏览器渲染在线浏览、手机阅读EPUBXML → HTML → EPUB 容器阅读器渲染电子书商店分发Jupyter Notebook / 幻灯片XML → 对应工程模板各平台工具教学课件、交互式实验上面每一条链路都不简单但在 PreTeXt 的设计里作者只需要掌握源文件那套 XML 词汇其他全是构建命令自动完成的。这个抽象做得越彻底内容团队就越不用关心“今天 PDF 模板里用了什么字体包”“明天网页版这块排版怎么不换行”。我自己的体会是PreTeXt 把一个传统上特别依赖“个人排版品味”的事情变成了“内容和样式按纪律分离”的工程流程。这也使得它非常适合有长期维护需求的项目。因为时间一长你会发现一套书真正值钱的不是它最后生成的 PDF 多漂亮而是那堆可复用、可重构、可自动转格式的内容资产。2. 这个文本排版方案真正让人眼前一亮的地方2.1 内容与样式彻底解耦约束反而带来自由很多从 LaTeX 过来的作者有一个毛病写着写着就分不清内容结构和视觉样式了。比如明明在讲一个概念会突然想“这里的标题我改成红色加粗好不好看”然后一路钻进样式微调里出不来。PreTeXt 从根上断了这个念头因为源文件里你根本没有颜色、字号、浮动体位置的标签只有章节、段落、图表、习题这些结构元素。这种约束一开始会让人不习惯但它极大地保护了内容质量。尤其是多人协作时如果在 LaTeX 项目里十个人有十种写法有人文首缩进、有人用\paragraph表达小节、有人看到空行就想加\vspace。PreTeXt 的 XML 字典把“语义”锁死了团队成员知道一个想法该落在p一个单独的补充说明可能是paragraphs想给读者出一道思考题就用exercise不需要讨论版面长什么样。有人担心 XML 写起来啰嗦。其实这是对现代编辑器的低估——配合 XML 词法校验和代码片段常用结构几乎都能自动补全。而且在一本书几十个章节里少一点“个性排版”的熵比多一点点书写自由值钱得多。2.2 书籍级引用、题注和练习解答体系开箱即用PreTeXt 最打动教育出版工作者的一点是它对教材常用逻辑单元的深度支持。它内置exercise、solution、hint、answer、exploration等元素而且会自动关联编号。举一个我们维护习题集时高频使用的场景题目写在正文小节里答案放在全书末尾的解答部分网页版则把答案默认折叠成交互区块读者点一下“查看答案”才会展开。在传统 LaTeX 里这个需求需要你自己管理计数器、标签、交叉引用、附录区域然后还要处理答案在 HTML 端如何显示。在 PreTeXt 里你只需要按语义写比如solution放在exercise里面构建工具就自动知道它在 PDF 端应该落到章后解答还是文后解答在 HTML 端应该渲染成 knowl 折叠区块。这种“一个语义多处自适应呈现”的能力是通用排版工具做不到的。题注、引用也一样。源文件里你只需要写xref reffig-classification/引用某张图系统会按当前输出格式动态决定显示成“图 3.1”还是“Figure 3.1”页码和完整上下文全部自动处理。2.3 数学公式的“双通道渲染”不用自己折腾写数学教材的人之前被公式折腾得不轻。在 HTML 里给 MathJax 配置在 PDF 里用 LaTeX 公式系统两套语法虽然有渊源但要保证同一公式在两边显示一致并不轻松。PreTeXt 的做法是源文件统一写语义化的数学标记如m表示行内公式、me表示独立公式内部用 LaTeX 语法描述数学内容生成网页时自动转成 MathJax 可识别格式生成 PDF 时直接把公式交给 XeLaTeX 原样排版。我不需要手动在网页模板里挂什么脚本也不需要给每个公式写 fallback它输出的都是可读的结构化内容。这对数学类书籍近乎救命。即便你不是做学术书的只要内容中含有大量公式、矩阵推导、化学式之类这套机制也能省下你几十个小时的对齐工作。2.4 和市面上主流工具横评一下还是用表格对比来得直接。这个基本是我长期使用后的感受不是官方文档式的中立对比项PreTeXtLaTeX 直接写Pandoc MarkdownSphinxTypst内容与版式分离程度很高源文件无版式低混写中等取决于模板中等中等数学公式双格式输出自动化程度最高PDF强、HTML需自配转换有时要踩坑配合插件可用生态起步较早练习/解答/交叉引用语义原生支持手动宏实现基本没有没有有早期雏形HTML 阅读体验好含可折叠 knowl靠构建工具单页可接受好Web 支持在前进多人协作友好度高语义固定低风格易乱中中高中学习成本中等偏高高低中中适合项目类型长寿命教材/手册短篇论文、模板单一轻量技术文章软件文档站新项目尝鲜/公司文档注意我并不是说 PreTeXt 在所有场景都能赢。比如你只是快速写一篇会议论文给一个固定模板用 LaTeX 可能更直接如果你维护的是 API 文档Sphinx 生态里那一堆插件显然更贴手。PreTeXt 的最强区间是“结构性极强、生命周期极长、需要同时分发多种格式”的技术出版项目。3. 亲手跑通一条“源码 → PDF/HTML”的完整流水线3.1 安装环节先避一个常见的坑PreTeXt 本身不是单一的可执行二进制它由 XSLT 样式表、Python 构建工具和一部分 LaTeX 模板共同组成。现代版本的推荐姿势是直接用 Python 安装pip install pretextbook pretext --help这里一定要提醒如果你用的是操作系统自带的包管理器装旧版本可能装到一个很老的 PreTeXt它与新版本项目结构不兼容。我踩过这个坑某个教程让用 Linux 发行版的 pretext 包结果创建出来的目录格式和官方文档完全对不上白白折腾一下午。所以不管你系统里有没有旧版都建议用虚拟环境装新的python3 -m venv .ptxenv source .ptxenv/bin/activate pip install pretextbook另外生成 PDF 前确保本机有可用的 LaTeX 发行版。PreTeXt 对引擎没有特别偏好操作系统中常见的 TeX Live 或 MiKTeX 都行但要保证命令行能直接调用xelatex或lualatex。写简体中文内容时建议优先确认 TeX Live 里装了ctex宏包和常用中文字体这一步直接决定后面 PDF 中文能不能正常显示。检查方法很简单xelatex --version kpsewhich ctex.sty如果ctex.sty找不到先补齐 LaTeX 宏包再往下走。3.2 建一个最小可用的书籍项目PreTeXt 的项目结构比单篇 Markdown 复杂一点但比传统写书要简单得多。官方脚手架一般会生成类似目录mybook/ ├── project.ptx # 项目清单告诉构建工具源文件在哪 ├── source/ │ ├── main.ptx # 书籍/文章总入口文件 │ ├── chapter-intro.ptx # 章节文件可拆可合 │ └── assets/ # 图片、样式等外部资源 └── output/ # 每次构建的产物目录这里我直接给一份极简main.ptx方便第一次跑通?xml version1.0 encodingUTF-8? book xmlnshttps://pretextbook.org/ns/1.0 xml:langzh-CN title第一个 PreTeXt 小册子/title frontmatter author personname一位正在摸引擎的作者/personname /author /frontmatter chapter xml:idch-intro title第一章 初次见面/title introduction p这是一段导语。PreTeXt 的 XML 标签看起来多但写作时常用的并不多。/p /introduction section xml:idsec-why title为什么结构重要/title p试试行内公式 mx^2 y^2 z^2/m以及独立公式/p me\sum_{n1}^{\infty} \frac{1}{n^2} \frac{\pi^2}{6}/me p下面是一道带答案的练习题/p exercise statement p如果 magt;0/m判断 ma \frac{1}{a}/m 的最小值。/p /statement answer p最小值是 m2/m当且仅当 ma1/m 时取到。/p /answer /exercise /section /chapter /book注意XML 里直接复制字符和必须是lt;、gt;实体形式数学内容因为属于 TeX 语法可以保留反斜杠命令。只要上面文件没有乱码问题后续构建基本就顺了。3.3 构建 PDF 与 HTML并观察背后发生了什么有了main.ptx之后构建是相当快的pretext build pdf如果一切顺利output目录下会出现一个名类似mybook.pdf的文件。但这里千万别把 PreTeXt 脑补成一个单体引擎它在后台实际做的是先把 XML 根据一套 XSLT 2.0 样式表转换成完整的 LaTeX 工程再调xelatex执行编译。也就是说你在 PDF 里看到的字体控制、页面尺寸、目录样式都是 LaTeX 模板决定的PreTeXt 只在生成层替你把这些模板选择自动化了。HTML 端是另一个值得优先试的构建目标pretext build html它会生成一组静态网页文件目录、索引、数学公式以及前面那个 exercise 的答案折叠都会以适合阅读的形式渲染出来。我自己真实工作流里往往先跑 HTML 看内容和结构是否错位再去跑 PDF 看印刷细节。前者构建只要数秒反馈非常快后者一旦到了几百页每次编译都够喝杯热茶的等全部定稿后再集中调 PDF 是效率最高的策略。3.4 中文字体与页面参数定制要从哪下手PreTeXt 早期在中文用户里不够流行一个重要原因是它的 PDF 默认样式表是按西文书籍设计的直接构建中文 PDF 会遇到字体选择问题。解决方案其实不复杂你基本不用改 XML 源文件要改的是 LaTeX 模板的 preamble或者用 publication 文件指定自定义的页面参数。PreTeXt 的项目清单里通常可以引入一份publication.xml里面能控制纸张尺寸、边距、默认字号、是否显示章首图等。比如准备一个适合国内 A4 输出的 publication 文件pdf geometry paper width210mm height297mm/ margin top25mm bottom28mm left25mm right25mm/ /geometry /pdf字体这一层更直接在项目源文件里自定义 LaTeX preamble让 XeLaTeX 调用系统中文字体。我常用的最小片段如下\usepackage{xeCJK} \setCJKmainfont{Noto Serif CJK SC} \setCJKsansfont{Noto Sans CJK SC} \setCJKmonofont{Noto Sans Mono CJK SC}不同系统字体名称略有差异Windows 上试SimSun、Microsoft YaHeimacOS 上可以试Songti SC、PingFang SC。不配置这一步中文大概率显示为一堆空白方块这是所有新人在 PDF 中文输出上遇到的第一个大坑。HTML 端则简单得多直接在自己的 CSS 里指定font-family就行页面渲染由浏览器负责不依赖 LaTeX 字体库。4. 从入门到落地这些弯路我替你踩完了4.1 别在 XML 里顺手写“版式”注记刚接触 PreTeXt 的人容易把 LaTeX 的坏习惯带进来比如在内容里嵌\newpage、\vspace{2em}这类命令。在 PreTeXt 的语义模型里这种行为是破坏性的。因为一份源文件要同时养活 PDF 和 HTML当你强行插入“这一页翻过去”之类的指令时HTML 端完全无法理解转 EPUB 时更会留下垃圾信息。我后来给自己定了一条纪律凡是涉及“物理页面”的操作尽量想清楚语义是什么。想另起一节检查是不是应该用section想让某个图强制显示找是不是缺少引用如果只是为了让列表间距好看一点那是排版的活不是写书的活。一旦你接受这条纪律PreTeXt 的多格式输出立刻变得稳定起来。4.2 如果你也做数学或代码混合内容把 HTML 当第一调试台我的真实工作流是“先 HTML、后 PDF”。原因很简单PreTeXt 在 HTML 端的构建路径极短逻辑错误两三秒就会暴露而 PDF 的 LaTeX 编译错误往往晦涩动辄抛出几百行日志。例如某个公式里少写了一个数学环境的结束括号HTML 构建可能直接给出带行号的 XML 解析错误定位快得多PDF 端报错信息却要层层剥开有时你会怀疑是不是字体问题。把 HTML 构建当成 CI 里的静态检查其实是很划算的做法。团队里任何人提交改动以后先看 HTML 是否正常生成这一步通过了内容结构上的 90% 问题已经被兜住只有到了版式精修阶段才需要逐页核对 PDF。4.3 字体、图片路径和缓存是三大高频故障源字体问题刚才说了一半。再补充一个不同平台下字体不通用项目如果要在 CI 里自动构建必须保证服务器和本机装了同一套字体否则今天本地好好的明天一提交云端构建就崩。我在 GitHub Actions 上部署构建时专门加过一步“安装 Noto CJK 字体”才把中文问题从本地成功迁移到云端。图片路径也是一个典型麻烦。PreTeXt 的图片资源一般放在source/assets/images下但 XML 里引用时应该使用相对路径或官方约定的路径而不是随意写绝对路径。我试过直接把C:\Users\me\...写进去在本地能出换台电脑完全不可用。正确做法是把资源交给项目统一管理构建时基于项目根目录解析项目搬家才不会有断裂问题。最后是目录缓存。PreTeXt 增量构建虽然比全量构建快但偶尔我会遇到改了源文件而 PDF 没反映出来的情况。这时候清掉output目录里对应的构建缓存再重跑一次多半就好了。工程上这叫“脏状态”跟 Webpack 缓存失灵的憋屈感一模一样。4.4 长表格跨页和表头重复早晚会碰到做技术手册或者习题答案时经常要排超长表格。PreTeXt 对表格有相对成熟的处理方式但默认表格样式到了一定行数以后跨页时表头是否自动重复、行内是否允许拆分都不是没有成本的。我的经验是先把表格想清楚是数据表还是排版表再用官方table标签实现数据表。如果直接在p里手贴制表符或者预格式化文本构建出来的 PDF 一旦换页就会乱七八糟。下面是实践要点给表格加title生成题注使用tabular单元格定义不要拿pre模拟表格默认情况下注意列宽在窄屏 HTML 和 A4 PDF 的差异必要时在 publication 或 CSS 指定表格字号和列宽策略。这个调整过程需要一点耐心但比直接拿 LaTeX 手工排仍然省心太多。4.5 大文档构建速度慢先把拆分做好一本书到了几百页之后pretext build pdf每次全量构建都让人着急。PreTeXt 没有像 Word 那样可视化“只编译改动页”的概念但你可以把每个章节拆成独立 XML 文件然后通过 XInclude 的方式收录进main.ptx。写某个章节时可先单独构建该章节或短暂裁剪入口文件减少无谓编译。等到发布版本再恢复全量构建。这里有一个细节XInclude 的链接如果写错构建时不会像普通 XML 解析那样报一个友好的“文件找不到”有时只是某个章节在文档中安静地缺失了。所以我养成了构建完成后先查导航/目录页的好习惯确认章节数量是对的再去做深层阅读。为了把这些问题统一记牢我给自己整理了一份速查表你可以直接抄走症状优先排查方向常用处置PDF 中文变方块、乱码字体配置 xeCJK确认 fonts 名称HTML 正常PDF 提示错误数学公式/特殊字符查main.ptx行号对应段落修改内容但输出没变缓存清掉 output 目录对应文件重试部分章节从书里“消失”XInclude 路径检查 chapter 文件引用是否合法表格跨页后没有表头publication/模板考虑拆表或启用重复表头设置多人项目格式不一致版式串扰检查是否有人在 XML 里塞 LaTeX 样式5. 这个引擎能落地的场景与真实边界5.1 团队知识库/技术手册再造的优秀底座如果你们团队要维护一份技术手册既有线上 HTML 版本客户又需要离线 PDF还要按季度更新几十页内容PreTeXt 的高结构化语义会让版本管理很舒服。因为.ptx本质是纯文本你在 Git 里 diff 时能精确看到“这一版增加了哪一段、改写了哪个习题”不会出现 docx 那种二进制冲突。多人协作时还可以围绕结构设置贡献规范。例如要求新章节必须练好结构骨架提交前先在本地构建 HTML 通过再进合并。这些东西一旦沉淀成团队流程后期维护成本会显著低于直接用各种在线文档工具反复复制粘贴。5.2 开源教材与在线课程的再创作场景PreTeXt 最成功的场景依然是开源教材。拿数学类来说很多开放教科书网站都在使用它许多志愿翻译团队也是直接维护.ptx源文件再自动产出中文站和 PDF。如果你有长期维护一套讲义或独立课程的计划这个方向非常划算。特别地它内置的习题体系意味着你可以围绕题库积累内容每一道题都能在网页上交互、在纸质版里排版将来拼装试卷也会容易许多。有一点需要坦白讲PDF 输出质量的上限依赖你对 LaTeX 模板的理解HTML 输出上限依赖你的 CSS 水平。PreTeXt 不是美工神器它给的是“工程秩序”不会替你自动解决一切精细视觉问题。但如果你的目标是结构干净、自动发布、跨端统一它一定优于从零堆模板。5.3 目前还不能太乐观的地方PreTeXt 的社区体量和主流排版工具比仍然偏小中文资料相对稀缺遇到冷门问题可能在 GitHub issues 里翻很久才有头绪。语法上XML 标签的存在注定它比 Markdown 重不适合随手记笔记。它的定制路线依赖 XSLT/CSS/LaTeX 三位一体想做大改版式需要三个方向都有一定功底门槛不算低。所以我不是劝所有人迁移——尤其你只是一人维护、不带多格式输出那 Markdown 也许是最好的朋友。但如果你已经感受到长文档内容失控的痛或者被“在线和印刷两套维护”折磨得不行PreTeXt 值得你专门为它开一个小项目跑通一次写书流程后再做判断。我自己的经验是凡是能把“写内容”和“管版面”这两件事在流程上分开的尝试最后长期收益都很可观。PreTeXt 在这方面走得比很多现代工具更远也正因为如此它那股质朴的“规则感”才能把一个几十人参与的教科书项目打磨得秩序井然。对追求内容长期复用的人来说这份确定性比任何即时渲染的花哨效果都更金贵。