The listings
package allows to index the appearance of keywords in a listing, for example similar to the following 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}
The PDF of this example looks as expected but it is not, really, as a look in \jobname.ilg
and \jobname.idx
shows:
\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}
This is no problem for the MWE but the second entry would be lost if it were on a different page. The \LaTeX-
part of the listing seems to have an expanded version of \textcompwordmark
inserted after the keyword as opposed to the \LaTeX{}
part which got the expected entry. The inserted command apparently is
\@namedef{\@lst @um@}{\leavevmode\kern\z@}
(line 990 of listings.sty
) which a redefinition of this command into
\@namedef{\@lst @um@}{\textcompwordmark}
shows. The \jobname.idx
file then is
\indexentry{LaTeX@\texttt {\textbackslash LaTeX}}{1}
\indexentry{LaTeX\textcompwordmark @\texttt {\textbackslash LaTeX\textcompwordmark }}{1}
which is correctly parsed by makeindex
but gives two distinct entries for \LaTeX
in the index. (IMHO a worse case than the first.)
Providing an empty definition
\@namedef{\@lst @um@}{}
gives the correct \jobname.idx
\indexentry{LaTeX@\texttt {\textbackslash LaTeX}}{1}
\indexentry{LaTeX@\texttt {\textbackslash LaTeX}}{1}
and no apparent issues seem to arise. I wonder, though, how safe it is. I traced the \@lst @um@
to the command \lst@CCECUse@
(line 1021 of listings.sty
) which seems to have to do with listings
extendedchars
option (it is finally used in \lst@DefEC
, line 998) but I'm lost there and don't really understand what the commands are for. My guess is that
\@namedef{\@lst @um@}{\leavevmode\kern\z@}
is some kind of precaution/safety net (but against what?) and since I'm getting apparently no issues in my real use case with currently about 150 listings the question is more out of curiosity: can something (and what) go wrong if I define
\@namedef{\@lst @um@}{}
Best Answer
I find
\textcompwordmark
a good idea, since it will enter horizontal mode exactly as\leavevmode
does.However, you can trick
\index
into not seeing the offending token:This produces the following
.idx
file: