
La idea es utilizar la información del índice para generar automáticamente referencias cruzadas. Si una entrada de índice se refiere a más de una página (por ejemplo, "Smith, Juan 5, 9"), entonces la entrada de índice junto con los otros números de página deberían aparecer en el margen en el lugar donde hago la entrada de índice (es decir, siguiendo el ejemplo anterior, en la página 5 al margen aparece "Smith, John 9").
¿Es posible cambiar el showidx
paquete en consecuencia?
Además, la solución debe ser compatible con hyperref
el hecho de que estoy usando, twosided
pero el margen más grande siempre está a la derecha (estoy usando tufte-latex
).
Gracias por cualquier pista.
Y aquí mi intento de un MWE (no estoy seguro si eso ayuda):
%\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}
Respuesta1
El"pequeño ajuste"es un eufemismo. Después del procesamiento habitual del .idx
archivo por parte de makeindex, la relación de los datos sin procesar dentro \index
(archivo LaTeX) o \indexentry
( .idx
archivo) con la entrada de índice formateada en el .ind
archivo se pierde. Ejemplo:
\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)
A partir del archivo de índice generado, \index
solo se puede adivinar la forma exacta de (por ejemplo, \index{foobar}
y \index{foo!bar}
. Las especificaciones de clasificación, rango y encapsulación desaparecieron. Por lo tanto, el resultado del archivo de índice generado sería una asignación de dichas claves a la lista de páginas, por ejemplo:
foobar ⇒ 1, \textbf{2}, 3
foo!bar ⇒ 3--7, 10
El siguiente paquete indexpagelist
define un archivo de estilo indexpagelist.ist
para makeindex que genera dicho mapeo.
De vuelta al nivel de LaTeX, necesitamos eliminar las especificaciones de clasificación, rango y encapsulación de la cadena, que se le da a \index
.
Para reducir el nivel de complejidad y ahorrar algo de tiempo, no he implementado el soporte para comillas y caracteres de escape. Además actual
, los caracteres level
, y encap
solo se admiten con sus valores predeterminados ( @
, !
, |
).
%%% 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
Entonces, el "ajuste" del archivo TeX principal es pequeño, sólo es necesario cargar el paquete. Debido a deficiencias en la codificación OT1, el encap
carácter |
se muestra como un guión —
, por lo tanto, he utilizado la codificación de fuentes T1 con fuentes latinas modernas.
%%% 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}
El archivo de índice sin formato 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}
El archivo de índice principal se genera como de costumbre:
$ makeindex test
El archivo de índice test.ind
para \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}
El archivo con las asignaciones de la lista de páginas se genera mediante:
$ makeindex -s indexpagelist.ist -t test-ipl.ilg -o test.ipl test.idx
Para mayor comodidad, agregué ambas llamadas de makeindex vía \immediate\write18
en el archivo del paquete (TeX Live las ejecuta con escape de shell restringido).
El archivo test.ipl
contiene las asignaciones de las claves de índice a sus listas de páginas:
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}
Eso define macros como \ipl@animals!dog
con contenidos 1, \textbf{2}, 3
. La macro \iplMultiPage
se utiliza como marcador para detectar listas de una o varias páginas más fácilmente.
Luego, el paquete se conecta \@showidx
para agregar la lista de páginas.
El índice:
Página 1:
Página 2:
Página 3: