在 LaTeX 数学模式中 & 表示对齐时前后的间距问题

\(\qquad\!\!\)这应该是本站的第一篇正式博文,所以希望是一篇能够代表本站风格的有趣又不失深度的文章,在搭建博客前便计划好了,留给这个从我初识 \(\mathrm{\LaTeX}\) 起便感到困惑不解的问题——“在 LaTeX 数学模式中 & 表示对齐时前后的间距问题”。

\(\qquad\!\!\)\(\mathrm{\LaTeX}\) 中使用需要对齐的多行公式时,最常使用的便是 amsmath 宏包提供的 align 环境,它使用列分隔符 & 将公式进行对齐,一般情况下,& 放在等号左边。但是一个等号后的公式的长度超过正常的一行长度需要断行时,根据 GB/T 7713.2-2022,一般在二元关系符后,二元运算符前断开,所以需要将 & 放到等号右侧,而根据经典 \(\mathrm{\LaTeX}\) 入门手册 lshort-zh-cn 中所述,此时需要在等号后添加一对括号 {} 以产生正常的间距:

\(\qquad\!\!\)虽然各种 \(\mathrm{\LaTeX}\) 入门教程中都存在这一对括号,但是对于这一对括号 {} 的作用也都没有进行仔细的/原理上的讲解。而在 LLM 还没有如此发达的我的 \(\mathrm{\LaTeX}\) 初学期,简单使用搜索引擎也未能搜到相关信息,所以便一度搁置,直到这个寒假终于有精力重拾起这个问题,在 latexstudiotse 和 AI 工具的帮助下,终于搞明白了这一对括号背后的原理及其深刻意义,倍感喜悦,遂整理成文于此,与大家一起分享下我学到的知识。

问题整理

\(\qquad\!\!\)在进行基本原理的陈述前,我们先来整理一下这篇文章涉及到的问题。

\(\qquad\!\!\)同样是非常经典的 \(\mathrm{\LaTeX}\) 入门书籍,刘海洋先生的《LaTeX 入门》一书中对于这个问题的例子有着更复杂的表述方式:

\(\qquad\!\!\)左侧的第一种方式和上面的 lshort-zh-cn 中的方式相同,都只是多了一对括号,但是右侧的另一种方式中的“幻影”和 \mathrel 命令又是什么呢?我们将在下面逐步展开,从基本原理讲起直至能够说明这两种方式的等价性。

\(\qquad\!\!\)另外,align 环境作为 amsmath 宏包中多行公式中的一个大家族,除了其本身还有 alignedalignat 及其组合或加*的环境,这些环境有哪些差异?使用 & 进行分隔和对齐又有哪些便利的应用,也会在最后一部分进行简单的介绍。

基本原理

\(\qquad\!\!\)\(\mathrm{\LaTeX}\) 数学模式中,math atoms 是构成数学公式的最小排版单元,每个字符或符号都会被分类为不同的 atom(原子),这些分类决定了公式中元素的间距和排版规则。在 \(\mathrm{\TeX}\) 中共有 \(13\) 种 atom:

Ord Op Bin Rel Open Close Punct Inner

Over Under Acc Rad Vcent

其中,第二行的五种在考虑间距时被视为 Ord 即可。

我们先简单介绍一下第一行的几种原子,再去看一下在排版过程中它们之间的间距是如何安排的。

  1. Ord atom(普通原子)

    默认的原子类型,用于普通数字、字母或无明显语法功能的符号,可使用 \mathord 命令手动指定。

    e.g. a, 2, \alpha, \mathrm{xyz}

  2. Op atom(操作符原子)

    大型运算符(如求和、积分符号),通常带有上下限,可使用 \mathop 命令手动指定。

    e.g. \sum, \int

  3. Bin atom(二元运算符原子)

    连接两个被操作数的运算符,如加减乘除,可使用 \mathbin 命令手动指定。

    e.g. +, -, \times

  4. Rel atom(关系符原子)

    表示具有逻辑关系的符号,如等于、不等号、箭头等,可使用 \mathrel 命令手动指定。

    e.g. =, \leq, \rightarrow

  5. Open/Close atom(开闭括号原子)

    括弧类符号,如 ([\{ 等,可使用 \mathopen\mathclose 命令手动指定。

    e.g. ([])

  6. Punct atom(标点符号原子)

    公式中的标点符号,如逗号、分号等,可使用 \mathpunct 命令手动指定。

    e.g. , ;

  7. Inner atom(内部结构原子)

    由特定结构(如分数、根号、绝对值)产生的原子,可使用 \mathinner 命令手动指定。

    e.g. \frac{a}{b}, \sqrt{x}, \left| \sum_{i} v_i \right|

    注意这里由 \left...\right 命令包裹起来的整体被视为一个 Inner atom,这就是为什么在一般的数学公式中使用 \left...\right 时会产生间距问题,所以需要使用 mleftright 宏包或 physics2 宏包这样的宏包进行纠正。

\(\qquad\!\!\)我们以简单的公式整理为例,$a+b=c$ 相应的序列即

Ord Bin Ord Rel Ord

$(a+b)\cdot c=ac+bc$ 相应的序列即

Open Ord Bin Ord Close Bin Ord Rel Ord Ord Bin Ord Ord

括号中的部分被称为子公式,被视为 Ord atom。

\(\qquad\!\!\) 对于这些不同种类的原子,\(\mathrm{\TeX}\) 按照如下表格在其中插入间距,表格中的指标与原子按照如下的方式进行对应:0 = Ord,1 = Op,2 = Bin,3 = Rel,4 = Open,5 = Close,6 = Punct,I = Inner 本表格来自于 Reference 2,其中行指标表示近邻的两个原子中左侧的那个,列指标表示近邻的两个原子中右侧的那个,表格中的数字大致表示这两个近邻原子的间距。如果数字在括号中,则当公式以下标/上标样式排版时,不会插入空格。

  • 0 = no space
  • 1 = thin space (\thinmuskip)
  • 2 = medium space (\medmuskip)
  • 3 = thick space (\thickmuskip)
  • * = impossible combination

\(\qquad\!\!\)了解了最基本的 atom 之后,我们就可以来看一下 align 环境中的“对齐”,是如何影响公式中各部分的间距。最核心的原理就是 \(\mathrm{\LaTeX}\) 对于列分隔符 & 的处理:

1
\hfil $\displaystyle #$ & $\displaystyle {}#$ \hfil

其中 # 分别代表 & 前后的实际内容,& 前的内容于 & 处右对齐,中间没有任何其他元素;& 后的内容前添加了一个空的子公式 \displaystyle {} 后于 & 处左对齐。这自然就产生了当 & 放在二元关系符前后时间距上的区别,我们还是以一个具体的例子来看:

1
2
3
4
5
6
\begin{align*}
a&=b+c
\end{align*}
\begin{align*}
a=&b+c
\end{align*}

\[ \begin{align*} a&=b+c \end{align*} \]

\[ \begin{align*} a=&b+c \end{align*} \]

其中前式 & 放在了二元关系符 = 前,后式 & 放在了二元关系符 = 后,能够直观地看到两者的区别。前式中 & 左侧为 Ord,右侧为 Ord Rel Ord Bin Ord,两者分别右对齐、左对齐在一起,自然产生了正确的间距;后式中 & 左侧为 Ord Rel ,右侧为 Ord Ord Bin Ord,两者分别右对齐、左对齐在一起,中间便缺少了正常情况下 Rel atom 和 Ord atom 之间的 thick space (\thickmuskip)。

\(\qquad\!\!\)所以要解决后式中的间距问题,就需要加入各种 \(\mathrm{\LaTeX}\) 入门教程中都存在的关系符和 & 中的那对括号 {},代表在 & 前的内容后添加了一个空的子公式后再于 & 处右对齐,依然是上面的那个例子,在加了一对括号 {} 后:

1
2
3
\begin{align*}
a={}&b+c
\end{align*}

\[ \begin{align*} a={}&b+c \end{align*} \]

& 左侧为 Ord Rel Ord,右侧为 Ord Ord Bin Ord,两者分别右对齐、左对齐在一起,虽然中间没有间距,但是在左侧内部自然已经产生了 Rel atom 和 Ord atom 之间的 thick space (\thickmuskip),等价于以下手动添加空格的情况:

1
2
3
\begin{align*}
a=\mskip\thickmuskip & b+c
\end{align*}

都能够使公式中产生正常的间距。

注:在这里我们再整理一遍 \(\mathrm{\TeX}\) 中的命令的长度及其对应的 \(\mathrm{\LaTeX}\) 中的空格的长度:

\(\qquad\!\!\)首先是单位:mu (math unit) 是数学模式下特有的相对单位,与字体大小相关。换算关系1em = 18mu。例如:

  • \mskip 18mu 等效于 \hspace{1em}(在数学模式中)。
  • LaTeX 预定义的间距命令实际基于 mu
1
2
3
4
\,\mskip  3mu = \mskip\thinmuskip   % 小间距
\:\mskip 4mu = \mskip\medmuskip % 中间距
\;\mskip 5mu = \mskip\thickmuskip % 大间距
\!\mskip -3mu = \mskip-\thinmuskip % 负间距
  • 对文本模式中的空格:
1
2
3
x\ y      → em/3
x\quad y → em
x\qquad y → 2em

总结:

1
$x\!y \\ xy \\ x\,y \\ x\:y \\ x\;y \\ x\ y \\ x\quad y \\ x\qquad y$

\[ \begin{align*} x\!y &宽度为\ -\dfrac{1}{6}\text{em}\\ xy &宽度为\ 0\text{em}\\ x\,y &宽度为\ \dfrac{1}{6}\text{em}\\ x\:y &宽度为\ \dfrac{2}{9}\text{em}\\ x\;y &宽度为\ \dfrac{5}{18}\text{em}\\ x\ y &宽度为\ \dfrac{1}{3}\text{em}\\ x\quad y &宽度为\ \text{em}\\ x\qquad y&宽度为\ 2\text{em} \end{align*} \]

注:在文档中,段落前空两格大概是 \(\dfrac{5}{3}\text{em}\) 的宽度,所以在段首键入 $\qquad\!\!$ 即可做到。

幻影 \phantom

\(\qquad\!\!\)基本的原理已经清楚,一般的情况下的对齐需求(e.g. 在需要多行公式折行后在二元运算符前&二元关系符后进行对齐),我们已经知道能够通过在列分隔符 & 前添加一对大括号 {} 将间距调整正确,但是在面对复杂的排版需求时,就不仅仅是这么简单就能够实现的。

\(\qquad\!\!\)比如说在问题整理中图片中的右侧实现,在缺少关系符的时候,我们如何进行对空间进行占位进而进行更好的对齐呢?这就需要用到 \(\mathrm{\LaTeX}\) 中的幻影实现。

\(\qquad\!\!\)幻影是 \(\mathrm{\LaTeX}\) 中最神奇的一种空格,幻影命令 \phantom 有一个参数,作用是产生与参数命令大小一样的空盒子,没有内容,就像是参数的一个幻影一样,所以,使用幻影可以完成一些特殊的占位和对齐效果:

1
2
幻影\phantom{参数}速速隐形\\
幻影参数速速显形

\[ \begin{align*} 幻影\phantom{参数}速速隐形\\ 幻影参数速速显形 \end{align*} \]

在数学模式中,幻影被视为 Ord atom,并以此保持和其他原子间的间距。类似地有 \hphantom\vphantom,分别表示水平方向和垂直方向的幻影,在另一个方向的大小为零。

\(\qquad\!\!\)所以像在问题整理中图片中的右侧实现,第一行需要在列分隔符 & 后加入一个虚拟的空白的 =,同时需要保持作为一个 Rel atom 以和其后产生正确的间距,所以就使用了 \mathrel{\phantom{=}} 命令来进行实现。因此,左侧在二元关系符后进行对齐的实现与右侧在二元关系符前进行对齐实现便产生了相同的效果。

align or aligned or alignat

\(\qquad\!\!\)谈到多行公式对齐,自然绕不开 amsmath 宏包中的 align 大家族,alignalignedalignat 及其组合或加 * 的环境,各有其特点及合适的应用场景。

\(\qquad\!\!\)首先,最基本的 align 环境,允许多行公式并进行对齐,会给每行公式都编号。我们仍然可以用 \notag 去掉某行的编号。

\(\qquad\!\!\)align 还能够对齐多组公式,除等号前的 & 之外,公式之间也用 & 分隔。这时,align 会在列之间插入自动的间距,但不同列公式间在观感上有时会感觉间距过大:

\(\qquad\!\!\)加 * 的版本 align*align 功能上完全相同,* 的作用也是唯一的区别就是不带标号

\(\qquad\!\!\)加 -ed 后缀的版本 aligned 即 inline 版本,可以被看作一个内联的盒子,不考虑编号,作为公式环境内部的一部分,可以与 equation 等环境套用,以实现将多个公式组在一起公用一个编号,编号位于公式的居中位置。以 -ed 结尾的环境用法与不以 -ed 结尾的环境用法一一对应:

\(\qquad\!\!\)aligned 环境可以看成一个盒子,我们还可以给这个盒子添加定界符,以实现相应的效果:

\(\qquad\!\!\)加 -at 后缀的版本 alignat 则不会在列之间插入任何自动间距,完全通过 & 手动控制间距。alignat 环境有一个参数,表示每行要对齐的公式个数,每两列一组,如下面把列间距设定为一个 \quad 的距离:

第 2 行第 3 列没用 \quad,但是间距依然保留下来,这是因为上一行的 \quad 位置必须在每一行都有所体现。

\(\qquad\!\!\)alignat 作为一个公式环境,和 align 环境一样,也可以加上 * 成为 alignat* 环境使得各行不带标号或者加上 -ed 后缀成为 alignedat 以实现公用标号等功能:

综合运用

\(\qquad\!\!\)经过了以上三部分的学习,我们首先通过引入 atom 这样一个基本概念展示了 \(\mathrm{\LaTeX}\) 中数学模式中的列分隔符 & 前后间距处理的基本原理,其次简单介绍了如何使用幻影 \phantom 实现更复杂的间距控制,再次还分别展示了 amsmath 宏包中的 align 大家族各种常用的环境的区别与联系及其基本的应用。那么,最后让我们来综合运用我们以上学习的这三部分内容,实现一个稍微复杂一点的线性方程组的排版。

\(\qquad\!\!\)根据各种 align 相关的环境的特性,我们发现使用 alignat 系列环境可以自己控制对齐的各部分(各列)之间的间距,非常适合实现一个多列对齐的方程组的排版:

\(\qquad\!\!\)第二行的对齐直接利用了第一行中设置的自定义的间距均为零,第三行因为除了第一列的对齐外所有其他列的都在加号前对齐,所以第一个未知数前没有加号但是还希望利用该位置进行对齐,就需要生成一个二元运算符类的 atom 的大小和一个加号相等的空格,即可使用 \mathbin{\phantom{+}} 实现,在其之前加 & 对齐即可。至此,我们便能够完全理解并实现了这样的一个稍微复杂一点的线性方程组的排版!

\(\qquad\!\!\)那么,我们便基本解释了在 LaTeX 数学模式中 & 表示对齐时前后的间距相关的各种问题,希望能够读到这里的你有一定的帮助,也欢迎各路大佬们批评指正!

Reference

  1. What's the right space to right the alignment of a right aligned align environment?
  2. "Simboli matematici in TeX e LaTeX", ArsTeXnica 8 (2009), pp. 7–24
  3. align和alignat环境的区别以及适用范围?
  4. 如何让cases环境下的多行公式在x_{1},x_{2},x_{3},+以及=处对齐?
  5. lshort-zh-cn – Introduction to LATEX, in Chinese
  6. 刘海洋. LaTeX 入门[M]. 北京: 电子工业出版社, 2013.
  7. 向禹. 多行公式编号技巧[OL]. latexstudio. https://www.latexstudio.net
  8. 部分学习自 AI 工具。