![Вставка команд в аргумент \sindex[]{} не раскрывается: отображается @-символ](https://rvso.com/image/298305/%D0%92%D1%81%D1%82%D0%B0%D0%B2%D0%BA%D0%B0%20%D0%BA%D0%BE%D0%BC%D0%B0%D0%BD%D0%B4%20%D0%B2%20%D0%B0%D1%80%D0%B3%D1%83%D0%BC%D0%B5%D0%BD%D1%82%20%5Csindex%5B%5D%7B%7D%20%D0%BD%D0%B5%20%D1%80%D0%B0%D1%81%D0%BA%D1%80%D1%8B%D0%B2%D0%B0%D0%B5%D1%82%D1%81%D1%8F%3A%20%D0%BE%D1%82%D0%BE%D0%B1%D1%80%D0%B0%D0%B6%D0%B0%D0%B5%D1%82%D1%81%D1%8F%20%40-%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB.png)
Я использую \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
, которая объединяет последовательные пробелы, но запись без пробела по-прежнему отличается от записи с пробелом.