# Package xparse \SplitList last token

I need to create a macro to render lists with a variable number of arguments (1+), e.g. \mylist{1,2,3} should expand to $\tilde{1}$--$\tilde{2}$--$\tilde{3}$. I'm trying to use xparse and \SplitList, but I didn't find a way to tell when I'm processing the last token (where I don't need the separator --).

\NewDocumentCommand\mylist{>{\SplitList{,}}m}
{
\ProcessList{#1}{\myitem}
}
\newcommand\myitem[1]{$\tilde{#1}$--}


This would expand \mylist{1} to $\tilde{1}$-- instead of the desired $\tilde{1}$.

Recognizing the first item is easier than the last.

There are many strategies for this.

1. Use a conditional

\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand\mylist{>{\SplitList{,}}m}
{%
\ProcessList{#1}{\myitem}%
\firstitemtrue
}

\newif\iffirstitem
\firstitemtrue
\newcommand\myitem[1]{%
\iffirstitem
\firstitemfalse
\else
--%
\fi
$\tilde{#1}$}

\begin{document}
\mylist{a,b,c}
\end{document}

2. Redefine the macro at first usage; doing the processing in a group will revert \myitem to the initial meaning.

\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand\mylist{>{\SplitList{,}}m}
{%
{\ProcessList{#1}{\myitem}}%
}

\newcommand\myitem[1]{$\tilde{#1}$\let\myitem\myitema}
\newcommand\myitema[1]{--$\tilde{#1}$}

\begin{document}
\mylist{a,b,c}
\end{document}

3. Use a different approach with expl3 macros, which is more flexible at the expense of some complication.

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand\mylist{m}
{
\egreg_process_list:n {#1}
}
% define a sequence for storing the "massaged" items
\seq_new:N \l_egreg_items_seq
\cs_new_protected:Npn \egreg_process_list:n #1
{
% clear the sequence
\seq_clear:N \l_egreg_items_seq
% cycle through the arguments, storing "\tilde{<arg>}" in the sequence
\clist_map_inline:nn { #1 }
{
\seq_put_right:Nn \l_egreg_items_seq { $\tilde{##1}$ }
}
% output the sequence putting "--" in between elements
\seq_use:Nnnn \l_egreg_items_seq { -- } { -- } { -- }
}
\ExplSyntaxOff

\begin{document}
\mylist{a,b,c}
\end{document}


The output in all three cases is

Note that you still need protecting end of lines with % in the body of \NewDocumentCommand unless you're in an \ExplSyntaxOn context.

• An alternative to the \clist_map_inline:nn construction is to store the sequence with \seq_set_split:Nnn <seq> { , } (stable, doesn't ignore blank entries) or \seq_set_from_clist:Nn <seq> (experimental, ignores empty/blank entries), then using \seq_set_map:NNn <seq> <seq> { \exp_not:n {$\tilde{##1}$} } (experimental function), then \seq_use:Nnnn as you did. It is more efficient :-), and (perhaps) clearer. – Bruno Le Floch May 22 '13 at 9:49

I have used this trick often (see Cunning (La)TeX tricks). The approach is to define a list separator using a "delay". That is, define it as a definition so that the first use just defines itself:

\documentclass{article}
\usepackage{xparse}% http://ctan.org/pkg/xparse
\NewDocumentCommand\mylist{O{--} >{\SplitList{,}}m}
{%
\def\itemdelim{\def\itemdelim{#1}}% Define list separator with one delay
\ProcessList{#2}{\myitem}% Process list
}
\newcommand\myitem[1]{\itemdelim$\tilde{#1}$}

\begin{document}
\mylist{a,b,c}
\end{document}


The additional optional argument to \mylist allows you to modify the list separator (or item delimiter) of the output. It defaults to --.