Sie sind hier

Wo auf der Seite wurde der Indexeintrag erzeugt?

Auf dem gestrigen TeX-Stammtisch in Ladenburg – kurioser Weise findet der Heidelberger TeX-Stammtisch seit einigen Jahren in meiner Nachbargemeinde statt – wurde mir eine schöne, alte Lateinische Grammatik vorgelegt. Schön daran war vor allem der Index. Dort waren bei den Seitenzahlen noch kleine hochgestellte Zahlen, die angaben, ob der entsprechende Indexeintrag im ersten, zweiten, dritten oder vierten Viertel der Seite erstellt wurde. Dadurch wird die Suche auf der Seite tatsächlich erleichtert. Wenn man bedenkt, dass vor 100  Jahren der gesamte Index noch von Hand erstellt wurde, kann man sich vorstellen, was das für eine Arbeit war.

Die Frage, die sich daran anschloss war klar: Kann man das auch mit TeX machen? Meine sofortige Antwort: Klar. Schätzungsweise eine Viertelstunde später hatte ich dann eine Lösung anzubieten:

\documentclass[ngerman]{scrartcl}
\usepackage{makeidx,babel,blindtext}\makeindex
 
\makeatletter
% Definition auf latex.ltx geklaut und etwas verändert:
\def\@wrindex#1{%
  \pdfsavepos
   \protected@write\@indexfile{}%
      {\string\indexentry{#1|pmark{\noexpand\the\pdflastypos}}{\thepage}}%
 \endgroup
 \@esphack}
% zusätzlich:
\newcommand*{\pmark}[2]{%
  #2\ifnum #1>\value{Grenze}\textsuperscript{1}\else\textsuperscript{2}\fi}
\newcounter{Grenze}
\setlength{\@tempdima}{.5\paperheight}
\setcounter{Grenze}{\@tempdima}
\makeatother
 
\usepackage{eso-pic}
 
\begin{document}
\AddToShipoutPicture{%
  \AtPageLowerLeft{%
    \setlength{\unitlength}{1sp}%
    \put(0,\value{Grenze}){\line(1,0){\LenToUnit{\paperwidth}}}%
  }%
}
\textbf{A}\marginpar{A}\index{TestA}\blindtext
\textbf{B}\marginpar{B}\index{testB}\blindtext
\textbf{C}\marginpar{C}\index{TestC}\blindtext
\textbf{D}\marginpar{D}\index{testD}\blindtext
\textbf{E}\marginpar{E}\index{TestE}\blindtext
\textbf{F}\marginpar{F}\index{testF}\blindtext
\textbf{G}\marginpar{G}\index{TestG}\blindtext
\textbf{H}\marginpar{H}\index{testH}\blindtext
\textbf{A}\marginpar{A}\index{TestA}\blindtext
\printindex
\end{document}

Im Unterschied zu der Anforderung unterscheidet diese schnelle Lösung nur die obere und untere Hälfte der Seite (nicht des Satzspiegels). Gegenüber der Lösung von gestern Abend ist hinzu gekommen, dass die Grenze nicht fest angegeben ist, sondern – wenn auch noch sehr primitiv – ausgerechnet wird, und via eso-pic veranschaulicht wird, damit man beurteilen kann, ob die Einträge auch korrekt eingeordnet sind.

Um das Ergebnis sehen zu können, benötigt man einen pdflatex-Lauf (egal ob im DVI- oder PDF-Modus oder draft-Modus), einen MakeIndex-Lauf und noch einen pdflatex-Lauf. Wie man am letzten Eintrag sieht, funktioniert das auch noch, wenn mehrere Einträge für einen Begriff erstellt werden. Nachteil der Lösung ist jedoch, dass hier mit der Seitenzahl-Formatierung gearbeitet wird, um die Information über die vertikale Position in die idx-Datei zu schreiben. Das bedeutet, dass Einträge wie \index{foo|textbf} nicht mehr funktionieren. Ebenso ist es mit der hyperpage-Formatierung durch hyperref. Um diese Features wieder zu aktivieren, müsste man obige Lösung in ähnlicher Weise erweitern, wie das bei neueren hyperref-Versionen gemacht wird. Lösbar ist dies.

Natürlich hätte ich auch folgende Umdefinition verwenden können:

\def\@wrindex#1{%
  \pdfsavepos
   \protected@write\@indexfile{}%
      {\string\indexentry{#1}{\thepage\string\pmark{\noexpand\the\pdflastypos}}}%
 \endgroup
 \@esphack}
\newcommand*{\pmark}[1]{%
  \ifnum #1>\value{Grenze}\textsuperscript{1}\else\textsuperscript{2}\fi}

Dabei wäre die Information über die vertikale Position dann direkt an die Seitenzahl gehängt. Leider kommt MakeIndex mit dieser Zusatzinformation an den Seitenzahlen überhaupt nicht klar. Vielleicht wäre dies jedoch eine Möglichkeit zur Verwendung mit Xindy. Eine entsprechende Xindy-Lösung zu präsentieren überlasse ich den Xindy-Cracks.

Das mein Paket luaindex keine Seitenzahlen sortiert, sondern davon ausgeht, dass die Seitenzahlen in der richtigen Reihenfolge in den Index geschrieben werden (man darf dann natürlich nicht mit Quick-Sort sortieren), müsste eine Erweiterung dafür ebenfalls eher einfach sein.

Natürlich kam gestern Abend auch gleich die Frage auf, ob man statt einer reinen vertikalen Teilung der Seite nicht ein richtiges Raster darüber legen könnte. Wenn man obige Lösung um \pdflastxpos erweitert und die Fallunterscheidung innerhalb von \pmark weiter verfeinert, kann man auch das ohne größere Probleme erreichen.

Wie man sieht, war das auf den erste Blick mal wieder eine etwas ungewöhnliche Frage. Trotzdem gehört sie zu den Kuriositäten, die mit TeX-Mitteln lösbar sind.