4

Trying to adapt the 1st code of this answer in order to format (say in bold) items of a LaTeX3 comma list, I stumbled upon an unexpected error: the following MWE works like a charm:

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\bolditems}{ m }
{
  \bold_items:n {#1}
}
\cs_new_protected:Npn \bold_items:n #1
{
  % does what the name suggests, set a sequence from the clist
  \seq_set_from_clist:Nn \l_tmpa_seq {#1}
  % applies final arg to each element of second seq and stores result in first seq
  \seq_set_map:NNn \l_tmpb_seq \l_tmpa_seq {
    ##1
    % \textbf{##1}
  }
  % \seq_use puts the items from the seq back in the input with "+" as a separator
  \seq_use:Nnnn \l_tmpb_seq {,~}{,~}{,~}
}
\ExplSyntaxOff
\begin{document}
\bolditems{}

\bolditems{foo}

\bolditems{foo,bar}

\bolditems{foo,bar,baz}
\end{document}

but, if ##1 is replaced by \textbf{##1}, fails with error:

! Argument of \reserved@a has an extra }.
<inserted text> 
                \par 
l.26 \bolditems{foo}

?

Why?

Denis Bitouzé
  • 9,652
  • 4
  • 27
  • 85
  • 1
    You should use \exp_not:N \textbf { ##1 }; as explained in the interface manual, \seq_set_map:NNn tries full expansion of the items it finds. Better yet, perhaps, \exp_not:n { \textbf { ##1 } } – egreg Oct 28 '15 at 18:39
  • 1
    As the documentation says the inline function is x-expanded. So better use \noexpand\textbf{##1} (or better the equivalent to \noexpand ;-)) – Ulrike Fischer Oct 28 '15 at 18:39
  • @egreg Please forgive my naivety, but why full expanded items would be a problem? – Denis Bitouzé Oct 28 '15 at 18:45

1 Answers1

6

The items passed through \seq_set_map:NNn are subject to full expansion. In the application showed in the linked to answer it's not really relevant, but it is in yours, because \textbf, and possibly also the items, doesn't survive full expansion. Just use \exp_not:n:

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\bolditems}{ m }
 {
  \bold_items:n {#1}
 }
\cs_new_protected:Npn \bold_items:n #1
 {
  % does what the name suggests, set a sequence from the clist
  \seq_set_from_clist:Nn \l_tmpa_seq {#1}
  % applies final arg to each element of second seq and stores result in first seq
  \seq_set_map:NNn \l_tmpb_seq \l_tmpa_seq { \exp_not:n { \textbf { ##1 } } }
  % \seq_use puts the items from the seq back in the input with "+" as a separator
  \seq_use:Nn \l_tmpb_seq {,~}
}
\ExplSyntaxOff
\begin{document}
X\bolditems{}X

X\bolditems{foo}X

X\bolditems{foo,bar}X

X\bolditems{foo,bar,baz}X
\end{document}

enter image description here

Note \seq_use:Nn that possibly was not available at the time the answer was written.

egreg
  • 1,121,712