排版包含汉语和 LaTeX 公式的 Markdown 文件

最近看到 fri3nd:如何使用 Pandoc 和 LaTeX 制作漂亮的 pdf 一文,了解到 pandoc 的一个模板 Wandmalfarbe/pandoc-latex-template 。试了试, 挺好用的!只是上文略过了配置中文字体的部分,此文是上文的补全,也简要介绍这套方法的工作原理。

我使用的是 macOS。如果读者用的是 Linux 或者 Windows,那么下文中安装字体文件的位置应该不一样。

工作原理

本文介绍的把 Markdown 排版成 PDF 文件的过程如下:

  1. 用户写 Markdown 文件,其中可以包含 CJK 字符和 LaTeX 格式的数学公司。
  2. 用户用 pandoc 命令把 Markdown 文件排版成为 PDF 文件。
  3. 因为我们预先安装了 Wandmalfarbe/pandoc-latex-template 这个 pandoc 模板,所以 pandoc 会按照这个模板定制排版结果,包括选择字体和配置封面的背景图。
  4. pandoc 其实是把 Markdown 文件转成一个 LaTeX 文件,再调用 LaTeX engine 来排版的。
  5. 常用的 LaTeX engine 有初创作者 Donald Knuth 写的 LaTeX,和后人写的几个实现。目前最常用,对 Unicode 和 PDF 支持最好的是 XeLaTeX。这个引擎也是 Wandmalfarbe/pandoc-latex-template 这个插件默认使用的。
  6. 我们需要预先安装可以被 XeLaTeX 使用的汉语字体(具体的说是 CJK 字体,里面包括对应 Chinese、Japanese 和 Korean 的 Unicode 字符)。
  7. 各种 LaTeX engines 通常都打包在一个“TeX 发布”中。Linux 用户常用的一个 TeX 发布是 TexLive。很多年前我用 Windows XP 的时候用过 MikTex。macOS 用户最常用的是 MacTeX。
  8. MacTeX 的安装有两种模式:简装(basic)和全装(full)。我们需要全装,里面包括 XeLaTeX 和其他各种 Wandmalfarbe/pandoc-latex-template 这个插件以及 pandoc 需要的包(packages)。

协同创作

fri3nd:如何使用 Pandoc 和 LaTeX 制作漂亮的 pdf 一文的评论区里,我看到有知友问到为什么不直接用更容易安装的工具,比如 VS Code 的一个插件来排版 Markdown 文件。这当然是一个好办法。不过团队协作时,我们通常需要用 Git 来管理编辑的文本(比如 Word 或者 Markdown 格式);而且需要 code review 来沟通。Word 格式不利于使用 code review 系统来 comment 和讨论,所以一般协作时文档用文本格式,比如 Markdown。当很多人协作修改一个或者多个 Markdown 文件的时候,我们希望 git push 命令出发 GitHub 调用一个 CI 流程来自动排版 —— 把大家对文本的修改排版成 PDF 文件。此时,了解本文的流程,就可以配置这个 CI 流程了。

配置 CI 过程自动排版得到 PDF 之后有很多后续用处。一个典型的路子是发布到 Kindle Store —— Kindle 电子书的自动排版和发布系统支持以 PDF 作为输入。另一个典型的例子是通过 GitHub Pages 让大家都可以通过浏览器访问,也就成了一个网站。请注意,网站的页面不一定要是 HTML 页面,完全可以是 PDF 格式。

安装字体

我们买来的 mac 电脑里已经预装了很多字体文件。macOS 系统自带一个程序叫 Font Book.app。打开它就可以看到已经安装的字体文件。如果我们下载了新的字体文件,也需要这个程序来安装。

一个字体文件的内容包括每个 Unicode 字符的“写法” —— 表示成一系列的落笔位置,移动方向和长度。这样的字体叫矢量字体。与之对应的是点阵字体,不过现在已经很难见到了,在此不提。常见的矢量字体文件的格式包括 TrueType 和 OpenType,对应的字体文件的扩展名分别是 ttf 和 otf。这两种字体文件都可以被 Font Book.app 识别和安装。

麻烦的一点是:很多 macOS 默认安装的字体文件里,都不包括所有 Unicode 字符的写法 —— 很多字体文件里只有西方国家常用的字符的写法。为此,我们需要寻找、下载、和安装包括中日韩字体的文件。

Standard CJK fonts for LaTeX? 这个帖子里,我发现了 Google 发布的一组免费又包含中日韩字体的文件 Noto Serif 系列。我下载和安装的是其中 SC 字体。大家可以从 https://www.google.com/get/noto/help/cjk/ 这里下载这组字体,或者在国内找一个镜像网站。

下载之后,用 Font Book.app 打开字体文件,就完成了在 macOS 里安装字体的操作了。而 XeLaTeX 能找到 macOS 里安装了的字体,不需要我们额外做什么配置,告知 XeLaTeX 字体文件在 macOS 系统里的存储位置。

