由宏中的可选参数标记导致的索引重复错误

由宏中的可选参数标记导致的索引重复错误

我正在尝试创建一个命令\term来打印定义然后对其进行索引。它有一个可选参数和一个强制参数;如果可选参数不存在,则使用强制参数代替。这是我的代码:

% .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}

问题是,这两个条目在索引中分开显示:

在此处输入图片描述

查看.ind文件可以查明问题所在:

% .ind file
\begin{theindex}

  \item $\pi _*$-boojum, 1
  \item $\pi_*$-boojum, 1

\end{theindex}

我认为这个问题的根源是对可选参数进行标记,在和\IfNoValueTF之间插入空格。然后,将和视为不同的东西。\pi_*makeindex\pi _*\pi_*

因此,我的问题是:有没有办法将强制参数用作可选参数的默认值,而无需对可选参数进行标记? 先验应该可以不处理字符串就检查它是否为空,但我也很高兴知道这在 LaTeX 中是不可能的。

以下是我尝试过的一些方法:

答案1

你的问题不是xparse,而是\index,或者更确切地说,试图读取已经标记的材料。后者非常刻意地逐字逐句地读取参数。与所有逐字逐句的东西一样,这只有在输入之前没有被标记的情况下才有效。要做到这一点换行\index到另一个命令中,您将必须进行逐字读取。我们没有“逐字可选参数” xparse(至少目前没有!),因此可以执行类似

\NewDocumentCommand{\term}{t[}{%
  \IfBooleanTF#1{\termauxi]}{\termauxii}%
}
\NewDocumentCommand\termauxi{vm}{%
  \index{#1}%
  {\bfseries #2}%
}
\NewDocumentCommand\termauxii{v}{%
  \index{#1}%
  {\bfseries\scantokens{#1}}%
}

上述收益.idx文件

\indexentry{pistar-boojum@$\pi_*$-boojum}{1}
\indexentry{pistar-boojum@$\pi_*$-boojum}{1}
\indexentry{$\pi_*$-boojum}{1}

从问题中的输入加上第三行测试行:

A \term[pistar-boojum@$\pi_*$-boojum]{$\pi_*$-boojum} is\dots

Now I'm going to index $\pi_*$-boojum again.\index{pistar-boojum@$\pi_*$-boojum}

A \term{$\pi_*$-boojum} is \dots

当然,\scantokens可能有点冒险,但它确实允许我们有一个或多或少逐字强制性的论点......

相关内容