如何使用 expl3 进行迭代期间处理序列成员?

如何使用 expl3 进行迭代期间处理序列成员?

我有几个环境,我想在它们之前和之后插入相同的代码。我想使用这个,expl3因为在我看来这是最好的解决方案。但我的解决方案不起作用,因为##1似乎无法扩展。

\documentclass{article}
\usepackage{expl3,etoolbox}
\begin{document}
\ExplSyntaxOn
\seq_const_from_clist:Nn\g__env_seq{equation,temp@env,align,multline}
\seq_map_inline:cn{g__env_seq}{
\BeforeBeginEnvironment{##1}{\message{before~##1}}
\AfterEndEnvironment{##1}{\message{after~##1}}
}
\ExplSyntaxOff
\makeatletter
\newenvironment{test@env}{\message{start~of~environment}}{\message{end~of~environment}}
\begin{equation}
x=0
\end{equation}
\begin{test@env}
some text
\end{test@env}
\makeatother
\end{document}

答案1

您不需要#在那里重复。每次引用位于另一个宏定义内的宏的参数时,您都需要重复使用哈希值。例如,如果您这样做:

\def\testout#1{%
  \def\testin##1{(#1) and (##1)}%
}
\testout{a} % This line does \def\testin#1{(a) and (#1)}
\testin{b} % this line prints "(a) and (b)"

参数#1指的是宏的参数\testout,而参数##1指的是的参数\testin。这适用于\seq_map_inline:Nn因为: \seq_map_inline:Nn <seq var> {<code>}基本上对中的每个项目执行\def\temp#1{<code>}然后调用。由于您是从任何宏定义外部调用的,因此不需要将中的哈希值加倍。另一方面,如果您执行以下操作:\temp<seq var>\seq_map_inline:Nn<code>

\cs_new:Npn \test:
  {
    \seq_map_inline:Nn <seq var> { <code> }
  }

那么中的哈希值<code>需要加倍,因为它们位于 的定义内\test:

这适用于更多级别的嵌套宏定义。每个定义在另一个定义中,都必须将哈希值加倍:

\def\testa#1{%
  \def\testb##1{%
    \def\testc####1{%
      \def\testd########1{%
        a(#1), b(##1), c(####1), and d(########1) :-)
      }%
    }%
  }%
}

修复这个问题然后你的代码就会打印(我替换\message\iow_term:n以获取换行符):

before equation
after equation
start of environment
end of environment

我还更改了代码中的其他一些内容。正如 egreg 在评论中所说,\g__env_seq不是一个好的变量名称,因为它缺少模块名称。此外,由于您使用 来定义它,因此该变量是一个常量,因此名称应该以 开头,而不是。更好的名称应该是(两个下划线不是必需的,因为它不是包内部的变量)。\seq_const_from_clist:Nn\c_...\g_...\c_kozlovskiy_env_seq

此外,由于您似乎只使用过此列表一次,因此无需为其定义变量:您可以\clist_map_inline:nn直接使用。

工作代码:

\documentclass{article}
\usepackage{expl3,etoolbox}
\begin{document}
\ExplSyntaxOn
\clist_map_inline:nn { equation , temp@env , align , multline }
  {
    \BeforeBeginEnvironment {#1} { \iow_term:n { before~#1 } }
    \AfterEndEnvironment {#1} { \iow_term:n { after~#1 } }
  }
\newenvironment{test@env}
  { \iow_term:n {start~of~environment} }
  { \iow_term:n {end~of~environment} }
\ExplSyntaxOff
\begin{equation}
x=0
\end{equation}
\begin{test@env}
some text
\end{test@env}
\end{document}

相关内容