^ 和 _ 是 LaTeX 中唯一不以反斜杠开头的命令吗?

^ 和 _ 是 LaTeX 中唯一不以反斜杠开头的命令吗?

LaTeX 中几乎所有命令前面都带有反斜杠。数学环境中的上标和下标命令(分别为 ^ 和 _)是唯一的例外吗?

答案1

在 TeX 和 LaTeX 中,区分“命令”或“控制序列”与 TeX 特殊字符至关重要。一般来说,只有前者以反斜杠 ( \) 字符开头。(但请参阅下面最后一段,了解不以反斜杠开头的命令示例。)

^_只是 TeX 特殊字符的两个例子。其他字符包括\(反斜杠)、{}$(“数学移位”)、&#%(注释字符)。从 TeX 和 LaTeX 的角度来看,这些字符之所以“特殊”,是因为它们各自都有特定的特殊类别代码,或简称为 catcode。如果需要排版某个特殊 catcode 字符,则适用各种规则。例如,要排版一个 & 号、井号或百分号字符,必须在相应符号前加上反斜杠字符,即分别输入 、 和 。\&\#\%文本模式下排版反斜杠符号,必须将其输入为“ \textbackslash”或“ \string\”。(后一种方法还需要T1字体编码——它不适用于OT1。使用后一种方法,\string\如果目标是生成单个反斜杠字符,则后面需要一个空格;可能出现的不良副作用是在反斜杠字符后输出一个空格。相反,输入 会\string\hello创建\hello,而没有空格。)在数学模式下,可以通过输入 或 来输出反斜杠字符\backslash\setminus具体取决于预期含义: 的数学状态为\backslash“ord”(普通),而 的数学状态\setminus为“bin”(二进制)。

