中文支持:ctex 宏集与 xeCJK

中文排版是 LaTeX 新手最关心也最容易翻车的环节:同一个文档在别人电脑上正常,自己编译却整页空白或乱码。问题的根源几乎都在引擎与字体,而不是源码写法。本文把中文支持拆成「选引擎、选宏集、选字体、调细节」四层,给出可以直接照抄的配置,并解释每一步为什么必要,让你面对排错日志时不再抓瞎。

一、为什么必须用 XeLaTeX

LaTeX 最初只处理基本字符集,后来扩展出多条中文路线,能力各不相同。结论先行:现代中文文档请认准 XeLaTeX 引擎加 ctex 宏集的组合,其余路线只有维护遗留文档时才会遇到。

引擎或方案 中文能力 现状
原始 latex 加早期中文扩展 需手工处理编码,易乱码 时代遗产,勿用
pdflatex 加 ctex 宏包 可用字体少,警告多 不推荐新文档使用
xelatex 加 ctex 或 xeCJK 原生 UTF-8,可调用系统字体 首选
lualatex 加对应中文方案 同样原生,可编程性强 可选

遇到旧文档使用前两行方案时,最实际的做法不是逐行改造,而是评估能否整体迁移到 xelatex 加 ctex:多数情况下迁移成本低于维护旧方案的成本,且从此享受官方长期维护。

XeLaTeX 直接读取 UTF-8 编码的源文件并支持系统安装的 TrueType 与 OpenType 字体,中文无需任何额外编码转换。判断自己文档能否走这条路很简单:用文本编辑器打开源文件,确认保存编码为 UTF-8;同时确认编辑器与编译器都按 UTF-8 处理。链条上任何一环是其他编码,就可能整页空白或乱码。这一步排查成本极低,但能挡住将近一半的中文报错。

一个常被忽略的环节是云端平台:若项目从旧压缩包导入,源文件可能是 GBK 编码。多数现代编辑器能自动识别编码,但自动识别偶尔会失败,保险起见在编辑器里统一另存为 UTF-8 再编译。判断当前编码最简单的方法是看编辑器右下角的状态栏,那里通常会标注打开文件的编码。

二、ctex 宏集与 xeCJK 的分工

xeCJK 是底层的字体与断行处理:它让中文字符使用指定字体、西文使用另一套字体,并自动处理中英文混排时的间距。ctex 宏集在 xeCJK 之上做了一整套本地化:章节名称变「第一章」、日期用中文格式、标题样式符合中文排版习惯。这两层各管各事,出问题时也能分层定位——标题样式不对找宏集,字体替换不生效找 CJK 层。先分清问题属于哪一层,排错方向就不会跑偏。

对绝大多数用户,两句话就够了:写论文报告直接用中文文档类(ctexart 或更高层级的那两个);已有英文文档想加中文,在导言区加载 ctex 宏包并指定 UTF-8 选项。默认参数下引入的字体与标题样式都不必自己设置。若学校强制特定字体,再用下一节的命令替换。默认值本身久经考验,没有特殊要求时不要轻易改动。

\documentclass{ctexart}
\setCJKmainfont{SimSun}      % 正文宋体(系统自带)
\setCJKsansfont{SimHei}      % 无衬线黑体
\setCJKmonofont{FangSong}    % 仿宋
\begin{document}
中文排版测试:宋体正文,黑体\textbf{加粗}。
\end{document}

一个常见的误用是同时加载 ctex 宏包又使用 ctexart 文档类——文档类已经内嵌了宏包的功能,重复加载会触发选项冲突警告。记住「文档类优先、宏包补充」的顺序即可。反过来,英文模板想加中文时,只加载宏包而不换文档类,也能获得完整的中文支持,这是遗留文档的最低成本汉化路径。

三、字体与跨设备编译的坑

最常见的事故是这样的:你在 Windows 上指定某款楷体编译成功,发给用 macOS 的同学就报错「字体未找到」。原因是字体名是操作系统相关的,同一视觉风格的字体在不同系统里名字不同。

