我有两组 keyval 参数和两个函数,我希望它们的行为像下面的玩具 MWE 一样。
\documentclass{article}
\usepackage{xkeyval}
\usepackage{xparse}
\makeatletter
\define@key{A}{a1}{\def\a@aOne{#1}}
\define@key{A}{a2}{\def\a@aTwo{#1}}
\DeclareDocumentCommand{\A}{ m }{%
\begingroup
\setkeys{A}{a1={}, a2={}, #1}
\fbox{$a_1$ = \a@aOne, $a_2$ = \a@aTwo}
\endgroup
}
\define@key{B}{left}{\def\b@left{#1}}
\define@key{B}{right}{\def\b@right{#1}}
\DeclareDocumentCommand{\B}{ m }{%
\begingroup
\setkeys{B}{left={}, right={}, #1}
\A{\b@left} \A{\b@right}
\endgroup
}
\makeatother
\begin{document}
\A{a1=1, a2=2}
\B{left={a1=1, a2=2}, right={a1=1, a2=2}}
\end{document}
但是我收到错误! Package xkeyval Error: 'a1=1, a2=2' undefined in families 'A' at line with using command
B`。
看完之后这个问题我理解为什么会发生这种情况,但无法将给出的建议应用于我的情况。在这种情况下如何进行正确的解析?
谢谢。
答案1
对于这种情况,解决方案就是使用 扩展\b@...
键\expandafter
,以便将其扩展值传递给\A
。因此,将您的\B
定义更改为以下内容:
\DeclareDocumentCommand{\B}{ m }{%
\begingroup
\setkeys{B}{left={}, right={}, #1}%
\expandafter\A\expandafter{\b@left}%
\expandafter\A\expandafter{\b@right}%
\endgroup
}
完整更新的示例(%
在行尾添加了一些额外的 s 以防止输出中出现多余的空格):
\documentclass{article}
\usepackage{xkeyval}
\usepackage{xparse}
\makeatletter
\define@key{A}{a1}{\def\a@aOne{#1}}
\define@key{A}{a2}{\def\a@aTwo{#1}}
\DeclareDocumentCommand{\A}{ m }{%
\begingroup
\setkeys{A}{a1={}, a2={}, #1}%
\fbox{$a_1$ = \a@aOne, $a_2$ = \a@aTwo}%
\endgroup
}
\define@key{B}{left}{\def\b@left{#1}}
\define@key{B}{right}{\def\b@right{#1}}
\DeclareDocumentCommand{\B}{ m }{%
\begingroup
\setkeys{B}{left={}, right={}, #1}%
\expandafter\A\expandafter{\b@left}%
\expandafter\A\expandafter{\b@right}%
\endgroup
}
\makeatother
\begin{document}
\A{a1=1, a2=2}
\B{left={a1=1, a2=2}, right={a1=3, a2=4}}
\end{document}
输出
答案2
我会直接选择l3keys
:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\evalA}{m}
{
\robur_eval_a:n { #1 }
}
\NewDocumentCommand{\evalB}{m}
{
\robur_eval_b:n { #1 }
}
\keys_define:nn { robur/A }
{
a1 .tl_set:N = \l__robur_A_aone_tl,
a2 .tl_set:N = \l__robur_A_atwo_tl,
}
\keys_define:nn { robur/B }
{
left .tl_set:N = \l__robur_B_left_tl,
right .tl_set:N = \l__robur_B_right_tl,
}
\cs_new_protected:Nn \robur_eval_a:n
{
\group_begin:
\keys_set:nn { robur/A } { a1=, a2=, #1 }
\fbox{$a\sb{1}=\l__robur_A_aone_tl$,~$a\sb{2}=\l__robur_A_atwo_tl$}
\group_end:
}
\cs_generate_variant:Nn \robur_eval_a:n { V }
\cs_new_protected:Nn \robur_eval_b:n
{
\group_begin:
\keys_set:nn { robur/B } { left=, right=, #1 }
\robur_eval_a:V \l__robur_B_left_tl
\robur_eval_a:V \l__robur_B_right_tl
\group_end:
}
\ExplSyntaxOff
\begin{document}
\evalA{a1=1, a2=2}
\evalB{left={a1=1, a2=2}, right={a1=3, a2=4}}
\end{document}
不\expandafter
,由于V
变体:\robur_eval_a:V <tl variable>
与
\robur_eval_a:n { <contents of the tl variable> }