使用 xstring 生成索引键

使用 xstring 生成索引键

我有一个文档,其中包含一个环境的许多实例,其中有一个强制参数,提供了一个简短的“标签”。这些标签类似于“M04”,我编写了一个宏,使用xstring它将其转换为例如“May!2004”。我想使用此宏自动添加索引条目imakeidx

似乎宏扩展在各个阶段都存在问题。在下面的 MWE 中,我可以使用\index{\genkey{M04}}添加到索引中,但似乎\genkey扩展得太晚了,因为“May!2004”字面上出现在索引中(而不是 2004 作为子条目)。我无法通过环境达到这一点 - 我最终收到许多关于来自 xstring 包的未定义控制序列的投诉。

我试图使用edef来完成所有的扩展,然后再传递给\index,但无济于事 - 按照这个答案,无法edef与 一起使用string

如能得到有关如何使下面的代码按预期工作的任何帮助,我们将非常感激。

\documentclass{article}
\usepackage{xstring}
\usepackage{imakeidx}

\makeindex

\newcommand\getmonth[1]{%
  \StrChar{#1}{1}[\firstchar]%
  \IfStrEq{\firstchar}{J}{January}{May}%
}
\newcommand\getyearprefix[1]{%
  \StrChar{#1}{2}[\secondchar]%
  \IfStrEq{\secondchar}{9}{19}{20}%
}
\newcommand{\genkey}[1]{%
    \getmonth{#1}!\getyearprefix{#1}\StrMid{#1}{2}{3}%
}

\newenvironment{entry}[1]{%
  \index{\genkey{#1}}%
}
{}

\begin{document}

\genkey{M04}

\genkey{J98}

\index{\genkey{M04}}

% \begin{entry}{M04}
% Here is the M04 entry
% \end{entry}

% \begin{entry}{J98}
% Here is the J98 entry
% \end{entry}

\printindex

\end{document}

答案1

以下定义了\getmonth\getyearprefix和的可扩展版本\genkey。参数必须由 3 个字符组成(参数已去标记化)。

\documentclass{article}

\usepackage{imakeidx}
\makeindex

\usepackage{xparse}

\ExplSyntaxOn
\NewExpandableDocumentCommand \getmonth { +m }
  {
    \str_case:nn { #1 }
      {
        { J } { January }
        { F } { February }
        { m } { March }
        { a } { April }
        { M } { May }
        { j } { June }
        { J } { July }
        { A } { August }
        { S } { September }
        { O } { October }
        { N } { November }
        { D } { December }
      }
  }
\NewExpandableDocumentCommand \getyearprefix { +m }
  {
    \int_case:nn { #1 }
      {
        { 0 } { 20 }
        { 1 } { 20 }
        { 2 } { 19 }
        { 3 } { 19 }
        { 4 } { 19 }
        { 5 } { 19 }
        { 6 } { 19 }
        { 7 } { 19 }
        { 8 } { 19 }
        { 9 } { 19 }
      }
  }
\msg_new:nnn { genkey } { improper-length }
  { The ~ token ~ list ~ has ~ the ~ wrong ~ length ~ ( #1 ) }
\cs_new:Npn \__genkey:nnn #1 #2 #3
  {
    \getmonth { #1 } ! \getyearprefix { #2 } #2 #3
  }
\NewExpandableDocumentCommand \genkey { +m }
  {
    \int_compare:nNnTF { \str_count_ignore_spaces:n { #1 } } = 3
      { \exp_after:wN \__genkey:nnn \tl_to_str:n { #1 } }
      {
        \msg_expandable_error:nnf { genkey } { improper-length }
          { \str_count_ignore_spaces:n { #1 } }
      }
  }
\NewDocumentEnvironment { entry } { m }
  {
    \exp_args:Ne \index { \genkey { #1 } }
  }
  {}
\ExplSyntaxOff

\begin{document}

\genkey{M04}

\genkey{J98}

% doesn't work, honestly no idea why index doesn't always expand its argument
\index{\genkey{M04}}

\begin{entry}{M04}
Here is the M04 entry
\end{entry}

\begin{entry}{J98}
Here is the J98 entry
\end{entry}

\printindex

\end{document}

相关内容