从命令参数中去除前导字符

从命令参数中去除前导字符

我有一个命令 (AlertShort),它有一个输入参数,既可以打印文本,又可以生成索引。对于标准文本,这可以正常工作,但在某些情况下,输入参数包含一个符号,这会导致索引排序不正确。可以通过在参数前加上“@”来控制排序顺序,但排序代码会与文本一起打印。

因此,我想将包括其排序代码的参数直接传递给索引,但在打印文本之前删除排序代码。在 MWE 中,我使用大写字母来提供所需的排序顺序,并在其前面加上引号,以便符号首先出现在索引中。

平均能量损失

    \documentclass{article}%

    \usepackage{fontspec}%
    \newfontfamily\symbolfamily{Asana Math}  

    \usepackage[hyperref, x11names]{xcolor}

    \usepackage{imakeidx}\makeindex%

    \usepackage[bookmarks, psdextra, unicode, hyperfootnotes=false]{hyperref}%

    \DeclareRobustCommand\Bts{{\symbolfamily\char"2663}}
    \pdfstringdefDisableCommands{%
      \renewcommand\Bts{\Uchar"2663\relax}%
      % Inside PDF strings, \Ts is replaced by Unicode char U+2663 "BLACK CLUB SUIT"
    }

    \DeclareRobustCommand\Bks{{\color{red}\symbolfamily\char"2666}}
    \pdfstringdefDisableCommands{%
      \renewcommand\Bks{\Uchar"2666\relax}%
    }

    \DeclareRobustCommand\Bcs{{\color{red}\symbolfamily\char"2665}}
    \pdfstringdefDisableCommands{%
      \renewcommand\Bcs{\Uchar"2665\relax}%
    }

    \DeclareRobustCommand\Bps{{\symbolfamily\char"2660}}
    \pdfstringdefDisableCommands{%
      \renewcommand\Bps{\Uchar"2660\relax}%
    }

    \newcommand{\Ts}{"C@\Bts}% 
    \newcommand{\Ks}{"D\Bks}% 
    \newcommand{\Cs}{"H@\Bcs}% 
    \newcommand{\Ps}{"S@\Bps}% 

    \newcommand{\AlertShort}[1]{Alert: #1\index[alerts]{#1}}% 

    \makeindex[name=alerts,title=List of Alerts]


    \begin{document}

    Text. \AlertShort{Our strongest opening}

    More text.\AlertShort{\Cs 5-card, 4-card minor}

    Yet more text.
    \AlertShort{\Ts solid}

  And sometimes the commands occur within the text.
    \AlertShort{Here be \Ts}

    \printindex[alerts]

    \end{document}

答案1

有一个比插入排序键后剥离排序键更简单的解决方案:如果您不在索引条目中,则可以避免添加排序键。

存档此问题的一种方法是创建一个添加排序键的宏,当您不在索引中时,它只会吞噬其参数:

\documentclass{article}%

\usepackage{fontspec}%
\newfontfamily\symbolfamily{Asana Math}  

\usepackage[hyperref, x11names]{xcolor}

\usepackage{imakeidx}\makeindex%

\usepackage[bookmarks, psdextra, unicode, hyperfootnotes=false]{hyperref}%

\DeclareRobustCommand\Bts{{\symbolfamily\char"2663}}
\pdfstringdefDisableCommands{%
  \renewcommand\Bts{\Uchar"2663\relax}%
  % Inside PDF strings, \Ts is replaced by Unicode char U+2663 "BLACK CLUB SUIT"
}

\DeclareRobustCommand\Bks{{\color{red}\symbolfamily\char"2666}}
\pdfstringdefDisableCommands{%
  \renewcommand\Bks{\Uchar"2666\relax}%
}

\DeclareRobustCommand\Bcs{{\color{red}\symbolfamily\char"2665}}
\pdfstringdefDisableCommands{%
  \renewcommand\Bcs{\Uchar"2665\relax}%
}

\DeclareRobustCommand\Bps{{\symbolfamily\char"2660}}
\pdfstringdefDisableCommands{%
  \renewcommand\Bps{\Uchar"2660\relax}%
}

\newcommand\usesortkey[1]{}
\DeclareRobustCommand\myindex[2][]{%
  \begingroup
    \renewcommand\usesortkey[1]{##1@}%
    \expanded{%
  \endgroup
      \noexpand\index[\unexpanded{#1}]{\unexpanded\expandafter{\romannumeral`\^^@#2}}%
  }
}

\newcommand{\Ts}{\usesortkey{"C}\Bts}% 
\newcommand{\Ks}{\usesortkey{"D}\Bks}% 
\newcommand{\Cs}{\usesortkey{"H}\Bcs}% 
\newcommand{\Ps}{\usesortkey{"S}\Bps}% 

\newcommand{\AlertShort}[1]{Alert: #1\myindex[alerts]{#1}}% 

\makeindex[name=alerts,title=List of Alerts]


\begin{document}

Text. \AlertShort{Our strongest opening}

More text.\AlertShort{\Cs 5-card, 4-card minor}

Yet more text.
\AlertShort{\Ts solid}

And sometimes the commands occur within the text.
\AlertShort{Here be \Ts}

\printindex[alerts]

\end{document}

编辑:添加了\expanded\expandafter并且\romannumeral技巧是在重新定义时仅扩展参数的第一部分,这样\Ts后面的内容就不会受到影响。当前版本需要 LuaTeX 作为\expanded原语,这可能可以使用\edef或大量\expandafters 为其他引擎重写。

相关内容