使用参数引用作为宏的可选参数

使用参数引用作为宏的可选参数

我目前正在尝试让索引条目在文本中自动以斜体显示,即,而不是\textit{Term}\index{Term},我希望能够使用\index{Term},它应该呈现与第一段代码相同的内容。

到目前为止,我已经能够某物类似于通过定义以下宏来工作:

\newcommand{\Index}[1]{\textit{#1}\index{#1}}

功劳归于https://www.namsu.de/Extra/pakete/Makeidx.html

现在通过使用\Index(注意大写的“I”),我部分获得了所需的结果。但是,我无法使用index提供的其他可能性,例如\index{term@termActuallyDisplayed}

我的下一个方法是使用:

\newcommand{\Index}[2][#2]{\textit{#2}\index{#1@#1}}

因此\Index{Term}渲染\textit{Term}\index{Term@Term},同时\Index[ActualIndexTerm]{Term}渲染\textit{Term}\index{ActualIndexTerm@ActualIndexTerm}

然而,我的问题是,使用上述代码将导致出现错误,提示“定义中的参数编号非法[...]”。因此,我的问题是 - 有谁知道如何规避这个问题,比如使用另一个包或其他什么?
(我知道我可以定义 2 个不同的命令,但这感觉有点原始)

提前致谢!

答案1

这种“自我参照”很容易通过以下方式获得:xparse

\documentclass{article}
\usepackage{xparse}
\usepackage{imakeidx}

\NewDocumentCommand{\Index}{O{#2}m}{%
  \textit{#1}\index{#2@#1}%
}

\makeindex

\begin{document}

Here I index `Term': \Index{Term}

Here I index `Actually Used Term' \Index[Actually Used Term]{z}

\printindex

\end{document}

进行调整以适应;在示例中,第二个术语将被排序为“z”,因此它将出现在第二个位置。

在此处输入图片描述

传统方法采用\@dblarg

\makeatletter
\DeclareRobustCommand{\Index}{\@dblarg\@Index}
\def\@Index[#1]#2{%
  \textit{#1}\index{#2@#1}%
}
\makeatother

如果要避免\Index{Term}\index{Term}会索引两次的问题,因为前者会做与 MakeIndex\index{Term@Term}不同的事情,你可以将命令修改为\index{Term}

\NewDocumentCommand{\Index}{om}{%
  \IfNoValueTF{#1}
    {\textit{#2}\index{#2}}
    {\textit{#1}\index{#2@#1}}%
}

答案2

xparse包是一个很棒的工具,它可以做你想做的事情(它可以声明一个带有可选参数的命令,其默认值取自另一个参数)。请参阅以下示例:

\documentclass{article}
\usepackage{xparse}
\usepackage{imakeidx}
\makeindex

\NewDocumentCommand\Index{O{#2}m}{%
  \textit{#2}\index{#2@#1}%
}
\begin{document}

\Index{xyz}

\Index[xyz|textbf]{xyz}
\printindex
\end{document}

这里两个词xyz在文本中都是斜体,可选参数可以为索引本身添加一些额外的格式信息。生成的.idx文件:

\indexentry{xyz@xyz}{1}
\indexentry{xyz@xyz|textbf}{1}

.ind(基本上是默认格式):

\begin{theindex}

  \item xyz, 1, \textbf{1}

\end{theindex}

答案3

已编辑以供实际使用\index

\documentclass{article}
\usepackage{imakeidx}
\newcommand\Index[2][\relax]{%
  \ifx\relax#1\def\actualarg{#2@#2}\else\def\actualarg{#2@#1}\fi%
  \textit{#2}%
  \expandafter\index\expandafter{\actualarg}%
}
\makeindex
\begin{document}

\Index{term}

\Index[TermActuallyDisplayed]{term}

\printindex

\end{document}

在此处输入图片描述

答案4

如果可以接受将宏输入设计稍微更改为\Index{...}[...]

\documentclass{article}
\makeatletter
\def\Index#1{%
  \textit{#1}%
  \kernel@ifnextchar[{\Index@optarg{#1}}{\index{#1@#1}}%
}
\def\Index@optarg#1[#2]{\index{#1@#2}}
\makeatother

\begin{document}
\Index{Term}

\Index{foo}[bar]
\end{document}

相关内容