Arbeiten mit großen Dokumenten

Niemand schreibt eine 300-seitige Dissertation als eine einzige .tex-Datei. Die Antwort von LaTeX auf ein großes Dokument besteht aus drei Befehlen – \input, \include und \includeonly –, die das Projekt in eine Datei pro Kapitel zerlegen und es erlauben, nur das gerade bearbeitete Kapitel neu zu setzen. Interessant ist die Mechanik darunter: Nach jedem eingebundenen Kapitel schreibt LaTeX einen Checkpoint in dessen .aux-Datei und hält darin den Stand sämtlicher Zähler fest, die Seitenzahl eingeschlossen. Deshalb bringt ein übersprungenes Kapitel die Nummerierung der folgenden nicht durcheinander. Diese Seite beginnt beim Verzeichnisaufbau, führt durch die Falle mit den relativen Pfaden, in die fast alle einmal tappen, und endet bei den Fehlern, die erst ein vollständiger Build zutage fördert.

Wie ein großes LaTeX-Projekt aufgebaut wird

Am Anfang steht eine einzige Regel: Die Hauptdatei enthält keinen Fließtext. In main.tex stehen die Dokumentklasse, die Präambel und eine Liste von \include-Zeilen, sonst nichts. Kapitel liegen in chapters/, Bilder in figures/, die Literaturdatenbank in bib/. Damit liest sich die Hauptdatei wie ein Inhaltsverzeichnis, und das Umstellen von Kapiteln wird zum Umstellen von Zeilen. Dieselbe Eigenschaft macht gemeinsames Schreiben erträglich: Alle bearbeiten verschiedene Dateien, Konflikte bleiben selten, und ein Git-Diff beschränkt sich auf das eine geänderte Kapitel. Wächst die Präambel, wandert sie nach preamble.tex und wird mit \input{preamble} geladen – eine Präambel wird nie mit \include eingebunden, aus einem Grund, den der nächste Abschnitt zeigt.

text
thesis/
  main.tex
  preamble.tex          % packages and settings
  chapters/01-intro.tex  02-method.tex  03-results.tex
  figures/              % all images, next to main.tex
  bib/refs.bib
latex
% main.tex -- no prose here, just structure
\documentclass[11pt,a4paper]{report}
\input{preamble}

\begin{document}
\tableofcontents

\include{chapters/01-intro}
\include{chapters/02-method}
\include{chapters/03-results}

\bibliographystyle{plain}
\bibliography{bib/refs}
\end{document}

Durchnummerierte Dateinamen – 01-intro.tex, 02-method.tex – sorgen dafür, dass die Dateiliste des Editors der Lesereihenfolge entspricht. Die zweite lohnende Zeile ist % !TEX root = ../main.tex am Kopf jeder Kapiteldatei. TeXShop, TeXstudio, VS Code und die meisten anderen Editoren lesen sie und bauen main.tex, auch wenn gerade ein Kapitel im Vordergrund steht. Ohne sie kompiliert man früher oder später ein Kapitel allein und stößt auf ! LaTeX Error: Missing \begin{document}. – die zwangsläufige Folge einer Datei ohne \documentclass, die trotzdem jedes Mal einige Minuten Ratlosigkeit kostet.

Der Unterschied zwischen \input und \include

\input{f} fügt den Inhalt von f.tex an dieser Stelle ein und tut sonst nichts. \include{f} arbeitet auf Kapitelebene: Davor und danach steht ein \clearpage, und – das ist der eigentliche Punkt – es öffnet eine eigene Datei f.aux und lenkt die Hilfsausgaben dorthin um. Diese .aux je Kapitel ist der ganze Daseinsgrund von \include. Seitenzahlen, Verweismarken und Inhaltsverzeichniszeilen werden kapitelweise abgelegt, sodass sich beim späteren Überspringen genau die Angaben dieses Kapitels aus dem vorigen Lauf zurücklesen lassen. \input hinterlässt dagegen keinerlei Spur einer Dateigrenze und ist damit das richtige Mittel für alles unterhalb der Kapitelebene: das Laden der Präambel, gemeinsame Makros, den Inhalt einer Tabelle, wiederkehrende Textbausteine.

