インデックス情報を使用して相互参照を生成する

インデックス情報を使用して相互参照を生成する

アイデアは、索引情報を使用して相互参照を自動的に生成することです。索引エントリが 1 ページ以上を参照している場合 (例: 「Smith, John 5, 9」)、索引エントリを作成した場所の余白に、索引エントリと他のページ番号が表示されます (つまり上記の例に従うと、5 ページの余白に「Smith, John 9」と表示されます。

それに応じてパッケージを変更することは可能ですかshowidx?

さらに、このソリューションは およびhyperrefと互換性があるはずですtwosidedが、大きい方の余白は常に右側にあります ( を使用していますtufte-latex)。

ヒントがあればよろしくお願いします。

以下は、私が試した MWE です (役立つかどうかはわかりません)。

%\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}

答え1

「ちょっとした調整」かなり控えめな表現です。makeindex によるファイルの通常の処理の後、 (LaTeX ファイル) または(ファイル) 内の生データとファイル内のフォーマットされたインデックス エントリの.idx関係は失われます。例:\index\indexentry.idx.ind

\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)

生成されたインデックス ファイルからは、 の正確な形式は\index推測することしかできません (例:\index{foobar}および ) \index{foo!bar}。ソート、範囲、カプセル化の指定はなくなります。したがって、生成されたインデックス ファイルの結果は、このようなキーからページ リストへのマッピングになります。例:

foobar  ⇒ 1, \textbf{2}, 3
foo!bar ⇒ 3--7, 10

次のパッケージは、このようなマッピングを生成する makeindex のindexpagelistスタイル ファイルを定義します。indexpagelist.ist

LaTeX レベルに戻って、 に与えられた文字列から、ソート、範囲、およびカプセル化の指定を削除する必要があります\index

複雑さを軽減し、時間を節約するために、引用符とエスケープ文字のサポートは実装していません。また、、actualおよびlevel文字encapはデフォルト値 ( @、、) でのみサポートされます。!|

%%% 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

メインの TeX ファイルへの「調整」はごくわずかで、パッケージをロードするだけで済みます。OT1 エンコーディングの欠陥により、文字はencapem|ダッシュとして表示されるため、私は Latin Modern フォントで T1 フォント エンコーディングを使用しました。

%%% 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}

生のインデックスファイル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}

メインのインデックス ファイルは通常どおり生成されます。

$ makeindex test

インデックスファイルtest.ind:\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}

ページ リスト マッピングを含むファイルは、次のように生成されます。

$ makeindex -s indexpagelist.ist -t test-ipl.ilg -o test.ipl test.idx

便宜上、\immediate\write18パッケージ ファイルに makeindex の両方の呼び出しを追加しました (TeX Live は制限されたシェル エスケープを使用してそれらを実行します)。

ファイルには、test.iplインデックス キーからページ リストへのマッピングが含まれています。

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}

\ipl@animals!dogこれは、 with contentsなどのマクロを定義します1, \textbf{2}, 3。マクロは、\iplMultiPage単一ページのリストと複数ページのリストをより簡単に検出するためのマーカーとして使用されます。

次に、パッケージがフックして\@showidxページ リストを追加します。

インデックス:

索引

ページ1:

ページ1

2ページ:

2ページ

ページ3:

3ページ

関連情報