Menu

HowTo_PartToC

Markus Kohm

Wie man Teile (\part) mit einem eigenen Inhaltsverzeichnis versehen kann

Das Standardvorgehen für Teil-Inhaltsverzeichnisse wäre die Verwendung des Pakets minitoc. Allerdings gibt es im Zusammenspiel mit KOMA-Script dabei einige Hürden zu überwinden und es ist weder sichergestellt, dass dieses Paket mit KOMA-Script-Klassen einwandfrei funktioniert, noch dass die KOMA-Script-Klassen nach laden dieses Pakets noch einwandfrei funktionieren. Allerdings bieten die Klassen selbst im Zusammenspiel mit dem von ihnen verwendeten Paket tocbasic bereits alles, was für Teil-Inhaltsverzeichnisse beispielsweise auf Ebene \part notwendig ist.

Hinweis: Die nachfolgend gezeigte Lösung funktioniert am besten mit LuaLaTeX. Bei Verwendung von PDFLaTeX oder dem für LaTeX nicht mehr empfohlenen XeLaTeX kann es leicht zu Fehlermeldungen wegen zu vieler \newwrite kommen.

Zunächst definieren wir uns einen Befehl, der zwischen unterschiedlichen Inhaltsverzeichnissen umschalten kann. Als Endung für die Hilfsdatei wird dabei .toc<Zusatz> verwendet, wobei <Zusatz> einfach über das optionale Argument der Anweisung bestimmt werden kann. Ist das Argument nicht angegeben, wird wieder auf das Haupt-Inhaltsverzeichnis umgeschaltet. Aussehen könnte das so:

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

Die verwendeten KOMA-Script-Besonderheiten dabei sind:

  • Die KOMA-Script-Klassen schreiben nicht direkt in die Datei mit der Endung toc. Stattdessen ist die Endung der Hilfsdatei für das Inhaltsverzeichnis über das Macro \ext@toc definiert, das wiederum in der Voreinstellung toc ist.
  • Das Paket tocbasic führt eine Liste der bekannten Endungen für Hilfsdateien. Mit \Ifattoclist kann man abfragen, ob eine Endung bereits verwendet wird und mit \addtotoclist kann man eine Endung der Liste der verwendeten Endungen hinzufügen.

Als nächstes definieren wir eine Anweisung, um auf ein Teil-Inhaltsverzeichnis umzuschalten. War das Teil-Inhaltsverzeichnis bei der Umschaltung noch nicht bekannt, so soll es außerdem ausgegeben werden. Als Voreinstellung für den <Zusatz> wird hier die Ausgabe des Zählers part verwendet:

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

Nun müssten wir also schlicht hinter einem \part{…}, das ein Teil-Inhaltsverzeichnis erhalten soll, \partcontents einfügen. Für nicht nummerierte Teile wäre als optionales Argument ein eindeutiger <Zusatz> anzugeben.

Allerdings wäre es natürlich wünschenswert, wenn wir die Wahl hätten, die Kapitel, Abschnitte etc. eines Teils, der über ein eigenes Teil-Inhaltsverzeichnis verfügt, auch im Hauptinhaltsverzeichnis zu sehen. Dazu ändern wir \switchcontents leicht ab:

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

Jetzt können wir vor \tableofcontents mit \parttocinmaintoctrue dafür sorgen, dass alle Teil-Inhaltsverzeichnisse auch im Hauptinhaltsverzeichnis erscheinen.

Achtung: Obige Erweiterung mit \ifparttocinmaintoc funktioniert nur, wenn \tableofcontents vor dem ersten \partcontents steht. Steht es erst nach \partcontents, so sind die Teil-Inhaltsverzeichnisse zum Zeitpunkt, wenn sie in \tableofcontents gelesen werden, bereits zum Schreiben geöffnet, aber noch leer.

Außerdem wäre es schön, wenn die Umschaltung auf das Haupt-Inhaltsverzeichnis bei jedem \part automatisch erfolgen würde. Dafür bietet sich zum einen der KOMA-Script spezifische DoHook heading/preinit/part an, der sehr weit am Anfang von \part ausgeführt wird:

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

Ähnliches kann man für appendix über den Hook \KOMAClassName/appendix erreichen:

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

Angenommen wir haben ein Dokument mit vier Teilen, wobei lediglich Teil II und Teil IV ein eigenes Inhaltsverzeichnis erhalten sollen. Dann könnte die Anwendung des ganzen so aussehen:

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

Bevor die Frage kommt: Ja, man kann das Ganze auch für die Verwendung mit \chapter statt mit \part adaptieren:

\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

Werden in dem Dokument auch Teile verwendet, so ist der DoHook heading/preinit/part beizubehalten. Anderenfalls kann er entfallen.

Sowohl \parttoc als auch \chaptertoc zu verwenden, funktioniert so nicht. Dazu müsste man bei heading/preinit/chapter zusätzlich wissen, ob man \switchcontents oder \switchcontents[\thepart] aufrufen muss. Das ist zwar eine bewältigbare Aufgabe, allerdings sollte man auch nicht zuviele Verzeichnisse verwenden.

Auch die Verwendung unterschiedlicher tocdepth-Einstellungen für das Haupt-Inhaltsverzeichnis und Teil-Inhaltsverzeichnisse ist lösbar (einfach entsprechende Zählereinstellungen an passender Stelle einfügen). Aber ich will hier einem zukünftigen Paket oder einer zukünftigen Erweiterung von KOMA-Script nicht zu sehr vorausgreifen.