如果有“特殊”的 catcode,那么也一定有“非特殊”的 catcode,对吧?事实确实如此。主要的非特殊 catcode 保留给字母(例如,azAZ),空格字符, 和“其他”字符(例如数字、标点符号、撇号、、、、"和)。非特殊 catcode 的字符可以直接输入,即它们不需要以@任何特殊字符作为前缀。行尾字符、“(忽略”字符和“无效”字符也由非特殊 catcode 标识。)-/

最后,有一个 catcode活跃角色。“活动”字符是执行以下任一操作的命令的示例不是以反斜杠开头。在大多数 TeX 安装中, (“波浪号”) 的 catcode~是“active”; 的主要用途~是在两个单词之间插入一个不可中断的空格。要直接排版波浪号,必须像\~{}在文本模式和\tilde{}数学模式中一样输入它。据我所知,独立的波浪号在一般的印刷应用程序中并不常见。(我认为排版 URL 字符串是一种特殊的应用程序。)波浪号经常作为变音符号或“重音符号”出现,例如\~nEspa\~na和中$\tilde{z}$。另一个例子:如果babel包使用选项 加载,某些标点符号(例如和)french的 catcode将从“其他”更改为“活动”。此更改有助于为这些标点符号实现法语印刷实践。:;

答案2

以下是从 TeX(具体来说是 Knuth TeX)程序内部的角度给出的答案。不需要知道以下任何一种都只是使用 TeX;这只是在您好奇其内部工作原理时才适用。

胃发出“指令”

TeX 程序的“主要”部分(经过一些初始化等)基本上是主循环(在源代码中调用main_control)。代码的结构有点像下面的伪代码:

def main_control():
    while True:
        get_x_token  # Sets `cur_cmd` and `cur_chr`.
        # Now perform some action based on `mode` and `cur_cmd`...
        # ... this action may use the value of `cur_chr`.

这个主控制程序就是 Knuth 在手册中描述的(TeXbook) 作为 TeX 的“胃”:它饥渴地等待着从 TeX 的“嘴” (上图) 传递给它的标记 (命令及其细节) get_x_token

因此从 TeX 的核心角度来看,一切到达它的是一个命令:例如,字母“e”作为命令“letter”(= cur_chr101)传递到胃中。对于这个“letter”命令,相应的操作(如果 TeX 处于水平模式)只是“将此字符附加到当前字体中的当前 hlist”。

这里有一些常见的“命令”(及其大多不相关的内部代码),在什么情况下 TeX 的胃会收到这些命令,以及采取的相应操作:

  • (11):当您输入被视为字母的字符时,TeX 的胃会获取此命令(默认情况下:A..Z、a..z)。操作(在水平模式下)是将该字符附加到当前 hlist。
  • 其他字符(12):当您输入字符(例如,默认情况下)"'()*+,-./0123456789:;<=>?@[]|或反引号时,TeX 的胃会获取此命令。操作(在水平模式下)是将该字符附加到当前 hlist。
  • 垫片(10):当您输入空格 (ASCII 32) 或制表符 (ASCII 9) 等字符时,TeX 的胃会获取此命令。操作是附加正常的单词间粘连或更大的粘连,具体取决于 space_factor(等)。
  • 跳过(26):当您输入\hskip\hfil或类似的东西时,TeX 的胃会收到此命令。操作是扫描(如果需要),然后附加相应的胶水。
  • 分配整数\tolerance(73):当您输入某些命令(如或 )时,TeX 的胃会收到此命令\day。操作是调用一个名为 的内部过程prefixed_command(在本例中,它将扫描一个值以查找相应的整数并分配该值)。
  • 定义(97): 当你输入\def\edef\xdef或 时,TeX 的胃会收到此命令\gdef。操作是调用一个名为的内部过程prefixed_command(在本例中,它将扫描控制序列名称,然后是参数,然后是定义标记列表,并赋予该含义)。
  • 左括号(1)(开始组):当您输入时,TeX 的胃会获取此命令(默认情况下){。操作是开始新的保存级别。
  • 数学移位(3):当您输入时,TeX 的胃会获取此命令(默认情况下)$。操作是进入或适当退出数学模式。
  • sup_mark(7):TeX 的胃会在您输入时获取此命令(默认情况下)^。如果不在数学模式下,则操作是打印错误和insert_dollar_sign(作为错误恢复),如果在数学模式下,则操作是调用sub_sup(处理下标和上标)。
  • par_end\par(13):TeX 的胃会在每个段落(或空白行)末尾获取此命令。
  • 扩大(59):留给 TeX 的扩展,包括一些已实现的 TeX 内置功能喜欢扩展只是为了说明。操作是调用do_extension
  • 输出参数(5)(输出一个参数):当 TeX 的胃在标记列表中遇到您输入#1或 ... 或 时它所放置在那里的内容时,它会获取此命令#9
  • 放松(0): 当你输入 时,TeX 的胃可能会收到此命令\relax。操作是不执行任何操作。

大约有 100 条命令可以进入 TeX 的胃口;eTeX、pdfTeX、XeTeX 或 LuaTeX 等 TeX 扩展有更多命令。其中一些命令(如“letter”)出现的频率非常高,以至于 TeX 将其视为经过更深入优化的“主循环”的一部分。

嘴巴“发号施令”

以上都是关于 TeX 的“胃”(主控制循环和语义例程/动作程序)的内容。但 TeX 的“嘴”(扫描例程)也同样有趣。在它向胃发出命令之前,那里发生了很多事情。

请注意,在上面,我说其中一些命令是由单个字符输入触发的,并且经常提到“默认情况下”。这是因为 TeX 有一个概念类别代码。共有 16 个,您可以在第 37 页阅读详细信息TeXbook或者这个网站上的许多问题,例如类别代码是什么?。我就不重复了,只举几个例子:

  • 当 TeX 的嘴巴看到 catcode 为 11(字母)的字符时,它会向胃部发送命令“字母”(也是 11)。

  • 当 TeX 的嘴巴看到 catcode 为 12(其他字符)的字符时,它会向胃部发送命令“other_char”(也是 12)。

  • 当 TeX 的嘴巴看到 catcode 为 1(组开头)的字符时,它会向胃部发送命令“left_brace”(也是 1)。

同样地,对于 catcode 2 (组结束/“right_brace”)、catcode 3 (数学移位/“math_shift”)、catcode 4 (对齐制表符/“tab_mark”)、catcode 7 (上标/“sub_mark”)、catcode 8 (下标/“sub_mark”)、catcode 10 (空格/“spacer”),其中包括问题中提到的^_

但!

  • 当 TeX 的嘴巴看到 catcode 为 14 的字符(%默认情况下为注释,类似)时,它不会立即向胃部发送任何内容,而只是跳到行尾——当它遇到真实命令时才会发送命令。

  • 当 TeX 的嘴巴看到 catcode 为 13(活动字符,默认情况下)的字符时~,它会查找该活动字符的含义,并相应地执行宏调用或扩展等。

  • 当 TeX 的嘴巴看到 catcode 为 0 的字符(转义字符,默认为反斜杠)时,它会扫描控制序列(基本上是单个非字母或字母序列),然后在哈希表中查找该控制序列以找出其含义,然后说“未定义的控制序列”或扩展它或......

嘴里会发生很多事情,例如条件语句\if,或宏调用(任何用\def或类似 定义的宏),或用 打开文件\input,或类似 的事情\expandafter。只有当所有这些“咀嚼”完成并且有“真正的”命令时,食物才会到达胃里。

概括

用户从这个角度来看,TeX 已经

  • “命令” 比如\hskip\llap
  • 像主动角色~(也可以称为命令)
  • 特殊 catcode 字符,如$^_(通常不称为命令),以及
  • 常见的 catcode(“字母”或“其他字符”)字符,如e5(几乎从不称为命令)。

内部的看法,

  • 角色有 catcode,
  • 在此基础上,嘴巴可能会做进一步的扫描或扩展(在反斜杠或类似 的活动字符的情况下~),
  • 并根据得到的结果继续进行扩展(就像\llap是扩展为 的宏一样\hbox to\z@{\hss#1}),
  • 最后向胃部发出命令(例如,\llap导致make_box命令被传递),
  • 这些“命令”不仅包括“hskip”(对应于用户可能认为的命令\hskip),还包括“math_shift”和“sup_mark”,甚至“other_char”和“letter”(通常由单个输入字符组成),
  • 但这些“命令”不是包括诸如\input\if\string您可能考虑的命令之类的内容。

答案3

LaTeX 可以打印哪些字符具有非文字含义:

\makeatletter
\def\do#1{\ifnum\catcode\string`#1=12 \else
\message{\expandafter\@gobble\string#1}\fi}
\typeout{}\message{Chars:}%
\do\!\do\"\do\#\do\$\do\%\do\&\do\'\do\(\do\)\do\*\do\+\do\,%
\do\-\do\.\do\/\do\:\do\;\do\<\do\=\do\>\do\?\do\@\do\[\do\\%
\do\]\do\^\do\_\do\`\do\{\do\|\do\}\do\~%
\typeout{}%
\@@end

它打印:

Chars: # $ % & @ \ ^ _ { } ~

如果我们重新运行它

\documentclass{article}
\usepackage[french]{babel}
\begin{document}

添加后,它会打印更多内容:

Chars: ! # $ % & : ; ? @ \ ^ _ { } ~

我在 TeX Live 2015 和 2018 中尝试过这个(并且有效),使用乳胶pdflatex路拉泰克斯

相关内容