2

(This question is somehow related to this answer.)

I want to create a document command with an arbitrary number of (comma separated) parameters, each of them being a comma list, the items of which having to be processed.

The following MCE:

\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand\signature{m}
 {
  \__mymodule_process_list:n {#1}
 }
\seq_new:N \l__mymodule_items_seq
\cs_new_protected:Npn \__mymodule_process_list:n #1
{
  \seq_clear:N \l__mymodule_items_seq
  \seq_set_from_clist:Nn \l_tmpa_seq {#1}
  \seq_map_inline:Nn \l_tmpa_seq {
    \seq_set_from_clist:Nn \l_tmpb_seq {##1}
    \seq_get_right:NN \l_tmpb_seq \l_tmpa_tl
    \seq_get_left:NN \l_tmpb_seq \l_tmpb_tl
    \seq_put_right:Nx \l__mymodule_items_seq {
    % \seq_put_right:NV \l__mymodule_items_seq {
      \l_tmpa_tl
      \c_space_tl \l_tmpb_tl
      % \c_space_tl \textsc{\l_tmpb_tl}
    }
  }
  \seq_use:Nn \l__mymodule_items_seq { ~ \& ~ }
}
\ExplSyntaxOff

\begin{document}
\signature{
  {Last1, First1}
}

\signature{
  {Last1, First1},
  {Last2, First2}
}

\signature{
  {Last1, First1},
  {Last2, First2},
  {Last3, First3}
}
\end{document}

works well, that is, the result is:

First1 Last1
First1 Last1 & First2 Last2
First1 Last1 & First2 Last2 & First3 Last3

but, if I replace \c_space_tl \l_tmpb_tl by \c_space_tl \textsc{\l_tmpb_tl} in order to get the last names in small caps, LaTeX complains:

! Missing control sequence inserted.
 <inserted text>
\inaccessible ```

In this context, if I replace \seq_put_right:Nx by e.g. \seq_put_right:NV, the compilation goes smoothly, but the result isn't the expected one (same last name on each line):

First1 Lᴀꜱᴛ1
First1 Lᴀꜱᴛ2 & First2 Lᴀꜱᴛ2 
First1 Lᴀꜱᴛ3 & First2 Lᴀꜱᴛ3 & First3 Lᴀꜱᴛ3

With \seq_put_right:Nx and, instead of \textsc{\l_tmpb_tl}, {\scshape \l_tmpb_tl}, it works as expected but why doesn't it work with \textsc{\l_tmpb_tl}?

2
  • 1
    Try \exp_not:N \textsc Jun 3 at 13:49
  • @PhelypeOleinik Exactly! Sigh... expansion... ;) If you turn your comment into a n answer I could accept it. Jun 3 at 13:52
1

You need to prevent the expansion of \textsc (or any other macro that should not expand) with \exp_not:N, so

\seq_put_right:Nx \l__mymodule_items_seq
  { \c_space_tl \exp_not:N \textsc { \l_tmpb_tl } }
%               ^^^^^^^^^^

Your usage of the NV variant is wrong. The V-type is supposed to take a single variable as argument, so this would be correct:

\seq_put_right:NV \l__mymodule_items_seq \l_tmpb_tl

this would be a slightly weird syntax (though not necessarily wrong):

\seq_put_right:NV \l__mymodule_items_seq { \l_tmpb_tl }

and this is completely off

\seq_put_right:NV \l__mymodule_items_seq { \l_tmpa_tl \l_tmpb_tl }

\scshape works (after \begin{document}) because it is defined with \protected. If you do \ShowCommand\scshape, you will see \scshape=\protected macro:->[...], so it does not expand in \edef (used by the x expansion in \seq_put_right:Nx).

\textsc, on the other hand, is a robust macro (\ShowCommand\textsc):

> \textsc=robust macro:
->\protect \textsc  .

> \textsc =\long macro:
#1->[...]

so it breaks inside an \edef (it would need \protected@edef to not explode).

1

You can use \exp_not:N \textsc, but tokens in the names could bomb as well. I suggest wrapping with \text_expand:n the parts were textual input might contain dangerous tokens.

\documentclass{article}

\ExplSyntaxOn

\NewDocumentCommand\signature{m}
 {
  \__mymodule_process_list:n {#1}
 }

\seq_new:N \l__mymodule_items_seq

\cs_new_protected:Npn \__mymodule_process_list:n #1
 {
  \seq_clear:N \l__mymodule_items_seq
  \seq_set_from_clist:Nn \l_tmpa_seq {#1}
  \seq_map_inline:Nn \l_tmpa_seq
   {
    \seq_set_from_clist:Nn \l_tmpb_seq {##1}
    \seq_get_right:NN \l_tmpb_seq \l_tmpa_tl
    \seq_get_left:NN \l_tmpb_seq \l_tmpb_tl
    \seq_put_right:Nx \l__mymodule_items_seq
     {
      \text_expand:n { \l_tmpa_tl \c_space_tl \textsc { \l_tmpb_tl } }
     }
   }
  \seq_use:Nn \l__mymodule_items_seq { ~ \& ~ }
 }
\ExplSyntaxOff

\begin{document}
\signature{
  {Last1, First1}
}

\signature{
  {Last1, First1},
  {Last2, First2}
}

\signature{
  {Last1, First1},
  {Last2, First2},
  {La\'st3, F\'irst3}
}
\end{document}

enter image description here

1
  • Tokens in the names seem to be harmless in case { \scshape \l_tmpb_tl } is used instead of \textsc { \l_tmpb_tl }, isn't it? Jun 4 at 19:53

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.