再次向@egreg 致敬,感谢他们的精彩表现解释3 技巧最终,我找到了这个\apply
我一直使用的宏:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
% use: \apply[parse][separator]{function}{list}
\NewDocumentCommand{\apply}{ O{##1} O{} m +m}{%
\Apply:nnnf { #1 } { #2 } { #3 } { #4 }%
}
% The list built and processed from the input items.
\seq_new:N \l__Apply_input_seq
% The list finally reinjected in the input stream with separators.
\seq_new:N \l__Apply_output_seq
% Main function.
\cs_new_protected:Nn \Apply:nnnn
{%
% Build up input list from comma-separated items.
\seq_set_from_clist:Nn \l__Apply_input_seq { #4 }%
% Define the function to map along the parsed sequence.
\cs_set:Npn \__Apply_process_multi_args:w%
#1 \q_stop % The 'arguments'
{ \exp_not:n { #3 } } % The 'body'
% Wrap the mapped function into a function that only takes 1 argument.
\cs_set:Nn \__Apply_process_single_arg:n%
{ \__Apply_process_multi_args:w ##1 \q_stop }%
% Map the function along the sequence.
\seq_set_map:NNn \l__Apply_output_seq \l__Apply_input_seq%
{%
% Expansion fiddling?
\__Apply_process_single_arg:f { \exp_not:n { ##1 } }%
}%
% Reinject into the input stream with the requested separator.
\seq_use:Nn \l__Apply_output_seq { #2 }%
}
% Extend signature so it correctly expands items?
\cs_generate_variant:Nn \__Apply_process_single_arg:n { f }%
% Extend signature so it correctly expands the input list?
\cs_generate_variant:Nn \Apply:nnnn { nnnf }%
\ExplSyntaxOff
\begin{document}
\apply[#1:#2 -> #3][, ]{%
#1 and #2 yield #3%
}{
first:last -> mid,
5:8 -> 13,
good:bad -> well,
}
\end{document}
为了改进 的使用\apply
,我希望[parse]
提供命名插槽的参数,这些插槽将在主体内expl3
转换为可扩展的。简而言之,上面的调用将被替换为csname
{function}
\apply[\some:\other -> \result][, ]{%
\some{} and \other{} yield \result
}{
first:last -> mid,
5:8 -> 13,
good:bad -> well,
}
那么为什么不把两者结合起来呢?
\apply[#1:\other -> #2][, ]{%
#1 and \other{} yield #2%
}{
first:last -> mid,
5:8 -> 13,
good:bad -> well,
}
这可以用 实现吗expl3
?我该从哪里开始呢?