将输入解析为 expl3 中的命令

将输入解析为 expl3 中的命令

再次向@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?我该从哪里开始呢?

相关内容