当我尝试在新机器上编译 Latex 文档时发现了这个错误:
! LaTeX Error: \relax undefined.
l.35 \renewcommand
{\cftchapaftersnum}{.}
它没有出现在我之前的机器上。我刚刚在那里安装了 Miktex 2.9 和基本标准这是我的最小工作示例。希望它足够清楚。:
\documentclass[12pt, a4paper, onecolumn, oneside, final]{report}
\usepackage[titles]{tocloft}
\setlength{\cftaftertoctitle}
\renewcommand{\cftchapaftersnum}{.}
\renewcommand{\cftdotsep}{1}
\renewcommand{\cftchapdotsep}{1}
\renewcommand{\cftchapleader}{\cftdotfill{\cftchapdotsep}}
\addtocontents{toc}{\protect\renewcommand{\protect\cftchapfont}{}}
\addtocontents{toc}{\protect\renewcommand{\protect\cftchappagefont}{\itshape}}
\addtocontents{toc}{\protect\renewcommand{\protect\cftchappagefont}{}}
\addtocontents{toc}{\protect\setlength{\cftbeforechapskip}{0pt}}
.
.
\begin{document}
.
.
\end{document}
乍一看,似乎只是忘记安装一个软件包。但是,在快速用\relax undefined
关键字谷歌搜索后,我发现事情并不像我想象的那么简单。真的那么复杂吗,还是真的只是缺少一个软件包?
答案1
您收到的错误消息确实令人费解:\setlength
大多数时候忘记第二个参数会导致
! Missing number, treated as zero.
或者,如果后面恰好跟着一个数字,
! Illegal unit of measure (pt inserted).
让我们看看你为什么会得到神秘的
! LaTeX Error: \relax undefined.
错误信息。
首先,正如评论中已经指出的那样,您忘记了 的第二个参数\setlength
,但 TeX 不知道它,并将以下标记或括号组作为参数。在本例中,它找到了\renewcommand
,所以您得到的是
\setlength{\cftaftertoctitle}\renewcommand{\cftchapaftersnum}{.}
(由于 TeX 正在寻找正常参数,因此行尾的空格将被忽略)。
现在 TeX\setlength
使用其定义进行扩展:
% latex.ltx, line 1874:
\def\setlength#1#2{#1#2\relax}
所以你得到
\cftaftertoctitle\renewcommand\relax{\cftchapaftersnum}{.}
现在\cftaftertoctitle
是不是一个参数,而是一个默认情况下扩展为空的宏。因此 TeX 面临着
\renewcommand\relax{\cftchapaftersnum}{.}
这是违法的,因为任何\relax
就 LaTeX 而言,相当于的命令是未定义的。
总而言之,您的代码有两个缺陷:
- 你缺少一个论点
\setlength
; - 您正在尝试将宏设置为一定长度,这是非法的。
事实上,这\setlength{\cftaftertoctitle}{2pt}
还会引发另一个令人费解的错误:
! LaTeX Error: Missing \begin{document}.
See the LaTeX manual or LaTeX Companion for explanation.
Type H <return> for immediate help.
...
l.4 \setlength{\cftaftertoctitle}{2pt}
练习:找出原因。