为了检验字体安装成功,我们可以打开一个文字编辑器软件,比如 Word for Mac 或者 macOS 自带的 Pages.app。尝试输入一段话,然后设置成 Noto Serif 字体。我们应该可以在编辑器的字体列表里看到已经安装了的各种字体。

安装 MacTeX

上文提到为了获得 XeLaTeX engine,macOS 用户可以安装 MacTeX 这个 TeX 发布。请注意,一定要选择全装,不要选择简装,否则在使用的时候会碰到格式报错信息,抱怨找不到某些 LaTeX 包。比如这个 issue File `footnotebackref.sty’ not found. · Issue #141 · Wandmalfarbe/pandoc-latex-template

有些用户从 MacTeX 网站下载,我更习惯于用 Homebrew 来安装。Homebrew 本身的安装过程可以参考 Homebrew

如果已经安装过简装版的 MacTex,要记得删除之。删除简装版和安装全装版本的命令如下:

brew remove basictex
brew cask install mactex

其中第一条命令删除简装版 MacTex。第二条安装全装版。

安装 Pandoc

用 Homebrew 安装的 Pandoc 的命令如下:

brew install pandoc

安装 Pandoc 模板

安装过程在 https://github.com/Wandmalfarbe/pandoc-latex-template#usage 这里。按照这个描述,在GitHub下载页面里下载一个最近版本的 .tar.gz 或者 zip 文件。我在本地解压缩后看到了不少文件;不过我们只需要其中的一个 eisvogel.tex。

为了安装这个文件,我们先要知道 Pandoc 把模板放在哪个目录里。为此,我们运行 pandoc 命令如下

yi@WangYis-iMac:/tmp $ pandoc --version
pandoc 2.9.2.1
Compiled with pandoc-types 1.20, texmath 0.12.0.1, skylighting 0.8.3.2
Default user data directory: /Users/yi/.local/share/pandoc or /Users/yi/.pandoc

可以看到,我使用的 pandoc version 2.9.2.1 期待模板文件在 ~/.local/share/pandoc 或者 ~/.pandoc 目录里。

我们需要

  1. 创建一个目录:mkdir -p ~/.local/share/pandoc/templates
  2. 把刚才下载的文件拷贝过去,顺便修改一下扩展名:cp /tmp/eisvogel.tex ~/.local/share/pandoc/templates/eisvogel.latex

配置字体

上述模板的作者貌似不是亚洲人,他的模板默认使用的字体是 Source Sans Pro 字体,这个字体文件里没有 CJK 字符的画法。为了让这个模板默认使用我们安装的 Noto Serif SC 字体,我们需要编辑一下 ~/.local/share/pandoc/templates/eisvogel.latex 。我的版本里,我在 \else % if not pdftex 这一行后面加了三行,使其看上去是这个样子。

\else % if not pdftex
  $if(mainfont)$
  $else$
  \usepackage[fallback]{xeCJK}
  \setCJKmainfont{Noto Serif SC}
  \setCJKfallbackfamilyfont{rm}{Noto Serif SC}
  \usepackage[default]{sourcesanspro}
  \usepackage{sourcecodepro}

我修改之后的 eisvogel.latex 的全文在这里:https://github.com/wangkuiyi/eisvogel-cjk/blob/main/templates/eisvogel.latex 。如果先修改麻烦,从我这里下载比从原始作者的 repo 里下载更方便。

封面背景

上述 Pandoc 插件是可以正儿八经用来写书的。书籍的封面通常有一个背景图。我的 GitHub repo 里的修改后的模板也附带了一个我随便弄的封面背景。可以把 https://github.com/wangkuiyi/eisvogel-cjk/blob/main/templates/cover.pdf 这个文件拷贝到你的 ~/.local/shared/pandoc/tempaltes/ 里。

一个例子

fri3nd:如何使用 Pandoc 和 LaTeX 制作漂亮的 pdf 这篇文章里有细致的例子。我的例子 https://github.com/wangkuiyi/eisvogel-cjk/blob/main/a.md 比较简单,主要是验证文档里可以有数学公式。

如果你已经完成了上述操作,那么编译这个例子的命令如下:

pandoc a.md -o a.pdf --from markdown --template eisvogel \
  --listing --pdf-engine=xelatex && open a.pdf

编译结果是这个 PDF 文件:https://github.com/wangkuiyi/eisvogel-cjk/blob/main/a.pdf

截图如下:

<img src="data:image/svg+xml;utf8,” data-caption=”” data-size=”normal” data-rawwidth=”808″ data-rawheight=”2292″ width=”808″ data-original=”https://pic3.zhimg.com/v2-2e6d23aed96413fc5b5308cd613034d6_r.jpg” data-actualsrc=”https://pic3.zhimg.com/v2-2e6d23aed96413fc5b5308cd613034d6_b.jpg”>