我正在使用该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
。由于\noexpand
s,扩展停止。在输出例程期间,\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
:任何命令吸收参数会导致同样的问题。