10

I want to process a clist, and I can't use \clist_use:Nn as I have to some rather complicated things with the items. But how do you remove the final separator without to much fuss when using \clist_map_inline:Nn?

\documentclass[a4paper]{article}
\usepackage{expl3}
\begin{document}
\ExplSyntaxOn
\clist_const:Nn\c_UF_clist {a,b,c,d}

\clist_map_inline:Nn\c_UF_clist
{\textbf{#1},~} %no comma after d!!!!
\ExplSyntaxOff
\end{document}

enter image description here

Ulrike Fischer
  • 327,261
  • 4
    I've seen egreg first poping the left item, and then use {,~\textbf{#1} mapping the rest of the clist. Still, I don't know what's the “official way”. May be something similar to \seq_set_map:NNn \foo \bar {\textbf{#1}} and then \seq_use:Nn \foo {,~}? – Manuel Mar 09 '15 at 19:50
  • Perhaps this might be helpful - splitting the list first. – Werner Mar 09 '15 at 19:52

2 Answers2

8

Without using sequences, you can pop the leftmost item in the clist and map the remaining clist:

\documentclass{article}
\usepackage{expl3}

\ExplSyntaxOn

\tl_new:N \l__UF_clist_use_head_tl
\clist_new:N \l__UF_clist_use_tail_clist
\cs_new_protected:Npn \UF_clist_use:NNn #1 #2 #3
 {
  \clist_set_eq:NN \l__UF_clist_use_tail_clist #1
  \clist_pop:NN \l__UF_clist_use_tail_tl \l__UF_clist_use_head_tl
  \exp_args:NV #2 \l__UF_clist_use_head_tl
  \clist_map_inline:Nn \l__UF_clist_use_tail_clist
   {
    #3 #2 { ##1 }
   }
 }

\clist_const:Nn \c_UF_clist {a,b,c,d}

\begin{document}

\UF_clist_use:NNn \c_UF_clist \textbf { ,~ }

\end{document}

The first argument of \UF_clist_xuse:NNn is a clist variable, the second argument is a one parameter function (here \textbf) and the third argument is the separator between arguments. This function can't be nested, but it doesn't seem to be a big limitation.

enter image description here

If you plan to emulate \clist_use:Nnnn, then transforming the clist into a sequence and applying \seq_set_map:NNn seems the best approach.

Kernel functions called \seq_use:NNnnn, \seq_use:NNn, \clist_use:NNnnn and \clist_use:NNn, where the second argument is a one parameter function to be applied to each item, would be welcome, in my opinion (even if they aren't fully expandable).

egreg
  • 1,121,712
5

This, seems to me, is natural, although a bit tedious. (I leave the \seq_pop_left:NN option for another answer).

\documentclass[a4paper]{article}
\usepackage{expl3}
\begin{document}
\ExplSyntaxOn
\seq_set_from_clist:Nn \l_tmpa_seq { a , b , c , d }
\seq_set_map:NNn \l_tmpb_seq \l_tmpa_seq { \exp_not:n { \textbf { #1 } } }
\seq_use:Nn \l_tmpb_seq { ,~ }
\ExplSyntaxOff
\end{document}

In case you can't use \seq_set_map:NNn because of its experimentalness, you can define your own function

\seq_new:N \l__map_and_use_seq
\cs_new_protected:Npn \uf_seq_map_use:Nnn #1 #2 #3
 {
  \seq_clear:N \l__map_and_use_seq
  \seq_map_inline:Nn #1 { \seq_put_right:Nn \l__map_and_use_seq { #2 } }
  \seq_use:Nn \l__map_and_use_seq { #3 }
 }

\seq_set_from_clist:Nn \l_tmpa_seq { a , b , c , d }    
\uf_seq_map_use:Nnn \l_tmpa_seq { \textbf { [#1] } } { ,~ }

Or even clist directly if you prefer

\seq_new:N \l__map_and_use_seq
\seq_new:N \l__set_and_map_seq
\cs_new_protected:Npn \uf_clist_map_use:nnn #1 #2 #3
 {
  \seq_clear:N \l__map_and_use_seq
  \seq_set_from_clist:Nn \l__set_and_map_seq { #1 }
  \seq_map_inline:Nn \l__set_and_map_seq { \seq_put_right:Nn \l__map_and_use_seq { #2 } }
  \seq_use:Nn \l__map_and_use_seq { #3 }
 }

\uf_clist_map_use:nnn { a , b , c , d } { \textbf { [#1] } } { ,~ }
Manuel
  • 27,118
  • This looks quite natural (apart from the fact that one has to convert to a sequence first, perhaps I should create sequences from start), but I can't use \seq_set_map:NNn as it is marked as "experimental" in source3.pdf. – Ulrike Fischer Mar 10 '15 at 08:50
  • You could declare a new function. – Manuel Mar 10 '15 at 12:05
  • @UlrikeFischer Part of the reason for having experimental functions is to see if they are useful! We don't remove stuff unless we have first checked for use in TeX Live. – Joseph Wright Mar 10 '15 at 14:24
  • @JosephWright: The code will be in a class of a customer. It will be never seen by texlive or CTAN. And I agree with egreg that more "use"-functions would be useful. It is imho very natural (in typesetting) that you want to do something different with the first and the last item of a list. – Ulrike Fischer Mar 10 '15 at 14:44
  • @UlrikeFischer Non-released code is of course a bit more tricky, but the point 'if it doesn't get tested we don't know it's useful' remains true! The present use functions are not exactly for typesetting or at least not focussed exclusively on that area. However, I can see the point: I need to work out the naming, etc. – Joseph Wright Mar 10 '15 at 15:47
  • Well now I really have the choice ;-). – Ulrike Fischer Mar 11 '15 at 19:48