
Die Idee ist, die Indexinformationen zu verwenden, um automatisch Querverweise zu generieren. Wenn sich ein Indexeintrag auf mehr als eine Seite bezieht (z. B. „Smith, John 5, 9“), dann sollte der Indexeintrag zusammen mit den anderen Seitenzahlen am Rand an der Stelle erscheinen, an der ich den Indexeintrag mache (dh, dem obigen Beispiel folgend, erscheint auf Seite 5 am Rand „Smith, John 9“).
Ist eine showidx
entsprechende Änderung des Pakets möglich?
Darüber hinaus sollte die Lösung mit hyperref
und der Tatsache, dass ich verwende, kompatibel sein twosided
, aber der größere Rand ist immer rechts (ich verwende tufte-latex
).
Danke für alle Hinweise.
Und hier mein Versuch eines MWE (nicht sicher, ob das hilft):
%\documentclass[twoside]{tufte-book}
\documentclass{book}
\usepackage{makeidx,showidx,lipsum}
\makeindex
\begin{document}
John Smith\index{Smith, John}
\lipsum
John Smith\index{Smith, John}
\lipsum
\printindex
\end{document}
Antwort1
Der"kleine Verbesserung"ist eine ziemliche Untertreibung. Nach der üblichen Verarbeitung der .idx
Datei durch makeindex geht der Bezug der Rohdaten darin \index
(LaTeX-Datei) oder \indexentry
( .idx
Datei) zum formatierten Indexeintrag in der .ind
Datei verloren. Beispiel:
\index{foobar} ⇒ \item foobar, ...
\index{foo@foobar} ⇒ \item foobar, ... (sort spec.
\index{foobar|(} ⇒ \item foobar, ... (range spec.)
\index{foobar|textbf} ⇒ \item foobar, \textbf{1} (encap feature)
\index{"f"o"o"b"a"r} ⇒ \item foobar, ... (quote char)
\index{foo!bar} ⇒ \item foo ...\subitem bar (level char)
\index{fooX@foo!barY@b"ar|(emph}
⇒ \item foo ...\subitem bar (sort + level + quote + range + encap)
Aus der generierten Indexdatei \index
kann die genaue Form nur erraten werden (z. B. \index{foobar}
und ) \index{foo!bar}
. Die Spezifikationen für Sort, Range und Encap sind verschwunden. Das Ergebnis der generierten Indexdatei wäre daher eine Zuordnung von solchen Schlüsseln zur Seitenliste, z. B.:
foobar ⇒ 1, \textbf{2}, 3
foo!bar ⇒ 3--7, 10
Das folgende Paket indexpagelist
definiert eine Stildatei indexpagelist.ist
für Makeindex, die eine solche Zuordnung generiert.
Zurück auf der LaTeX-Ebene müssen wir die Sortier-, Bereichs- und Kapselungsspezifikationen aus dem String entfernen, der an übergeben wird \index
.
Um die Komplexität zu reduzieren und Zeit zu sparen, habe ich die Unterstützung für Anführungszeichen und Escape-Zeichen nicht implementiert. Außerdem werden die Zeichen actual
, level
, und encap
nur mit ihren Standardwerten ( @
, !
, |
) unterstützt.
%%% indexpagelist.sty %%%
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{indexpagelist}[2013/07/16 v0.1 Index page list for showidx]
\RequirePackage{filecontents}
\begin{filecontents*}{indexpagelist.ist}
preamble ""
postamble ""
setpage_prefix ""
group_skip ""
headings_flag 0
symhead_negative ""
numhead_negative ""
item_0 "\\iplItemA{"
item_1 "\\iplItemB{"
item_2 "\\iplItemC{"
item_01 "\\iplItemB{"
item_x1 "}\n\\iplItemB{"
item_12 "\\iplItemC{"
item_x2 "}\n\\iplItemC{"
delim_0 "}\n\\iplPageList{"
delim_1 "}\n\\iplPageList{"
delim_2 "}\n\\iplPageList{"
delim_n "\\iplMultiPage, "
delim_r "\\iplMultiPage--"
delim_t "}\n"
line_max 1000
\end{filecontents*}
\immediate\write18{%
makeindex %
-s indexpagelist.ist %
-t \jobname-ipl.ilg %
-o \jobname.ipl %
\jobname.idx%
}
\immediate\write18{makeindex \jobname}% for convenience
\newcommand*{\iplItemA}[1]{%
\def\iplCurrentItemA{#1}%
\@onelevel@sanitize\iplCurrentItemA
\let\iplCurrent\iplCurrentItemA
}
\newcommand*{\iplItemB}[1]{%
\def\iplCurrentItemB{#1}%
\@onelevel@sanitize\iplCurrentItemB
\edef\iplCurrent{\iplCurrentItemA!\iplCurrentItemB}%
}
\newcommand*{\iplItemC}[1]{%
\def\iplCurrentItemC{#1}%
\@onelevel@sanitize\iplCurrentItemC
\edef\iplCurrent{\iplCurrentItemA!\iplCurrentItemB!\iplCurrentItemC}%
}
\newcommand*{\iplPageList}[1]{%
\expandafter\@ipl@PageList#1\iplMultiPage\@nil
}
\newcommand*{\iplMultiPage}{}
\def\@ipl@PageList#1\iplMultiPage#2\@nil{%
\def\@ipl@Temp{#2}%
\ifx\@ipl@Temp\@empty
\else
\expandafter\protected@xdef\csname ipl@\iplCurrent\endcsname{#1#2}%
\fi
}
\InputIfFileExists{\jobname.ipl}{}{}
\newcommand*{\iplGetPageList}[1]{%
\def\@ipl@Temp{#1}%
\@onelevel@sanitize\@ipl@Temp
\let\@ipl@Key\@empty
\expandafter\@ipl@GetPageList@Encap\@ipl@Temp|\@nil
\@ifundefined{ipl@\@ipl@Key}{}{%
, \@nameuse{ipl@\@ipl@Key}%
}%
}
\def\@ipl@GetPageList@Encap#1|#2\@nil{%
\let\@ipl@Key\@empty
\@ipl@GetPageList@Level#1!\@nil
}
\def\@ipl@Temp#1{%
\def\@ipl@GetPageList@Level##1!##2\@nil{%
\@ipl@GetPageList@Sort##1#1\@nil
\def\@ipl@Temp{##2}%
\ifx\@ipl@Temp\@empty
\else
\@ipl@GetPageList@Level##2\@nil
\fi
}%
\def\@ipl@GetPageList@Sort##1#1##2\@nil{%
\def\@ipl@Temp{##2}%
\edef\@ipl@Key{%
\ifx\@ipl@Key\@empty
\else
\@ipl@Key!%
\fi
\ifx\@ipl@Temp\@empty
##1%
\else
\@ipl@RemoveSortChar##2\@nil
\fi
}%
}%
\def\@ipl@RemoveSortChar##1#1\@nil{##1}%
}
\expandafter\@ipl@Temp\string @
% remaining "small tweak" for package showidx
\newcommand*{\iplPatchShowidx}{%
\@ifpackageloaded{showidx}{%
\@ifdefinable{\saved@showidx}{%
\let\saved@showidx\@showidx
\renewcommand*{\@showidx}[1]{%
\saved@showidx{##1\iplGetPageList{##1}}%
}%
}%
\global\let\iplPatchShowidx\relax
}{}%
}
\iplPatchShowidx
\AtBeginDocument{\iplPatchShowidx}
\endinput
Dann ist die "Optimierung" an der TeX-Hauptdatei minimal, es muss nur das Paket geladen werden. Aufgrund von Mängeln in der OT1-Kodierung wird das encap
Zeichen |
als Geviertstrich angezeigt —
, daher habe ich die T1-Schriftkodierung mit Latin Modern-Schriftarten verwendet.
%%% test.tex %%%
\documentclass{book}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{makeidx,showidx,lipsum,indexpagelist}
\makeindex
\begin{document}
John Smith\index{Smith, John}, John Doe\index{Doe, John},
cat\index{animals!cat|(}, dog\index{animals!dog}
\lipsum
John Smith\index{Smith, John}, dog\index{animals!dog|textbf},
Donald E. Knuth\index{Knuth, Donald E.}
\lipsum
cat\index{animals!cat|)}, dog\index{animals!dog},
Donald E. Knuth\index{Knuth, Donald E.}
\newpage
\printindex
\end{document}
Die Rohindexdatei test.idx
:
\indexentry{Smith, John}{1}
\indexentry{Doe, John}{1}
\indexentry{animals!cat|(}{1}
\indexentry{animals!dog}{1}
\indexentry{Smith, John}{2}
\indexentry{animals!dog|textbf}{2}
\indexentry{Knuth, Donald E.}{2}
\indexentry{animals!cat|)}{3}
\indexentry{animals!dog}{3}
\indexentry{Knuth, Donald E.}{3}
Die Hauptindexdatei wird wie gewohnt generiert:
$ makeindex test
Die Indexdatei test.ind
für \printindex
:
\begin{theindex}
\item animals
\subitem cat, 1--3
\subitem dog, 1, \textbf{2}, 3
\indexspace
\item Doe, John, 1
\indexspace
\item Knuth, Donald E., 2, 3
\indexspace
\item Smith, John, 1, 2
\end{theindex}
Die Datei mit den Seitenlistenzuordnungen wird generiert durch:
$ makeindex -s indexpagelist.ist -t test-ipl.ilg -o test.ipl test.idx
Der Einfachheit halber habe ich beide Aufrufe von makeindex über \immediate\write18
in die Paketdatei hinzugefügt (TeX Live führt sie mit eingeschränktem Shell-Escape aus).
Die Datei test.ipl
enthält die Zuordnungen der Indexschlüssel zu ihren Seitenlisten:
iplItemA{animals}
\iplItemB{cat}
\iplPageList{1\iplMultiPage--3}
\iplItemB{dog}
\iplPageList{1\iplMultiPage, \textbf{2}\iplMultiPage, 3}
\iplItemA{Doe, John}
\iplPageList{1}
\iplItemA{Knuth, Donald E.}
\iplPageList{2\iplMultiPage, 3}
\iplItemA{Smith, John}
\iplPageList{1\iplMultiPage, 2}
Damit werden Makros definiert, beispielsweise \ipl@animals!dog
mit Inhalten 1, \textbf{2}, 3
. Makros \iplMultiPage
werden als Markierungen verwendet, um ein- und mehrseitige Listen einfacher zu erkennen.
Anschließend wird das Paket eingehängt, \@showidx
um die Seitenliste hinzuzufügen.
Der Index:
Seite 1:
Seite 2:
Seite 3: