如果定义了 \nin,XeLaTeX + unicode-math 是否会进入无限循环?

如果定义了 \nin,XeLaTeX + unicode-math 是否会进入无限循环?

我经常使用缩写 \nin 来定义

\newcommand{\nin}{\not\in}

但是,当我开始使用 xelatex 和 unicode-math 执行此操作时,它会导致 xelatex 停滞。特别是以下文档似乎使 xelatex 陷入无限循环

\documentclass{amsart}
\usepackage{unicode-math}
\newcommand{\nin}{\not\in}
\begin{document}
    \( a \nin b \)
\end{document}

坦率地说,我很困惑,因为我的命令是在所有包加载之后定义的(即使我在开始文档之后定义命令仍然会失败)并且没有现有命令与它冲突,那么发生了什么?

有什么方法可以让这个宏工作吗(理想情况下以在 xelatex+unicode-math 和 pdflatex 中都有效的方式)

需要明确的是定义\nin 加上 \not\in 的使用会造成麻烦,就像我替换一样。

\( a \nin b \)

\( a \not\in b \)

它仍然停滞,但如果我将其替换为

\( a \in b \)

它执行得很好。

根据 egreg 的评论,我可以将 \nin 定义为 \notin,并且一切都可以正常编译。不过,我仍然想知道这里发生了什么,这样我就不会再遇到同样的问题。

答案1

\not定义如下unicode-math

\cs_new:Npn \__um_newnot:N #1
 {
   \tl_set:Nx \l_not_token_name_tl { \token_to_str:N #1 }
   \exp_args:Nx \tl_if_empty:nF { \tl_tail:V \l_not_token_name_tl }
    {
     \tl_set:Nx \l_not_token_name_tl { \tl_tail:V \l_not_token_name_tl }
    }
   \cs_if_exist:cTF { n \l_not_token_name_tl }
    {
     \use:c { n \l_not_token_name_tl }
    }
    {
     \cs_if_exist:cTF { not \l_not_token_name_tl }
      {
       \use:c { not \l_not_token_name_tl }
      }
      {
       \__um_oldnot: #1
      }
    }
 }

\__um_oldnot:是遗留的\not;在文档开始时,\not设置为等于\__um_newnot:N

本质上,当您执行 时\not\foo,宏会检查 是否\nfoo已定义(多个否定符号以此方式命名)。否则,它会检查\notfoo,如果失败,则使用否定斜杠。

你看到问题了吗?如果\nin按照你的方式定义,它就会被执行,从而重新启动循环,因为它确实\not\in……无限循环。

请注意,\not\in自 TeX(及其标准字体)诞生的第一天起,它就是错误的,而应该是\notin

解决方案

\newcommand{\nin}{\notin}

评论

的基本思想unicode-math是帮助用户获得正确的符号。您的案例表明用户忽略了使用的建议,\notin而不是:您能发现使用和 Computer Modern\notin时的区别吗?pdflatex

在此处输入图片描述

类似地,经常会发现\not\mid而不是\nmid

更重要的是,如果 Unicode 字符集中存在否定符号,则应该可以独立于用户输入使用。因此\not\mid 應該内部转换为\nmid,类似地\not\in转换为\notin(其中unicode-math表示单个字符,而不是像传统字体那样两个字形的叠加)。如果我们查看unicode-math-table.tex,我们会发现

\nexists
\notin
\nni
\nmid
\nparallel
\nsim

以及其他几个。可能还应该有\nin,但传统上称之为\notin

请注意,如果您定义\nfoo\not\foo,那么您会遇到与相同的问题\in

相关内容