ifthen 和 etoolbox 导致错误索引

ifthen 和 etoolbox 导致错误索引

我正在使用该ifthen包来包含/排除文档中的段落。但是,我注意到,当我为同一个术语设置两个格式化的索引条目(一个在内部\ifthenelse,一个在外部)时,它们不会合并在索引中,尽管它们应该合并。

例子:

\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}

结果索引中有两行“myterm”单独的内容。

我也尝试了 etoolbox 而不是 ifthen,但有趣的是出现了同样的问题。

\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}

我正在使用 pdflatex。有什么想法吗?

答案1

原因已由 Joseph Wright 解释回答,第二次\index调用是在另一个宏的参数内。然后索引条目文本不会被逐字读取,宏将被展开。由于 LaTeX 的保护机制,健壮宏被展开\textit\protected@write\protect\textit␣末尾的空格是宏名的一部分。\protect具有含义\noexpand\protect\noexpand。由于\noexpands,扩展停止。在输出例程期间,\protect变为\noexpand,并且标记\textit␣作为写入输出文件\textit␣␣。额外的空间来自 TeX,它在多字母命令标记后放置一个空格。

文件.idx

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

Makeindex 知道-c将连续空格压缩为一个空格的选项。然后,具有一个或多个空格的条目将被视为相同(例如,\textit␣\textit␣␣将相等)。但这对有空格和没有空格的条目没有帮助。

有一个手动解决方法。\string通过将标记转换为字母而不附加空格来防止标记扩展:

\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}

现在文件.idx是正确的:

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

答案2

\index命令以逐字方式读取其参数。这意味着它不能在其他命令的参数中使用,至少如果你想让它继续正常工作的话。如果你查看.idx你拥有的文件,你会发现

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

其中带空格的条目是您第二次使用\index。请注意,这不是由于ifthen或造成的etoolbox任何命令吸收参数会导致同样的问题。

相关内容