BefehlWirkungSeitenumbruchSchachtelbar
\inputfügt den Inhalt einer .tex-Datei an Ort und Stelle einkeinerja
\includebindet ein Kapitel mit eigener .aux ein\clearpage davor und danachnein
\includeonlynur in der Präambel; schränkt die bearbeiteten \include ein
\subfileaus subfiles; der Teil lässt sich auch allein setzenkeinerja
\subimportaus import; relative Pfade darin gelten ab jenem Ordnerkeinerja

Die rechte Spalte enthält den folgenreichsten Unterschied. Ein \include innerhalb einer selbst eingebundenen Datei bricht den Lauf mit ! LaTeX Error: \include cannot be nested. ab. Das wirkt willkürlich, ist aus der Implementierung heraus aber zwingend: Der Kernel hält genau einen Ausgabestrom für die .aux eines Kapitels bereit, ein inneres \include hätte also keinen Ort für seine eigene. Wer ein Kapitel weiter unterteilen möchte, ruft die Teile aus der Kapiteldatei heraus mit \input{chapters/02-method/setup} auf. Und noch eine Folge: In die Präambel gehört \include ebenfalls nicht, dort erscheint die Warnung \include should only be used after \begin{document}. Genau deshalb wird eine Präambel mit \input geladen.

Eine weitere Asymmetrie kostet still und leise. \input{chapters/ch9} auf eine nicht vorhandene Datei bricht mit ! LaTeX Error: File ... not found. ab, während \include{chapters/ch9} in derselben Lage nur No file chapters/ch9.tex. ins Log schreibt und weiterläuft, als sei nichts geschehen. Ein Tippfehler in einem \include erzeugt also keinen Fehler, sondern ein PDF, in dem ein ganzes Kapitel fehlt. Nach dem Umbenennen eines Kapitels sollte die Suche nach No file im Log zur Gewohnheit werden.

Mit \includeonly nur ein Kapitel bauen – warum die Seitenzahlen stimmen

Ein \includeonly{chapters/02-method} in der Präambel verarbeitet genau dieses eine \include und überspringt den Rest. Ein Vollbuild, der Minuten dauerte, ist in Sekunden fertig – und Seitenzahlen wie Querverweise der ausgelassenen Kapitel bleiben korrekt. Der Kniff besteht aus zwei Teilen. Erstens schreibt LaTeX auch für ein übersprungenes Kapitel die Zeile \@input{chapters/01-intro.aux} in main.aux; die .aux des vorigen Laufs wird also stets zurückgelesen, und die dort abgelegten \newlabel-Einträge halten \ref funktionsfähig. Zweitens hängt LaTeX am Ende jedes Kapitels den aktuellen Stand sämtlicher Zähler an dessen .aux an. Die Kernel-Quellen nennen diesen Eintrag wörtlich einen Checkpoint; beim Überspringen wird er einfach abgespielt, und Seiten-, Kapitel- und Abbildungszähler springen genau dorthin, wo das Kapitel geendet hatte.

latex
% in the preamble of main.tex
\includeonly{chapters/02-method}
% several at once, comma separated, no spaces needed around the commas
% \includeonly{chapters/02-method,chapters/03-results}
text
% chapters/01-intro.aux, written by the last full build (trimmed)
\newlabel{ch:intro}{{1}{2}{}{}{}}
\@setckpt{chapters/01-intro}{
\setcounter{page}{5}
\setcounter{chapter}{1}
\setcounter{figure}{0}
}

Dank dieser beiden Teile kommt das PDF eines Teilbuilds dem Endergebnis näher als erwartet. Selbst das Inhaltsverzeichnis bleibt intakt: Die .toc wird am Ende des Laufs aus den .aux-Dateien geschrieben, sodass ein übersprungenes Kapitel weiterhin mit seiner Seitenzahl vom letzten Mal im Verzeichnis steht. Eine Voraussetzung bleibt aber bestehen: zuerst einmal vollständig bauen. Wird ein Kapitel übersprungen, dessen .aux noch gar nicht existiert, bleiben seine Verweise ??, und im Log steht LaTeX Warning: There were undefined references. Zwei Details lohnen sich noch: \include und \includeonly streichen vor dem Namensvergleich ein abschließendes .tex, weshalb auch \includeonly{chapters/02-method.tex} passt; und \includeonly gehört ausschließlich in die Präambel – nach \begin{document} folgt ! LaTeX Error: Can be used only in preamble. Vor der Abgabe wird die Zeile entfernt und alles neu gebaut. Das PDF eines Teilbuilds ist eine Arbeitsnäherung, nicht das fertige Dokument.

