这是一个公共利益问题。
问题标题为什么我明明已经修复了这个错误,却还是不断弹出?深刻地表达了使用 LaTeX 的一个基本事实:有时错误消息并不意味着它所说的内容。可以从 TeX 获取更多信息,但这是在最低级别上操作的:基本命令行交互。无论多少,都无法从概念上清楚地说明出了什么问题。
在这方面,特别阴险的是那些充当巨大宏的环境,因为错误不是在发生错误的行上报告的,而是在完成所有处理的标记处报告的(当然,这可能发生在带有巨大参数的宏上,但您几乎看不到这些)。例如,从的环境\end{}
中永远无法提取任何有用的诊断信息,因为它在最后第二次排版之前会测量其全部内容。amsmath
align
我认为收集一份此类环境发出的常见错误消息及其解释的列表(必然是轶事且不完整)会很有用。具体来说,我正在寻找以下形式的答案:
一个环境。
该环境产生的误导性错误消息,尤其是包含无用行信息的消息。
产生该错误的典型输入以及对错误原因的有用描述。
解释输入中的错误如何导致 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}
,align
像environ
包一样,在使用任何环境内容之前会吸收环境中的全部内容,这仅(最终)发生在标签中\end{align}
,因此 TeX 将错误与输入文件的这一行(执行位置)相关联,而不是写入位置。
答案2
环境: array
,eqnarray
和别的。
错误信息:
! 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}
再次强调,平衡环境\(
……\)
以及可选/强制分组似乎完全没问题。然而,与上述相同的讨论与数学模式在某处丢失有关。