下面是一段小代码,其中宏允许的键值是一个不需要的功能:例如, single[both = OK, only = KO]
没有像我希望的那样给出任何错误。但另一方面,我也想吃掉这种不需要的键:参见\single
内部的调用\both
。具体来说,我想\single
在调用时使用选项\both
,但也允许从中使用更多选项\both
。
\documentclass{article}
\ExplSyntaxOn
\tl_new:N \l_mbc_both_tl
\tl_new:N \l_mbc_only_tl
\keys_define:nn { strict-mode } {
both .tl_set:N = \l_mbc_both_tl,
both .groups:n = { single-use },
only .tl_set:N = \l_mbc_only_tl,
only .groups:n = { both-use },
}
\NewDocumentCommand{\single}{ O{} }{
\group_begin:
\keys_set_groups:nnn { strict-mode }
{ single-use }
{ #1 }
Single used...
\group_end:
}
\NewDocumentCommand{\both}{ O{} }{
\group_begin:
\keys_set:nn { strict-mode } { #1 }
Both used... ~ \single[#1]
\group_end:
}
\ExplSyntaxOff
\begin{document}
\single[both = OK]
\single[both = OK, only = KO]
\single[after = math KO]
\both[both = OK]
\both[both = OK, only = OK]
\both[after = math OK]
\end{document}
有没有办法定义只允许在一个环境中使用的子键?
答案1
一种方法是使用两条路径。然后处理应接受其他密钥的命令,方法是首先针对一条路径处理已知密钥,然后针对另一条路径处理剩余密钥。这样,两个命令都会为完全未知的密钥(after
)生成错误,而限制性更强的命令也会为专门为扩展性更强的命令(only
)定义的密钥生成错误。
在下面的代码中,我通过排版“未知密钥”消息来防止错误,这只是为了举例。显然,您可以在实际代码中重新定义它,或者直接删除它并使用默认消息。
\documentclass{article}
\ExplSyntaxOn
%
% internal names should be double-underscored
\tl_new:N \l__mbc_both_tl
\tl_new:N \l__mbc_only_tl
\keys_define:nn { mbc / strict-mode / common } {% try to guarantee unique name space
both .tl_set:N = \l__mbc_both_tl,
unknown .code:n = { % just for testing
\texttt{\l_keys_key_str} ~ not ~ recognised! \par
},
}
\keys_define:nn { mbc / strict-mode / exclusive } {% try to guarantee unique name space
only .tl_set:N = \l__mbc_only_tl,
}
\NewDocumentCommand {\single}{ O{} }{
\group_begin:
\keys_set:nn { mbc / strict-mode / common } { #1 }
\texttt{\textbackslash l \_\_ mbc \_ both \_ tl} ~ is ~ \texttt{\l__mbc_both_tl}\par
\texttt{\textbackslash l \_\_ mbc \_ only \_ tl} ~ is ~ \texttt{\l__mbc_only_tl}\par
\group_end:
}
\NewDocumentCommand {\both}{ O{} }{
\group_begin:
\keys_set_known:nnN { mbc / strict-mode / exclusive } { #1 } \l_tmpa_tl
\keys_set:nV { mbc / strict-mode / common } \l_tmpa_tl
\texttt{\textbackslash l \_\_ mbc \_ both \_ tl} ~ is ~ \texttt{\l__mbc_both_tl}\par
\texttt{\textbackslash l \_\_ mbc \_ only \_ tl} ~ is ~ \texttt{\l__mbc_only_tl}\par
\group_end:
}
\ExplSyntaxOff
\begin{document}
\single[both = OK]
\single[both = OK, only = KO]
\single[after = math KO]
\both[both = OK]
\both[both = OK, only = OK]
\both[after = math OK]
\end{document}