Warum relative Pfade von der Hauptdatei aus aufgelöst werden

Weder \input noch \include wechselt das Arbeitsverzeichnis. TeX löst jeden relativen Pfad gegen das Arbeitsverzeichnis des Laufs auf, und das ist normalerweise der Ort von main.tex. Ein Bildpfad in chapters/02-method.tex muss also so geschrieben werden, wie er von main.tex aus aussieht. \includegraphics{figures/plot} funktioniert; \includegraphics{../figures/plot}, aus dem Ordner des Kapitels betrachtet völlig richtig, scheitert mit ! LaTeX Error: File ... not found. An dieser Stelle entsteht der Eindruck, das Verschieben eines Kapitels habe seine Abbildungen zerstört. Verschoben wurde jedoch nur die Datei; der Bezugspunkt blieb main.tex.

Es gibt zwei Abhilfen. Die übliche ist \graphicspath aus graphicx, das die zu durchsuchenden Ordner registriert. Seine Syntax ist eigenwillig und einprägenswert: jeder Ordner steht in einem eigenen Klammerpaar, und jeder braucht einen abschließenden Schrägstrich\graphicspath{{figures/}{chapters/figures/}}. Danach genügt in jedem Kapitel \includegraphics{plot}, ohne Ordner und ohne Dateiendung. Als Trenner dienen auch unter Windows Vorwärtsschrägstriche. Die zweite Abhilfe passt zu Projekten, in denen jedes Kapitel seine eigenen Abbildungen mitbringt: \subimport{chapters/}{02-method} aus dem Paket import lässt relative Pfade in diesem Kapitel ab chapters/ gelten. Soll ein Kapitel später in ein anderes Projekt wandern, ist das die portablere Lösung.

latex
% option A -- one shared figure folder, registered once in the preamble
\usepackage{graphicx}
\graphicspath{{figures/}{chapters/figures/}}   % braces per folder, trailing slash
% then, anywhere in any chapter:
%   \includegraphics[width=0.8\linewidth]{plot}

% option B -- each chapter carries its own figures
\usepackage{import}
% in main.tex, instead of \include{chapters/02-method}:
\subimport{chapters/}{02-method}   % paths inside resolve from chapters/

Ein Kapitel einzeln setzen: subfiles und standalone

\includeonly dient dazu, ein Kapitel innerhalb des Ganzen schnell zu bauen, nicht dazu, ein Kapitel in ein eigenständiges PDF zu verwandeln. Soll das Kapitel selbst ein Dokument sein, hilft das Paket subfiles. Steht am Kopf der Kapiteldatei \documentclass[../main]{subfiles}, lässt sie sich allein übersetzen und leiht sich dabei die Präambel der Hauptdatei, während diese das Kapitel weiterhin mit \subfile{chapters/02-method} an seinen Platz setzt. Für Abbildungen gibt es dasselbe Prinzip: Eine gegen die Klasse standalone geschriebene TikZ-Zeichnung ergibt für sich genommen ein einseitiges PDF, und das Hauptdokument bindet sie mit \usepackage{standalone} und einem gewöhnlichen \input ein.

latex
% main.tex
\documentclass{report}
\usepackage{graphicx}
\usepackage{subfiles}
\begin{document}
\subfile{chapters/02-method}
\end{document}

% chapters/02-method.tex -- also compiles on its own
\documentclass[../main]{subfiles}
\begin{document}
\chapter{Method}
This chapter builds alone and inside the book.
\end{document}

Der Preis ist ebenso klar. Ein allein gebautes Kapitel beginnt auf Seite 1 und sieht keine \labels aus anderen Kapiteln, weshalb \ref ?? liefert und das Log LaTeX Warning: There were undefined references. meldet. Die Wahl folgt dem Zweck: \includeonly, wenn Tempo bei erhaltener Gesamtnummerierung zählt, subfiles, wenn der Betreuung „Kapitel 3“ als eigene Datei übergeben werden soll. Eine Arbeit, die als ein PDF eingereicht wird, fährt mit \include und \includeonly am besten; ein Projekt, dessen Kapitel auch als Aufsätze, Vorlesungsskripte oder Handouts bestehen, mit subfiles. Beides im selben Projekt zu mischen bedeutet doppelte Präambelpflege und lohnt sich selten.

Schnellere Testbuilds mit der Option draft

