\chapter{排除错误、寻求帮助}\label{chap:error-helps} \begin{intro} \LaTeX{} 入门用户总会为两大问题头疼:我写的代码到底哪里出错了?如果想要实现某种用法该怎么办? 本章首先总结了常见的 \LaTeX{} 错误及应对的办法。 \end{intro} \section{\LaTeX{} 错误}\label{sec:errors} 当我们用排版引擎编译 \LaTeX{} 代码时,命令行的窗口(终端)会显示大量信息(TeXworks 等编辑器会有一个区域显示这些信息)。 当编译过程中出现错误时,信息将会停止在出错的地方,等待我们接下来的操作。 比如说我们有一个明显出错的例子: \begin{verbatim} \documentclass{article} \begin{document} Test \LaTEx{} and it's friends. \end{document} \end{verbatim} 编译过程中遇到这个错误将会停顿下来,提示错误,并等待用户输入指令: \begin{verbatim} ! Undefined control sequence. l.3 Test \LaTEx {} and it's friends. \end{verbatim} 这种错误信息分两部分,前一部分提示了错误的信息,后一部分指出了错误发生的行号, 以及通过错落的文字告知发生错误的命令所在位置。如上错误显示 \cmd{LaTEx} 位置发生了错误,错误信息是“未定义的控制序列”, 意思是 \cmd{LaTEx} 是 \TeX{} 编译器无法识别的一个命令,很显然是我们把 \cmd{LaTeX} 的大小写写错了。 \subsubsection{处理方式} 出现错误时,编译过程将暂停,等待用户输入命令。用户可以直接敲回车跳过当前的错误,继续编译,相当于丢掉了写错的命令, 将“Test and it's friends.”排版出来。但这个例子过于简单,有些复杂的代码中,有可能会由于一个小问题导致一连串的错误。 此时可以选择按 \textbf{S/R/Q} 选择跳过接下来的所有错误,或者按 \textbf{X} 直接退出编译,将源代码中的错误修改后重新编译。 \subsubsection{常见的 \LaTeX{} 错误信息} 我们在此总结一些经常发生、问题比较明确的 \LaTeX{} 错误: \long\def\LaTeXerror#1{\begingroup\color{red}\bfseries\ttfamily{}#1\endgroup} \begin{itemize} \item \LaTeXerror{! Undefined control sequences.} 使用了未定义的命令。拼写错误是原因之一,如把 \cmd{LaTeX} 写作 \cmd{Latex} 这样。 也有可能是没有调用某个宏包,但用了该宏包定义的命令。 \item \LaTeXerror{! LaTeX error: Environment ... undefined.} 使用了未定义的环境。 \item \LaTeXerror{! Missing \$ inserted.} 缺少数学环境的符号 \texttt\$。多由于将数学符号用在公式之外而导致。 \item \LaTeXerror{Runaway argument? \\ ! Paragraph ended before ... was complete.} \item \LaTeXerror{! File ended while scanning definition/use of ...} 这两个错误主要是由于漏写了包裹命令参数的花括号,导致识别参数时出现错误。许多编辑器的括号配对功能有助于检查和消除这类错误。 这类错误还有可能是由于前一次编译中断导致 \texttt{.aux} 等辅助文件不完整,再次编译读入不完整的文件产生错误。解决办法是删除辅助文件并重新编译。 \item \LaTeXerror{! Extra alignment tab has been changed to \cmd{cr}.} \item \LaTeXerror{! Misplaced \cmd{noalign}.} 两个错误信息都与表格有关。 \begin{itemize} \item 前者的字面意义是“一行中使用的列分隔符 \texttt\& 太多”,有时可能确实是 \texttt\& 的个数和列格式不匹配, 但多数情况是漏掉了行尾的 \crcmd{} 命令。 \item 后者常出现于漏掉了行尾的 \crcmd{} 命令而接着使用 \cmd{hline} 命令画横线的时候。 \end{itemize} \item \LaTeXerror{! LaTeX Error: Lonely \cmd{item}-{}-perhaps a missing list environment.} \item \LaTeXerror{! LaTeX Error: Something's wrong-{}-perhaps a missing \cmd{item}.} 两个错误信息都与列表环境和 \cmd{item} 命令有关。前者意味着在没有使用列表环境的情况下用了 \cmd{item}; 后者则相反,是在列表环境中漏了 \cmd{item}。 \item \LaTeXerror{! I can't find file `...'.} \item \LaTeXerror{! LaTeX Error: File `...' not found.} 两个错误都意味着缺少文件。 \begin{itemize} \item 如果使用 \cmd{input} 或者 \cmd{include} 命令添加文件,出现上述错误的原因当然是文件不存在或者文件名不对; \item 如果错误提示里的文件名带 \texttt{.sty} 或者 \texttt{.cls} 扩展名,那么很显然,是因为\textbf{没有安装所需的宏包或文档类}。 \end{itemize} \item \LaTeXerror{! LaTeX Error: Missing \cmd{begin}\marg*{document}.} 字面上是缺少 \cmd{begin}\marg*{docu\-ment},实际上往往是由于在 \cmd{begin}\marg*{docu\-ment} 之前(导言区)输入了文字或某些命令。 \item \LaTeXerror{! LaTeX Error: Can be used only in preamble.} 与上一条相反,由于将必须用于导言区的命令在 \cmd{begin}\marg*{docu\-ment} 之后使用而产生。 \item \LaTeXerror{! LaTeX Error: \cmd{begin}\marg*{...} on input line ... ended by \cmd{end}\marg*{...}.} 环境首尾不匹配。比如 \cmd{begin}\marg*{enumerate} 用了 \cmd{end}\marg*{itemize} 结尾。或者也可能是由于漏写了 \cmd{begin} 或者 \cmd{end} 命令。 \item \LaTeXerror{! LaTeX Error: Option clash for package `...'.} 以\textbf{不同选项}重复调用宏包造成冲突。有可能是因为其它宏包内部事先调用了这个宏包,用户再次带选项调用而导致冲突。 解决问题的办法是去掉重复调用的宏包。如果宏包允许的话,尽量使用其定义的命令改变设置,减少宏包选项的使用。 \item \LaTeXerror{! LaTeX Error: Command ... already defined, \\ or name \cmd{end}... illegal ...} 使用 \cmd{newcommand} 或 \cmd{newenvironment} 定义已有的命令/环境时产生的错误。如果自己确实作了定义,可考虑用 \cmd{re\-new\-command} 或 \cmd{re\-new\-environment} 定义;如果是宏包定义的命令产生了这个错误,则属于隐性的宏包冲突。 相比之前的“Option clash”,隐性宏包冲突是更难以解决的问题,对各种宏包不熟悉的用户,尤其是使用模板的用户而言,往往难以下手。 用户可尝试查找引起冲突的宏包的帮助文档。详尽的手册里通常会告知用户这个宏包应当在某个宏包的前面/后面调用,或者不能与某个宏包一起调用。 如果是模板调用了大量宏包导致冲突,可联系模板的作者解决。 \item \LaTeXerror{! LaTeX Error: Unknown option `...' for package `...'.} 调用宏包时指定了不能被其识别的选项。此时应该查找宏包的帮助文档来解决问题。 \item \LaTeXerror{! Package `...' error: ...} 宏包或文档类自定义的错误,由于不正确地使用宏包里的命令而导致。此时应该查找宏包的帮助文档来解决问题。 \end{itemize} \section{查找帮助文档}\label{sec:texdoc} \index{texdoc@\texttt{texdoc} 工具} 无论是 \hologo{TeXLive} 还是 \hologo{MiKTeX},都提供了一个命令行模式的程序 \texttt{texdoc}。 比如对 \ref{subsec:fancyhdr} 小节的 \pkg{fancyhdr} 宏包感兴趣,这时在 Windows 命令提示符或者 Linux 终端输入以下命令, 则会弹出宏包的帮助文档 \texttt{fancyhdr.pdf}: \begin{verbatim} texdoc fancyhdr \end{verbatim} 除了宏包的帮助文档外,\TeX{} 发行版还包括了各类有用的文档,有一部分在参考文献中给出。 %如果不熟悉命令行工具的话,\hologo{TeXLive} 提供了一个图形界面的程序 TeXdoc GUI。打开后,可以看到程序里的许多按钮,分别代表某一类的帮助文档。 %除此之外,点击 File Search 弹出搜索框,输入想要搜索的宏包和文件并按回车键,TeXdoc GUI 会弹出它搜索到的所有结果,可点击任意一项来打开文档。 当然对于初学者,有一个现实而棘手的问题:\textbf{某个命令到底是 \LaTeX{} 自有的,还是哪个宏包提供的?} 很遗憾地说,除了通过慢慢积累、熟悉较多宏包之外,没有很方便的办法解决这个问题,因为 \LaTeX{} 的宏包实在太丰富了。 本手册末尾的索引给出了所有在本手册见到的命令和环境,其中哪些命令和环境需要调用哪个宏包才能使用,一目了然。但是这个索引远远不够。 解决这个问题有几点可行的办法: \begin{enumerate} \item 查询一些综述性的资料,如总结所有 \LaTeX{} 自带命令的文档 \cite{latex2e}、\LaTeX{} 符号大全 \cite{symbols} 等; \item 在互联网上搜索自己不清楚的命令; \item 在论坛上提问求助有经验的人。 \end{enumerate} \section{常用宏包简介}\label{sec:pkg-list} \def\pkglabel#1{\makebox[60pt][l]{\pkg{#1}}} \newenvironment{pkglist}% {\list{}{% \labelwidth=60pt \itemindent=0pt \leftmargin=60pt \labelsep=0pt \let\makelabel\pkglabel}}% {\endlist} 此处不包含设置字体或数学符号的宏包,它们已经在表 \ref{tbl:font-pkgs} 中列出。 \subsection{文字、公式和符号}\label{subsec:text-math-symbols} \begin{pkglist} \item[amsmath] \hologo{AmS} 数学公式扩展。 \item[mathtools] 数学公式扩展宏包,提供了公式编号定制和更多的符号、矩阵等。 \item[amsfonts] \hologo{AmS} 扩展符号的基础字体支持。 \item[amssymb] 在 \pkg{amsfonts} 基础上将 \hologo{AmS} 扩展符号定义成命令。 \item[bm] 提供将数学符号加粗的命令 \cmd{bm}。 \item[unicode-math] 使用 Unicode 数学字体。 \item[nicematrix] 排版复杂矩阵。 \item[siunitx] 以国际单位规范排版物理量的单位。 \item[mhchem] 排版化学式和方程式。 \item[tipa] 排版国际音标。 \end{pkglist} \subsection{排版元素}\label{subsec:pkg-elements} \begin{pkglist} \item[ulem] 提供排版可断行下划线的命令 \cmd{uline} 以及其它装饰文字的命令。 \item[endnote] 排版尾注。 \item[marginnote] 改善的边注排版功能。 \item[multicol] 提供将内容自由分栏的 \env{multicols} 环境。 \item[multitoc] 生成多栏排版的目录。 \item[minitoc] 为章节生成独立的小目录。 \item[glossaries] 生成词汇表。 \item[verbatim] 对原始的 \env{verbatim} 环境的改善。提供了命令 \cmd{verbatiminput} 调用源文件。 \item[fancyvrb] 提供了代码排版环境 \env{Verbatim} 以及对版式的自定义。 \item[listings] 提供了排版关键字高亮的代码环境 \env{lstlisting} 以及对版式的自定义。类似宏包有 \pkg{minted} 等。 \item[algorithmic] 一个简单的实现算法排版的宏包。如果要生成浮动体的话,需要搭配 \pkg{algorithm} 宏包使用。 \item[algorithm2e] 较为复杂的、可定制的算法排版宏包。类似宏包有 \pkg{algorithmicx} 等。 \item[amsthm] 定制定理环境。类似宏包包括 \pkg{theorem}、\pkg{ntheorem}、\pkg{thmtools} 等。 \item[mdframed] 排版可自动断页的带边框文字段落,提供边框样式的定制功能。 \item[tcolorbox] 以 \hologo{TikZ} 为基础提供排版样式丰富的彩色盒子的功能。 \end{pkglist} \subsection{图表和浮动体}\label{subsec:pkg-tab-fig} \begin{pkglist} \item[array] 对表格列格式的扩展。 \item[booktabs] 排版三线表。 \item[tabularx] 提供 \env{tabularx} 环境排版定宽表格,支持自动计算宽度的 \texttt{X} 列格式。 \item[arydshln] 支持排版虚线表格线。 \item[colortbl] 支持修改表格的行、列、单元格的颜色。 \item[multirow] 支持合并多行单元格。 \item[makecell] 支持在单元格里排版多行内容(嵌套一个单列的小表格)。 \item[diagbox] 排版斜线表头。 \item[longtable] 提供排版跨页长表格的 \env{longtable} 环境。 \item[ltxtable] 为跨页长表格提供 \env{tabularx} 的 \texttt{X} 列格式。 \item[tabularray] 排版复杂表格(基于 \LaTeX3 实现)。 \item[graphicx] 支持插图。 \item[bmpsize] \texttt{latex} + \texttt{dvipdfmx} 命令下支持 BMP/JPG/PNG 等格式的位图。 \item[epstopdf] \texttt{pdflatex} 命令下支持 EPS 格式的矢量图。 \item[wrapfig] 支持简单的文字在图片周围的绕排。 \item[caption] 控制浮动体标题的格式。类似宏包有 \pkg{keyfloat} 等。 \item[subcaption] 提供子图表和子标题的排版。类似宏包有 \pkg{subfigure} 和 \pkg{subfig} 等。 \item[bicaption] 生成双语浮动体标题。 \item[float] 为浮动体提供不浮动的 \texttt{H} 模式;提供自定义浮动体结构的功能。 \end{pkglist} \subsection{修改版式}\label{subsec:pkg-layout} \begin{pkglist} \item[geometry] 修改页面尺寸、页边距、页眉页脚等参数。 \item[fancyhdr] 修改页眉页脚格式,令页眉页脚可以左对齐、居中、右对齐。 \item[titlesec] 修改章节标题 \cmd{chapter}、\cmd{section} 等的格式。 \item[titletoc] 修改目录中各条目的格式。类似宏包有 \pkg{tocloft} 等。 \item[tocbibind] 支持将目录、参考文献、索引本身写入目录项。 \item[footmisc] 修改脚注 \cmd{footnote} 的格式。 \item[indentfirst] 令章节标题后的第一段首行缩进。 \item[enumerate] 提供简单的自定义标签格式的 \env{enumerate} 环境。 \item[enumitem] 修改列表环境 \env{enumerate} 和 \env{itemize} 等的格式。 \item[lettrine] 生成段落首字母大写的效果。 \end{pkglist} \endinput