Comma-separated list environment

This question is somewhat of a follow up to an answer to a previous question (http://tex.stackexchange.com/a/11587/13522).

I would like to create a list environment (similar to itemize and enumerate) such that the output of the list environment is a comma-separated list.

For example, the following input:

\begin{commalist}
\item Item A
\item Item B
\item Item C
\end{commalist}


Should produce the following output:

Item A, Item B and Item C.


Additionally, it would be nice to be able to specify the use of a comma instead of the final and (so that the output is instead Item A, Item B, Item C..

-

3 Answers

\documentclass{article}
\usepackage[inline]{enumitem}
\newlist{commalist}{description*}{4}
\setlist[commalist]{itemjoin={{,}},itemjoin*={{, and}},afterlabel=\unskip{{~}}}

\begin{document}
\begin{commalist}
\item Item A
\item Item B
\item Item C
\end{commalist}
\end{document}


If there should be no comma before and, then delete it in the setting.

-
@Herbert. Wow, great! Thanks. Only problem I have is that the text from the list is spaced evenly along the row, whereas I want the whole text to be left-justified. Can this be fixed? – Joshua Spence Jul 8 '12 at 21:49
@JoshuaSpence: write the first entry as \item[\kern-0.3em] Item A. I suppose that there is no easy way to get rid of the space – Herbert Jul 9 '12 at 6:16
@Herbert: that didn't work but \hfill does the job. – Joshua Spence Jul 9 '12 at 9:22
\setlist[commalist]{before=\kern-0.3em, ...} seems to work. – Hans Lundmark Aug 14 '12 at 12:59

The package enumitem may give a solution. Use inline-list. See section 4 in the manual, and especially the possibility to set up a list using itemjoin (see page 9).

-

A solution with expl3:

\documentclass{article}
\usepackage{xparse,environ,xspace}

\ExplSyntaxOn
\NewEnviron{commalist}[1][\space]{\spence_comma_list:V \BODY #1}
\seq_new:N \l_spence_items_seq
\cs_new_protected:Npn \spence_comma_list:n #1
{
\seq_set_split:Nnn \l_spence_items_seq { \item } { #1 }
\seq_pop_left:NN \l_spence_items_seq \l_tmpa_tl % we have an empty element at the beginning
\seq_use:Nnnn \l_spence_items_seq { ~ and ~ } { , ~ } { , ~ and ~ }
}
\cs_generate_variant:Nn \spence_comma_list:n { V }
\ExplSyntaxOff

\begin{document}
Here is a comma list
\begin{commalist}
\item Item A
\item Item B
\item Item C
\end{commalist}
and another
\begin{commalist}
\item Item A
\item Item B
\end{commalist}
and another
\begin{commalist}
\item Item A
\end{commalist}
which ends the game.
Another one to see that a period can follow
\begin{commalist}[.]
\item Item A
\item Item B
\item Item C
\end{commalist}
\end{document}


A punctuation after the list should be specified beforehand as optional argument, because \NewEnviron works hard to gobble a space following \end{commalist}.

The code prior to the addition of \seq_use:Nnnn follows, just in order to appreciate the elegance of the new method. Thanks to Bruno for providing it.

\ExplSyntaxOn
\NewEnviron{commalist}[1][\space]{\spence_comma_list:V \BODY#1}
\cs_new_protected:Npn \spence_comma_list:n #1
{
\seq_set_split:Nnn \l_spence_items_seq { \item } { #1 }
\seq_pop_left:NN \l_spence_items_seq \l_tmpa_tl % we have an empty element at the beginning
\seq_pop_right:NN \l_spence_items_seq \l_spence_lastitem_tl
\seq_if_empty:NTF \l_spence_items_seq
{
\tl_use:N \l_spence_lastitem_tl
}
{
\spence_andify:
}
}
\cs_new_protected:Npn \spence_andify:
{
\seq_pop_right:NN \l_spence_items_seq \l_spence_lastbutoneitem_tl
\seq_map_inline:Nn \l_spence_items_seq { ##1,~ }
\tl_use:N \l_spence_lastbutoneitem_tl
\c_space_token and ~
\tl_use:N \l_spence_lastitem_tl
}
\cs_generate_variant:Nn \spence_comma_list:n { V }
\tl_new:N \l_spence_lastbutoneitem_tl
\tl_new:N \l_spence_lastitem_tl
\seq_new:N \l_spence_items_seq
\ExplSyntaxOff

-
With the upcoming CTAN update (in July 2012), you'll be able to simplify this to \seq_set_split:Nnn and \seq_use:Nnnn \l_spence_items_seq { ~ and ~ } { , ~ } { , ~ and ~ }. – Bruno Le Floch Jul 9 '12 at 12:15
@BrunoLeFloch Very nice and welcome addition! – egreg Jul 9 '12 at 13:22
And since \seq_use:Nnnn is expandable, coding it was a mess (no \seq_pop_right:NN available, for instance). – Bruno Le Floch Jul 9 '12 at 13:48