6

I'm trying to define a local function with parameters in expl3 where the replacement text of that function should be the content of a token list variable.

My current approach is

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

where the expected output is something like

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

but it results in

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

How do you handle such dynamic function definitions in expl3?

6

The main problem is the parameter text that must not be braced. You can skip it by using the “without parameter” syntax. See https://tex.stackexchange.com/search?q=cs_set%3ANV for examples of usage

\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

The output on the console is

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

You can also do with the parameters, but it's really ugly:

\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
3

There is the p argument type, which is a wrapper around TeX's #{ argument. The advantage is that anything valid in the parameter text of a macro is valid here without changing the code. The downside is that the argument that follows must be braced, so you'd either need to change the expansion type from V to o (which will work because of an implementation detail), or to pass a braced, single-token argument to V (which will work because of another implementation detail).

To stick with the expl3 syntax and have the braces required for p you can use 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}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.