使用 \big| 和 \right| 与 \bigr\rvert 和 \right\rvert

使用 \big| 和 \right| 与 \bigr\rvert 和 \right\rvert

根据以下问题的答案这个问题(关于\bigl、、\bigr\big)以及这个问题(关于、、\lvert等),我认为任何时候使用竖线在右侧划线时,他们都应该写、等或(或)。但是,我觉得我在一些答案中看到了这些混杂在一起的内容。以摘录为例\rvert|\rvert\bigr\rvert\right\rvert\mright\rvert

\right|_{#2} % this is the delimiter

这个答案或摘录

\NewDocumentCommand{\evalat}{sO{\big}mm}{%
  \IfBooleanTF{#1}
   {\mleft. #3 \mright|_{#4}}
   {#3#2|_{#4}}%
}

这个答案。为什么在这里使用不同的组合是合适的?

答案1

好的,简短的答案在评论中;这里是一。

请注意: 这个答案适用于 Knuth 的原始 TeX、eTeX 和 pdfTeX。我不知道其他排版引擎如何管理数学模式中的字符输入和数学字体,例如在 XeTeX 中。此外,原则上输入包可能会干扰下面描述的过程,这将在最后进行简要讨论。

已经存在的答案提供了有关该主题的有用信息,其中包括:


字符标记、其数学代码和原子种类

众所周知,当 TeX 从输入文件读取要排版的公式时,输入的标记会在“数学模式”下处理。这些输入标记大部分都是简单字符,如“x”、“y”、“+”、“=”等,代表公式的语法单位:例如,“x”和“y”是变量,“+”是二元运算,“=”是关系,等等。当然,也有许多数学符号无法用普通文本中的简单字符表示,因此需要作为控制序列输入:例如,\sum\int\cup\cap等,但也有\langle\rangle。显然,|属于第一种情况,而\vert\lvert\rvert属于第二种情况。

现在,无论使用何种方法输入,对于每个字符,TeX 都必须排版在公式中,它需要知道:

  1. 从哪里获取字符,即从哪种字体以及从该字体内的哪个位置获取字符;

  2. 该字符代表哪一种句法实体,即它是变量,二元运算,还是关系等等。

TeX 需要2中提到的信息,因为公式中相邻字符之间的间距取决于它:例如,在公式中 ax+by=0,变量“a”和“x”之间不应该插入空格,或者“b”和“y”之间不应该插入空格,但是相反,“+”和“=”符号应该与周围的元素隔开一定的空格(实际上,“=”需要比“+”更粗的空格)。

现在,问题是如何以灵活且可重新配置的方式为每个可能的输入标记指定所有这些信息,以便例如,“+”是二元运算符,“=”是关系符号的约定不是硬编码在 TeX 本身的代码中。您已经可以猜到,对于像 、 或 这样的控制序列来说,这根本不是问题: \cup毕竟,控制序列可以代表任意的“程序”,因此您可以轻松地在其中打包尽可能多的信息(我们将在下面看到详细信息)。但是如何为像“x”\vert\lvert“+”(或“|”)这样的简单字符指定这些信息?

答案:通过将每个字符与所谓的“数学代码”关联起来。TeX 内部维护一个由 256 个条目组成的表,每个条目可以保存一个 16 位整数(尽管,除了一个例外,实际上只使用 15 位值):对于每个输入字符,其关联条目中包含的整数指定必要的信息。(这称为表 \mathcode,与其他 TeX 表非常相似,例如您可能已经知道的\catcodes、\sfcodes、\uccodes 等表。)更准确地说,如果我们将这样的整数表示为四个十六进制数字的字符串

韓國

仅在 0 到 7 之间变化,则:

  • 给出了正在排版的符号的 ind:例如,0 = 普通符号,1 = 大运算符(如\sum),2 = 二元运算符,等等(参见TeXbook,第 154 页,查看完整列表);

  • F指定Font,通过一种这里不讨论的间接机制(其中 LaTeX2e 的 NFSS 发挥了其作用);

  • 表示该字体内的位置。

关于这一“\mathcode关于如何设置和管理 很多在 LaTeX2e 中,它们比在TeXbook,甚至在这里触及它们也是不可行的(参见 NFSS 文档)。然而,为了回答我们的问题,只要知道 TeX 在需要知道什么时有“某个地方”可以查看就足够了即将排版的符号的 ind。让我们再回顾一下:

  • TeX 仅在以数学模式处理字符标记时才查看该\mathcode表(实际上,这个说法应该改进,但我们先忽略 TeXnicalities);

  • 如果是的话,它会在表中查找相应的条目,该条目的内容除其他外指定了所讨论字符所代表的句法实体的类型;

  • 这种类型的原子最终会被附加到当前数学列表中,可能还会在其上附加上标或下标。


原子的数学特征和种类

在文本模式下,您不仅可以通过在输入中包含该文字字符来指定要排版的字符,还可以通过 \char与 LaTeX\symbol命令等效的原语来指定。例如,bubble您可以在源文件中写入 而不是 ,\char98 u\char98 \char98 le并获得完全相同的结果。当然,\char 当您需要排版“奇怪”的字符(如“¿”)时,原语实际上很有用。

类似地,在数学模式下,您可以使用\mathchar原语指定所需的任何数学字符(或数学符号)。但是\char和之间存在一个重要区别\mathchar:在\char 仅指定 8 位数字之后,仅提供表示预期字符的内部代码,而在\mathchar预期 15 位整数之后,其中包含与我们在\mathcode表条目中找到的完全相同的信息:aind,一种字体F家人和 位置,以完全相同的格式指定。例如,

\matchar"1350

是一个(原始)命令,仅在数学模式下有效,它告诉 TeX 构造一个 Op[erator] 原子(= 1) 包含在字体编号 3 中找到的字符 (F= 3),无论这意味着什么,在位置 80( = 50 十六进制)。在通常的设置中,它就是 ∑ 符号。

当然,\mathchar命令从来不会直接使用,而是通过被定义为等效命令的控制序列来使用。例如,在习惯设置中,\sum相当于 \mathchar"1350,这就解释了为什么输入\sum在输入文件中键入会导致包含正确符号的 Op 原子附加到当前数学列表(可能带有下标/上标)。这里要注意的一点是,这一次印地语/F上/位置信息不是在表中查找的,就像在“裸”字符标记的情况下一样,而是随命令本身一起提供,无论是\mathchar原始命令还是更高级的命令\sum

现在,我们总是假设习惯惯例仍然有效,结果是,单独使用时,而不是在\left\big或 之后使用\biggr或...之后使用。

  • \vert最终相当于\mathchar"026A,因此它生成一个普通原子(= 0) 包含在某个字体的某个位置找到的字符;

  • \lvert最终相当于\mathchar"426A,因此它生成一个 Open[ing] 原子(= 4) 包含与上面完全相同的字符;

  • \lvert最终等同于\mathchar"526A,因此它生成一个 Clos[ing] 原子(= 5) 再次包含相同的字符。

此外,我们可以看到\mathcode与“|”字符相关联的"026A也是如此,因此|输入中的 简单 的行​​为,至少在它单独使用时而不是在\right\Bigm\Biggl或... 之后使用时,与 完全一样\vert

但这只是整个故事的一个简化版本:我们将在接下来的两节中完善这个图景。


分隔符

有些数学符号,比如括号和根号,会随着它们所包含的子公式的大小而增大,因此需要特殊处理。对于这些符号,TeX 提供了“分隔符”和“根号”的概念,这里只讨论前者。

在原始级别(可以说是 TeX 的“机器语言”级别),TeX 仅在少数明确定义的情况下将符号视为分隔符:在 \leftor\right命令之后,以及与处理分数的某些原始命令结合使用。例如,(本身被排版为“正常”(IE(非分隔符)字符,根据上述规则,但\left(会导致 TeX 将括号视为“分隔符”,即可以增长的字符。为了能够排版这种增长的字符,TeX 需要比“普通”字符更多的信息,因为它需要知道括号的位置 不同的可以找到分隔符的大小。因此,\mathcodeTeX 不会查看该字符的数学代码 ( ),而是搜索其另一个内部表,该表同样包含 256 个可能字符代码的条目:每个条目都保存着\delcode相关字符的所谓“分隔符代码”( ),它可以是负数(对于不应用作分隔符的字符,如“x”或“+”),也可以是非负的 24 位数字(即六个十六进制数字的序列)

韓國

指定所讨论字形的两种变体,使用与表格中使用的约定类似的双折叠版本\mathcode。更准确地说,前三位数字(韓輯)表示字体F阿米莉和可以找到字形的最小尺寸的位置,以及最后三个(咕咕咕)以类似的方式指定可以找到更大尺寸的位置(实际上,QQ指示第一个较大变体在字体中的位置;可能还有更大的变体,可以通过字体度量文件本身包含的信息从第一个变体开始找到它们)。特别需要注意的是,在这种情况下,关于当前符号的句法性质的信息是不是包括在内\delcode,因为它是不是需要:TeX 已经从导致其寻找分隔符(\left\right或我们没有考虑到的其他分隔符)的命令中知道了此信息。

让我们用一个例子进一步说明这个概念:当 TeX 在输入中遇到字符标记时| 通过它自己,它将其视为“正常”符号:它查找它的\mathcode,发现它是,比如说,,"026A并且从的第一位数字中,\mathcode它了解到手头的字符应该作为(内容)普通原子附加到当前数学列表中;的另外三位数字\mathcode 告诉 TeX 在哪里找到适当的字形。另一方面,当 TeX 遇到输入,比如说,时\left|,它已经知道,从\left 命令本身来看,需要一个开始分隔符,它唯一存在的问题就是找到字形;为此,也正是为此,它会查看 \delcode随后的|,从中检索必要的信息。

如果分隔符可以通过字符标记指定,例如圆括号((, ))、方括号([, ])或竖线( ) ,则此方法可行|;但是花括号或双竖线等分隔符呢?如您所知,这些分隔符是通过控制序列(\lbrace,或其同义词)指定的。好吧,所有这些控制序列实际上都是宏,它们扩展为对另一个名为 的原始命令的适当调用,该命令与 大致类似。\rbrace\Vert\|\delimiter\mathchar


命令\delimiter

原始 TeX 命令\delimiter后面必须跟一个 27 位无符号整数,可以表示为七个十六进制数字的字符串

qqqq

仅在 0 到 7 之间变化。此命令可用于 TeX 寻找分隔符的所有地方(即,在\left、 之后\right,以及一些其他处理分数的原始命令),在这种情况下,最右边的六位数字告诉 TeX 在哪里找到分隔符的字形,其方式与 完全相同\delcode。现在,

\left \vert

工作原理如下:\vert是一个扩展为的宏 \delimiter "026A30C,因此上面那行扩展为

\left \delimiter "026A30C

并且 TeX 知道它必须构造一个开始分隔符(因为 \left),其小变体可以在字体中找到Family 2(TeX 知道这是哪种字体)位置 106,其第一个较大的变体位于字体 3、位置 12。问题是:数字到底是什么为...提供?

\vert好吧,我们都知道,我们不仅可以在\left\right(或等)之后使用,\bigl还可以单独使用,在这种情况下,它完全等同于单独的|。这是因为\delimiter 命令也可以出现在 TeX 被允许出现的地方不是寻找分隔符;在这种情况下,随后的数字的最后三个十六进制数字将被删除,并且该命令的行为就像 \mathchar。换句话说,当它确实不是跟随\left等,

\delimiter "qqqq

就像

\mathchar "韓國

这次,它来自 k 数字TeX 会了解它必须构造哪种原子,这就是提供它的原因。因此,您可以定义\vert以扩展为\delimiter "026A30C,并且此定义在任何情况下都适用。


答案终于揭晓了!

我们终于可以回答这个问题了。考虑以下输入示例:

  • |自行:TeX 查看\mathcode与 相关的 内容|,从中学习两个都在哪里可以找到相关的字形 构造哪种原子。

  • \left|\right|:TeX已经知道它必须构建一个左(或右)分隔符,并查看\delcode才能 | 了解在哪里可以找到必要的字形。

  • \vert单独使用:这是一个扩展为 的宏 \delimiter "026A30C;在此上下文中,它的作用与 相同 \mathchar "026A,数字的第一位数字"026A 告诉 TeX 要构造哪种原子(后面三位数字是字形的所在位置,在本例中始终使用它的小变体)。因此,一个普通原子( = 0) 在这里被构造。

  • \left\vert\right\vert:第一个扩展为 \left \delimiter "026A30C。TeX 已经知道需要左分隔符,因此忽略数字的第一位数字"026A30C,并使用其余数字来了解在哪里找到所需的字形。的效果\right\vert是类似的。

  • \lvert本身:这是一个扩展为 的宏 \delimiter "426A30C;在此上下文中,它的作用与 相同 \mathchar "426A,数字的第一位数字"426A 告诉 TeX 要构造哪种原子,这次是 Open[ing] 原子( = 4);接下来的三位数字告诉 TeX 在哪里可以找到适当的字形,在这种情况下总是使用它的小变体。

  • \left\lvert\right\lvert:其中第一个扩展为 \left \delimiter "426A30C。TeX 已经知道需要左分隔符,因此它会忽略数字 的第一位数字"426A30C,并使用其余六位数字来定位必要的字形。对于 也类似\right\lvert

  • \rvert单独使用:锻炼。(提示:\rvert扩展为 \delimiter "526A30C = 5 表示 Clos[ing] 原子)。

  • \left\rvert\right\rvert:锻炼。

从上文中我们可以看出(假设惯常的\mathcode和 定义)\left|\left\vert\left\lvert, 甚至\left\rvert 都是完全相同的东西。 而 也是如此\right


那么\bigl亲戚呢?

控制序列\big,,,,\bigl\bigm\bigr\Big等是带有一个参数的宏,每个宏都制造一个包含“伪分隔符”的预定类型的原子(IE,不是技术意义上的分隔符)具有预定的大小;它们通过\left...构造来实现这一点,该构造仅包含适当大小的空框,该空框由、 、或命令\right明确包裹(实际上并未使用,因为它是“默认隐含的”)。更准确地说,正如您已经知道的那样:\mathord\mathrel\mathopen\mathclose\mathord

  • \big,, …系列\Big生成普通原子;

  • \bigl,, …系列\Bigl生成 Open[ing] 原子;

  • \bigm,, …系列\Bigm生成 Rel[ation] 原子;

  • \bigr,, ...系列\Bigr生成 Clos[ing] 原子。

因此,这里仅使用该参数来定位所需的字形。


关于 inputenc 的说明

为了简单起见,在上面的描述中,我们没有提到\mathcode表查找仅针对类别代码为 11(字母)或 12(其他)的字符标记进行。请记住 输入包使位置 128 … 255 中的字符处于活动状态,并且编码定义文件可以在数学模式下为这些活动字符中的某些字符分配特定含义。当然,用其含义替换此类活动字符会发生 上述过程都已发生。仅举一个例子,该文件latin1.def除其他内容外还包含以下声明:

\DeclareInputMath{177}{\pm}

因此,字符编号 177 在数学模式下使用时始终与控制序列相等\pm。当然,这种替换完全独立于\mathcode机器。

答案2

Gustavo 的回答有很多有趣的细节,值得仔细阅读。但大部分内容相当简单。

之后\left\middle只有\right一些标记是合法的:

  • 具有非负的字符(或最终扩展为一个的宏)\delcode
  • 一个宏,其最终扩展以 开头,\delimiter后面跟着一个 27 位数字。

请注意,TeX 在扫描 或 之后会执行扩展\left\middle以便\right找到具有非负\delcode或 的所需字符\delimiter(这反过来会触发扩展来寻找数字)。

限制为标准 TeX/LaTeX(与带有 的 XeTeX/LuaTeX 相反unicode-math),唯一具有非负值的字符\delcode

( "028300
) "029301
. 0
/ "02F30E
< "26830A
> "26930B
[ "05B302
\ "26E30F
] "05D303
| "26A30C

第二种典型的宏在纯 TeX 中定义为

\def\rangle{\delimiter"526930B }

在 LaTeX 中这样写

\DeclareMathDelimiter{\rangle}{\mathclose}{symbols}{"69}{largesymbols}{"0B}

这只是用更清晰的方式表达相同含义的样板代码。

那里一个重要的区别:LaTeX 使用符号名称,而不是像普通 TeX 那样硬连线数学组(或家族)数字。

A\delcode是一个 24 位数字;与代码的区别\delimiter在于,代码中最左边的三位\delimiter指定符号的类型,以防它不在\left\middle\right(以下称为 LMR)的上下文中使用。因此,例如,\rangle构建一个关闭原子相对于间距(\mathclose在 LaTeX 中,第一个十六进制数字为 5)。

相反,在 LMR 中使用时,这三位会被忽略,因为 TeX 已经知道类型(打开奥德或者关闭分别)进行分配。最右边的 24 位意味着什么并不重要。

\bigl\big和如何\bigr与它们的兄弟一起进入游戏?它们实际上是\left伪装的,但隐藏在类型分配命令中,分别是\mathopen\mathord\mathclose。还有\bigm一个构建一个相对原子以同样的方式:

\math<X>{\left<token><box>\right.\kern-\nulldelimiterspace}

完成,其中<token>是紧随\big和朋友之后的,是<box>一个适当大小的框(用于区分\big\Big\bigg\Bigg,并且<X>openord或,具体取决于、和(或朋友)中的哪一个被调用。特别是和 朋友构成 LMR 上下文。closerel\bigl\big\bigr\bigm\big

两者之间没有任何区别

\big| \big\lvert \big\rvert

或之间

\bigl| \bigl\lvert \bigl\rvert

类似地,\left|\left\lvert完全相同\left\rvert,因为|\lvert\rvert指向同一个字符(从技术上讲,\delcode\delimiter代码中的最低有效 24 位是相同的)。


您可能已经注意到,在代码中,>和分别在和中\rangle共享最低有效 24 位;和也是如此。这允许我们说\delcode\delimiter<\langle

\left<
\bigl<
\Bigl<

(或者甚至\big<,但这是错误的)而不是使用\langle;类似地对于\rangle

|(或同义词\vert\lvert和之间的区别\rvert仅当它们没有出现在 LMR 上下文中时才有意义。

最简单的例子是

\log|-2|
\log\lvert-2\rvert

正确的是后者;前者会导致

对数<thinmuskip>| <medmuskip>- <medmuskip>2|

而后者给出了正确的

对数|-2|


总结一下:\bigl\lvert如果您感觉更舒服,可以使用它,但\bigl|时间更短,并且效果相同。

相关内容