![具有典型 LaTeX 错误的文档](https://linux22.com/image/242190/%E5%85%B7%E6%9C%89%E5%85%B8%E5%9E%8B%20LaTeX%20%E9%94%99%E8%AF%AF%E7%9A%84%E6%96%87%E6%A1%A3.png)
我正在教授 LaTeX 课程,我有一个想法,让学生在几个文档中查找和解决问题。基本上,他们将学习如何创建最少的示例并阅读错误消息。
然而,目前我手头上没有任何包含“典型”错误的文档。
如果有人有自己或论坛中这样的示例,我希望得到代码或链接。代码长短不重要。只要足以让学生玩几分钟就行。
答案1
以下是列表:
使用与数学相关的内容但未明确说明其为数学:
\documentclass{article} \begin{document} Let's do \alpha and then \beta. \end{document}
虽然编译器可以从中恢复,但输出并不符合预期:
此外,TeX 还会抱怨以下非常典型的错误:
要修复此错误,请通过使用 `$`..`$` 或 `\(`..`\)`(用于内联数学内容)明确引入数学模式的切换。也就是说,使用 `让我们先做 $\alpha$,然后做 $\beta$。`。! Missing $ inserted. <inserted text> $ l.3 Let's do \alpha and then \beta. I've inserted a begin-math/end-math symbol since I think you left one out. Proceed, with fingers crossed.
当混合文本和数学时,有些人习惯
\mbox
将与文本相关的内容框起来。原因是\mbox
必然会切换到文本模式。因此,如果 中有数学内容\mbox
,则需要明确重申其用法。这是一个简短的示例(导致错误Missing $ inserted
):\documentclass{article} \begin{document} \[ f(x) = ax^2 + bx + c, \mbox{where x \geq 0} \] \end{document}
该符号
\geq
需要数学模式。此外,如果未在数学模式下设置数学内容,则间距会关闭(但这本质上是印刷上的)。可以使用类似 的方法来修复此错误
\mbox{where $x\geq 0$}
。更好的方法是,amsmath
包裹提供\text
根据上下文将文本更改为适当的字体样式/形状的功能,而不\mbox
提供。代码可读性是受鼓励的,有时可读性与在代码中留空格同义。然而,在下面的基本示例中,留(太多)空格会导致错误(
Missing $ inserted
):\documentclass{article} \begin{document} \[ f(x) = ax^2 + bx + c \] \end{document}
(当然,删除上面任何一个空行也会导致问题。但由于等式周围有一条对称的空行,这个问题看起来更隐蔽。)
可以通过删除空行或引入注释字符来避免这种情况
%
。请参阅align
环境中的空白行。在排版常规分隔符时,无需匹配对。例如,您可以使用
(a,b]
或 甚至 这样的表达式|a,b
。但是,在使用可扩展分隔符时,您需要使用\left
和定义一对\right
。如果您只想使用单个可扩展分隔符,那么您仍然必须使用 定义一对分隔符.
,如下例所示:\documentclass{article} \begin{document} \[ f(x) = \left\{\begin{array}{@{}ll} ax^2 + bx + c, & x < 0 \\ dx^2 + ex + f, & x \geq 0 \end{array} \] \end{document}
在上面的例子中,尽管不需要右分隔符,也必须使用 来指定
\right.
。值得注意的是,以下也是一个常见的错误,在使用时会导致错误
{ }
(如上例所示 - 忘记转义{
):\documentclass{article} \begin{document} \[ f(x) = \left{\begin{array}{@{}ll} ax^2 + bx + c, & x < 0 \\ dx^2 + ex + f, & x \geq 0 \end{array}\right. \] \end{document}
正确的用法是
\left\{
。或者,如果您打算使用类似的符号
]a,b[
(无论出于何种原因)并且想要可扩展的分隔符,则使用\right]
然后\left[
仅仅因为括号朝外似乎合乎逻辑,但却不起作用:\documentclass{article} \begin{document} \[ f(x) = \right]a,\frac{b}{c}\left[ \] \end{document}
左分隔符使用
\left
,而右分隔符使用\right
,无论分隔符的方向如何。-
使用它
\\
来引起换行绝对是直观的。而且,这在某些情况下有效。然而,在其他情况下,LaTeX 会抱怨这一事实There's no line here to end
。提议的复杂化是 LaTeX 端纯粹意外的换行。\documentclass{article} \begin{document} \begin{description} \item[Very long label] \\ Text... \end{description} \end{document}
在上面的例子中,建议的快速解决方案是将换行符修改
\\
为\hspace*{\fill} \\
。下面是另一个示例:
\begin{center} First (heading) line \\ \\ body of the centred text... \end{center}
解决方案是将双换行符修改
\\
为单换行符,并可选跳过长度\\[\baselineskip]
。 您正在学习如何编写宏或您自己的命令,并尝试类似以下操作:
\documentclass{article} \newcommand{\i}{$\iota$}% My macro: \i -> \iota \begin{document} This is \verb!\i!:~\i. \end{document}
只会看到 LaTeX 抱怨
Command \i already defined
。但你从未以任何其他方式定义过它,它怎么可能已经定义了?!原因是文档类本身可以定义某些命令,就像任何加载的包都可以定义自己的宏(和环境)一样。此外,TeX 还默认定义一些宏(大约 900 个左右)。具体到这个案例,可以查看\i
之前定义的内容以及如何使用以下方法更正这个新定义\documentclass{article} \begin{document} This is \verb!\i!:~\i. \par \renewcommand{\i}{$\iota$}% My macro: \i -> \iota This is \verb!\i!:~\i. \end{document}
或者可以使用
\show\i
和检查该.log
文件来查看“正式定义”。LaTeX2e 提供的另一种解决方案是使用
\providecommand
而不是\newcommand
或\renewcommand
,因为它具有内置的存在性检查。或者,可以使用 TeX 的\def
命令,该命令具有略微不同的界面。但是,请谨慎使用这些命令,因为包或类定义的命令具有特定含义,并且在不知情的情况下重新定义可能会带来灾难性的后果。您可以在线找到一段 LaTeX 代码并将其包装成一个最小文档:
\documentclass{article} \newcommand{\my@macro}[1]{-#1-}% This is magic \begin{document} \my@macro{hi} \end{document}
但是,LaTeX 并不高兴,并抱怨
Missing \begin{document}
。显然它在那里……那么问题是什么呢?好吧,符号@
在宏定义中是保留的,如果不采取一些预防措施,就不能使用。的类别代码
@
需要更改才能在宏定义中使用。使用\makeatletter
将“使@
‘字母’/11 成为类别代码”以便可以使用。通常,它伴随着一个\makeatother
对应项,即“使@
‘其他’/12 成为类别代码”。您希望定义一个命令进行一些格式化,并决定定义一个类似名称的环境也许是为了方便,它的作用是一样的:
\documentclass{article} \newcommand{\dosomething}[1]{\textbf{#1}}% Make argument bold \newenvironment{dosomething}{\bfseries}{}% Make contents bold \begin{document} \dosomething{test} \end{document}
尽管你只定义了一次(第 2 行),但LaTeX 还是会
Command \dosomething already defined
在(第 3 行)抱怨这一点。l.3 \newenvironment{dosomething}{\bfseries}{}
\dosomething
这里的问题是,当使用时
\newenvironment{myenv}{<beg env>}{<end env>}
,LaTeX 定义了两个命令\myenv
和\endmyenv
,分别使用<beg env>
和<end env>
定义。为了纠正这个问题,请为命令和环境使用唯一的名称,即使它们执行的任务非常相似。例如,在上面的例子中,定义命令\boldcmd
和环境boldenv
, 说。您开始摆弄图形,并希望使用
graphicx
包裹:\documentclass{article} \begin{document} \usepackage{graphicx}% http://ctan.org/pkg/graphicx \includegraphics{tiger}% Rooooaaaarrrrr!!!!! \end{document}
但 LaTeX 抱怨说“只能在序言中使用”。这不是因为使用了
\includegraphics
(这是正确的),而是因为必需/包含的包(graphicx
)。文档结构要求某些“东西”只能在某些地方使用。在这种情况下,您无法在环境中加载包document
。放置
\usepackage{graphicx}
在\documentclass{article}
和之间\begin{document}
- 文件前言。您熟悉以以下形式向宏传递参数
\textbf{Here is some \textit{text}.}
这里
\textit
作为参数传递给\textbf
。但是,您尝试对所谓的逐字内容执行相同操作:\documentclass{article} \begin{document} \textbf{Here is some \verb|verbatim text|.} \end{document}
并收到错误“
\verb
命令参数非法。”\verb
和朋友都很微妙,应该小心处理。它涉及类别代码的高级主题,也许在 TeX FAQ 条目中描述得最好为什么逐字在...内不起作用?以及适当的解决方案/替代方案。最值得注意的是问自己是否真的有必要使用逐字记录。有人建议你使用
amsmath
align
读完后的环境\eqnarray
对比\align
并要求复制泰勒展开的\sqrt{1-x}
:你雄心勃勃,尝试:
\documentclass{article} \usepackage{amsmath}% http://ctan.org/pkg/amsmath \begin{document} \begin{align*} \sqrt{1+x} = 1 + x\left(\tfrac{1}{2} - \tfrac{1}{8}x + \tfrac{1}{16}x^2 & - \tfrac{5}{128}x^3 \cdots \\ & + \tfrac{(-1)^i(2i)!}{(1-2i)(i!)^2(4i)}x^{i-1}\cdots\right) \end{align*} \end{document}
(La)TeX 吐出一个错误
Extra }, or forgotten \right
。\left
和\right
是分隔符的对应项,在数学模式中应始终一起出现,并位于同一(嵌套)组中。在上面的示例中,\left
和\right
位于不同的组中,不仅跨越align
列,还跨越行。在这种情况下,使用可分离的\Bigl
和\Bigr
分隔符扩展器要方便得多。替代方案还包括使用将\vphantom
单独的组垂直缩放到最大大小,同时使用空分隔符\right.
和\left.
需要的位置。请参阅\left
/\right
跨多线方程。
使用表格时,您希望使用
[..]
样式符号在第一列插入某种形式的行标签:\documentclass{article} \begin{document} \begin{tabular}{ll} Header row & Some content \\ \hline [a] & Stuff A \\ [b] & Stuff B \end{tabular} \end{document}
LaTeX 会抱怨“缺少数字,视为零”和“非法计量单位(插入 pt)”。这些错误与可以使用控制序列指定的可选参数有关
\\
;[b]
被视为 的可选参数\\
,实际上试图评估\\[b]
,其中b
预计是长度/维度。事实并非如此,因此它被替换为零(如第一条错误消息所报告的),但没有与之关联的维度(如第二条错误消息所报告的)。对此类实例的一个引用在允许[
无需进入数学模式即可。此处的解决方法是
[
在适当位置插入非元素,以避免 LaTeX 将它们抓取为 的可选参数\\
。例如{}[b]
就可以了。通过试验页眉/页脚,您尝试堆叠一些内容以便向读者提供更多信息:
\documentclass{article} \usepackage{lipsum,fancyhdr}% http://ctan.org/pkg/{lipsum,fancyhdr} \fancyfoot[C]{\thepage My Name} \pagestyle{fancy} \begin{document} \lipsum[1-5] \end{document}
LaTeX 抱怨
Runaway argument? {\thepage ! Paragraph ended before \f@ncyhf was complete.
但一切似乎都很好。
这个问题与 (2) 部分相关,但源于 TeX 中非正式地存在两种不同的定义类型:允许段落分隔符和不允许段落分隔符。前者是使用
\newcommand
或定义的宏,\long\def
而后者是使用\newcommand*
或定义的宏\def
。作为参考,请参阅\newcommand
和有什么区别\newcommand*
?为了解决这个问题,不要在无法处理多个段落的宏中使用多个段落。可以使用从
\thepage \\ My Name
技术上设置单个段落来避免此特定解决方案。也可以使用tabular
提供堆叠外观。为了加快编码速度,您开始使用某些常用结构的缩写,如以下最小示例:
\documentclass{article} \newcommand{\bv}{\begin{verbatim}} \newcommand{\ev}{\end{verbatim}} \begin{document} Some regular text. \bv Some verbatim text. \ev \end{document}
\bv
人们会认为和的替换文本\ev
将被插入到输入流中,从而产生预期的输出一般来说,这是可行的,因为 TeX 只是将给定缩写的替换文本插入到输入流中。它们的替换执行遵循预期的语法,一切都运行良好。但在某些情况下,情况并非如此。上面就是其中之一,尽管还有其他 以及。 这特征在于编码环境它期望明确的
\end{<env>}
表单并扫描,直到找到为止。如果存在,请按照软件包文档中建议的解决方法操作。在其他情况下,最好完全避免使用简写。
答案2
为什么两行的输出不一样?
\documentclass{article}
\newcommand{\foo}{bar}
\begin{document}
bar bar
\foo \foo
\end{document}
您还可以添加第三行\foo\foo
,但这可能太多了。
宏的输出在哪里?
\documentclass{article}
\newcommand{\foo}[1]{\textbf{#1}}
\begin{document}
\foo \foo
bar bar
\end{document}
这会导致错误:
段落在 \text@command 完成之前结束
\documentclass{article}
\newcommand{\foo}[1]{\textbf{#1}}
\begin{document}
\foo
bar bar
\end{document}
%
TeX 忽略多余的空格和换行符,那么为什么如果删除注释字符,这里的输出会改变?
\documentclass{article}
\newcommand{\foo}[1]{
\textbf{#1}
}
\begin{document}
\foo{bar}%
bar bar
\end{document}
答案3
二不同的具有相同错误消息的错误类型
\documentclass{article}
\begin{document}
foo \textt{bar} baz
\rotatebox{45}{45}
\end{document}
答案4
当我将 Microsoft Word 中的文本插入 LaTeX 时,我遇到了一些有趣的错误。特别是字符 sch 如“-”,在 Word 中的编码与在 TeXniccenter 中的编码不同。查找这些错误总是很乏味。