与 \Umathcode 和 \let 相比,使用 \Umathchardef 有哪些优势?

与 \Umathcode 和 \let 相比,使用 \Umathchardef 有哪些优势?

我一直在尝试使用 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=+\Umathchardefunicode-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/63https://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

相关内容