12

I'm trying to build a macro that processes a comma-separated-list of elements so that:

\MapAndUse{a,b,c}

would produce:

expected

My first intuition is to use a expl3 combination of \seq_map* to process each element in turn (here, wrap into parentheses) then \seq_use* to organize them around -- markers.

But this does not work as expected:

\documentclass{standalone}

\usepackage{expl3}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\MapAndUse}{ m }{%
    \seq_set_from_clist:Nn \l_raw_seq {#1}
    \seq_map_variable:NNn \l_raw_seq \i {(\i)}
    % \seq_show:N \l_raw_seq
    \seq_use:Nn \l_raw_seq {\ --\ }
}

\ExplSyntaxOff

\begin{document}

\MapAndUse{a,b,c}

\end{document}

Since it produces:

unexpected

From what I understand:

  • from the doc: \seq_map_* macros directly expand to the input stream.
  • from \seq_show:N \l_raw_seq: the sequence is not actually affected by the\seq_map command (elements are not parenthesized)
The sequence \l_raw_seq contains the items (without outer braces):
>  {a}
>  {b}
>  {c}.

How do I process each element "in place" with \seq_map* without having them pushed to the input stream?

Naive tries:

  • \seq_set_from_clist:Nx \l_processed_seq {\seq_map_variable:NNn \l_raw_seq \i {,(\i)}}: does not compile in consistence with the doc: this Nx variant does not exist, and \seq_map* cannot be expanded this way into another "variable".
  • \Use{\Map{a,b,c}} with a 2-stages processing: does not work as expected since \Map{a,b,c} remains unexpanded.

Is there anything I've missed about expl3 logic there?
Is it possible to process my comma-separated input this way?
Are there alternatives or workarounds?

1 Answer 1

12

You can use two sequences; first apply the mapping to get the “adorned” items, then use them.

\documentclass{article}

\usepackage{expl3}
\usepackage{xparse}

\ExplSyntaxOn

\seq_new:N \l__iagolito_in_seq
\seq_new:N \l__iagolito_out_seq

\NewDocumentCommand{\MapAndUse}{ m }
 {
  \seq_set_from_clist:Nn \l__iagolito_in_seq { #1 }
  \seq_set_map:NNn \l__iagolito_out_seq \l__iagolito_in_seq { (\exp_not:n { ##1 }) }
  \seq_use:Nn \l__iagolito_out_seq {~--~}
}

\ExplSyntaxOff

\begin{document}

\MapAndUse{a,b,c}

\end{document}

An extended version where you can specify how to adorn the items and what to use between them:

\documentclass{article}

\usepackage{expl3}
\usepackage{xparse}

\ExplSyntaxOn

\seq_new:N \l__iagolito_in_seq
\seq_new:N \l__iagolito_out_seq

\NewDocumentCommand{\MapAndUse}{ mmm }
 {
  \cs_set_protected:Nn \__iagolito_mapanduse:n { #2 }
  \seq_set_from_clist:Nn \l__iagolito_in_seq { #1 }
  \seq_set_map:NNn \l__iagolito_out_seq \l__iagolito_in_seq
   {
    \__iagolito_mapanduse:n { \exp_not:n { ##1 } }
   }
  \seq_use:Nn \l__iagolito_out_seq { #3 }
}

\ExplSyntaxOff

\begin{document}

\MapAndUse{a,b,c}{(#1)}{ -- }

\end{document}

enter image description here

5
  • 2
    Awesome, cheers :) I was missing \seq_set_map and \exp_not. It turns out the second one was actually the one I was trying to build :)
    – iago-lito
    Commented Feb 16, 2019 at 12:21
  • \MapAndUse does not work within \caption in a figure environment, what could be wrong? The compiler spits ! Illegal parameter number in definition of \reserved@a. <to be read again> I can work around this bug using \savebox.
    – iago-lito
    Commented Feb 18, 2019 at 9:17
  • 1
    @iago-lito The generic \MapAndUse should be employed for defining semantic macros rather than explicitly. Do \NewDocumentCommand{\parendash}{m}{\MapAndUse{#1}{(##1)}{ -- }} and use \parendash{a,b,c}.
    – egreg
    Commented Feb 18, 2019 at 9:27
  • This is what I actually did but the error was spat by the very semantic macro. My mistake was to define the semantic macro with \newcommand instead of \NewDocumentCommand.. so your version does work :)
    – iago-lito
    Commented Feb 18, 2019 at 9:37
  • 1
    @iago-lito Always remember that the argument to \caption is a moving argument and that fragile commands need to be protected or made robust at the outset (which \NewDocumentCommand does).
    – egreg
    Commented Feb 18, 2019 at 9:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .