3

Here I want to automatically add string "toc" after the numbered chapter, and "notoc" after the unnumbered chapter, like this:

enter image description here

so I wrote this:

\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}

I've learned the star-version and a non-star-version of \chapter are defined by \@schapter and \@chapter.

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

So I want to just redefine these two commands to meet my demand.

After \def\@chapter[#1]#2..., everything works fine.

enter image description here

However after \def\@schapter, an error came out:

! 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}{}
                                                  %
? 

Why would this happen?

2
  • Please clarify what you're trying to achieve by "add[ing] "toc" after the number[ed] chapter, and "notoc" after the unnumber[ed] chapter".
    – Mico
    Jan 15 at 5:05
  • 1
    I updated my question with suggest by @Mico
    – Syvshc
    Jan 15 at 5:13
4

When you have “weird” error messages, one of the first things to do is to try setting

\errorcontextlines=1000

at the very beginning of the file. Upon running LaTeX again, you'll see, instead of just

! 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}{}
                                                  %
?

something more, namely

! 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}{}
                                                  %
?

So we see that \@noitemerr is issued when \addpenalty is being performed.

What's \addpenalty? We can see it in the LaTeX kernel

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

But where does \addpenalty come from? We have a clue, because it's apparent that LaTeX is doing something with the first line in the .toc file, in your case

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

Since \contentsline{chapter} becomes \l@chapter and we see

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

we do recognize the tokens in the extended error message, so this is where things go wrong.

But what can cause this weird behavior? Well, it must be what you added to \@schapter.

Indeed, it is used when \tableofcontents is executed, because it contains \chapter*{\contentsname...}.

So your notoc is the cause of the problem? Why? Because it starts a paragraph and after this action \contentsline{chapter} is executed, leading to \addpenalty not in vertical mode.

I'm not sure what would be a reason to do those changes: are you perhaps trying to start chapters with some code for drop capitals or similar? Well, don't. You definitely would need to take precautions about not doing that action also on auxiliary chapters like the table of contents or the list of tables.

But do you have so many chapters that manually adding the styling is tedious?

1
  • Thanks for your answer. After reading your answer, source2e.pdf and classes.pdf, I understood why renewcommand \@schapter would lead to the error.
    – Syvshc
    Jan 16 at 6:32
3

Since you're employing the etoolbox package, I'd like to suggest that you make use of its \apptocmd macro to achieve your formatting objective -- in a way that doesn't involve redefining the existing contents of \@chapter and \@schapter. Specifically, I'd like to suggest you execute

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

in the preamble.

5
  • Thanks, it works. Could I ask why it didn't work without \par?
    – Syvshc
    Jan 15 at 5:56
  • @Syvshc - Sorry, I don't know the answer to your follow-up question; maybe somebody else will post an answer that addresses that issue. At any rate, I think it's a good idea to employ an explicit \par directive, as otherwise the instruction \chapter[option]{test}aaa will output tocaaa, a single string -- probably not the desired outcome, is it?
    – Mico
    Jan 15 at 6:06
  • 2
    @Syvshc: If you follow the chain of execution, \tableofcontents calls \@starttoc after you have set notoc. \@starttoc sets the ToC via repeated commands \contentsline (look in the .toc file). Each of these \contentsline entries expects you to be in vertical mode (since it issues \addpenalty), otherwise it throws a "no list item" error. Since you've set notoc, you're in horizontal mode, not vertical mode. That's why there's an error. Issuing an additional \par puts you in vertical mode and everything runs smoothly.
    – Werner
    Jan 15 at 7:41
  • @Werner Sorry, I didn't understand. In my opinion, \@starttoc inputs main.toc, but things in main.toc are the same as the correct compiling. Also, \chapter* didn't do anything with the .toc file, no things like \contentsline, why would it effect?
    – Syvshc
    Jan 15 at 8:21
  • 2
    @Syvshc: Every item within the .toc should first check whether to break the page in order to continue on the next or not, similar to an \item in a list (like itemize or enumerate), even though the ToC is not set as a list. This is just because of the nature of a ToC - it is list-like and could span multiple pages (in general). To encourage a break-point, LaTeX inserts a negative penalty, but to do so, it has to also be in "vertical" mode, which it isn't due to setting notoc. The first \contentsline in main.toc (set by your first nonstarred \chapter) is where this happens.
    – Werner
    Jan 15 at 13:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.