原 文:Multilingual typesetting on Overleaf using polyglossia and fontspec
译 者:Xovee
翻译时间:2021年1月1日
介绍
本篇文章介绍如何在 Overleaf 中使用 XeLeTeX (或者 LuaLaTeX)来进行多语言输入(利用 fontspec
和polyglossia
LaTeX 包。
大多数的 LaTeX 文档使用的是pdfTeX
,它不支持读取 UTF-8 编码的文本文件。使用pdfTeX
来输入某种特定语言的流程特别繁琐,尤其是那些不是基于拉丁字母的语言。有一些包,例如inputenc
、fontenc
、babel
、arabtex
等,它们可以允许你在使用pdfTeX
等情况下输入非拉丁文字,但并不是所有的字符都能在 PDF 中正确显示,就算你使用了inputenc
的utf8
或utf8x
选项。
使用 XeTeX
和 LuaTeX
XeTeX
和LuaTeX
引擎可以直接读取和处理 UTF-8 编码的文本,也就是说,它们支持原生的 Unicode,支持 True Type 和 OpenType 字体。它们的这些特性允许你在 LaTeX 文档中轻松地输入各种语言。例如:
这些例子可以在 Overleaf Gallery 中找到:如何输入多语言文本 和 多种语言的“谢谢你”。
最新版本的babel
已经支持在 XeLaTeX 中使用\babelfont
来选去字体,但是合适的babel
版本在 Overleaf 中还不支持。所以我们主要讨论polyglossia
,因为很多 Overleaf 用户都希望在一个文档中输入各种各样的语言和字体。
如果你在寻找如何在文档中输入中文、日文、韩文,请参考下面几篇文档:
Xe(La)TeX 环境对这几个语言仍旧很有用,但是更专业的特有 TeX 引擎已经被设计出来支持输入 CJK(中日韩)语言,例如输入日文的pTeX
。
如果你在 Overleaf 中输入某种特定语言的时候遇到了问题,你可以在 Overleaf 的菜单中更改“Font Family”选项。你也可以改变“浏览器的等宽字体偏好”,或者使用 Overleaf 的富文本试图。当前,某些从右到左的文字编辑功能也许会出现问题,我们正在解决这个问题。
改变项目的编译器
fontspec
和polyglossia
包需要 XeLaTeX 或 LuaLaTeX 环境,所以你需要改变项目的默认编译器。你可以参考这个文章。
如果你的整个文档只包含一种语言
当使用fontspec
包的时候,你也许只需要设置一个主要的(serif)字体、一个sans-serif字体,或者再包括一个等宽字体。例如,当你的整个文档都是希腊语(以及一些英文单词),你可以简单地使用下面的代码
\usepackage{fontspec}
\setmainfont[Script=Greek]{GFS Artemisia}
\setsansfont[Script=Greek]{GFS Neohellenic}
\setmonofont[Script=Greek]{Noto Mono}
. . .
Το Lorem Ipsum είναι \textsf{απλά} ένα κείμενο χωρίς νόημα
για τους επαγγελματίες της \texttt{τυπογραφίας} και στοιχειοθεσίας.
你可以从支持的 TrueType 和 OpenType 字体 中选择想要的字体。上面的代码的输出是:
在一个文档中进行多语言/文本输入:polyglossia 入门
如果你的文档包含为数不少的多语言文本,那么polyglossia
包可以帮你解决很多麻烦。
\usepackage{fontspec}
\setmainfont{FreeSerif}
\setsansfont{FreeSans}
\setmonofont{FreeMono}
\usepackage{polyglossia}
\setdefaultlanguage{french}
\setotherlanguages{english,russian,thai}
\begin{document}
\begin{abstract}
Le Lorem Ipsum est simplement du faux texte employé dans
la composition et la mise en page avant impression.
\end{abstract}
Merci. \textenglish{Thank you.} \textrussian{Спасибо.} Et plus de
texte en français!
Le Lorem Ipsum est le faux texte standard ...
\begin{english}
Lorem Ipsum is simply dummy text ...
\end{english}
\begin{russian}
Lorem Ipsum - это текст-`\textsf{рыба}', часто используемый в
\texttt{печати} и вэб-дизайне. ...
\end{russian}
\begin{thai}
\XeTeXlinebreaklocale "th_TH"
\textenglish{Lorem Ipsum} คือ เนื้อหาจำลองแบบเรียบๆ ที่ใช้กันในธุรกิจงานพิมพ์หรืองานเรียงพิมพ์
\end{thai}
你可以使用\setdefaultlanguage
(默认是英语)来设置文档的主语言,用\setotehrlanguages
命令来设置其他的语言。
上面的例子里使用法语作为主语言,以及一些英语、一些俄语、一些泰语。我们使用了 FreeSerif、FreeSans、FreeMono 字体。
因为文档的主语言是法语,所以在abstract
环境里,系统自动生成了标题Résumé
。注意,在文档第一段的末尾,感叹号的间隔位置是遵从于法语的习惯的。
在主文档中,一些英语、一些西里尔字母、和一些泰文可以使用\textenglish{Thank you}
、\textrussian{Спасибо}
、\text{ขอบคุณ}
命令放置在以法语为主的段落中。一般来说,你可以使用\textLANGUAGE{}
来输入任何在\setdefaultlanguage
和\setotherlanguages
命令中定义好的任何LANGUAGE
。因为文档的主语言使用的是FreeSerif,而FreeSerif支持拉丁字符、西里尔字符、以及泰语字符(以及更多),所以fontspec
和polyglossia
可以使用它来生成 PDF 中的文字。
如果某个段落的主要语言不是文档的主语言,我们建议你使用\begin{LANGUAGE}...\end{LANGUAGE}
,例如\begin{russian}...\end{russian}
等。对于阿拉伯语,你应该使用\begin{Arabic}...\end{Arabic}
。
有时候你还需要注意一些东西,例如在thai
环境中,单词Lorem Ipsum
需要被放置在\textenglish{...}
或者\textfrench{...}
中来确保它们使用了基于拉丁文本的字形。
现在你可能会问,既然FreeSerif
这么厉害,甚至包含了俄语和泰语的字符,那么我们为什么还需要把俄语和泰语文字放在例如\textrussian
、\begin{english}...\end{english}
等环境里?这不是多此一举吗?让我们来看看,如果移除了这些环境,会发生肾摸事情:
很显然,拉丁和西里尔字母在PDF中都显示了出来,但是有些(用连字符连接的)单词发生了错误:unk-nown
、unchan-ged
,而стандартной
压根没有被分开。当没有在基于特定语言的环境里,编译器会认为这些文字仍旧是法语,所以会用法语的传统来分割这些单词。所以会发生这些错误。字体输入和文字打印学并不是简单的去设计字体和选择字体:它们有着很多基于语言和基于文化的准则。
回到我们的第一个使用希腊语的例子,你应该明白了我们为什么引入polyglossia
包,设置了\setdefaultlanguage{greek}
。这样做是去确保文档主要使用希腊语的输入传统。
混用从右到左(RTL)和从左到右(LTR)语言
当你在一个文档中混用RTL和LTR语言的时候,你需要特别小心。考虑下面的一小段使用Amiri
字体的阿拉伯语文档(混入了一些英语单词):
\usepackage{polyglossia}
\setdefaultlanguage{arabic}
\setmainfont{Amiri}
\begin{document}
ما هو differentiation
\end{document}
输出是:
文字自动地被设置为从右到左。不错~诶,不对,单词differentiation
好像出了问题。发生肾摸事了?
Amiri
字体中包含了拉丁字母,但是在这里,differentiation
并没有被标记为英语:编译器把differentiation
当作一个从右到左的文字,当作一系列阿拉伯字符。在输入的时候,序列iff
被处理成ffi
。所以,将英文单词包装在\textenglish{...}
中可以保证英文单词依旧是从左到右的。
\setmainfont{Amiri}
\setotherlanguage{english}
\newfontfamily\englishfont{TeX Gyre Termes}
\begin{document}
ما هو \textenglish{differentiation}
一些与特定语言有关的选项
有些语言支持更多的自定义选项,例如greek
接受variant=ancient
, =mono
, =poly
等选项来设置古希腊语、单音希腊语、多音希腊语。hindi
可以被设置为numerals=western
或=devanagari
。更多细节请参考polyglossia包文档。
这些选项可以在加载语言的时候设置:
\setdefaultlanguage[variant=poly]{greek}
\setotherlanguage[numerals=western]{hindi}
也可以在随后设置:
\setkeys{greek}{variant=ancient}
甚至在某个环境里设置:
\begin{greek}[variant=ancient]
...
\end{greek}
对某个特定的语言设置字体
你可以为不同的语言设置不同的字体。设想我们准备将所有的英语都设置为斜体,你可以这样做:
\newfontfamily\englishfont{FreeSerif Italic}
当然,你也可以使用一些更炫酷的字体:
\newfontfamily\englishfont{Free Chancery}
这种机制对于你所使用的主语言的字体不包含文档中其他语言的字形的时候。设想我们打算使用 Caladea 作为文档的主字体:
\setmainfont{Caladea}
编译之后我们会看到下面的报错:
Package polyglossia Error: The current roman font
does not contain the Cyrillic script!
(polyglossia) Please define
\cyrillicfont with \newfontfamily.
See the polyglossia package documentation for
explanation.
Type H <return> for immediate help.
...
l.15 \select@language {russian}
Package polyglossia Error: The current roman font
does not contain the Thai script!
(polyglossia) Please define
\thaifont with \newfontfamily.
See the polyglossia package documentation for
explanation.
Type H <return> for immediate help.
...
l.23 \select@language {thai}
...
我们现在必须设置Cyrillic
和Thai
文字应该使用哪种字体。
\newfontfamily\cyrillicfont[Script=Cyrillic]{Charis SIL}
\newfontfamily\thaifont[Script=Thai]{Garuda}
注意,我们已经定义了\cyrillicfont
而不是\russianfont
,也就是说,我们对 Cyrillic 文本设定里字体,而不是俄语。设定\cyrillicfont
对优点是,例如,serbian
是文档里另外一种定义好的语言,然后\textserbian
会自动使用定义好的\cyrillicfont
。如果你只定义了\russianfont
,那么使用\textserbian
会出现问题(当前的罗马字体不支持Cyrillic 文本),然后你需要定义\cyrillicfont
,除非你故意对 Serbian 文本去使用一种不同的字体。
另外一种类似的情况是 Devanagari 文本,它在 Hindi 语和 Sanskrit 语中使用;Arabic 文本,它在 Arabic 语和 Farsi (Persian) 语中使用。
\setdefaultlanguage{english}
\setotherlanguages{hindi,sanskrit}
\newfontfamily\devanagarifont[Script=Devanagari]{Lohit Devanagari}
...
Hindi: \texthindi{हिन्दी}
Sanskrit: \textsanskrit{संस्कृतम्}
在使用\newfontfamily
的时候,你需要指定Script
,不然某些字形可能会输出错误;例如,当我们只使用了\newfontfamily\thaifont{Garuda}
,输出的结果可能是错误的(见下图左),正确的做法应该是添加选项[Script=Thai]
。
定义其他的字体
让我们来看另外一个使用希伯来文的例子:
\documentclass{article}
\usepackage{polyglossia}
\setdefaultlanguage[numerals=hebrew]{hebrew}
\setotherlanguage{english}
\newfontfamily\hebrewfont[Script=Hebrew]{Hadasim CLM}
\begin{document}
\section{מבוא}
זוהי עובדה מבוססת שדעתו של הקורא תהיה מוסחת עלידי טקטס קריא כאשר הוא יביט בפריסתו. -
\end{document}
似乎还不错。让我们来看这种情况,我们使用了一种原本为英语设计的模版文档,它将章节的标题的字体设置为 sans serif:
\RequirePackage{titlesec}
\titleformat{\section}{\Large\sffamily\bfseries}{\thesection}{1em}{}
\usepackage{polyglossia}
\setdefaultlanguage[numerals=hebrew]{hebrew}
...
我们会遇到下面的报错:
Package polyglossia Error: The current roman font
does not contain the Hebrew script!
(polyglossia) Please define
\hebrewfont with \newfontfamily.
See the polyglossia package documentation for
explanation.
Type H <return> for immediate help.
...
l.27 \section{מבוא}
这真是令人困扰:我们不是已经定义了\hebrewfont
为Hadasim CLM
了吗?这是因为我们还没有为 Hebrew 设定 sans serif 字体。我们来解决这个问题,为\hebrewfontsf
增加一个定义:
\newfontfamily\hebrewfontsf[Script=Hebrew]{Miriam CLM}
现在来看看输出:
如果还有需要,我们还可以为\hebrewfonttt
定义一种等宽字体。
致谢
所有的 lorem ipsum 片段都来自于 https://lipsum.com