![与 \Umathcode 和 \let 相比,使用 \Umathchardef 有哪些优势?](https://linux22.com/image/479120/%E4%B8%8E%20%5CUmathcode%20%E5%92%8C%20%5Clet%20%E7%9B%B8%E6%AF%94%EF%BC%8C%E4%BD%BF%E7%94%A8%20%5CUmathchardef%20%E6%9C%89%E5%93%AA%E4%BA%9B%E4%BC%98%E5%8A%BF%EF%BC%9F.png)
我一直在尝试使用 unicode 数学输入。我注意到
\Umathchardef\plus = 2 0 "002B
和
\Umathcode "002B = 2 0 "002B
\let\plus=+
导致\plus
与数学模式相同的行为(假设已为第 0 系列分配了合适的数学字体)。
定义用于数学输入的控制序列的方法有哪些优点/缺点(如果有的话)?
答案1
首先,有性能:\Umathchardef
会稍微快一点(毕竟间接性较少),但在大多数情况下这并不重要。
另一方面,先设置\Umathcode
,+
然后使用\let
定义符号也会设置正确的\Umathcode
,+
因此您也可以+
直接使用。当然,即使您使用 ,\Umathchardef
您仍然可以分配\Umathcode
,但它们没有连接:如果有人更改\Umathcode
,则定义为 的+
命令也会更改,但必须单独更改。这在数学代码更改很多的情况下尤其重要。\plus
\let\plus=+
\Umathchardef
unicode-math
此外,它们在数学模式之外的行为也不同:对于 XeTeX,由 定义的命令\Umathchardef
在数学模式之外总是会产生错误。(在 LuaTeX 中,它将从文本字体中插入相应的字符。)而\let
基于的命令始终插入命令\let
在文本模式下要插入的字符。哪个更好又取决于字符:对于\sum
,在数学模式之外允许它是没有意义的,因此它应该在那里产生错误。另一方面,对于\alpha
,您可能希望名称还允许在文本模式下插入希腊字符。在这种情况下,例如,您可以这样做
\Umathcode"03B1=2 0 "1D6FC
\let\alpha=α
那么你的数学\alpha
是斜体数学阿尔法
答案2
hyperref 不会喜欢你\let
对字符发出命令。检测这样的命令很棘手,目前 hyperref 代码无法做到这一点(这可能会改变,但不会直接改变)。hyperref 和 unicode-math github 上有许多关于此的错误报告,例如https://github.com/latex3/hyperref/issues/63和https://github.com/wspr/unicode-math/issues/532。与其使用,不如\let
使用\def
(\newcommand
)。
在书签中你也会看到差异。\Umathchardef
变体目前已丢失(这也许也会改变,但不会直接改变)。
\documentclass{article}
\Umathchardef\plusmathchar = 2 0 "002B
\Umathcode "002B = 2 0 "002B
\let\pluslet=+
\Umathcode "002B = 2 0 "002B
\newcommand\plusdef{+}
\usepackage{hyperref}
\begin{document}
$a$ % initialize math fonts
text: M \plusmathchar\ L \pluslet\ D \plusdef %error with xelatex
math: $ M \plusmathchar L \pluslet D \plusdef $
\tableofcontents
\section{mathchar text X \plusmathchar\ Y} % error with xelatex
\section{mathchar math X $\plusmathchar$ Y}
%\section{let text X \pluslet\ Y} %lots of errors with hyperref
%\section{let math X $\pluslet$ Y}%lots of errors with hyperref
\section{def text X \plusdef\ Y}
\section{def math X $\plusdef$ Y}
\end{document}
使用 lualatex 输出
编译时不使用 hyperref,但包含注释部分:
书签:
答案3
我们可以在日志中检查这两次赋值的区别:
\Umathchardef\plus = 2 0 "002B
\show\plus
\Umathcode "002B = 2 0 "002B
\let\plus=+
\show\plus
\bye
> \plus=\Umathchar"2"00"00002B.
l.2 \show\plus
?
> \plus=the character +.
l.6 \show\plus
?
根本的区别在于\Umathchardef\plus
你会得到一个代表这个特定数学符号的代币在输出中,而\let\plus=+
你为+
你为角色在输入中。
第二种变体的另一个问题是它是非本地的,即数学码的分配和控制序列的定义不在同一个语句中进行。
此外,第一个陈述是如何完成它™。摘自 TeXbook:
A~hundred or so definitions like
\begintt
\def\sum{\mathchar"1350 }
\endtt
would therefore suffice to define the special symbols of plain \TeX\null. But
there is a better way: \TeX\ has a primitive command ^|\mathchardef|,
which relates to |\mathchar| just as ^|\chardef| does to |\char|.
Appendix~B has a hundred or so definitions like
\begintt
\mathchardef\sum="1350
\endtt
to define the special symbols.
答案4
unicode-math
对几乎所有符号都使用第二种方法,您可以检查(参见 Henri Menke 的回答):
\documentclass[20pt]{extarticle}
\usepackage{unicode-math}
\begin{document}
$\meaning\Bbbzero$, $\meaning\equiv$
\end{document}
因此,如果您使用 Lua 或 XeLaTeX,工作已经完成,您无需手动完成。这种方法的最佳理由是,通过避免使用许多宏,您的代码将更具可读性。比较:
$∫₀¹ x³ \, dx$
- $\int_0^1 x^3 \, dx$
,
$d²r²/d\vec r² = 2