\sindex[]{} の引数に挿入したコマンドは展開されません: @ シンボルが表示されます

\sindex[]{} の引数に挿入したコマンドは展開されません: @ シンボルが表示されます

\sindex[]{}パッケージのコマンドを使用してsplitxdxインデックス エントリを作成しています。並べ替えを制御するには@、たとえば というシンボルを使用しています\sindex[...]{1@One}

もう少し設定しやすくするために、カスタム コマンドを定義します\newcommand{\sortedOne}{1@One}

問題は、このコマンドを\sindexの引数に挿入すると、リテラル テキストが1@One表示されることです。たとえば、コードは\sindex[myindex]{\sortedOne!This fails.}次のエントリの最初のものを生成します。

ここに画像の説明を入力してください

\expandafterこれを回避する簡単な方法はありますか?を使用するたびに、のようなものを手動で入力する必要がない方法が望ましいです\sindex

興味深い余談ですが、するコマンドをパッケージのコマンド\sindexでラップすると、正しく動作します。\comma@parsekvsetkeys\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}

後者の 2 つの形式は、連続するスペースを結合する makeindex のオプションによって結合できます-cが、スペースのないエントリはスペースのあるエントリとは異なるままです。

関連情報