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