expl3 宏可扩展地迭代列表并对每个项目应用宏

expl3 宏可扩展地迭代列表并对每个项目应用宏

如果可能的话,有人能告诉我如何\applyeach使用来扩展以下宏()吗?expl3

\documentclass{article}

\newcounter{applyeachposition}
\newcommand\applyeachmacro{}


% #1 : macro to apply
% #2 : multi-args
\newcommand\applyeach[2]{
    \setcounter{applyeachposition}{0}
    \renewcommand\applyeachmacro{#1}
    \applyeachrecu#2|\nil
    \renewcommand\applyeachmacro{}
}


\def\applyeachrecu#1|#2\nil{
    \stepcounter{applyeachposition}
    \applyeachmacro{#1}
    \if\relax\detokenize{#2}\relax\else
        \applyeachrecu#2\nil
    \fi
}


\newcommand\decoone[1]{%
    [(\textbf{#1})] \quad%
}

\newcommand\multiapply[1]{%
    \applyeach{\decoone}{#1}
}
 

\begin{document}

\multiapply{1|12|123|1234}

\end{document}

答案1

由于无法更改分隔符,因此定义非常简单。不过请注意,正如 egreg 所说,设置计数器是一种赋值,而赋值是不是可扩展,所以您不能使用它们。您必须“动态”增加一个数字并将其传递给宏,但不能将其作为计数器。

宏本身在 a 处拆分参数,|并对其应用给定函数,直到循环结束。添加 a \prg_do_nothing:(稍后再删除)会处理参数周围的括号项和空格。如果您需要更改分隔符,那么代码将变得更加复杂。

我这样定义\multiapply<cmd>{<list>}它,使其在|-separated上迭代<list>并应用于<cmd>每个项目。需要<cmd>采用两个参数:#1是列表中项目的编号,#2是项目本身。

在此处输入图片描述

\documentclass{article}

\ExplSyntaxOn
\NewExpandableDocumentCommand \multiapply { m +m }
  { \mbc_multiapply:Nn #1 {#2} }
\cs_new:Npn \mbc_multiapply:Nn #1 #2
  {
    \__mbc_multiapply:nNw { 0 } #1
      | \prg_do_nothing: #2 | \q_recursion_tail | \q_recursion_stop
  }
\cs_new:Npn \__mbc_multiapply:nNw #1 #2 | #3 |
  { \exp_args:Nof \__mbc_multiapply:nnN {#3} { \int_eval:n {#1+1} } #2 }
\cs_new:Npn \__mbc_multiapply:nnN #1 #2 #3
  {
    \quark_if_recursion_tail_stop:n {#1}
    \exp_not:e { \exp_not:N #3 {#2} { \tl_trim_spaces:n {#1} } }
    \__mbc_multiapply:nNw {#2} #3 | \prg_do_nothing:
  }
\ExplSyntaxOff

\newcommand\decoone[2]{%
  Item #1: [(\textbf{#2})]\quad}

\begin{document}
\multiapply\decoone{ 1 | 12 | 123 | 1234 }
\end{document}

相关内容