Sie sind hier

Kann man chapteratlists=entry auf Kapitel mit Verzeichniseinträgen beschränken?

Bild von Markus Kohm

Da wurde mal wieder eine interessante Frage an mich herangetragen, bei der sich der Fragesteller nicht traute, sie hier selbst öffentlich zu stellen. Es geht darum, dass ein Anwender die Kapiteleinträge auch in den Gleitumgebungsverzeichnissen – namentlich dem Abbildungsverzeichnis – haben will. Allerdings will er nur die Kapiteleinträge der Kapitel haben, die auch eine entsprechende Gleitumgebung – namentlich eine Abbildung – haben. Die Frage dabei ist, ob man diese Anforderung manuell oder sogar automatisch umsetzen kann.

Bild von Markus Kohm

Manuell gibt es eine recht einfache Lösung. Dazu setzt man ohne chapteratlists=entry nach der \chapter-Anweisung betroffener Kapitel einfach ein

  \addxcontentslilne{lof}{chapteratlist}[\thechapter]{Text, der im Verzeichnis angezeigt werden soll}

Unschön ist dabei, dass man den Text für den Eintrag selbst wiederholen muss. Daher könnte man auf die Idee kommen, die entsprechende Überschrift als

\KOMAoption{chapteratlists}{entry}
\chapter{Überschrift}
\KOMAoptions{chapteratlists}{0pt}

zu setzen. Das funktioniert, solange man nur ein Gleitumgebungsverzeichnis hat. Sobald man aber beispielsweise sowohl ein Abbildungs- als auch ein Tabellenverzeichnis hat, geht es nicht mehr, weil die Option sozusagen eine Alles-oder-Nichts-Option ist, sich also immer auf alle Verzeichnisse bezieht.

Da das ganze jedoch über TOC-Eigenschaften (siehe tocbasic-Kapitel in der Anleitung oder im Buch) gelöst ist, kann man tatsächlich die entsprechende Eigenschaft lokal setzen:

\documentclass[listof=chapterentry]{scrbook}% Feature generell einschalten …
\makeatletter
% … aber für alle Dateiendungen erst einmal deaktivieren
\doforeachtocfile{%
  \unsettoc{\@currext}{chapteratlist}%
}
\makeatother
\usepackage{mwe}
\begin{document}
\tableofcontents
\listoffigures
\listoftables
\setuptoc{lof}{chapteratlist}% Kapitel mit Abbildungen
\chapter{First Chapter}
\unsettoc{lof}{chapteratlist}
\blindtext
\begin{figure}
  \centering
  \includegraphics{example-image}
  \caption{Testfigure}
  \label{fig:test}
\end{figure}
 
\setuptoc{lot}{chapteratlist}% Kapitel mit Tabellen
\chapter{Second Chapter}
\unsettoc{lot}{chapteratlist}
\blindtext
\begin{table}
  \centering
  \begin{tabular}{ll}
    test & table
  \end{tabular}
  \caption{Testtable}
  \label{tab:test}
\end{table}
\Blinddocument
 
\setuptoc{lof}{chapteratlist}
\chapter{Fourth Chapter}
\unsettoc{lof}{chapteratlist}
\begin{figure}
  \centering
  \includegraphics{example-image-a}
  \caption{Testfigure A}
  \label{fig:testA}
\end{figure}
 
\setuptoc{lot}{chapteratlist}
\chapter{Fifth Chapter}
\unsettoc{lot}{chapteratlist}
\begin{table}
  \centering
  \begin{tabular}{ll}
    test & table
  \end{tabular}
  \caption{Testtable A}
  \label{tab:testA}
\end{table}
 
\end{document}

Wie man sieht, muss man dabei auch Option listof=chapterentry verwenden, danach jedoch erst einmal für alle Endungen die TOC-Eigenschaft chapteratlist wieder wegnehmen. Man setzt sie dann nur individuell bei den Kapiteln, bei denen man sie haben will.

Aber natürlich ist das ganze anfällig für Fehler, wenn man in einem Kapitel Gleitumgebungen hinzufügt oder weg nimmt.

Bild von Markus Kohm

Da die manuelle Lösung fehleranfällig ist, stellt sich die Frage, wie man das ganze automatisch machen könnte. Dazu müsste man zunächst einmal bei jedem Kapitel wissen, ob es eine entsprechende nummerierte Gleitumgebung hat. Ich klinke mich dazu in die Anweisung \addcontentsline ein. Wird darüber ein Eintrag in das entsprechende Gleitumgebungsverzeichnis geschrieben, ist klar, dass auch der Kapiteleintrag geschrieben werden muss. Dieses Wissen schreibe ich einfach in der Form \chapterhas{Kapitelnummer}{Dateiendung} in die aux-Datei:

