在 \sindex[]{} 的参数中插入命令不会展开:出现 @ 符号

在 \sindex[]{} 的参数中插入命令不会展开:出现 @ 符号

我使用包\sindex[]{}中的命令splitxdx来创建索引条目。为了控制排序,我使用符号@,例如\sindex[...]{1@One}

为了使事情更易于配置,我定义了一个自定义命令:\newcommand{\sortedOne}{1@One}

问题是,当我将此命令插入到\sindex的参数中时,显示的是文字1@One。例如,代码\sindex[myindex]{\sortedOne!This fails.}生成以下条目中的第一个:

在此处输入图片描述

有没有简单的方法可以避免这种情况?我更喜欢一种方法,这样我就不必\expandafter每次使用时都手动输入类似的东西\sindex

有趣的是,\sindex如果我将命令包装在包\comma@parse中的命令中,则可以正常工作kvsetkeys\comma@parse{\sortedOne!This works with comma parse}{\sindex[myindex]}

这是产生上述输出的我的 MWE:

\documentclass[12pt]{book}

\usepackage[split]{splitidx}\makeindex
    \newindex{myindex}
\usepackage{lipsum}
\usepackage{kvsetkeys}
%\usepackage{hyperref}
%\newcommand{\mainindexentry}[1]{\textbf{\hyperpage{#1}}}
\newcommand{\sortedOne}{1@One}

\begin{document}

\lipsum[1]

\sindex[myindex]{1@One!This works fine}
\sindex[myindex]{\sortedOne!This fails.}
\sindex[myindex]{Even subentries fail!\sortedOne}
\makeatletter
\comma@parse{\sortedOne!This works with comma parse}{\sindex[myindex]}
\makeatother

\printindex[myindex]

\end{document}

答案1

通常索引命令不会扩展其参数并逐字读取其内容。这也可以防止宏被扩展。通过在索引命令看到之前读取参数,逐字更改不会产生任何效果,因为标记已经形成,请参阅 的定义\Sindex

\documentclass[12pt]{book}

\usepackage[split]{splitidx}\makeindex
    \newindex{myindex}
\usepackage{lipsum}
%\usepackage{kvsetkeys}
%\usepackage{hyperref}
%\newcommand{\mainindexentry}[1]{\textbf{\hyperpage{#1}}}
\newcommand{\sortedOne}{1@One}

\newcommand*{\myindex}{\sindex[myindex]}
\newcommand*{\smyindex}[1]{\sindex[myindex]{#1}}
\newcommand*{\Sindex}[2][]{\sindex[{#1}]{#2}}

\begin{document}

\lipsum[1]

\sindex[myindex]{1@One!This works fine}
\expandafter\myindex\expandafter{\sortedOne!This also works.}
\smyindex{Even subentries work!\sortedOne}
\Sindex[myindex]{\sortedOne!\sortedOne}

\printindex[myindex]

\end{document}

结果

当然,不应该扩展的命令应该受到保护\string

\Sindex[myindex]{...\string\fragilecmd...}

或者可以通过以下方式保护多个令牌\detokenize

\Sindex[myindex]{...\detokenize{...}...}

此外,不应混合使用扩展/不扩展的方法,以防止由于扩展/未扩展索引条目而导致重复的索引条目。根据方法的不同,命令后的空格数可能会有所不同:

\sindex[myindex]{\textbf{...}}
\Sindex[myindex]{\string\textbf{...}}
\Sindex[myindex]{\protect\textbf{...}}
\Sindex[myindex]{\textbf{...}}

文件中的结果.idx

\indexentry{\textbf{...}}{1}
\indexentry{\textbf{...}}{1}
\indexentry{\textbf {...}}{1}
\indexentry{\textbf  {...}}{1}

后两种形式可以通过 makeindex 选项合并-c,该选项合并连续的空格,但没有空格的条目与有空格的条目仍然不同。

相关内容