我创建了一个简单的包,其中的选项可以通过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
而不是令牌列表变量。
我还将 修复NNN
为nnn
。因为我想设置默认值,所以键处理程序中的设置器现在是\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 } }
但对于一些人来说,这可能会使您的代码变得更加复杂而不是更简单。