常用中文字体 Windows 名称 macOS 名称
宋体 SimSun Songti SC
黑体 SimHei Heiti SC
楷体 KaiTi Kaiti SC
仿宋 FangSong STFangsong

稳妥做法有两类:其一是写字体回退逻辑,按系统选择字体名;其二是固定编译环境(如固定一台电脑,或使用云端平台)。更省心的第三种方案是改用开源中文字体:TeX Live 自带的几款免费中文字体随发行版安装,换电脑时不依赖系统字体,协作时少很多麻烦。指定方式与上例的命令相同,仅字体名不同。

如何拿到可复制的字体名也有技巧:用系统字体管理工具查看完整名称,或使用字体检测命令列出当前可用的中文字体名。直接照抄网上教程里的名字经常错一个字母,导致编译报「找不到字体」却以为是环境问题。字体问题排查清楚后,中文文档就只剩下审美层面的取舍了。

报到缺字体时日志会明确写出「找不到字体」的错误,去日志最后几行找关键词即可,不必整段通读。更多读日志技巧见「编译排错」一章。报错信息里出现的英文字体名往往不是你以为的那个中文名,复制日志里的确切名称去系统字体表里核对,是最快的解决路径。

四、行距、标点与细节微调

xeCJK 默认在中英文之间自动插入约四分之一字宽的空白,并压缩连续中文标点。一般情况下不需要手工调整,但两个参数值得知道:行距倍数与段首缩进。

\documentclass[UTF8]{ctexart}
\linespread{1.3}\selectfont          % 全局行距 1.3 倍
\setlength{\parindent}{2em}          % 段首缩进两字符
\begin{document}
中文段落测试。
\end{document}

中文写作里还有三个细节值得注意。其一,xeCJK 默认行距偏紧,调到一点二至一点四倍更接近中文排版习惯。其二,中文标点的断行与压缩由 xeCJK 自动完成,不要自己在源文件里加空格制造间距,那样反而破坏自动处理。其三,中文段落首行缩进两字宽是约定俗成的规范,用长度命令设置一次即可,不要逐段手工敲空格。遵守这三条,中文文档的「气质」立刻接近正式出版物。

还有一条建议给强迫症同学:不要追求在源文件里对齐中文。等宽字体下中文与西文宽度不等,源码里的对齐在编译后毫无意义,还可能引入多余空格。源文件保持自然换行即可,排版交给引擎——这是「声明式」思维在中文场景下的又一次体现。

五、最小中文模板与排障顺序

给一份可直接复制的骨架,覆盖九成中文场景:中文文档类加 UTF-8 选项、常用宏包、自动标题。这份骨架同时是中文排障的起点——把它单独编译通过,再逐项往里加自己的内容,任何一步失败都能立刻定位到新加入的部分。这比一上来就拿整篇论文排障要高效得多。

\documentclass[UTF8]{ctexart}
\usepackage{graphicx}
\usepackage{amsmath}
\title{中文标题}
\author{作者}
\begin{document}
\maketitle
正文内容。
\end{document}

中文编译不出来时的标准排查顺序,按命中频率排列:第一,确认编译器是 xelatex 而不是 pdflatex;第二,确认源文件保存为 UTF-8 编码;第三,读日志报错行,若是找不到字体就按上一节换字体名或改用随发行版安装的字体。九成问题落在这三步之内,按顺序排查比胡乱搜索快得多。记住一个原则:中文报错几乎都在「引擎、编码、字体」这三者之一,不要往源码写法上怀疑。

现象 第一步检查 第二步检查
整页空白 编译引擎是否 xelatex 源文件编码
方块或乱码 字体缺失 编码与引擎
标点间距异常 是否手工加过空格 字体是否替换成功
英文字母间距怪 是否误用中文字体排西文 字体族设置

写中文论文时,把目光从工具收回到内容本身同样重要。本站的论文写作指南讨论如何组织论证结构,AI 辅助写作则给出用 AI 润色中文表达的工作流,都建议在排版之外一并阅读。

延伸阅读