如何从标记列表变量中设置函数的替换文本?

如何从标记列表变量中设置函数的替换文本?

我正在尝试在 expl3 中定义一个带有参数的本地函数,其中该函数的替换文本应该是标记列表变量的内容。

我目前的方法是

\tl_set:Nn \l_tmpa_tl { \textbf{##1} }
\exp_args:NNnV \cs_set:Npn \foo {##1} \l_tmpa_tl
\cs_show:N \foo

预期输出如下

\foo #1:->\textbf {#1}

但结果是

! Illegal parameter number in definition of \reserved@b.

如何处理 expl3 中的此类动态函数定义?

答案1

主要问题是参数文本不能用括号括起来。您可以使用“无参数”语法跳过它。请参阅https://tex.stackexchange.com/search?q=cs_set%3ANV使用示例

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\tl_set:Nn \l_tmpa_tl { \textbf{#1} }

\exp_args:NNV \cs_new:Nn \foo:n \l_tmpa_tl
\cs_set_eq:NN \foo \foo:n

\cs_show:N \foo

控制台上的输出是

> \foo=\long macro:#1->\textbf {#1}.

您也可以使用参数,但它真的很丑陋:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\exp_args_generate:n { NNNV }

\tl_set:Nn \l_tmpa_tl { \textbf{#1} }
\tl_set:Nn \l_tmpb_tl { #1 }

\exp_args:NNNNV
\exp_last_unbraced:NNV
\cs_new:Npn \foo \l_tmpb_tl \l_tmpa_tl

\cs_show:N \foo

答案2

有一个p参数类型,它是 TeX 参数的包装器#{。优点是宏的参数文本中有效的任何内容在这里都是有效的,而无需更改代码。缺点是后面的参数必须是用大括号括起来的,因此您要么需要将扩展​​类型从 更改为Vo由于实现细节,这将起作用),要么将用大括号括起来的单标记参数传递给V(由于另一个实现细节,这将起作用)。

为了遵守expl3语法并使用所需的括号,p您可以使用v

\documentclass{article}
\usepackage{expl3}
\ExplSyntaxOn
\exp_args_generate:n { Npv } % p = #{
%
\tl_set:Nn \l_tmpa_tl { \textbf{#1} }
\exp_args:NNpv \cs_set:Npn \foo #1 { l_tmpa_tl }
% \foo=\long macro:#1->\textbf {#1}.
\exp_args:NNpv \cs_set:Npn \bold text #1 { l_tmpa_tl }
% \bold=\long macro:text#1->\textbf {#1}.
\ExplSyntaxOff
\begin{document}
\foo{hello} \bold text{world}
\end{document}

相关内容