Menu

HowTo_ChapterAtLists

How to output chapter headings in the list of figures and list of tables and in other directories of floating environments

Anyone who has read the KOMA-Script user guide knows that with scrbook and scrreprt the chapter headings can also be displayed in all directories of floating environments using the option chapteratlists=entry in addition to the table of contents. However, the option works very consistently and adds the chapter heading to the list of figures, for example, even if the corresponding chapter has no figures at all and therefore the list of figures for this chapter does not display any figures. However, it is often desired that the chapter heading is only displayed if this chapter also has a corresponding floating environment entry.

The chapter entries are written to the directories in both classes within \addchaptertocentry. This instruction is called by \chapter (or \addchap), i.e. at a time when it is not yet known whether the chapter will subsequently have a corresponding floating environment. So we first need an indicator for this. Since all entries are written via \addcontentsline, the idea of generating this indicator within \addcontentsline is obvious. As the indicator must be available in the next LaTeX run, it is written to the aux file. The easiest way to do this is to generate a label:

\AddToHookWithArguments{cmd/addcontentsline/before}{%
  \Ifstr{#1}{\ext@toc}{}{%
    \@ifundefined{chapter@\thechapter @has@#1@done}{%
      \expandafter\global\@namedef{chapter@thechapter @has@#1@done}{true}%
      \label{chapter@\thechapter @has@#1}%
    }{}%
  }%
}

Here we use a generic LaTeX hook for the beginning of the \addcontentsline command, which also receives all arguments of \addcontentsline. The first argument is the file extension of the respective directory. Here we first test that it is not the table of contents itself and only then generate the indicator. Although this is not absolutely necessary, it does make sense.

We use a label as an indicator because in current LaTeX versions we can very easily test for its existence with \IfLabelExists:TF and at the same time LaTeX automatically issues a message at the end of the LaTeX run in the event of changes, so that we know that another LaTeX run is necessary. The name of the label is simply made up of the chapter number and the file extension of the respective directory as well as some meaningful strings. We get the number of the chapter (in this first version) simply via \thechapter.

However, as multiple defined labels lead to warnings, we use a second indicator to decide whether the label still needs to be defined or whether a label has already been created for the current chapter. To do this, we define another macro globally and only set the label if this macro has not yet been defined.

Next, we must ensure that the chapter entry is only written if the label for this chapter exists. To do this, we only need to set or delete the ToC feature chapteratlist depending on whether the indicator label exists. We do not have to completely redefine \addchaptertocentry for this either, but can use a generic LaTeX hook at the beginning of the command:

\AddToHook{cmd/addchaptertocentry/before}{%
  \if@chaptertolists
    \doforeachtocfile[float]{%
      \IfLabelExistsTF{chapter@\thechapter @has@\@currext}{%
        \setuptoc{\@currext}{chapteratlist}%
      }{%
        \unsettoc{\@currext}{chapteratlist}%
      }%
    }%
  \fi
}

We use \if@chaptertolists to check whether the chapteratlists option is used at all. Strictly speaking, we could do without this test. We then check for each auxiliary file in the float category whether the corresponding indicator label exists for the current chapter. If this is the case, we set the chapteratlist feature for the corresponding file extension. If this is not the case, we delete the feature.

That was actually all. However, the use of \thechapter has a decisive disadvantage. The whole thing does not work correctly if not only \chapter but also \addchap is used. Other unnumbered chapters, for example in the area of \frontmatter or \backmatter, also pose a problem. To solve the problem, we can use an absolute chapter counter abschapter, which also counts unnumbered chapters. This can also be incremented using a generic hook for each \chapter (and therefore also each \chapter* and each \addchap or \addchap*). Then only \thechapter needs to be replaced by \theabschapter in the above definitions.

Here a complete example:

\documentclass[chapteratlists=entry]{scrbook}
% Code to limit chapteratlists=entry to chapters with float entries.
% → https://sf.net/p/koma-script/wiki-en/HowTo_ChapterAtLists
\makeatletter
\newcounter{abschapter}
\AddToHook{cmd/chapter/before}{\stepcounter{abschapter}}
\AddToHookWithArguments{cmd/addcontentsline/before}{%
  \Ifstr{#1}{\ext@toc}{}{%
    \@ifundefined{chapter@\theabschapter @has@#1@done}{%
      \expandafter\global\@namedef{chapter@\theabschapter @has@#1@done}{true}%
      \label{chapter@\theabschapter @has@#1}%
    }{}%
  }%
}
\AddToHook{cmd/addchaptertocentry/before}{%
  \if@chaptertolists
    \doforeachtocfile[float]{%
      \IfLabelExistsTF{chapter@\theabschapter @has@\@currext}{%
        \setuptoc{\@currext}{chapteratlist}%
      }{%
        \unsettoc{\@currext}{chapteratlist}%
      }%
    }%
  \fi
}
\makeatother
\usepackage{mwe}
\begin{document}
\tableofcontents
\listoffigures
\listoftables
\Blinddocument
\begin{figure}
  \centering
  \includegraphics{example-image}
  \caption{Test Figure}
  \label{fig:test}
\end{figure}
\Blinddocument
\begin{table}
  \centering
  \begin{tabular}{ll}
    test & table
  \end{tabular}
  \caption{Test Table}
  \label{tab:test}
\end{table}
\Blinddocument
\Blinddocument
\begin{figure}
  \centering
  \includegraphics{example-image-a}
  \caption{Test Figure A}
  \label{fig:testA}
\end{figure}
\Blinddocument
\begin{table}
  \centering
  \begin{tabular}{ll}
    test & table
  \end{tabular}
  \caption{Test Table A}
  \label{tab:testA}
\end{table}
\addchap{Test addchap}
\begin{table}
  \renewcommand*{\thetable}{\arabic{table}}%
  \renewcommand*{\theHtable}{\theabschapter.\arabic{table}}%
  \centering
  \begin{tabular}{ll}
    test & test
  \end{tabular}
  \caption{Test Table addchap}
  \label{tab:addchap}
\end{table}

\addchap{Another addchap}
\blindtext

\appendix
\Blinddocument
\begin{table}
  \centering
  \begin{tabular}{ll}
    test & table
  \end{tabular}
  \caption{Test Table B}
  \label{tab:testB}
\end{table}

\Blinddocument

\end{document}

Incidentally, the example still works if you load hyperref, whereby it does not matter whether you load the package before or after the additional preamble code.


Related

Wiki (English): HowTo_ToCConfiguration

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.