Menu

HowTo_PartToC

How to create a custom table of contents for parts (\part)

The standard approach for part-specific tables of contents would be to use the minitoc package. However, there are a few hurdles to overcome when using it with KOMA-Script, and there is no guarantee that this package will work flawlessly with KOMA-Script classes, nor that the KOMA-Script classes will continue to function properly after loading this package. However, the classes themselves, in conjunction with the tocbasic package they use, already provide everything necessary for partial tables of contents, for example at the \part level.

Note: The solution shown below works best with LuaLaTeX. If you use PDFLaTeX or XeLaTeX—which is no longer recommended for LaTeX—you may easily encounter error messages due to too many \newwrite commands.

First, we define a command that can switch between different tables of contents. The extension for the helper file is .toc<addition>, where <addition> can be specified using the command’s optional argument. If the argument is not provided, the command reverts to the main table of contents. It might look something like this:

\NewDocumentCommand{\switchcontents}{o}
{%
  \IfValueT{#1}
  {%
    \edef\ext@toc{toc#1}% define new toc extension
  }{%
    \edef\ext@toc{toc}% switch back to main ToC
  }
  % If you do not want bookmarks for the following \chapter etc. remove
  % the next three lines.
  \scr@ifundefinedorrelax{hypersetup}{}{%
    \edef\reserved@a{\noexpand\hypersetup{bookmarkstype=\ext@toc}}\reserved@a
  }%
  % Reserve the toc extension
  \Ifattoclist{\ext@toc}{}{\addtotoclist[toc]{\ext@toc}}%
}

The specific features of KOMA-Script used here are:

  • The KOMA-Script classes do not write directly to the file with the toc extension. Instead, the extension of the auxiliary file for the table of contents is defined via the \ext@toc macro, which is set to toc by default.
  • The tocbasic package maintains a list of known extensions for auxiliary files. With \Ifattoclist, you can check whether an extension is already in use, and with \addtotoclist, you can add an extension to the list of used extensions.

Next, we define a command to switch to a partial table of contents. If the partial table of contents was not yet known at the time of the switch, it should also be printed. The default value for the <addition> here is the value of the part counter:

\newcommand*{\partcontents}[1][\thepart]{%
  \Ifattoclist{toc#1}{%
    \switchcontents[#1]%
  }{%
    \switchcontents[#1]%
    \listoftoc[Contents of this Part]{\ext@toc}% show contents only for new extensions
  }%
}

So now we simply need to insert \partcontents after a \part{…} that is to have a sub-table of contents. For unnumbered parts, a unique <suffix> should be specified as an optional argument.

However, it would of course be desirable if we had the option to include the chapters, sections, etc., of a part that has its own sub-table of contents in the main table of contents as well. To do this, we slightly modify \switchcontents:

\newif\ifparttocinmaintoc
\NewDocumentCommand{\switchcontents}{o}
{%
  \IfValueTF{#1}
  {%
    \addtocontents{\ext@toc}{\protect\ifparttocinmaintoc\protect\InputIfFileExists{\jobname.toc#1}{}{}\protect\fi}% conditionally load the part ToC into the main ToC
    \edef\ext@toc{toc#1}% define new toc extension
  }{%
    \edef\ext@toc{toc}% switch back to main ToC
  }
  % If you do not want bookmarks for the following \chapter etc. remove
  % the next three lines.
  \scr@ifundefinedorrelax{hypersetup}{}{%
    \edef\reserved@a{\noexpand\hypersetup{bookmarkstype=\ext@toc}}\reserved@a
  }%
  % Reserve the toc extension
  \Ifattoclist{\ext@toc}{}{\addtotoclist[toc]{\ext@toc}}%
}

Now we can use \parttocinmaintoctrue before \tableofcontents to ensure that all sub-tables of contents also appear in the main table of contents.

Note: The above extension using \ifparttocinmaintoc only works if \tableofcontents appears before the first \partcontents. If it appears after \partcontents, the sub-tables of contents are already open for writing but still empty by the time they are read by \tableofcontents.

It would also be nice if the switch to the main table of contents occurred automatically with every \part. One option for this is the KOMA-Script-specific DoHook heading/preinit/part, which is executed very early in the \part command:

\AddtoDoHook{heading/preinit/part}{\switchcontents\@gobble}

You can achieve something similar for appendix using the hook \KOMAClassName/appendix:

\AddToHook{\KOMAClassName/appendix}{\switchcontents}

Suppose we have a document with four parts, and only Parts II and IV are to have their own table of contents. In that case, the code might look something like this:

\documentclass{scrreprt}

\usepackage{hyperref}
\usepackage{mwe}

\newif\ifparttocinmaintoc
\makeatletter
\NewDocumentCommand{\switchcontents}{o}
{%
  \IfValueTF{#1}
  {%
    \addtocontents{\ext@toc}{\protect\ifparttocinmaintoc\protect\InputIfFileExists{\jobname.toc#1}{}{}\protect\fi}% conditionally load the part ToC into the main ToC
    \edef\ext@toc{toc#1}% define new toc extension
  }{%
    \edef\ext@toc{toc}% switch back to main ToC
  }
  % If you do not want bookmarks for the following \chapter etc. remove
  % the next three lines.
  \scr@ifundefinedorrelax{hypersetup}{}{%
    \edef\reserved@a{\noexpand\hypersetup{bookmarkstype=\ext@toc}}\reserved@a
  }%
  % Reserve the toc extension
  \Ifattoclist{\ext@toc}{}{\addtotoclist[toc]{\ext@toc}}%
}
\newcommand*{\partcontents}[1][\thepart]{%
  \Ifattoclist{toc#1}{%
    \switchcontents[#1]%
  }{%
    \switchcontents[#1]%
    \listoftoc[Contents of this Part]{\ext@toc}% show contents only for new extensions
  }%
}
\AddtoDoHook{heading/preinit/part}{\switchcontents\@gobble}% automatic switch back to main ToC at next \part
\AddToHook{\KOMAClassName/appendix}{\switchcontents}% automatic switch back to main ToC at \appendix
\makeatother
\parttocinmaintoctrue% show the contents of the part ToC also in the main ToC
%\parttocinmaintocfalse% don't show the contents of the part ToC in the main ToC

\begin{document}
\tableofcontents
\part{First Part}
\blinddocument

\part{Second Part}
\partcontents% use \jobname.toc\thepart as new toc file and show the contents
\blinddocument

\part{Third Part}
\blinddocument

\part{Fourth Part}
\partcontents% use \jobname.toc\thepart as new toc file and show the contents
\blinddocument

\appendix
\blinddocument
\end{document}

Before you ask: Yes, you can also adapt this for use with \chapter instead of \part:

\newcommand*{\chaptercontents}[1][\thechapter]{%
  \Ifattoclist{toc#1}{%
    \switchcontents[#1]%
  }{%
    \switchcontents[#1]%
    \setuptoc{leveldown}{toc#1}% the chapter toc is a section not a chapter
    \listoftoc[Contents of this Chapter]{\ext@toc}% show contents only for new extensions
  }%
}
\AddtoDoHook{heading/preinit/chapter}{\switchcontents\@gobble}% automatic switch back to main ToC at next chapter

If the document also uses parts, the DoHook heading/preinit/part must be retained. Otherwise, it can be omitted.

Using both \parttoc and \chaptertoc does not work this way. To do so, you would also need to know, in heading/preinit/chapter, whether to call \switchcontents or \switchcontents[\thepart]. While this is a manageable task, you should avoid using too many tables of contents.

Using different tocdepth settings for the main table of contents and sub-tables of contents is also possible (simply insert the appropriate counter settings in the right places). But I don’t want to get too far ahead of myself here regarding a future package or extension for KOMA-Script.


Related

Issues: #1
Wiki (English): HowTo_AppendixToC
Wiki (English): HowTo_ToCConfiguration