8

I'm creating a technical document with lots of index entries. To reduce typing I defined an index command that typesets the word to be indexed using \emph{}:

\newcommand{\ind}[1]{\index{#1@\emph{#1}}}

I turns out the .ind file gets different entries when I use this command, compared to typing the \index{} command myself: the entries created with the \ind{} command get two spaces inserted before the { of the \emph command. Consequently, the index will contain two entries for the same word if I use both the \ind{} command and the \index{} command (e.g. when defining a region using

\index{someword@\emph{someword}\(}

to start a region for that word.

Here is an MWE:

\documentclass[a4paper]{article}

\usepackage{makeidx}
\makeindex

\newcommand{\ind}[1]{\index{#1@\emph{#1}}}

\begin{document}
Testing our self-defined command\ind{italictext}. This is the
normal way\index{italictext@\emph{italictext}}.

\printindex
\end{document}

The contents of the .ind corresponding file is:

\begin{theindex}

  \item \emph  {italictext}, 1
  \item \emph{italictext}, 1

\end{theindex}

Note 1: my actual use case is not with \emph{}, but with \lstinline{} from the listings package, but this simplified example already shows the problem. I observed the same behaviour when using the imakeidx package.

Note 2: using \DeclareRobustCommand instead of \newcommand doesn't change anything.

Note 3: I am actually using a KOMA class documentclass, so the scrindex package would be an option since the spacing problem doesn't appear there (in fact, both entries end up as one index entry with a single space between the \emph and opening { in the .ind file. However, with that package I haven't managed to get the page numbers for the index entries hyperlinked when using the hyperref package.

1
  • I am not sure that \lstinline would work inside of \index however
    – user31729
    Jan 28, 2018 at 10:18

2 Answers 2

7

LaTeX's \index reads its argument as a verbatim argument to prevent the expansion of commands. If \index is used in the argument of another macro, then the argument of \index is already read and the switching to verbatim read mode of \index comes too late.

That \index is called in side \ind can be fixed by defining \ind in the same manner as \index, see its definition in latex.ltx:

\def\index{%
  \@bsphack % space handling around `\index`
  \begingroup % localize category code changes
  \@sanitize % change category codes to verbatim
  \@wrindex % reads argument, writes the index entry and ends the group
}

Example with new \ind:

\documentclass[a4paper]{article}

\usepackage{makeidx}
\makeindex

\makeatletter
\newcommand*{\ind}{%
  \@bsphack
  \begingroup
  \@sanitize
  \@ind
}
\newcommand*{\@ind}[1]{%
  \@wrindex{#1@\string\emph{#1}}%
}
\makeatletter

\begin{document}
Testing our self-defined command\ind{italictext}. This is the
normal way\index{italictext@\emph{italictext}}.

\printindex
\end{document}

Now, the two index entries (.idx file) are equal:

\indexentry{italictext@\emph{italictext}}{1}
\indexentry{italictext@\emph{italictext}}{1}
1
  • Thanks Heiko, your answer also works for my actual use case with \lstinline.
    – ph0t0nix
    Jan 28, 2018 at 10:50
5

You could use \string\emph inside of \ind, preventing a premature expansion of \emph etc. and insertion of a stray space character.

\documentclass[a4paper]{article}

\usepackage{makeidx}
\makeindex

\newcommand{\ind}[1]{\index{#1@\string\emph{#1}}}
\begin{document}
Testing our self-defined command\ind{italictext}. This is the
normal way\index{italictext@\emph{italictext}}.

\printindex
\end{document}
5
  • Thanks for the quick answer. However, adding \string doesn't seem to work. With the MWE I get one italictext entry (from the manual typing of \index) and one “emphitalictext entry. In the.ind file this entry is: \item \string \emph {italictext}, 1
    – ph0t0nix
    Jan 28, 2018 at 10:35
  • @ph0t0nix: However, it works for me and there is only one entry, without \string etc
    – user31729
    Jan 28, 2018 at 10:36
  • Sorry, you are right, it works as you described. When I tested I still had the scrindex package loaded instead of makeidx.
    – ph0t0nix
    Jan 28, 2018 at 10:42
  • @ph0t0nix: Ah yes, the KOMA packages/classes introduces strange things sometimes...
    – user31729
    Jan 28, 2018 at 10:44
  • as you expected, your answer doesn't work for my actual use case with \lstinline. Since Heiko Oberdiek's answer does work in that case, I'll accept that one. Nevertheless, thanks for the quick reply.
    – ph0t0nix
    Jan 28, 2018 at 10:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .