我使用多个索引,例如“姓名”、“主题”,并使用以下形式的条目执行此操作
\index{names}{Columbus}
。这些索引是使用multind
包创建的。
不幸的是,一些 tex 文件有以下形式的索引命令\index{Columbus}
。我不想浏览所有这些文件并替换\index{Columbus}
为\index{names}{Columbus}
。
我可以重新定义\index
为指向正确的索引文件吗?即从myfile.ind
到names.ind
答案1
语法\index{names}{Columbus}
和\index{Columbus}
是有歧义的,因为后一种形式后面可能跟着另一个花括号组,例如:
\index{abc}{xyz}
是否有abc
登记条目xyz
或abc
名称为名称的登记册?
有几种方法可以解决歧义问题:
\index
可以检查第一个参数是否是已知的寄存器名称,然后使用两个参数形式。限制:
\index
必须知道所有寄存器并且寄存器名称不能作为条目出现。\index
可以读取第一个参数并检查下一个标记。如果后面跟着一个左花括号,则使用两个参数形式,否则第一个参数已经是名称寄存器的名称。限制:左花括号不能位于单参数形式之后。
下面的例子实现了后一种情况。
\index
有点棘手:
条目参数会逐字逐句地读取,并更改类别代码以防止过早扩展。相反,该参数应不加修改地进入文件
.idx
。\index
通过查找前后空格来尝试隐藏。如果检测到前一个空格,它会忽略后面的空格。因此代码被 和 包围\@bsphack
。\@esphack
在这种情况下,原始命令\index
将继续工作,因为原始命令\index
是在参数检查后调用的。
完整示例:
\documentclass{article}
\usepackage{multind}% Caution: old LaTeX 2.09 package
% Better alternatives:
% imakeidx: http://www.ctan.org/pkg/imakeidx
% index: http://www.ctan.org/pkg/index
\makeindex{names}
\makeatletter
\newcommand*{\org@index}{}
\let\org@index\index
\newcommand*{\index@param}{}
\renewcommand*{\index}{%
\begingroup % limit the scope for verbatim category codes
\@sanitize % verbatim category codes
\index@i
}
\newcommand*{\index@i}[1]{%
\gdef\index@param{#1}% remember the first argument in global macro
\endgroup
\futurelet\@let@token\index@ii % peek at next token
}
\newcommand*{\index@ii}{%
\ifx\@let@token\bgroup
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
{%
\org@index{\index@param}%
}{%
\org@index{names}{\index@param}%
}%
}
\makeatother
\begin{document}
\index{names}{Columbus}
\index{Knuth}
% Test spaces
[ \index{test} ][\index{test} ][ \index{test}][\index{test}]
\printindex{names}{Name register}
\end{document}