5

I was trying to use recursion in LaTeX to create a list of items. I don't have much experience with LaTeX so kindly explain any uncommon commands used. Here's my code for the same.

\makeatletter

\newcommand\@itemsi{\@ifnextchar\stopitems{}{\@add}}

\newcommand\@add[1]{
  \item #1
  \@itemsi
}

\newcommand\@newitems{
    \begin{itemize}
    \@itemsi
    \end{itemize}
}

\makeatother

This is the output I'm getting using this code

\@newitems
{Fruits}
{Vegetables}
{Drink}
\stopitems

Output: newitemsFruitsVegetablesDrink

I instead want this,

  • Fruits
  • Vegetables
  • Drink
  • Interesting question, but I'm curious: why do you want this behavior? It's much harder to read. – Sean Allred May 5 '15 at 19:58
4
\documentclass{article}

\begin{document}

\makeatletter% don't use @ for commands intended for document use....



\newcommand\@newitems{\begin{itemize}\@itemsi}


\def\@itemsi#1{%
  \ifx\stopitems#1%
    \end{itemize}\expandafter\@gobble
  \else
    \item#1\expandafter
  \fi
  \@itemsi}


This is the output I'm getting using this code

\@newitems
{Fruits}
{Vegetables}
{Drink}
\stopitems

\end{document}
  • Thanks for your answer. It's pretty concise. Though since I'm a bit new to LaTeX can you explain what \expandafter does here? I know it takes the token after the next one but it's not clear to me how that's used here – Milap May 5 '15 at 23:30
  • 1
    @MilapSheth see tex.stackexchange.com/questions/107753/… – David Carlisle May 5 '15 at 23:59
4

Recursive Approach

See also the giggles at the bottom for a generic implementation. :)

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\quark_new:N \StopItems

\cs_new:Nn \milap_new_items: { \begin{itemize} \milap_next_item:n }
\cs_new:Nn \milap_next_item:n {
  \tl_if_eq:nnTF {#1} {\StopItems}
    { \end{itemize} }
    { \item #1 \milap_next_item:n }
}

\NewDocumentCommand \NewItems { } {
  \milap_new_items:
}
\ExplSyntaxOff

\begin{document}
\NewItems
  {hello}
  {there}
  {world}
\StopItems
\end{document}

Idiomatic expl3 (in my opinion)

Using xparse to grab all the arguments and expl3 to work with them:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand \NewItems { u{\StopItems} } {
  \tl_set:Nn \l_tmpa_tl {#1}
  \begin{itemize}
    \tl_map_inline:Nn \l_tmpa_tl { \item ##1 }
  \end{itemize}
}
\ExplSyntaxOff

\begin{document}
\NewItems
  {hello}
  {world}
\StopItems
\end{document}

Comma-Separated List

For completion :)

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand \NewItems { m } {
  \clist_set:Nn \l_tmpa_clist {#1}
  \begin{itemize}
    \clist_map_inline:Nn \l_tmpa_clist { \item ##1 }
  \end{itemize}
}
\ExplSyntaxOff

\begin{document}
\NewItems{hello,world}
\end{document}

Giggles

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\quark_new:N \StopItems

\cs_new:Nn \milap_new_items:nn { \begin{#1} \milap_next_item:nnn {#1} {#2} }
\cs_new:Nn \milap_next_item:nnn {
  \tl_if_eq:NNTF {#3} {\StopItems}
    { \end{#1} }
    { \item #3 \milap_next_item:nnn {#1} {#2} }
}

\NewDocumentCommand \NewItems { O{itemize} O{\item} } {
  \milap_new_items:nn {#1} {#2}
}
\ExplSyntaxOff

\begin{document}
\NewItems[enumerate]
  {hello}
  {there}
  {world}
\StopItems
\end{document}
  • It should be \tl_if_eq:nnTF, shouldn't it? Also \StopItems should probably be defined as a quark: \quark_new:N \StopItems – egreg May 5 '15 at 22:50
  • @egreg Hmm, yes it should; I must have gotten a little too happy with my shift key :) And you're absolutely right! \StopItems is definitely a quark here. – Sean Allred May 5 '15 at 22:52
  • @egreg Is it appropriate to define \StopItems as a quark when it's used in a u-type xparse argspec? – Sean Allred May 5 '15 at 22:55
  • In the case of a delimiter it's irrelevant: it can even be undefined. – egreg May 5 '15 at 23:09
  • 1
    @MilapSheth xparse is great :) Read up on texdoc xparse for more goodies. As for the other things, I'll refer you to texdoc interface3 for the full documentation, but \cs_new: and \tl_if_eq: are expl3 functions. expl3 is the (very well-organized) programming layer with which LaTeX3 is being built. The two functions correspond roughly to \def and \ifx, respectively. Note that everything after the : is part of the function name, too. expl3 has a different syntax to it, toggled with \ExplSyntaxOn/Off (analogous to \makeatother/letter). – Sean Allred May 6 '15 at 0:05
1

Taken from iterate over commaseparated list

Add this to your preamble and call inside document with

\documentclass{article}
\usepackage{etoolbox}
\makeatletter
\newcommand\makeitemize[1]{%
  \begin{itemize}
    \forcsvlist{\makeitemize@item}{#1}
  \end{itemize}
}
\newcommand\makeitemize@item[1]{\item #1}
\makeatother

\begin{document}
\makeitemize{A,B,C} 
\end{document}
  • Your solution do not work in a simple article document like \documentclass{article} \begin{document} Test \end{document} Can you provide a MWE? – Fran May 5 '15 at 19:56
  • @DavidCarlisle you are right. I have corrected my answer and learned, to test code bevor submit to the community. This will never happen again. – Peter Ebelsberger May 6 '15 at 8:09
  • @PeterEbelsberger thanks for updating (original comment deleted) – David Carlisle May 6 '15 at 8:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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