\documentclass[draft]{report} erledigt beim Testbau großer Dokumente zwei Aufgaben. Erstens markiert es jede Zeile, die über den Satzspiegel hinausragt – eine overfull hbox – mit einem schwarzen Balken am Rand, sodass schlechte Umbrüche sofort auffallen. Zweitens rendert es Bilder nicht mehr, sondern setzt einen Rahmen mit dem Dateinamen ein; da die Bildverarbeitung entfällt, wird der Lauf spürbar leichter, und je mehr Abbildungen ein Kapitel enthält, desto stärker wirkt das. Wer nur die Bilder betreffen will, schränkt mit \usepackage[draft]{graphicx} ein. Umgekehrt liefert \overfullrule=5pt allein die Balken, während die Bilder sichtbar bleiben. Für den echten Build wird draft wieder zu final.

latex
\documentclass[draft]{report}   % skip images, show overfull rules
% scope it to images only:
% \usepackage[draft]{graphicx}
% keep images, still flag overfull lines:
% \overfullrule=5pt

Wenn ein Kapitel allein durchläuft, das ganze Dokument aber nicht

Die Ursache ist fast immer eine von vieren. (1) Das Kapitel verwendet ein Paket oder ein Makro, das nur in seiner eigenen Präambel steht – allein läuft es, im Buch folgt ! Undefined control sequence. (2) Zwei Kapitel definieren dasselbe \label, es erscheint LaTeX Warning: Label ... multiply defined. und ein Verweis zeigt still auf die falsche Stelle. (3) Ein relativer Pfad, geschrieben aus Sicht des Kapitelordners – die Falle des vorigen Abschnitts. (4) Eine veraltete .aux. Fall (2) ist der gefährlichste, weil er keine Fehlermeldung erzeugt, sondern eine falsche Nummer druckt; ein Kapitelpräfix im Label, etwa \label{fig:method-setup}, schließt ihn strukturell aus.

Auch wie eine .aux verdirbt, lohnt sich zu wissen. Ein abgebrochener Lauf oder ein umbenanntes Kapitel kann eine halb geschriebene .aux hinterlassen. Der nächste Lauf liest sie und scheitert an einer Zeile, die mit der letzten Änderung nichts zu tun hat. Tritt ein Fehler an einer nicht angerührten Stelle auf, werden zuerst die erzeugten Dateien gelöscht. Von Hand sind das .aux, .toc, .lof, .lot und .out – wobei die kapitelweisen .aux-Dateien zusätzlich in chapters/ liegen. Mit latexmk räumt latexmk -c die Zwischendateien weg und latexmk -C zusätzlich die Ausgabe. Danach zweimal bauen, damit sich Verweise und Inhaltsverzeichnis wieder einpendeln.

  • Vor einer Sitzung mit \includeonly einmal vollständig bauen, damit jedes Kapitel eine frische .aux besitzt.
  • Schwere TikZ-Abbildungen externalisieren oder vorab als PDF rendern und mit \includegraphics einbinden.
  • % !TEX root = ../main.tex an den Kopf jeder Kapiteldatei setzen, damit stets das Hauptdokument gebaut wird.
  • Ohne import gehören figures/ und bib/ neben main.tex, nicht neben die Kapitel.
  • Labels mit dem Kapitel präfigieren, etwa fig:method-setup, damit multiply defined gar nicht erst auftreten kann.
  • Vor der Abgabe \includeonly und draft entfernen, erzeugte Dateien löschen, sauber bauen und das Log bis zum Ende nach Warning und No file durchsehen.

Zum Schluss ein Wort über Rhythmus. Lange Dokumente gelingen weder denen, die immer alles bauen, noch denen, die stets nur ein Fragment bauen, sondern denen, die abwechseln. Im Alltag wird mit \includeonly am aktuellen Kapitel gearbeitet, während latexmk das Neubauen beim Speichern übernimmt. Zu Meilensteinen fallen \includeonly und draft weg, das Ganze wird gebaut, und Nummerierung, Inhaltsverzeichnis, Index und Bibliografie dürfen sich einpendeln. Vor der Abgabe werden die erzeugten Dateien gelöscht, sauber gebaut und das Log bis zum Ende gelesen. Das Aufteilen wirkt wie ein Trick für Tempo, ist aber ebenso einer für Gelassenheit: Es macht das korrekte Neubauen des Ganzen an jedem beliebigen Tag billig.