我有一些相当复杂的参数,必须逐步构建,然后传递给另一个宏。MWE 大大简化了。
这是我使用 的尝试expl3
。问题是无论我如何尝试\exp_args:....
(无论是NnV
、Nno
、Nnx
),扩展都不会像我预期的那样发生。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\tl_new:N \l_aepoly_arguments_tl
\NewDocumentCommand\macroA{ mmmm }
{
\tl_set:Nx \l_aepoly_arguments_tl
{
{\fp_eval:n { #1*#3 }}
{\fp_eval:n { #1*#4 + #2*#3 }}
{\fp_eval:n { #2*#4}}
}
\iow_term:x {===> \l_aepoly_arguments_tl }
\exp_args:NnV \_aepoly_parse:nnnn {SIMPLIFIED} \l_aepoly_arguments_tl
}
\NewDocumentCommand\macroB{ mmmm }
{
\_aepoly_parse:nnnn {#1}{#2}{#3}{#4}
}
\cs_new:Npn \_aepoly_parse:nnnn #1#2#3#4 {
%% something elaborate, but below will suffic for MWE
\iow_term:n {===>(#1)[#2][#3][#4]}
\fbox{#1} $\rightarrow #2x^2 + #3x + #4$
}
\ExplSyntaxOff
\pagestyle{empty}
\begin{document}
\macroB{Poly}{3}{4}{5}
\macroA{2}{3}{5}{2}
{NOT}{THIS}
\end{document}
如果我没有写这篇文章,expl3
我将会做一些如下的事情,这些事情会按照我预期的方式进行。
\documentclass{article}
\makeatletter
\def\aetypeout#1{\typeout{===>#1}}
\newcommand\macroA[4]{%%
\def\ae@tmp@A{%%
{\number\numexpr #1*#3\relax}%%
{\number\numexpr #1*#4 + #2*#3\relax}%%
{\number\numexpr #2*#4\relax}}%%
\expandafter\aetypeout\expandafter{\l_aepoly_arguments_tl}%%
\def\ae@tmp@B{{SIMPLIFIED}}%%
\expandafter\ae@parse\expandafter\ae@tmp@B\ae@tmp@A
}
\newcommand\macroB[4]{\ae@parse{#1}{#2}{#3}{4}}
\def\ae@parse#1#2#3#4{%%
\typeout {===>(#1)[#2][#3][#4]}%%
\fbox{#1} $\rightarrow #2x^2 + #3x + #4$%%
}
\makeatother
\begin{document}
\macroB{Poly}{3}{4}{5}
\macroA{2}{3}{5}{2}
{NOT}{THIS}
\end{document}
的优点expl3
是它能够更好地处理算术(除其他外)。我知道我可以将参数的每个部分保存到标记列表中,然后创建\_aepoly_parse:nnnn
诸如 的变体\_aepoly_parse:nVVV
。但目前这会使我正在处理的文档变得过于复杂。
答案1
如果你
\cs_new:Npn \xyz_func:n #1
{
code with #1
}
\cs_generate_variant:Nn \xyz_func:n { V }
然后调用
\tl_set:Nn \l_xyz_var_tl { aaa }
\xyz_func:V \l_xyz_var_tl
相当于调用
\xyz_func:n { aaa }
你必须执行两个步骤。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\tl_new:N \l_aepoly_arguments_tl
\NewDocumentCommand\macroA{ mmmm }
{
\tl_set:Nx \l_aepoly_arguments_tl
{
{\fp_eval:n { #1*#3 }}
{\fp_eval:n { #1*#4 + #2*#3 }}
{\fp_eval:n { #2*#4}}
}
\iow_term:x {===> \l_aepoly_arguments_tl }
\__aepoly_parse_aux:nV {SIMPLIFIED} \l_aepoly_arguments_tl
}
\NewDocumentCommand\macroB{ mmmm }
{
\__aepoly_parse:nnnn {#1}{#2}{#3}{#4}
}
\cs_new:Npn \__aepoly_parse_aux:nn #1 #2
{
\__aepoly_parse:nnnn { #1 } #2
}
\cs_generate_variant:Nn \__aepoly_parse_aux:nn { nV }
\cs_new_protected:Npn \__aepoly_parse:nnnn #1 #2 #3 #4
{
%% something elaborate, but below will suffic for MWE
\iow_term:n {===>(#1)[#2][#3][#4]}
\fbox{#1} $\rightarrow #2x^2 + #3x + #4$
}
\ExplSyntaxOff
\pagestyle{empty}
\begin{document}
\macroB{Poly}{3}{4}{5}
\macroA{2}{3}{5}{2}
\end{document}
因此辅助宏只是调用主宏并去掉括号。
请注意,私有函数的约定是二下划线开头。此外,该函数\__aepoly_parse:nnnn
应该受到保护。
您可能使用\exp_last_unbraced:NV
,但是当有其他方法时,它们更为可取。
当然,你也可以简单地这样做
\NewDocumentCommand\macroA{ mmmm }
{
\__aepoly_parse:nxxx
{SIMPLIFIED}
{\fp_eval:n { #1*#3 }}
{\fp_eval:n { #1*#4 + #2*#3 }}
{\fp_eval:n { #2*#4}}
}
(生成变体)如果您不需要诊断。