2

I am searching for a way to include the text "Chapter" as a prefix to the chapter numbering in a ToC for a book class AND have the chapter title wrap to the left-most edge in the ToC listing. I am building this into a common resource, currently in two pieces, one as the class file only with packages and the other as a settings .tex file that is \input in the preamble. I have tried two different approaches within the settings file. The first below does not capture the required patch correctly.

\documentclass{book}

\usepackage{xpatch}
\usepackage{hyperref}

\makeatletter
\xpatchcmd{\@chapter}
    {\addcontentsline{toc}{chapter}{\numberline {#1}}}
    {\addcontentsline{toc}{chapter}{\numberline {Chapter~\thechapter{}.~#1}}}
    {\typeout{Success}}
    {\typeout{Failed!}}
\makeatother

\begin{document}

\tableofcontents

\chapter{This is First}

Some day this will work.

\chapter{This is Second}

Perhaps soon!

\end{document}

This second approach puts the Chapter word in place in the ToC but, the text in the longer Chapter 2 title does not wrap as required in the ToC line.

\documentclass{book}

\usepackage{tocloft}

\begin{document}

\newlength{\tocchapwidth}
\settowidth{\tocchapwidth}{\chaptername\ }
\addtolength{\cftchapnumwidth}{\tocchapwidth}
\renewcommand{\cftchappresnum}{\chaptername\ }
\renewcommand{\cftchapaftersnum}{.}
\renewcommand{\cftchapaftersnumb}{~}
\renewcommand{\cftchapdotsep}{\cftdotsep}

\tableofcontents

\chapter{This is First}

Some day this will work.

\chapter{This is Second, a Rather Long and Windy Road Leading to a Door Going to Nowhere Fast}

Perhaps soon!

\end{document}

This is an attempt to meet formatting requirements for a thesis / dissertation document. We currently have a crude work around -- we type the chapter title including the prefix, e.g. \chapter{Chapter 2.~This is the Second ...} (and suppress the chapter number outputs in the ToC using the titlesec package).

Also, while I do not include it in the second example, the document does require the hyperref package. I infer from a separate posting that I might need to patch into its Hy@... chapter command, but even my attempts to do this failed.

I'm not conversant enough with LaTeX3 but will be glad to incorporate such modifications. Finally, I should hope that whatever option is offered will work readily enough to Overleaf, where a large contingent of those who will use the package will likely do their work.

1
  • @cabohah Yes. Amazing that I could not find this. Thank you. Commented Jan 15 at 22:34

1 Answer 1

2

There are several issues with you first approach.

First of all, even the original definition of book.cls does not have:

\addcontentsline{toc}{chapter}{\numberline {#1}}

in the definition of \@chapter, but:

\addcontentsline{toc}{chapter}{\protect\numberline{\thechapter}#1}

So there is a \protect missing and the correct argument to \numberline and the first argument of \@chapter is used without braces.

Second problem is that after loading hyperref the definition of \@chapter changes. So the patch must be before loading hyperref.

BTW: To see the original definition, just add \show\@chapter before \xpatchcmd. This will output the current definition before patching \@chapter in the log-file.

Third problem is, that the replacement:

\addcontentsline{toc}{chapter}{\protect\numberline {Chapter~\thechapter{}.~#1}}

Would put not only Chapter~<number>. into the number argument but also the title. So it should be at least:

\addcontentsline{toc}{chapter}{\numberline {Chapter~\thechapter{}.}#1}

But for this definition you would also need a change of \l@chapter to increase the space reserved for the number. Maybe instead you don't want to reserve number space and instead like to use:

\addcontentsline{toc}{chapter}{Chapter~\thechapter{}.~#1}

So with:

\documentclass{book}

\usepackage{xpatch}

\makeatletter
\xpatchcmd{\@chapter}
  {\addcontentsline{toc}{chapter}{\protect\numberline{\thechapter}#1}}
  {\addcontentsline{toc}{chapter}{Chapter~\thechapter{}.~#1}}
  {\typeout{Success}}
  {\typeout{Failed!}}
\makeatother

\usepackage{hyperref}

\begin{document}

\tableofcontents

\chapter{This is First}

Some day this will work.

\chapter{This is Second}

Perhaps soon!

\end{document}

you get:

Chapter 1. This is the …

The alternative with using Chapter <number>. as argument of \numberline would be, e.g.:

\documentclass{book}

\usepackage{xpatch}

\makeatletter
\xpatchcmd{\@chapter}
  {\addcontentsline{toc}{chapter}{\protect\numberline{\thechapter}#1}}
  {\addcontentsline{toc}{chapter}{\protect\numberline{Chapter~\thechapter{}.}#1}}
  {\typeout{\string\@chapter\space patch success}}
  {\typeout{\string\@chapter\space patch failed!}}
\xpatchcmd{\l@chapter}
  {\setlength\@tempdima{1.5em}}
  {\setlength\@tempdima{6em}}% increase reserved number width
  {\typeout{\string\l@chapter\space patch success}}
  {\typeout{\string\l@chapter\space patch failed!}}
\makeatother

\usepackage{hyperref}

\begin{document}

\tableofcontents

\chapter{This is First}

Some day this will work.

\chapter{This is Second}

Perhaps soon!

\end{document}

The result for one line entries is similar to the first suggestion. To see a difference try entries with more than one line, e.g.

\chapter{This is Second Chapter with very long Titel Needing more than one
  Line in the Table of Contents}

So IMHO this second approach of mine is, what you want.


Your problem with your second approach is, that you don't take the dot . and the space ~ after the number into account, when increasing \cftchapnumwidth. Here one possible correction of your setting:

\documentclass{book}

\usepackage{tocloft}

\begin{document}

\newlength{\tocchapwidth}
\renewcommand{\cftchappresnum}{\chaptername\ }
\settowidth{\tocchapwidth}{\cftchappresnum}
\renewcommand{\cftchapaftersnum}{.~}
\newlength{\tocchapafternumwidth}
\settowidth{\tocchapafternumwidth}{\cftchapaftersnum}
\addtolength{\cftchapnumwidth}{\tocchapwidth}
\addtolength{\cftchapnumwidth}{\tocchapafternumwidth}
\renewcommand{\cftchapdotsep}{\cftdotsep}

\tableofcontents

\chapter{This is First}

Some day this will work.

\chapter{This is Second, a Rather Long and Windy Road Leading to a Door Going to Nowhere Fast}

Perhaps soon!

\end{document}

using tocloft

But if you have a intense look into this suggestion it is still not correct, because you are measuring text in the current document font not in the font used for the chapter entries. So the previous code only seems to be correct, but it isn't. For correct code you have to take the \cftchapfont into account, when measuring the text widths. (And now you don't need to increase the width also by the space, if the number width without the prefix Chapter and the postfix . was already enough). So better code would be something like:

\documentclass{book}

\usepackage{tocloft}

\newlength{\tocchapwidth}
\newlength{\tocchapafternumwidth}
\renewcommand{\cftchappresnum}{\chaptername\ }
\renewcommand{\cftchapaftersnum}{.}
\renewcommand{\cftchapdotsep}{\cftdotsep}
\AtBeginDocument{% final font setup is done in \begin{document} so we delay all text measuring
  \settowidth{\tocchapwidth}{\cftchapfont\cftchappresnum}%
  \settowidth{\tocchapafternumwidth}{\cftchapfont\cftchapaftersnum}%
  \addtolength{\cftchapnumwidth}{\tocchapwidth}%
  \addtolength{\cftchapnumwidth}{\tocchapafternumwidth}%
}

\begin{document}
\tableofcontents

\chapter{This is First}

Some day this will work.

\chapter{This is Second, a Rather Long and Windy Road Leading to a Door Going to Nowhere Fast}

Perhaps soon!

\end{document}

The Appendix Problem

Note: Both examples are not suitable for documents with appendix, because in this case Chapter wouldn't be the correct term in the appendix.

Making the recommended suggestion without tocloft suitable for documents with appendix would be easy. You just need to replace the hard-coded Chapter by \@chapapp and increase the width:

\documentclass{book}

\usepackage{xpatch}

\makeatletter
\xpatchcmd{\@chapter}
  {\addcontentsline{toc}{chapter}{\protect\numberline{\thechapter}#1}}
  {\addcontentsline{toc}{chapter}{\protect\numberline{\@chapapp~\thechapter{}.}#1}}
  {\typeout{\string\@chapter\space patch success}}
  {\typeout{\string\@chapter\space patch failed!}}
\xpatchcmd{\l@chapter}
  {\setlength\@tempdima{1.5em}}
  {\setlength\@tempdima{7em}}% increase reserved number width
  {\typeout{\string\l@chapter\space patch success}}
  {\typeout{\string\l@chapter\space patch failed!}}
\makeatother

\usepackage{hyperref}

\begin{document}

\tableofcontents

\chapter{This is First}

Some day this will work.

\chapter{This is Second}

Perhaps soon!

\appendix
\chapter{This is a Rather Long and Windy Road Leading to a Door Going
  to Nowhere Fast}

\end{document}

For the tocloft solution you could use something like:

\documentclass{book}

\usepackage{tocloft}

\newlength{\tocchapwidth}
\newlength{\tocappwidth}
\newlength{\tocchapafternumwidth}
\renewcommand{\cftchappresnum}{\chaptername\ }
\renewcommand{\cftchapaftersnum}{.}
\renewcommand{\cftchapdotsep}{\cftdotsep}
\AtBeginDocument{%
  \settowidth{\tocchapwidth}{\cftchapfont\chaptername}%
  \settowidth{\tocappwidth}{\cftchapfont\appendixname}%
  \ifdim\tocappwidth>\tocchapwidth
    \addtolength{\cftchapnumwidth}{\tocappwidth}%
  \else
    \addtolength{\cftchapnumwidth}{\tocchapwidth}%
  \fi
  \settowidth{\tocchapafternumwidth}{\cftchapfont\cftchapaftersnum}%
  \addtolength{\cftchapnumwidth}{\tocchapafternumwidth}%
}
\AddToHook{cmd/appendix/after}{%
  \addtocontents{toc}{%
    \protect\renewcommand{\protect\cftchappresnum}{\protect\appendixname{} }%
  }%
}
\begin{document}
\tableofcontents

\chapter{This is First}

Some day this will work.

\chapter{This is Second, a Rather Long and Windy Road Leading to a Door Going to Nowhere Fast}

Perhaps soon!

\appendix
\chapter{A Rather Long Appendix Heading and Windy Road Leading to a Door Going to Nowhere Fast}


\end{document}
1
  • I've marked this as answering my question. Your reference to titletoc is by far the easiest approach. Not sure how I missed it. Thank you. Commented Jan 15 at 22:36

Not the answer you're looking for? Browse other questions tagged .