重新定义 \@schapter 会导致“可能缺少 \item。”错误

重新定义 \@schapter 会导致“可能缺少 \item。”错误

这里我想在编号章节后自动添加字符串“toc”,在未编号章节后自动添加字符串“notoc”,如下所示:

在此处输入图片描述

所以我写了这个:

\documentclass{book}
\usepackage{etoolbox}
\makeatletter
\let\@@chapter\@chapter
\let\@@schapter\@schapter
\def\@chapter[#1]#2{\@@chapter[#1]{#2} toc}
% \def\@schapter#1{\@@schapter{#1} notoc}   % if uncomment, there will be a "missing \item" error 
% \apptocmd{\@schapter}{notoc}{}{}          % same behavior as above
\makeatother
\begin{document}
\tableofcontents
    \chapter[option]{test}
    \chapter{test2}
    \chapter*{notoc}
\end{document}

我了解到的星级版本和非星级版本是由和\chapter定义的。\@schapter\@chapter

\newcommand\chapter{\if@openright\cleardoublepage\else\clearpage\fi
                    \thispagestyle{plain}%
                    \global\@topnum\z@
                    \@afterindentfalse
                    \secdef\@chapter\@schapter}

所以我只想重新定义这两个命令来满足我的需求。

之后\def\@chapter[#1]#2...,一切正常。

在此处输入图片描述

但是之后\def\@schapter出现错误:

! LaTeX Error: Something's wrong--perhaps a missing \item.

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

l.1 ...sline {chapter}{\numberline {1}option}{3}{}
                                                  %
? 

为什么会发生这种情况?

答案1

当你收到“奇怪”的错误信息时,首先要做的事情之一就是尝试设置

\errorcontextlines=1000

在文件的最开头。再次运行 LaTeX 后,你会看到,而不仅仅是

! LaTeX Error: Something's wrong--perhaps a missing \item.

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

l.1 ...sline {chapter}{\numberline {1}option}{3}{}
                                                  %
?

还有更多的东西,即

! LaTeX Error: Something's wrong--perhaps a missing \item.

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

\GenericError  ...
                                                  \endgroup
\addpenalty ...roup \fi \fi \fi \else \@noitemerr
                                                  \fi
\l@chapter ...>\m@ne \addpenalty {-\@highpenalty }
                                                  \vskip 1.0em \@plus \p@ \s...
l.1 ...sline {chapter}{\numberline {1}option}{3}{}
                                                  %
?

因此我们看到的是执行\@noitemerr时发出的。\addpenalty

是什么\addpenalty?我们可以在 LaTeX 内核中看到它

% latex.ltx, line 6540:
\def\addpenalty#1{%
  \ifvmode
    [<code that isn't relevant here>]
  \else
    \@noitemerr
  \fi}%

但是它从何\addpenalty而来?我们有一个线索,因为很明显 LaTeX 正在对文件的第一行进行操作.toc,就你的情况而言

\contentsline {chapter}{\numberline {1}option}{3}{}%

由于\contentsline{chapter}变成\l@chapter,我们看到

% book.cls, line 618:
\newcommand*\l@chapter[2]{%
  \ifnum \c@tocdepth >\m@ne
    \addpenalty{-\@highpenalty}%
    \vskip 1.0em \@plus\p@

我们确实识别了扩展错误消息中的标记,所以这就是出错的地方。

但是什么导致了这种奇怪的行为呢?嗯,必须就是你添加的内容\@schapter

\tableofcontents事实上,它在执行时被使用,因为它包含\chapter*{\contentsname...}

那么你的notoc问题是什么原因造成的呢?为什么?因为它开始了一个段落,并且在此操作\contentsline{chapter}执行之后,导致\addpenalty不是垂直模式。

我不确定进行这些更改的原因是什么:您是否想在章节开头添加一些用于首字母下沉或类似符号的代码?好吧,不要。您肯定需要采取预防措施,不要在目录或表格列表等辅助章节上也执行该操作。

但是,您是否有太多章节,以至于手动添加样式很繁琐?

答案2

由于你使用的是电子工具箱包,我建议您利用其\apptocmd宏来实现格式化目标——以一种不涉及重新定义和现有内容的方式\@chapter\@schapter具体来说,我建议您执行

\makeatletter
\apptocmd{\@chapter}{toc\par}{}{}
\apptocmd{\@schapter}{notoc\par}{}{}
\makeatother

在序言中。

相关内容