本文已加入专栏文章目录,归入「进阶使用」文章系列。
引入
LaTeX 有两种模式,文本模式(text mode)和数学模式(math mode)。逗号也有两个「符号」,西文的逗号(U+002C)和中文的逗号(U+FF0C)。两两组合,共有四种情况。使用 ctex 文档类,默认的输出是这样的

看默认输出,似乎只有中西的差异,而没有文本-数学模式的差异。通过配置其他公式字体、使用 setCJKmathfont
(xeCJK
宏包提供),可以让数学模式中的中西逗号使用其他字体,从而与相应的文本模式下的逗号「长得不像」。
对纯西文的文档而言,使用合适的正文、数学字体,能在文本和数学模式下获得比较一致的逗号。西文排版中,对于文本和数学模式下的逗号「长得不像」,也有较大的宽容。
目前的中文排版,对于「在文本和数学模式下的逗号应该长得一模一样」有比较强的需求。一种做法是,麻烦作者,在文本模式中也使用「西文逗号 + 空格」的方式来替代中文句子中的逗号,以达到全篇逗号一致的效果。
比较折衷的方案可以是,
- 对公式内部的逗号(如分隔有序数组的逗号
和
、进行列举的逗号
),输入西文逗号,输出时使用(西文)公式字体;
- 对于在行文中起到标点作用的逗号(见下例),输入中文逗号,输出时使用中文字体;
- 另有一些不明确的情况,由作者和编辑共同商议决定,并在全文保持一致。第三种情况的例子,比如「
在
,
时的值为 5」中的逗号。
本文尝试「让数学模式下输入的西文逗号,与文本模式下输入的中文逗号在外观上保持一致」。
三种方案
首先是最优雅的方案,使用 unicode-math
宏包提供的 setmathfont
命令的 range
选项。为了凸显效果,特意为数学模式下的西文逗号使用了思源宋体的最大字重。range
选项以前出现过「实际影响范围超出指定的字符范围」 的问题,虽然现在已经修复,使用时仍需注意。

第二种方案,是使用 LaTeX 的 NFSS 机制,让公式模式里的西文逗号使用中文字体。使用辅助命令(修改自这个 TeX.SX 回答)可以输出当前字体在 NFSS 机制下的编码、字族、字体系列和字形信息,这些信息正是命令 DeclareSymbolFont
所需的。


第三种方案最为自由,是把数学模式下的逗号变成 active character,从而可以定义为宏。如果恰好使用了其他把逗号定义为宏的宏包(例如调整数学标点前后间距的宏包 mathpunctspace
),就需要进行特殊的处理。

方案讨论
前两种方案,其实是使用中文字体替代(西文)公式字体,来排版数学模式下的西文逗号。这两种方案都没有使用「中文字体提供的中文逗号」,来排版数学模式下输入的西文逗号。它们之所以有效,是因为中文字体在设计时,通常会保持同一字体内的中西逗号「长得像」,即只在符号宽度方面有差别。
后两种方案,尤其是第三种方案,因为改动相对底层,使用时务必提高警惕;最好是别用。
本文介绍的方案,都是「让输入的西文逗号,在排版结果中长得像中文逗号」。也可以从另一个方向来尝试满足「逗号一致性」的需求,即「使用西文字体,排版输入的中文逗号」。搭配使用 xeCJK
宏包的 Mapping
选项和分区字体设置功能,似乎可以做出一个方案。
稍微脱离现实一些,理想情况是,(至少)有一套「中文 - 西文 - 公式」字体,它们搭配使用十分和谐。
相关源码,见项目 muzimuzhi/latex-examples 里的文件
unicode-math-multiple-math-fonts.*
nfss-declare-math-symbol.*
add-math-active-character.*