Вставка команд в аргумент \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

Обычно команды index не расширяют свой аргумент и считывают его содержимое дословно. Это также предотвращает расширение макросов. При считывании аргумента до того, как команда index его увидит, дословные изменения не имеют эффекта, поскольку токены уже сформированы, см. определение \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, которая объединяет последовательные пробелы, но запись без пробела по-прежнему отличается от записи с пробелом.

Связанный контент