A inserção de comandos no argumento de \sindex[]{} não é expandida: símbolo @ aparecendo

A inserção de comandos no argumento de \sindex[]{} não é expandida: símbolo @ aparecendo

Estou usando o \sindex[]{}comando do splitxdxpacote para criar entradas de índice. Para controlar a classificação estou usando o @símbolo, por exemplo \sindex[...]{1@One}.

Para tornar as coisas um pouco mais configuráveis, defino um comando personalizado: \newcommand{\sortedOne}{1@One}.

O problema é que quando insiro este comando no \sindexargumento de, recebo o texto literal 1@Oneaparecendo. Por exemplo, o código \sindex[myindex]{\sortedOne!This fails.}produz a primeira das seguintes entradas:

insira a descrição da imagem aqui

Existe uma maneira fácil de evitar isso? Eu preferiria um método em que não precisasse digitar manualmente algo como \expandaftercada vez que uso \sindex.

Como uma observação interessante,fazfuncionar corretamente se eu agrupar o \sindexcomando em um \comma@parsecomando do kvsetkeyspacote: \comma@parse{\sortedOne!This works with comma parse}{\sindex[myindex]}.

Aqui está meu MWE que produziu a saída acima:

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

Responder1

Normalmente, os comandos de índice não expandem seus argumentos e leem seu conteúdo literalmente. Isso também evita que as macros sejam expandidas. Ao ler o argumento antes que o comando index o veja, as alterações literais ficam sem efeito, pois os tokens já estão formados, veja a definição de \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}

Resultado

É claro que os comandos que não devem ser expandidos devem ser protegidos por \string:

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

ou vários tokens podem ser protegidos por \detokenize:

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

Além disso, os métodos (com/sem expansão) não devem ser misturados para evitar entradas de índice duplicadas devido a entradas de índice expandidas/não expandidas. Dependendo do método, o número de espaços após um comando pode variar:

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

Resultado no .idxarquivo:

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

As duas últimas formas podem ser mescladas pela opção makeindex' -c, que mescla espaços consecutivos, mas uma entrada sem espaço permanece diferente de uma entrada com espaço.

informação relacionada