# Special handling of first and/or last item in an etoolbox list

Is there a simple way of handling the first and/or the last item in an etoolbox-based list in a special way? Here’s a simple example:

\documentclass{article}

\usepackage{etoolbox}

\begin{document}

\renewcommand*{\do}[1]{; #1}
\dolistloop{\namelist}

\renewcommand*{\do}[1]{#1, }
\dolistloop{\namelist}

\end{document}


The output is

; Tom; Dick; Harry; Jack

Tom, Dick, Harry, Jack,

How would I go about changing the above code to create the output

Tom; Dick; Harry; Jack

Tom, Dick, Harry and Jack

The first output would be easy to achieve if one could define the first item’s formatting to be simply #1 while the rest are formatted as ; #1. The second output would be easy to achieve if one could define all items to be formatted as , #1 except the first one, which should be #1 and the last one, which should be and #1.

Note that I’m looking for a solution for etoolbox lists, not other list structures.

-

For the first problem, I'd define \do to precede the entry with \process, whose initial meaning is just to redefine itself to the desired separator:

\newcommand{\semicolonlist}[1]{%
\def\process{\def\process{; }}%
\def\do##1{\process##1}%
\dolistloop{#1}}

\semicolonlist\namelist


For the second problem, one can process the list once to get the number of elements and then use this information in a second pass:

\newcommand{\commaorandlist}[1]{%
\count255=0
\dolistloop{#1}%
\count255=0
\ifnum\count255=\finalitem
\space and\space
\else
\ifnum\count255=1
\else
,\space
\fi
\fi##1}
\dolistloop{#1}}

\commaorandlist\namelist


These commands print the list; if you need to use them in an expandable context you can do, say for \commaorandlist,

\newcommand{\xcommaorandlist}[2]{%
\count255=0
\dolistloop{#1}%
\count255=0
\toks0={}%
\edef\next{%
\ifnum\count255=\finalitem
\space and\space
\else
\ifnum\count255=1
\else
,\space
\fi
\fi
}
\toks2={##1}%

\edef\next{\the\toks0 \next \the\toks2}%
\toks0=\expandafter{\next}%
}%
\dolistloop{#1}%
\edef#2{\the\toks0 }%
}


and then call

\xcommaorandlist\namelist\finallist
\hypersetup{pdfauthor={\finallist}}

-
Thanks. It seems to work perfectly. This might really be a new question, but is there an easy way to also define the result as a fully expanded macro? I’m trying to use it to set the pdfauthor in \hypersetup, which doesn’t work. –  Karl Ove Hufthammer Nov 7 '11 at 20:48
@KarlOveHufthammer See edited answer –  egreg Nov 7 '11 at 21:06
Wow! That looks complicated, but works perfectly. Thanks! I’m currently reading the TeXbook and TeX by Topic, hoping to some day being able to understand that code. :) –  Karl Ove Hufthammer Nov 7 '11 at 21:24

here a simple solution which also counts the lists and the counter is used to locate the last element inside the list:

\documentclass{article}

\usepackage{etoolbox}

\begin{document}
\newcounter{elementcount}