Verwenden von Indexinformationen zum Generieren von Querverweisen

Verwenden von Indexinformationen zum Generieren von Querverweisen

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 showidxentsprechende Änderung des Pakets möglich?

Darüber hinaus sollte die Lösung mit hyperrefund 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 .idxDatei durch makeindex geht der Bezug der Rohdaten darin \index(LaTeX-Datei) oder \indexentry( .idxDatei) zum formatierten Indexeintrag in der .indDatei 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 \indexkann 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 indexpagelistdefiniert eine Stildatei indexpagelist.istfü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 encapnur 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 encapZeichen |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.indfü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\write18in die Paketdatei hinzugefügt (TeX Live führt sie mit eingeschränktem Shell-Escape aus).

Die Datei test.iplenthä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!dogmit Inhalten 1, \textbf{2}, 3. Makros \iplMultiPagewerden als Markierungen verwendet, um ein- und mehrseitige Listen einfacher zu erkennen.

Anschließend wird das Paket eingehängt, \@showidxum die Seitenliste hinzuzufügen.

Der Index:

Index

Seite 1:

Seite 1

Seite 2:

Seite 2

Seite 3:

Seite 3

verwandte Informationen