从子密钥生成 l3keys 元密钥

从子密钥生成 l3keys 元密钥

我创建了一个简单的包,其中的选项可以通过l3keys2e. 我能够弄清楚如何使语法

\usepackage[format = international]{phone}

工作,但我想使语法

\usepackage[international]{phone}

是同义词。我在下面的代码中使用的方法有效,但重复性很强,尤其是当我有更多格式选项时。有没有更简单的方法?

代码如下:

\RequirePackage{expl3, l3keys2e, xparse}
\ProvidesExplPackage
    {phone}{2013/06/19}{0.1}{Format phone numbers}

\cs_new_nopar:Npn \phone_international_fmt:NNN  #1#2#3
  { +1 - #1 - #2 - #3 }

\cs_new_nopar:Npn \phone_parendash_fmt:NNN  #1#2#3
  { (#1) \nobreakspace #2 - #3 }

\keys_define:nn { phone }
  {
    format .choice_code:n =
      {
        \cs_new_eq:Nc \phone_fmt:NNN 
          { phone_ \tl_use:N \l_keys_choice_tl _fmt:NNN }
      },
    format .generate_choices:n =
      {
        international,
        parendash,
      },
% These next lines will become repetitive if I have many more formatting options
    international .meta:n = { format = international },
    parendash     .meta:n = { format = parendash     },
  }

\ProcessKeysOptions { phone }

\NewDocumentCommand \phone
  { >{ \SplitArgument {2} {-} } m }
  { \phone_fmt:NNN #1 }

\endinput

使用此包的最小示例如下所示:

\documentclass{article}

% \usepackage[parendash]{phone}
\usepackage[format = parendash]{phone}

\begin{document}

\phone{212-555-1212}

\end{document}

这样就得到了想要的结果

(212) 555-1212

答案1

您可以使用unknown密钥处理程序来实现这一点,从而将任何未知密钥传递回系统format = <unknown key>(TikZ 使用类似的系统来识别颜色和节点形状)。下面是一个使用它的示例。如果没有相应的格式,它会发出警告。

我必须使用辅助命令将未知密钥送回密钥处理程序,因为如果我这样做,format / unknown .code:n = { \keys_set:nn { phone} { format = #1 } }L3#1\l_keys_key_tl非常小心,不是展开\l_keys_key_tl直到最后一分钟,到那时它的值将从未知键更改为format。辅助宏允许我使用的值\l_keys_key_tl而不是令牌列表变量。

我还将 修复NNNnnn。因为我想设置默认值,所以键处理程序中的设置器现在是\cs_set_eq:Nc而不是\cs_new_eq:Nc

\documentclass{article}
%\url{http://tex.stackexchange.com/q/120102/86}
\usepackage{filecontents}

\begin{filecontents}{phone.sty}
\RequirePackage{expl3, l3keys2e, xparse}
\ProvidesExplPackage
    {phone}{2013/06/19}{0.1}{Format phone numbers}

\cs_new_nopar:Npn \phone_international_fmt:nnn  #1#2#3
  { +1 - #1 - #2 - #3 }

\cs_new_nopar:Npn \phone_parendash_fmt:nnn  #1#2#3
  { (#1) \nobreakspace #2 - #3 }

% Set a default
\cs_set_eq:NN \phone_fmt:nnn \phone_parendash_fmt:nnn

\msg_new:nnnn {phone} {no~ format} {Format~ `#1'~ is~ not~ recognised~ by~ this~ package,~ using~ the~ default~ `parendash'~ instead.} {}

\keys_define:nn { phone }
  {
    format .choice:,
    format .choice_code:n =
      {
        \cs_set_eq:Nc \phone_fmt:nnn 
        { phone_ \tl_use:N \l_keys_choice_tl _fmt:nnn }
      },
    format .generate_choices:n =
      {
        international,
        parendash,
      },
      format / unknown .code:n = {
        \msg_warning:nnn {phone} {no~ format} {#1}
      },
    unknown .code:n = {
      \phone_unknown_key:V \l_keys_key_tl
    },
  }

\cs_new:Npn \phone_unknown_key:n #1
{
  \keys_set:nn { phone} { format = #1 }
}

\cs_generate_variant:Nn \phone_unknown_key:n {V}


\ProcessKeysOptions { phone }

\NewDocumentCommand \phone
  { >{ \SplitArgument {2} {-} } m }
  { \phone_fmt:nnn #1 }

\endinput
\end{filecontents}
 \usepackage[british]{phone}

\begin{document}

\phone{212-555-1212}

\end{document}

答案2

您采取的方法看起来是正确的。在内部,该.meta:n属性正在创建一个标准键,它或多或少相当于

key-name-1 .code:n = { \keys_set:nn { module } { key-name-2 = #1 } }

如果你需要创建大量元键,则可能需要使用逗号列表映射

\clist_map_inline:nn { key-one , key-two , key-three ... }
  { \keys_define:nn { mymodule } { #1 .meta:n = { format = #1 } }

但对于一些人来说,这可能会使您的代码变得更加复杂而不是更简单。

相关内容