mathcode 和 catcode 之间有什么区别以及如何使用 mathcode?

mathcode 和 catcode 之间有什么区别以及如何使用 mathcode?

该命令\catcode通常用于更改一些内部内容。例如,该命令\makeatletter更改 catcode @。但它是什么\mathcode,它是如何工作的?

catcodes 在此处有很好的解释:Wiki TeX 目录代码

与之相关的\mathcode命令可以找到\delcode。请添加一些关于这些命令的一致性的信息。

答案1

在文本中,字符标记只有两个属性,即字符代码和类别代码。如果+在文件中看到,则(通常)给出类别代码 12(标点符号),字符代码来自文件编码,因此在本例中为 43。

在数学模式列表中,数学原子需要更多的结构,每个符号来自不同的字体,并根据其类别(运算符、二进制中缀、关系等)获得不同的间距。在典型的 1970 年代风格中,这些属性被紧凑地打包成单个整数中的位字段,称为数学码,通常以十六进制表示,因此您可以轻松地将这些字段分开。+纯文本中的数学码设置为

\mathcode`\+="202B

这意味着它属于类 2(二进制中缀)、fam0(罗马字体)和字符十六进制 2B,即十进制 43(罗马字体编码中 + 的字符代码)。

正如 egreg 在评论中指出的那样,数学代码仅用于普通字符标记,即 catcode 11 和 12(字母和标点符号),具有特殊 catcode(如 4)的字符标记(通常)保留其特殊行为,并且不参考其数学代码。但是,如果您从宏或 via&生成 catcode 12,则将参考其数学代码。&\string&

\delcode类似,但包含一些额外的位,因为分隔符需要更多信息,(纯文本的解码是

\delcode`\(="028300

这表明小字符(来自字体 \fam0 中的十六进制 28 位置,但随后您需要切换到字符十六进制 0\fam3才能获得大括号。(字体指标指定了用于构建更大字符的字形链(如果需要),但它们需要知道从哪里开始。

\mathcode"8000是一种不以常规方式查找的特殊代码。如果字符具有该数学代码,则将使用活动(catcode 13)标记的定义,即使字符本身不是活动的。这在纯文本和 LaTeX 中用于允许'在文本中用作正常的非活动撇号,但在数学中它具有 catcode 十六进制 8000,因此使用活动定义,扩展为^{\prime}

答案2

我想补充一个最近对我来说至关重要的技术要点:虽然\catcode更改是出了名的脆弱,因为它们不能在标记化之后发生(具体来说,在读取宏的参数之后),但\mathcode更改发生。例如,我有以下宏:

\def\genby#1{\langle#1\rangle}

在代数中指定某个事物的生成器,其中#1表示生成集。如果我有几组生成器,我当然想使用数学上正确的符号,\genby{S \cup T}而不是更简单但不太正确的符号\genby{S, T}。不幸的是,我总是忘记,所以我没有搜索并替换所有逗号,而是尝试重新定义命令:

{\catcode`\,=\active \gdef,{\cup}}
\def\genby#{%
  \langle\bgroup \aftergroup\rangle
  \catcode`\,=\active
  \let\next=
}

(使用这个技巧以避免标记化),虽然这在$\genby{S,T}$(产生相当于)中可以正常工作,但在构造$\genby{S \cup T}$中却完全失败了amsmath

\begin{gather}
  \genby{S,T}
\end{gather}

但它没有效果!我立即意识到这是一个“amsmath读两次参数”的例子(我第一次了解到这个问题(这不是它在这个网站上出现的唯一地方),并认为这是一个标记化问题,阻止了 catcode 更改。所以我尝试了\mathcode(另请参阅 egreg 的评论):

{\catcode`\,=\active \gdef,{\cup}}
\def\genby#1{%
  \langle\begingroup
  \mathcode`\,="8000
  #1
  \endgroup\rangle
}

或者,如果不使用活动逗号的全局定义,这可能会与其他包发生冲突,

\newcommand{\genby}[1]{%
  \begingroup
  \begingroup\lccode`\~=`\,
  \lowercase{\endgroup\let~\cup}%
  \mathcode`\,=\string"8000
  \langle#1\rangle
  \endgroup}

并且这再次起作用,即使在gather

此功能强调了数学模式的一个重要理论点:在数学模式下操作时,TeX 具有中间的解释阶段,类似于标记化,在此阶段,它会构建一个“数学列表”,该列表不仅仅是文本输入(“代码”),而且少于排版输出(“水平列表”)。数学代码、delcode 等的解释仅在从标记化输入流转换为数学列表时发生,因此会更改其中一个标记化后有效。(但是,一旦构建了数学列表,您仍然无法执行任何操作。)

相关内容