Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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..

share|improve this question

3 Answers 3

up vote 23 down vote accepted
\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}

enter image description here

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

share|improve this answer
    
@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
1  
@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

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
share|improve this answer
1  
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
1  
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

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).

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.