3

I am using the ifthen package to include/exclude passages in my document. However, I have noticed that when I have two formatted index entries for the same term, one inside \ifthenelse and one outside, then they are not combined in the index, although they should be.

Example:

\documentclass{article}
\usepackage{makeidx, ifthen}
\newboolean{include}
\setboolean{include}{true}
\makeindex
\begin{document}
foo\index{myterm@\textit{myterm}}%
\ifthenelse{\boolean{include}}{%
bar\index{myterm@\textit{myterm}}%
}{}%
\printindex
\end{document}

The resulting index has two separate lines for "myterm".

I also tried etoolbox instead of ifthen, but interestingly the same problem occurs.

\documentclass{article}
\usepackage{makeidx, etoolbox}
\newtoggle{include}
\toggletrue{include}
\makeindex
\begin{document}
foo\index{myterm@\textit{myterm}}%
\iftoggle{include}{%
bar\index{myterm@\textit{myterm}}%
}{}%
\printindex
\end{document}

I'm using pdflatex. Any ideas?

2 Answers 2

3

The reason is already explained by Joseph Wright's answer, that the second \index call is inside the argument of another macro. Then the the index entry text is not read verbatim and macros are expanded. Due to LaTeX's protection mechanism, the robust macro \textit is expanded by \protected@write to \protect\textit␣. The space at the end is part of the macro name. \protect has the meaning \noexpand\protect\noexpand. Because of the \noexpands, the expansion stops. During the output routine, \protect becomes \noexpand and the token \textit␣ is written to the output file as \textit␣␣. The additional space comes from TeX, which puts a space after multi-letter command tokens.

The .idx file:

\indexentry{myterm@\textit{myterm}}{1}
\indexentry{myterm@\textit  {myterm}}{1}

Makeindex knows option -c which compresses successive spaces to one space. Then entries with one or more spaces would be treated the same (e.g., \textit␣ and \textit␣␣ would be equal then). But this does not help with entries with and without space.

There is a manual workaround. \string prevents the expansion of the token by converting it to letters without appending a space:

\documentclass{article}
\usepackage{makeidx, ifthen}
\newboolean{include}
\setboolean{include}{true}
\makeindex
\begin{document}
foo\index{myterm@\textit{myterm}}%
\ifthenelse{\boolean{include}}{%
  bar\index{myterm@\string\textit{myterm}}%
}{}%
\printindex
\end{document}

The .idx file now is correct:

\indexentry{myterm@\textit{myterm}}{1}
\indexentry{myterm@\textit{myterm}}{1}
2

The \index command reads its argument in a verbatim-like manner. That means that it cannot be used inside the argument to other commands, at least not if you want it to continue to work correctly. If you look at the .idx file you have you'll find

\indexentry{myterm@\textit{myterm}}{1}
\indexentry{myterm@\textit  {myterm}}{1}

where the entry with the spaces is from your second use of \index. Note that this is not due to ifthen or etoolbox: any command absorbing an argument will cause the same issue.

1
  • At present I'm not quite sure what the wider context is here, but I wonder if you want something like the comment package.
    – Joseph Wright
    Commented Aug 9, 2015 at 6:05

You must log in to answer this question.

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