Index I: Anlegen und Verarbeiten

Diesen und nächsten Monat werden wir uns mit der Indexerstellung in befassen. Dabei geht es in diesem Beispiel zunächst nur darum, wie man die Einträge erzeugt und daraus einen sortierten Index generiert. Dazu werden wir xindy und das Paket imakeidx verwenden.

Im nächsten Monat folgt dann ein Beispiel über individuelle Anpassungen der Darstellung des Index.

Grundlagen

Bevor wir uns den Code ansehen, müssen wir uns kurz klar machen, wie die Indexerstellung in grundsätzlich abläuft:

  1. In der .tex-Datei werden an geeigneten Stellen die Indexeinträge markiert.
  2. Beim Kompilieren werden diese Einträge unsortiert (roh) in eine .idx-Datei geschrieben.
  3. Aus diesem Rohindex muss mit einem Hilfsprogramm (texindy oder makeindex) der sortierte Index erzeugt werden; das Ergebnis ist eine .ind-Datei.
  4. Beim nächsten Kompilieren der Hauptdatei wird die Index-Datei eingelesen und der Index ausgegeben.

Für die Indexerstellung sind also zwei Hilfsdateien nötig, die nicht direkt von verarbeitet werden können. Und der Index ist immer einen Kompilierungsvorgang „hinterher“ – genau wie wir es von Querverweisen und Verzeichnissen kennen, die ebenfalls diverse Hilfsdateien benötigen.

Das schöne ist, dass man sich als Autor nicht darum kümmern muss, wie oft ein Eintrag möglicherweise auf eine Seite verweist, denn doppelt vorkommende Seitenzahlen werden automatisch aussortiert und Seitenzahlen folgten (bspw. 4, 5, 6, 7, 8) zu Bereichen (4–8) zusammengefasst.

xindy oder texindy?

xindyist ein Indexprozessor, der im Grunde beliebige Eingangsformate verarbeiten und Ausgangsformate erzeugen kann. texindy ist ein davon abgeleiteter und explizit für die Zusammenarbeit mit gedachter Prozessor. Im Folgenden werden beide Wörter quasi synonym gebraucht; man muss sich nur merken, dass die Verarbeitung des Index hier immer mit dem Programm texindy erfolgt.

Datei index.tex

Wie jedes Beispiel beginnt auch dieses mit dem Laden der Dokumentklasse (FAQ 2) und ein paar Standardpaketen (FAQs 3, 4, 5)

\documentclass[ngerman]{scrartcl}
 
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
 
\usepackage{babel}

Dieses Paket brauchen wir nur, um im Beispiel Blindtext zu erzeugen, so dass die Indexeinträge nicht alle auf einer Seite stehen. Der dafür genutzten Befehl \lipsum bleibt im Folgenden unkommentiert.

\usepackage{lipsum}

Für die Erstellung des Index laden wir das Paket imakeidx mit der Option xindy. Das Paket sorgt dafür, dass die oben besprochene Verarbeitung des Index automatisch im Hintergrund erledigt wird. Dazu ist es allerdings nötig, dass shell-escape/Write18 aktiv ist (FAQ 16). Ist das nicht möglich, muss man die Verarbeitung des Index manuell anstoßen (s. u.).

\usepackage[xindy]{imakeidx}

Da hyperref nicht ohne Weiteres mit xindy zusammenarbeitet, müssen wir seine Index-Funktionen mit der Option hyperindex explizit deaktivieren. Wie man dennoch klickbare Seitenzahlen im Index erhält, besprechen wir im nächsten Monat.

\usepackage[hyperindex=false]{hyperref}

Damit der Rohindex (.idx) überhaupt geschrieben wird, müssen wir an dieser Stelle (= irgendwo vor \begin{document} = in der Präambel) den Befehl \makeindex aufrufen. Dabei geben wir die Option intoc an, damit der Index im Inhaltsverzeichnis erscheint.

\makeindex[intoc]
\begin{document}

Einträge und Untereinträge

Einen Indexeintrag erzeugt man mit dem Befehl \index. „merkt“ sich dann, dass auf dieser Seite etwas zum Thema „Eintrag“ steht.

Hier geht es um einen Eintrag\index{Eintrag}
\lipsum

Untereinträge werden erzeugt, in dem sie mit einem ! dem übergeordneten angehängt werden. Das funktioniert auch, wenn im Dokument nie der Haupteintrag (\index{Haupteintrag}) indiziert wurde.

xindy erlaubt dabei beliebig viele Ebenen, ist aber ab Werk nur für max. zwei Unterebenen vorbereitet.

makeindex erlaubt generell nur max. zwei Unterebenen.

Hier um einen Untereintrag\index{Eintrag!Untereintrag}
Hier um einen Untereintrag\index{Haupteintrag!Untereintrag}
\lipsum
 
Und hier um einen Untereintrag 2. Ebene\index{Eintrag!Untereintrag!zweite Ebene}
\lipsum

Um im Index ganze Bereiche zu vermerken, markiert man den Bereichsbeginn mit |( und das Ende mit |) jeweils an den Eintrag angehängt.

Hier beginnt ein Bereich über Licht\index{Licht|(}
\lipsum\lipsum\lipsum
Und hier endet der Bereich wieder\index{Licht|)}

Einträge mit Attributen

Um auf eine Stelle besonders hinzuweisen, ist es möglich die entsprechende Seitenzahl im Index bspw. fett hervorzuheben. Dazu führt xindy das Konzept der Attribute ein: Jedem Eintrag kann entweder kein oder genau ein Attribut zugewiesen werden. Welche Darstellung ein Attribut verursacht entscheidet der Index-Stil (damit befassen wir uns im nächsten Monat genauer).

Im Standard-Stil sind die beiden Attribute textbf und textit vorgesehen, die eine fette bzw. kursive Seitenzahl erzeugen. Das Attribut wird mit | and den Eintrag angehängt.

Stellen mit formatierten Seitenzahlen\index{Eintrag|textbf}
\lipsum
Hier soll die Seitenzahl kursiv hervorgehoben werden\index{Eintrag|textit}
\lipsum

Sollen ganze Bereiche mit einem Attribut versehen werden, muss das Attribut sowohl am Bereichsbeginn als auch am -ende vermerkt werden.

Hier beginnt ein Bereich über Licht\index{Licht|(textbf}
\lipsum\lipsum\lipsum
\textbf{Und hier endet der Bereich wieder}\index{Licht|)textbf}

Hinweis: Dass die Attribute hier heißen wie -Befehle, ist so zu sagen Zufall! Für ein richtiges Dokument wäre es wesentlich sinnvoller, eigene Attribute zu definieren, deren Namen sich auf die Bedeutung und nicht auf die Darstellung beziehen (bspw. \index{Licht|important}). Wie das geht wird auch im nächsten Monat behandelt.

Korrekte Sortierung?

Um zu prüfen, ob xindy richtig sortiert, notieren wir hier ein paar entsprechende Testeinträge.

Werden diese Einträge richtig sortiert?
\index{Affe}
\index{Äffchen}
\index{Aerodynamik}
\index{$a^2+b^2=c^2$}
\index{3D-Brille}
\index{\%-Werte}
\index{Ohm, Georg Simon}
\index{Ørsted, Hans Christian}
\index{Oxford}
\index{\textsc{öpnv}}
\index{Wellen!Elektromagnetische}
\index{Wellen!-berg}
\index{Wellen!-tal}
\index{Wellen!Teilchen-}
\index{\verb+\tableofcontents+}
\lipsum

Wie wir sehen, werden alle Einträge korrekt einsortiert:

  • Umlaute gemäß Duden: ä = ae etc.
  • Bei Formeln werden nur die reinen Buchstaben interpretiert, hier abc
  • Zahlen und Symbole erscheinen als erste Gruppe im Index
  • -Befehle werden ignoriert
  • - wird ebenfalls ignoriert

Mit makeindex hätten wir für die meisten dieser Einträge manuell die Sortierung vorgeben müssen.

Sollte die automatische Sortierung einmal nicht das gewünschte Ergebnis bringen, kann man mit der Syntax Sortierung@Eintrag nachhelfen. Dann muss aber jeder entsprechende Eintrag so notiert werden!

Alternativ dazu kann man in einer eigenen Stil-Datei benutzerdefinierte Sortierregeln ergänzen.

Eintrag mit manueller Sortierung\index{a-Strahlung@$\alpha$-Strahlung}
\lipsum

Sonderzeichen

Wir haben gesehen, das einige Zeichen eine spezielle Bedeutung haben. Um diese im Index darzustellen, müssen sie mit vorangestelltem "-Symbol escaped werden.

Spezielle Sonderzeichen
\index{"! (Ausrufezeichen)}
\index{"@ (Klammeraffe)}
\index{"| (Pipe)}
\index{"" (Ersatzanführungszeichen)}

Hier steht ganz bewusst Ersatzanführungszeichen, denn das "-Zeichen ist ein Notbehelf aus Schreibmaschinen-Tagen, der sowohl die Anführungszeichen als auch das Zollzeichen ersetzte. Auch wenn sich die Verwendung dieses Zeichens wohl leider nicht mehr unterbinden lässt: Die korrekten Formen im Deutschen sind „diese“ oder »diese«, im Englischen “diese”!

Das ist selbst dann der Fall, wenn diese Zeichen Teil von Verbatim-Text sind.

\index{\verb+\+ (Backslash)}
\index{\verb+"\"|+ (Symbole in Code)}
\index{\verb+""+ (Symbole in Code)}
\lipsum

Verweise auf andere Einträge

Mit den Schlüsselwörtern see und seealso ist es Möglich einen Eintrag, auf einen anderen verweisen zu lassen. Der Übersichtlichkeit halber ist es empfehlenswert, diese Einträge an einer Stelle (bspw. direkt vor der Ausgabe des Index) zu sammeln; sie sind ja ohnehin keiner bestimmten Seite zugeordnet.

Verweise auf andere Einträge (an einer Stelle im Dokument sammeln!)
\index{Prozent-Werte|see{\%-Werte}}
\index{Pythagoras, Satz von|see{$a^2+b^2=c^2$}}
\index{Satz von Pythagoras|see{$a^2+b^2=c^2$}}
\index{Licht|seealso{Wellen!Elektromagnetische}}

Index ausgeben

Um den Index auszugeben nutzen wir einfach den Befehl \printindex.

\printindex
\end{document}

Mögliche Probleme

Zuletzt sei noch auf ein paar mögliche Probleme hingewiesen …

Schlechte Umbrüche im Index

Wie wir im Beispiel sehen, fällt der Spaltenumbruch genau zwischen den Eintrag „Haupteintrag“ und den zugehörigen Untereintrag. Eine mögliche Lösung dafür besprechen wir im nächsten Monat.

Unerwartete Ergebnisse im Index

Wenn der Index nicht ausgegeben wird, wie erwartet, kann es sein, dass die Einträge falsch eingeben wurden und folglich nicht korrekt verarbeitet werden können. Um den Fehler einzugrenzen sollte man einen Blick in die Konsolen-Ausgabe (des Editors) zu werfen. Dort werden auch die Meldungen von texindy ausgegeben.

Konsolen-Ausgabe-Fenster von TeXstudio

Die relevanten Ausgaben beginnen mit Reading indexstyle... und enden, sofern es keine schwerwiegenden Probleme gab, mit Markup written into file "./Dateiname.ind".

Hier wird übrigens auch vermerkt, wenn das Ziel eines see-Eintrages nicht exsitiert.

Leere Indexeinträge

Die etwas kryptische Meldung ERROR: CHAR: index 0 should be less than the length of the string erhält man, wenn das Dokument einen leeren Indexeintrag (\index{}) enthält.

Index manuell kompilieren

Wer den Index nicht mit den Funktionen von imakeidx automatisiert verarbeiten kann oder will, kann die .idx-Datei mit dem Befehl

texindy Dateiname.idx

übersetzen, bzw. seinen Editor entsprechend auf diesen Befehl einrichten.