重新定义 \index

重新定义 \index

我使用多个索引,例如“姓名”、“主题”,并使用以下形式的条目执行此操作 \index{names}{Columbus}。这些索引是使用multind包创建的。

不幸的是,一些 tex 文件有以下形式的索引命令\index{Columbus}。我不想浏览所有这些文件并替换\index{Columbus}\index{names}{Columbus}

我可以重新定义\index为指向正确的索引文件吗?即从myfile.indnames.ind

答案1

语法\index{names}{Columbus}\index{Columbus}是有歧义的,因为后一种形式后面可能跟着另一个花括号组,例如:

\index{abc}{xyz}

是否有abc登记条目xyzabc名称为名称的登记册?

有几种方法可以解决歧义问题:

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

姓名登记册

相关内容