I'm trying to create a command \term
for printing a definition and then indexing it. It has one optional argument and one mandatory argument; if the optional argument is absent, the mandatory argument is used in its place. Here's the code I have:
% .tex file
\documentclass{article}
\usepackage{makeidx}
\usepackage{xparse}
\makeindex
\NewDocumentCommand{\term}{o m}{
{\bfseries #2}
\IfNoValueTF{#1}{
\index{#2}
}{
\index{#1}
}
}
\begin{document}
A \term[pistar-boojum@$\pi_*$-boojum]{$\pi_*$-boojum} is\dots
Now I'm going to index $\pi_*$-boojum again.\index{pistar-boojum@$\pi_*$-boojum}
\printindex
\end{document}
The problem is, these two entries are displayed separately in the index:
Looking at the .ind
file pinpoints the problem:
% .ind file
\begin{theindex}
\item $\pi _*$-boojum, 1
\item $\pi_*$-boojum, 1
\end{theindex}
I think the source of this issue is that \IfNoValueTF
tokenizes the optional argument, inserting the space between \pi
and _*
. Then, makeindex
treats \pi _*
and \pi_*
as different things.
Hence, my question is: is there a way to use the mandatory argument as the default value of an optional argument without tokenizing the optional argument? A priori it should be possible to check whether a string is empty without processing it, but I'd also be content to know that it's impossible in LaTeX.
Here are some things I tried:
- Using
\IfNoValueTF
as above - Using
\@dblarg
as in this answer - Using the
ifmtarg
package. - Wrapping in
\mbox
as in this answer - Using
\detokenize
as in this answer
xparse
you can do{O{#2}m}
.xparse
. If nothing else works, I'll use that, but I'd prefer a solution that works on a wider range of distributions. Thank you for the suggestion!