常见环境给出的不透明错误消息

常见环境给出的不透明错误消息

这是一个公共利益问题。

问题标题为什么我明明已经修复了这个错误,却还是不断弹出?深刻地表达了使用 LaTeX 的一个基本事实:有时错误消息并不意味着它所说的内容。可以从 TeX 获取更多信息,但这是在最低级别上操作的:基本命令行交互。无论多少,都无法从概念上清楚地说明出了什么问题。

在这方面,特别阴险的是那些充当巨大宏的环境,因为错误不是在发生错误的行上报告的,而是在完成所有处理的标记处报告的(当然,这可能发生在带有巨大参数的宏上,但您几乎看不到这些)。例如,从的环境\end{}中永远无法提取任何有用的诊断信息,因为它在最后第二次排版之前会测量其全部内容。amsmathalign

我认为收集一份此类环境发出的常见错误消息及其解释的列表(必然是轶事且不完整)会很有用。具体来说,我正在寻找以下形式的答案:

  • 一个环境。

  • 该环境产生的误导性错误消息,尤其是包含无用行信息的消息。

  • 产生该错误的典型输入以及对错误原因的有用描述。

  • 解释输入中的错误如何导致 TeX 在产生给定消息的处理中出现矛盾。

我将首先解释一下我链接的第一个问题中的错误,作为一个例子。

答案1

环境: align(来自包amsmath)和eqnarray(核心 LaTeX,但不要使用它)。

错误信息:

ERROR: Missing } inserted.

--- TeX said ---
<inserted text> 
                }
l.6 \end{align*}

使用的代码:

\documentclass{article}
\usepackage{amsmath}
\begin{document}
\begin{align*}
  a$
\end{align*}
\end{document}

怎么了:数学移位$不属于显示数学环境的中间。实际上,如果放在任何数学环境,但代码$ a$ $给出了更清晰的错误消息Missing $ inserted,因为内部$结束数学模式和最后一个,这是故意的结束一件事,实际上开始了另一件事未完成的事。

显示数学错误,类似上面的:

\documentclass{articl
\begin{document}
\[
a$
\]
\end{document}

给出诊断

ERROR: Display math should end with $$.

--- TeX said ---
<to be read again> 

l.4 a$

这是非常有用的,也是人们所希望的预计align

真正的问题是什么: align做了很多复杂的事情,但最终使用以as\halign给出的前导码创建 TeX 对齐,其最基本的功能如下:amsmath.sty\align@preamble

\halign{
  % Preamble
  &\hfil$\displaystyle{#}$%
  &$\displaystyle{#}$\hfil\cr
  % Whatever is in the align
  ....
}

其重要特征是#,对齐的每个单元格中的材料都放在括号中:{#};这样做的目的是强制两端符号的正确间距,以便关系表现得好像两边都有操作数,等等。如果# = a$,那么该单元格中实际排版的内容是

$\displaystyle{a$}$

第一的TeX 认为错误的地方在于我们在关闭括号组之前就离开了数学模式。它没有给出消息,Missing $ inserted因为实际错误发生在 extra 处$,此时它发现该组没有关闭。事实上,上面的表达式中没有任何内容包含在 extra 之后数学模式之外的非法内容$

最后,消息只引用的原因是\end{align}alignenviron包一样,在使用任何环境内容之前会吸收环境中的全部内容,这仅(最终)发生在标签中\end{align},因此 TeX 将错误与输入文件的这一行(执行位置)相关联,而不是写入位置。

答案2

环境: arrayeqnarray和别的。

错误信息:

! Missing number, treated as zero.
<to be read again>
                   f
l.100 \end{rray}

导致错误的输入:

\begin{array}
 a+b\\
 [f,g]\\
 m+n
\end{array}

真正的问题是什么:在多行结构中,括号内的尺寸指定了行后的额外垂直空间,因此[2pt]预期会出现类似这样的情况。如果这不是想要的,请将括号内的表达式括在括号中{[f,g]}(或者甚至只使用左括号,{[},尽管这会使输入更难阅读)。

amsmath提供了一种解决方法:如果和括号内的表达式之间有空格\\,它将不会被解释为间距命令。(但是,如果额外的空格想要,请确保输入如下指令:\\[2pt],没有空格。这有效。仅有的对于由amsmath和定义的环境不是在基本的乳胶补体中。

答案3

环境: alignat(从包装中amsmath)。

错误信息:

! Missing number, treated as zero.
<to be read again>
                   a
l.100 \end{alignat}

导致错误的输入:

\begin{alignat}
 a&  =b&  c& =d\\
a'& =b'& c'& =d'
\end{alignat}

真正的问题是什么:环境alignat需要一个数字参数来告诉它每行允许有多少个“方程列”。

要修复此问题,请计算任意行中的最大数量&,除以 2,然后加 1。然后将第一行(对于此示例)更改为

\begin{alignat}{2}

答案4

这是非常特殊的,但在我看来仍然有效。

宏:具有可选参数的宏(例如\section,,\caption...)使用方括号进行分组。

错误信息:

! Extra }, or forgotten $.
\\mymacroA [#1]#2->{#1}
                       \ #2
l.10 \mymacroA[$a[b]$
                     ]{$c$}

导致错误的输入:

\newcommand{\mymacroA}[2][x]{{#1}\ #2}% or {#1\ {#2}}
\mymacroA[$a[b]$]{$c$}

真正的问题是什么: 一开始,不清楚为什么会出现错误,因为输入看起来很完美合法的。但是,可选参数的设置要求[左侧和]右侧的平衡组由 组成。在构造中

\mymacroA[$a[b]$]{$c$}

第一个平衡的[..]$a[b,作为第一个参数传递#。随后,强制参数#2如下令牌(因为没有括号组{...}存在)$。因此替换文本的\mymacroA结果为

{$a[b}\ $

(后面跟着]{$c$}与 无关的\mymacroA)。虽然原始设置似乎到处都有平衡的组件(外部[..]和内部$.. $),但替换文本揭示了 TeX 引擎明显有问题的解释。内部分组\mymacroA与平衡输入的拆分一起产生了“额外}”或“被遗忘的$错误”。

一个基本的修复方法是在参数级别屏蔽/隐藏{..中的方括号}

\mymacroA[$a{[b]}$]{$c$}

如果需要,可以手动补偿丢失的数学间距。更复杂的修复方法是xparse

\usepackage{xparse}% http://ctan.org/pkg/xparse
\NewDocumentCommand{\mymacroB}{O{x} m}{{#1}\ #2}% or {#1\ {#2}}

在这种情况下,它采用一种“不太贪婪”的方法来组装可选参数的内容。

使用上述格式非常常见,通常发生在将与 ToC 相关的内容传递给具有数学内容的分段命令时:

\section[The function $f[x]$]{The function $f[x]$ is awesome}

或者

\caption[The function $f[x]$]{The function $f[x]$ is awesome}

参考:


当使用 LaTeX 语法\(..\)以及fixltx2e,错误消息

! LaTeX Error: Bad math environment delimiter.

See the LaTeX manual or LaTeX Companion for explanation.
Type  H <return>  for immediate help.
 ...                                              

l.4 \section[\(a[b]\)
                      ]{C}

由 MWE 生成:

\documentclass{article}
\usepackage{fixltx2e}% htpp://ctan.org/pkg/fixltx2e
\begin{document}
\section[\(a[b]\)]{C}
\end{document}

再次强调,平衡环境\(……\)以及可选/强制分组似乎完全没问题。然而,与上述相同的讨论与数学模式在某处丢失有关。

相关内容