我正在尝试说服 unicode-math 包允许我在数学公式中插入 CJK 字符(中文表意文字)。这是一个示例输入(前几行仅用于检查是否存在基本功能和字体:
\documentclass[a4paper]{article}
\usepackage{fontspec}
\usepackage{unicode-math}
\setmainfont{Linux Libertine O}
\newfontfamily\cjkfont[Script=CJK]{Kochi Mincho}
\setmathfont{XITS Math}
\setmathfont[range={"4E00-"9FFF},Script=CJK]{Kochi Mincho}
\begin{document}
Hello, world! Здравствуй, мир! Unicode est vraiment \emph{épatant} !
\cjkfont{漢字}
$\mathbf{Δ} = (Δ_ι)_{ι∈I}$
$無 = ∅$
\end{document}
我的系统中分别有“Linux Libertine O”和“Kochi Mincho”字体,分别为LinLibertine_R.otf
和kochi-mincho-subst.ttf
。我使用的lualatex
是 TeXlive 2012 及其包含的fontspec
和unicode-math
包。除了最后一个公式之外,一切都运行正常,其中字符 無 根本没有出现。
现在
\setmathfont[range={"4E00-"9FFF},Script=CJK]{Kochi Mincho}
曾是应该意思是“对于从 U+4E00 到 U+9FFF 范围内的所有 Unicode 字符(即主 CJK 块),使用 Kochi Mincho 字体”。
我唯一的线索就是这个警告:
*************************************************
* fontspec warning: "script-not-exist"
*
* Font 'KochiMincho' does not contain script 'CJK'.
*************************************************
但首先我无法想象这是什么意思(所讨论的字体是 CJK 字体,因此明显地它确实包含 CJK 脚本,并且事实上,在文本模式下它工作正常);此外,使用\cjkfont
我定义的命令会产生相同的警告但仍然有效,因此仅此警告不会造成致命后果。
答案1
数学模式中使用的字符来自 CJK 语言。一般来说,这些字符可以视为普通符号。根据数学分类——另请参阅下面的解释!-- 有两个这样的类别:0 和 7。CJK 语言的排版与使用字母的语言的排版不同。例如,传统上 CJK 语言不使用斜体来强调(但可能有其他方式来强调)。如果斜体、粗体形状... 不存在这样的字体,并且\mathit
、\mathbf
、 ... 无法使用,那么选择 0 类而不是 7 类似乎是合适的。实际上,默认情况下,unicode 字符"zzzzzz
("0
- "10FFFF
)被分配 Umathcode "0"0"zzzzzz
。因此,该字符已被视为字体系列 0 的普通符号,无需进行任何更改。
但似乎\setmathfont
(unicode-math,版本 0.7c) 无法正常工作。作为一种解决方法,我们定义了\adjustmathfont
使用计数器的命令my@char
,以遍历从第一个索引#1
到最后一个索引的范围#2
。在每一步中,我们将字体系列调整\Umathcode\value{my@char} = "0 #3 \value{my@char}
为第三个参数给出的字体系列#3
。例如,如果#1
和#2
等于"7121
且#3
等于"4
这只会产生\Umathcode"7121="0"4"7121
。MWE 中的完整代码如下。
\documentclass{article}
\usepackage{fontspec}
\usepackage{unicode-math}
\setmainfont{Linux Libertine O}
\newfontfamily\cjkfont{Kochi Mincho}
%------ workaround ------
\usepackage{etoolbox}
\makeatletter
%usage: \adjustmathfont{arg1}{arg2}{arg3}
% where arg1 is the beginning of the unicode range, e.g. "4E00
% arg2 is the end of the unicode range, e.g. "9FFF
% arg3 is the font number, e.g. "4
\newcounter{my@char}
\newcommand{\adjustmathfont}[3]{%
\ifnumgreater{#1}{#2}{%
\PackageWarning{}{No adjustment of math font since #1 is greater than #2.}
}{
\setcounter{my@char}{#1}
\Umathcode\value{my@char}="0 #3 \value{my@char}
\whileboolexpr{%
test {\ifnumless{\value{my@char}}{#2}}
}{%
\stepcounter{my@char}
\Umathcode\value{my@char}="0 #3 \value{my@char}
}
}
}
\makeatother
%------------------------
\setmathfont{XITS Math}
\setmathfont[range={"4E00-"9FFF}]{Kochi Mincho}
%the new math font (here "Kochi Mincho") might use font number 4 or higher;
%please see @Gro-Tsen's comment how to automate this;
\adjustmathfont{"4E00}{"9FFF}{"4}
\begin{document}
Hello, world! Здравствуй, мир! Unicode est vraiment \emph{épatant}! \cjkfont{漢字}
$\mathbf{Δ} = (Δ_ι)_{ι∈I}$ $無_無^無 = ∅$
\end{document}
\cjkfont
顺便说一句,可以通过使用如下方法避免使用这个博客。例如,包fontspec
可以用 替换ctex
,\setCJKmainfont{Kochi Mincho}
需要添加。则\cjkfont
不需要。
关于数学模式的一些细节
数学模式的规则与“普通”文本排版不同。在数学模式下,每个字符都分配有一个“数学代码”(十六进制"xyzz
),它指示如何打印该字符。数学代码由三部分组成:“数学类” x
、字体系列、字符在该字体系列中的y
位置。zz
该类x
控制字符排版的几个方面,尤其是间距,并且可以采用以下八个值:0:普通符号,1:大运算符,2:二元运算符,3:关系,4:打开符号,5:关闭符号,6:标点符号,7:变量系列(= 普通符号,但 \fam 被选择而不是y
\fam 在 0-15 范围内)。字体系列的y
范围是 0-15。位置的范围zz
是 0-255。
例如,符号的数学代码\,
设置为\mathcode`\,="613B
,这意味着它\,
被视为标点符号,并使用字体系列 1 的符号“3B”进行排版。更多示例可以在文件“tex/plain/base/plain.tex”中找到。
如今,计算机的限制比几十年前少得多。因此,通过使用包,unicode-math
数学代码的范围得到了扩展:对于字体系列,数学代码的范围为yy
(8 位),对于字符位置,数学代码的范围为zzzzzz
(范围"0
为"10FFFF
,约 21 位),以适应 Unicode 字体。扩展字段可以通过设置\Umathcode"zzzzzz="x"yy"zzzzzz
,例如\Umathcode\leftarrow="3"0"02190
。(有关详细信息,请参阅提到的 luatexref 文档这里。