索引中的列表和关键字

索引中的列表和关键字

listings包允许对列表中关键字的出现进行索引,例如类似于以下 MWE:

\documentclass{article}
\usepackage[T1]{fontenc}

\usepackage{imakeidx}
\makeindex
\usepackage{listings}
\lstset{
  language   = [LaTeX]TeX,
  basicstyle = \ttfamily,
  moretexcs  = [2]{LaTeX},
  index      = [2][texcs2],
  indexstyle = [2]\cmdidx
}
\newcommand*\cmdappearance[1]{\texttt{\textbackslash#1}}
\newcommand*\cmdidx[1]{\index{#1@\cmdappearance{#1}}}
\newcommand*\cmd[1]{\cmdappearance{#1}\cmdidx{#1}}

\begin{document}

\begin{lstlisting}
 \LaTeX{} and \LaTeX-code
\end{lstlisting}

\printindex
\end{document}

此示例的 PDF 看起来符合预期,但实际上并非如此,如下\jobname.ilg所示\jobname.idx

\jobname.ilg

This is makeindex, version 2.15 [TeX Live 2012] (kpathsea + Thai support).
Scanning input file test.idx....
!! Input index error (file = test.idx, line = 2):
   -- Extra `@' at position 31 of first argument.
done (1 entries accepted, 1 rejected).
Sorting entries...done (0 comparisons).
Generating output file test.ind....done (5 lines written, 0 warnings).
Output written in test.ind.
Transcript written in test.ilg.

\jobname.idx

\indexentry{LaTeX@\texttt  {\textbackslash LaTeX}}{1}
\indexentry{LaTeX\unhbox \voidb@x \kern \z@ @\texttt  {\textbackslash LaTeX\unhbox \voidb@x \kern \z@ }}{1}

对于 MWE 来说这不是问题,但如果第二个条目位于不同的页面上,它将丢失。\LaTeX-列表的这一部分似乎\textcompwordmark在关键字后插入了一个扩展版本,而不是\LaTeX{}获得预期条目的部分。插入的命令显然是

\@namedef{\@lst @um@}{\leavevmode\kern\z@}

(第 990 行listings.sty)将此命令重新定义为

\@namedef{\@lst @um@}{\textcompwordmark}

显示。\jobname.idx然后文件

\indexentry{LaTeX@\texttt  {\textbackslash LaTeX}}{1}
\indexentry{LaTeX\textcompwordmark @\texttt  {\textbackslash LaTeX\textcompwordmark }}{1}

可以正确解析,makeindex\LaTeX在索引中给出了两个不同的条目。(在我看来,这比第一种情况更糟糕。)


提供空定义

\@namedef{\@lst @um@}{}

给出正确的\jobname.idx

\indexentry{LaTeX@\texttt  {\textbackslash LaTeX}}{1}
\indexentry{LaTeX@\texttt  {\textbackslash LaTeX}}{1}

似乎没有出现任何明显问题。不过,我想知道它有多安全。我追踪\@lst @um@到命令\lst@CCECUse@(第 1021 行listings.sty),它似乎与选项有关listings extendedchars(它最终在 中使用\lst@DefEC,第 998 行),但我迷失在那里,不太明白这些命令的用途。我猜

\@namedef{\@lst @um@}{\leavevmode\kern\z@}

是某种预防措施/安全网(但针对什么?),而且由于我目前实际使用案例中大约有 150 个列表,显然没有遇到任何问题,所以这个问题更多的是出于好奇:如果我定义

\@namedef{\@lst @um@}{}

答案1

我发现了\textcompwordmark一个好主意,因为它将完全按照水平模式进入\leavevmode

但是,你可以用诡计\index让自己看不到有问题的标记:

\makeatletter
\newcommand*\cmdidx[1]{%
  \begingroup\let\lst@nolig\@empty
  \index{#1@\cmdappearance{#1}}\endgroup}
\makeatother
\newcommand*\cmdappearance[1]{\texttt{\textbackslash#1}}
\newcommand*\cmd[1]{\cmdappearance{#1}\cmdidx{#1}}

这将生成以下.idx文件:

\indexentry{LaTeX@\texttt  {\textbackslash LaTeX}}{1}
\indexentry{LaTeX@\texttt  {\textbackslash LaTeX}}{1}

相关内容