跳至内容
Topos Uranos

摘要

本课讲解如何声明文档的语言并为其选择字体。课程说明在 babel 中声明一种语言会改变什么(断词、自动生成的名称、日期和引号),并区分切换语言的三种方式:\selectlanguage、\foreignlanguage 和 otherlanguage 环境。随后把这些知识用于一篇引用多调号古希腊语和拉丁语的中文文本,各举一段引文为例,并说明为什么在 luatexja 中希腊字母需要另加设置。接着介绍 fontspec:文档的三个字体族、为每种语言指定字体的 \babelfont,以及最有用的 OpenType 特性(旧式数字、小型大写字母和连字),同时说明中文字体与西文字体的分工。课程教你检查字体是否包含文档中的全部字符:阅读“Missing character”警告,并用 albatross 查找字体;还解释当文档也要在 Overleaf 上编译时,为什么应优先使用 TeX Live 自带的字体。最后简要提及从右向左书写的文字、中日韩文字的排版宏包以及 polyglossia。

学习目标

  1. 用 babel 声明文档的主语言和次要语言,并说明每种语言在排版结果中决定了什么。
  2. 根据需要改变的内容,在 \foreignlanguage、otherlanguage 和 \selectlanguage 之间作出选择,并预测由此得到的日期、名称和引号。
  3. 以正确的断词和合适的字体排印多调号古希腊语和拉丁语的段落。
  4. 用 fontspec 和 babel 指定字体,并启用旧式数字、小型大写字母和连字。
  5. 检查所选字体是否包含文档用到的全部字符和字形,并解读提示缺字的警告。
  6. 根据文档需要在何处编译,在 TeX Live 自带的字体和系统字体之间作出选择。

语言改变了什么

前面各课的中文文档都加载了 luatexja-fontspec,在需要自动名称时还加载了 \usepackage{babel} 和 \babelprovide[import,main]{chinese},但没有停下来解释它们的作用。一种语言并不只是一张字符表:它有自己在行末断开单词的规则、对文档各部分的称呼、书写日期的方式以及自己的引号。babel 宏包按语言汇集这些约定,声明一种语言就是请它应用这些约定。中文的排版规则(汉字之间如何断行、标点如何压缩、汉字与西文之间如何留空)则由 luatexja 负责。这项工作不能两家同时做:\babelprovide[import,main]{chinese} 还会启用 babel 自己的中文断行处理,它与 luatexja 重叠,把逗号、句号、引号和括号压缩成半角宽度,而且不给任何提示;所以本课程的文档在它后面写 \babeladjust{linebreak.cjk=off},把中文排版完全交给 luatexja。具体而言,语言决定:

  • 断词:排版引擎按哪一套模式寻找单词可以断开的位置;
  • LaTeX 自动写出的名称,例如目录的标题、表格和插图的名称;
  • \today 打印的日期,即编译当天的日期;
  • 某些语言为键盘输入定义的简写,例如西班牙语为引号定义的简写;中文没有这类简写,本节稍后会说明中文的引号怎样输入。
例题同样的命令,三种语言

三个段落使用同样的命令,只是用来解读它们的语言不同。\tablename、\figurename 和 \contentsname 分别是表格、插图和目录的名称。

LaTeX 代码
\documentclass{article}\usepackage{luatexja-fontspec}\setmainjfont{Noto Serif CJK SC}\usepackage[latin, english]{babel}\babelprovide[import,main]{chinese}\babeladjust{linebreak.cjk=off}\begin{document}日期:\today{}。名称:\tablename{}、\figurename{}、\contentsname{}。​\begin{otherlanguage}{english}Date: \today. Captions: \tablename, \figurename, \contentsname.\end{otherlanguage}​\begin{otherlanguage}{latin}Dies: \today. Tituli: \tablename, \figurename, \contentsname.\end{otherlanguage}\end{document}
结果
结果

中文那一行在每个命令后都写了 {}:在 LuaLaTeX 中汉字也算字母,紧跟在命令名之后的汉字会被读成命令名的一部分。拉丁语用罗马数字写日和年。中文的日期中,数字与汉字之间的小空白是 luatexja 自动加上的。

断词

断词是语言带来的效果中最不显眼、却最重要的一项。中文本身不断词:luatexja 允许在任意两个汉字之间换行,只遵守标点的禁则(例如句号不能出现在行首)。可是中文文本中常常夹着西文单词,而每种西文都按自己的传统断词:英语常常尊重单词的构成,如 stand-ing;拉丁语按其模式所依循的传统,把后接辅音的 s 移到下一行。一段其他语言的文字如果不加标记,引擎就按当前语言的模式来断它,提出的断点在那种语言里可能是错的。

命令 \showhyphens 把引擎在所给单词中允许的断点写进日志,而不在文档中打印任何东西。用它可以检查每个位置上起作用的是哪一套模式。

例题同样的单词,不同的模式

下面的源代码先按主语言中文的模式、再按各自语言的模式,求两个英语单词和两个拉丁语单词的断点。文档中没有汉字,因此这里不需要 luatexja。

LaTeX 代码
\documentclass{article}\usepackage{fontspec}\usepackage[latin, english]{babel}\babelprovide[import,main]{chinese}\begin{document}\showhyphens{understanding knowledge}\foreignlanguage{english}{\showhyphens{understanding knowledge}}\showhyphens{nostrum conscientia}\foreignlanguage{latin}{\showhyphens{nostrum conscientia}}\end{document}

日志对每一行先给出一条关于盒子的警告(无害:\showhyphens 把单词排在一条很宽的行里加以检查),然后是带断点的单词。

编译日志
Underfull \hbox (badness 10000) in paragraph at lines 6--6[] \TU/lmr/m/n/10 un-der-stand-ing knowl-edge​Underfull \hbox (badness 10000) in paragraph at lines 7--7[] \TU/lmr/m/n/10 un-der-stand-ing knowl-edge​Underfull \hbox (badness 10000) in paragraph at lines 8--8[] \TU/lmr/m/n/10 nos-trum con-sci-en-tia​Underfull \hbox (badness 10000) in paragraph at lines 9--9[] \TU/lmr/m/n/10 no-strum con-scien-tia

babel 的中文没有自己的断词模式,对西文单词改用英语的模式,日志中有一条信息说明这一点:“Hyphen rules for 'chinese' set to \l@english”。所以第 6 行和第 7 行完全相同。拉丁语则不同:第 8 行按英语的方式断开 con-sci-en-tia,而第 9 行按拉丁语的传统断开 no-strum con-scien-tia。中文文本中的拉丁语、法语或德语引文,都需要标记出来。

中文的引号

中国大陆的规范在第一层用双引号“”,在其内部用单引号‘’(竖排和港台则用直角引号「」『』)。babel 的中文不为引号定义简写,也不按层次替换引号:选哪一种由作者决定。在 LuaLaTeX 中可以直接从键盘输入,如下例所示。

例题两层引号
LaTeX 代码
“老师说:‘大声重复一遍。’”​``英文引号''与`单引号',手工输入。
结果
结果

第二行展示 LaTeX 的经典写法,它与语言无关:两个反引号开启英文引号,两个撇号关闭引号;各用一个则得到单引号。这样得到的引号由西文字体排出,因为反引号和撇号是 ASCII 字符;直接输入的“”和‘’则由 luatexja 交给中文字体。

不过,必须区分简写与巧合。fontspec 加载西文字体时默认带有 TeX 连字特性(后文会讲到),它会把两个连续的 < 变成一个尖角引号«,在任何语言中都如此。西班牙语和法语的文档用的正是这种引号;中文的引号则应直接输入。关于脚注、引文和诗句的那一课会更详细地讨论引文。