\let\chapterhas@original@addcontentsline\addcontentsline
\renewcommand*{\addcontentsline}[1]{%
  \immediate\write\@auxout{\string\chapterhas{\thechapter}{#1}}%
  \chapterhas@original@addcontentsline{#1}%
}

Jetzt müssen die chapterhas-Anweisungen natürlich auch noch beim Lesen der aux-Datei ausgewertet werden. Ich definiere in diesem Fall einfach eine Art Markeranweisung \chapterhas@Kapitelnummer@Dateiendung:

\newcommand*{\chapterhas}[2]{%
  \global\@namedef{chapterhas@#1@#2}{true}%
}

Später kann dann geprüft werden, ob die entsprechende Anweisung definiert ist. \global ist hier notwendig, weil alle Definitionen aus der aux-Datei sonst lokal zum Einlesen der aux-Datei sind.

Jetzt muss noch die Erzeugung des Kapiteleintrags in das jeweilige Gleitumgebungsverzeichnis geregelt werden. Das passiert bei KOMA-Script über die Anweisung \addchaptertocentry. In die Originaldefinition

\newcommand*{\addchaptertocentry}[2]{%
  \addtocentrydefault{chapter}{#1}{#2}%
  \if@chaptertolists
    \doforeachtocfile{%
      \iftocfeature{\@currext}{chapteratlist}{%
        \addxcontentsline{\@currext}{chapteratlist}[{#1}]{#2}%
      }{}%
    }%
    \@ifundefined{float@addtolists}{}{\scr@float@addtolists@warning}%
  \fi
}

muss nun noch ein Test auf die Markeranweisung eingefügt werden:

\renewcommand*{\addchaptertocentry}[2]{%
  \addtocentrydefault{chapter}{#1}{#2}%
  \if@chaptertolists
    \doforeachtocfile{%
      \iftocfeature{\@currext}{chapteratlist}{%
        \scr@ifundefinedorrelax{chapterhas@\thechapter @\@currext}{%
        }{%
          \addxcontentsline{\@currext}{chapteratlist}[{#1}]{#2}%
        }%
      }{}%
    }%
    \@ifundefined{float@addtolists}{}{\scr@float@addtolists@warning}%
  \fi
}

Wie man sieht, ist die Änderung nicht sehr groß (man könnte sie übrigens auch mit xpatch hineinpatchen).

Hier noch ein Gesamtbeispiel:

\documentclass[chapteratlists=entry]{scrbook}
 
\makeatletter
\let\chapterhas@original@addcontentsline\addcontentsline
\renewcommand*{\addcontentsline}[1]{%
  \immediate\write\@auxout{\string\chapterhas{\thechapter}{#1}}%
  \chapterhas@original@addcontentsline{#1}%
}
\newcommand*{\chapterhas}[2]{%
  \global\@namedef{chapterhas@#1@#2}{true}%
}
\renewcommand*{\addchaptertocentry}[2]{%
  \addtocentrydefault{chapter}{#1}{#2}%
  \if@chaptertolists
    \doforeachtocfile{%
      \iftocfeature{\@currext}{chapteratlist}{%
        \scr@ifundefinedorrelax{chapterhas@\thechapter @\@currext}{%
        }{%
          \addxcontentsline{\@currext}{chapteratlist}[{#1}]{#2}%
        }%
      }{}%
    }%
    \@ifundefined{float@addtolists}{}{\scr@float@addtolists@warning}%
  \fi
}
\makeatother
 
\usepackage{mwe}
\begin{document}
\tableofcontents
\listoffigures
\listoftables
\Blinddocument
\begin{figure}
  \centering
  \includegraphics{example-image}
  \caption{Testfigure}
  \label{fig:test}
\end{figure}
\Blinddocument
\begin{table}
  \centering
  \begin{tabular}{ll}
    test & table
  \end{tabular}
  \caption{Testtable}
  \label{tab:test}
\end{table}
\Blinddocument
\Blinddocument
\begin{figure}
  \centering
  \includegraphics{example-image-a}
  \caption{Testfigure A}
  \label{fig:testA}
\end{figure}
\Blinddocument
\begin{table}
  \centering
  \begin{tabular}{ll}
    test & table
  \end{tabular}
  \caption{Testtable A}
  \label{tab:testA}
\end{table}
 
\end{document}

Nach dem zweiten LaTeX-Lauf ergibt das Abbildungs- und Tabellenverzeichnis noch ohne Kapiteleinträge, nach dem dritten Lauf werden auch die Kapiteleinträge angezeigt.

Nur der Vollständigkeit halbe und weil ich grad ne ganze Weile suchen musste, um rauszufinden, warum deine Lösung in meinem Dokument nicht geht: Wenn das Paket hyperref benutzt wird, müssen die von dir gezeigten Anpassungen nach dem Laden dieses Paketes gemacht werden.

Viele Grüße
Tobi

Tobi W_
Grafikdesign und TeX-Beratung

tobiw.de
mail@tobiw.de

Mein Blog: TeX-Beispiel des Monats

Bild von Markus Kohm

Aber natürlich die Umdefinierung/Erweiterung von \addcontentsline. Da hyperref nicht auf die vorhandene Anweisung aufbaut (und leider nicht einmal testet, ob diese den Erwartungen entspricht und ggf. eine Warnung ausgibt), sondern \addcontentsline einfach hart neu definiert.

So genau hatte ich nicht getestet, ich hab einfach immer den ganzen Code-Block verschoben …

Und noch eine Anmerkung: Deine Lösung funktioniert nur mit nummerierten Kapiteln, aber nicht, wenn man \addchap benutzt. Ich habe sie deswegen wie folgt angepasst:

\makeatletter
 
   \newcounter{chapterID}
   \renewcommand{\thechapterID}{chapID@\alph{chapterID}}
   \preto{\chapter}{\stepcounter{chapterID}}
   \preto{\addchap}{\stepcounter{chapterID}}
 
   \let\chapterhas@original@addcontentsline\addcontentsline
 
   \renewcommand*{\addcontentsline}[1]{%
     \immediate\write\@auxout{\string\chapterhas{\thechapterID}{#1}}%
     \chapterhas@original@addcontentsline{#1}%
   }
 
   \newcommand*{\chapterhas}[2]{%
     \global\@namedef{chapterhas@#1@#2}{true}%
   }
 
   \renewcommand*{\addchaptertocentry}[2]{%
     \addtocentrydefault{chapter}{#1}{#2}%
     \if@chaptertolists
       \doforeachtocfile{%
         \iftocfeature{\@currext}{chapteratlist}{%
           \ifundefinedorrelax{chapterhas@\thechapterID @\@currext}{%
           }{%
             \addxcontentsline{\@currext}{chapteratlist}[{#1}]{#2}%
           }%
         }{}%
       }%
       \@ifundefined{float@addtolists}{}{\scr@float@addtolists@warning}%
     \fi
   }
 
\makeatother

Ist das sinnvoll? Oder habe ich was vergessen, was später vielleicht Probleme machen könnte?

Tobi W_
Grafikdesign und TeX-Beratung

tobiw.de
mail@tobiw.de

Mein Blog: TeX-Beispiel des Monats

Bild von Markus Kohm

Ich selbst würde den zusätzlichen Zähler allerdings schlicht in \addchaptertocentry hochzählen.

Dass meine ursprüngliche Lösung ein Problem mit nicht nummerierten Kapiteln hat, liegt daran, dass ich nummerierte Elemente in nicht nummerierten Kapiteln allgemein für problematisch halte (jedenfalls, solange deren Nummer von der Kapitelnummer abhängt). Deshalb vergesse ich die gerne.

Danke für Deinen Erweiterungsvorschlag. Es gibt sicher immer mal wieder jemanden, der den brauchen kann.

… kommen auch nicht vor. (Finde ich auch unsinnig) – aber die unnumerierten Überschriften landen/landeten trotzdem mit im Abbildungsverzeichnis. Man könnte vielleicht alternativ auf deiner Lösung aufsatteln und bei den nummerierten Abschnitten verbinden, das diese überhaupt einen Eintrag erzeugen. Je nachdem, was weniger aufwändig ist.

Der Nachteil meiner Lösung ist übrigens, dass diese nur funktioniert, wenn alle Kapitel eingebunden werden. E geht nicht, wenn \includeonly benutzt wird, aber das kommt ja für den finalen Satz meistens auch nicht vor und während man am Dokument arbeitet muss das Verzeichnis ja nicht unbedingt stimmen.

Insgesamt wäre es vielleicht ein feines Feature für eine zukünftige Version von KOMA-Script :-)

Tobi W_
Grafikdesign und TeX-Beratung

tobiw.de
mail@tobiw.de

Mein Blog: TeX-Beispiel des Monats

Comments for "Kann man chapteratlists=entry auf Kapitel mit Verzeichniseinträgen beschränken?" abonnieren