Iterating through a character/string array in LaTeX

3k views Asked by At

This is a continuation of my question posted earlier (Outputting character string elements neatly in Sweave in R). I have an array of strings, and am trying to output each element into LaTeX. I am able to achieve that using the following code:

\documentclass[12pt,english,nohyper]{tufte-handout}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{longtable}
\usepackage{wrapfig}
\usepackaage{hyperref}
\usepackage{graphicx}
\usepackage[space]{grffile}
\usepackage{geometry}
\usepackage{enumitem}
\usepackage{pgffor}

\makeatletter
\makeatother

\begin{document}

<<include=FALSE>>=
library(ggplot2)
library(reshape2)
library(xtable)
@

\centerline{\Large\bf This is a test}
\vspace{1cm}

\noindent
My List:
\vspace{2mm}

.

<<echo=FALSE,results='asis'>>=
myList = c("A. This is the first item in my list.", "B. This is the second item in my list, and it will span across two lines because it is so long. This is the second item in my list, and it will span across two lines because it is so long.", "C. This is the third item in my list")
@

\begin{enumerate}[label=\Alph*., itemsep=-1ex]
  \item \Sexpr{str_trim(unlist(strsplit(chapter_outcomes[1], "[.]"))[2])}
  \item \Sexpr{str_trim(unlist(strsplit(chapter_outcomes[2], "[.]"))[2])}
  \item \Sexpr{str_trim(unlist(strsplit(chapter_outcomes[3], "[.]"))[2])}
\end{enumerate}

\end{document}

This provides me the correct output that I had wished to achieve:

Correct formatting

However, I am now trying to get this iteration to occur in a for-loop, as I may not always have exactly three elements in my chapter_outcomes string array. I have tried variants of the following:

\begin{enumerate}[label=\Alph*., itemsep=-1ex]
  \foreach \i in {\Sexpr{length(chapter_outcomes)}} {
  \item \Sexpr{str_trim(unlist(strsplit(chapter_outcomes[\i], "[.]"))[2])}
  }
\end{enumerate}

However, this leads to an error of "unexpected input" at the above syntax for chapter_outcomes[\i].

I have tried looking at similar posts (Iteration in LaTeX, http://www.bytemining.com/2010/04/some-latex-gems-part-1-tikz-loops-and-more/) but their focus is different enough that I cannot apply it to solve my problem here.

Thank you for any advice.

2

There are 2 answers

0
Sean Allred On

Sounds like you should be taking a look at expl3. I don't use R/Sweave, but here's an example that should get you going.

\documentclass{article}
\usepackage{xparse,enumitem}

\ExplSyntaxOn

\cs_new_protected:Nn \lanner_sweave_wrap:n
  { \item \Sexpr { str_trim(unlist(strsplit(#1, "[.]"))[2]) } }

\cs_new_protected:Nn \lanner_sweave_enumlist:nn
  {
    \begin{enumerate}[#2]
      \seq_set_split:Nnn \l_tmpa_seq { ;;; } { #1 }
      \seq_map:NN \l_tmpa_seq \lanner_sweave_wrap:n
    \end{enumerate}
  }
\cs_generate_variant:Nn \lanner_sweave_enumlist:nn { f }

\NewDocumentCommand \EnumerateIt { O{label=\Alph*., itemsep=-1ex} m }
  { \lanner_sweave_enumlist:fn {#1} {#2} }

\ExplSyntaxOff

\begin{document}

<<echo=FALSE,results='asis'>>=
myList = c("A. This is the first item in my list.", "B. This is the second item in my list, and it will span across two lines because it is so long. This is the second item in my list, and it will span across two lines because it is so long.", "C. This is the third item in my list")
@

\EnumerateIt{\Sexpr{join(myList,";;;")}} % join myList with ";;;" -- I don't know the exact syntax

\end{document}

Of course, this can be done with pure expl3:

\documentclass{article}
\usepackage{xparse,enumitem}

\ExplSyntaxOn

\tl_new:N \l_lanner_tmp_tl
\seq_new:N \l_lanner_tmp_seq
\cs_new_protected:Nn \lanner_sweave_enumlist:nn
  {
    \begin{enumerate}[#2]
      \tl_map_inline:nn {#1}
        {
          \seq_set_split:Nnn \l_lanner_tmp_seq { .~ } {##1}
          \seq_pop_left:NN \l_lanner_tmp_seq \l_lanner_tmp_tl

          \tl_set:Nf \l_lanner_tmp_tl
            { \seq_use:Nn \l_lanner_tmp_seq { .~ } }

          \tl_trim_spaces:N \l_lanner_tmp_tl

          \item \l_lanner_tmp_tl
        }
    \end{enumerate}
  }
\cs_generate_variant:Nn \lanner_sweave_enumlist:nn { f }

\NewDocumentCommand \EnumerateIt { O{label=\Alph*., itemsep=-1ex} >{ \SplitList { ;; } } m }
  {
    \tl_show:n{#2}
    \lanner_sweave_enumlist:fn {#2} {#1} }

\ExplSyntaxOff

\begin{document}

\EnumerateIt{
  A. This is the first item in my list. ;;
  B. This is the second item in my list, and it will span across two lines because it is so long,
     This is the second item in my list, and it will span across two lines because it is so long. ;;
  C. This is the third item in my list}

\end{document}
0
Gnudiff On

I don't have Latex handy and have not done it a long time, but :

1) doesn't \foreach require a range? If I understand your code correctly, \Sexpr evaluates just to the length (eg. {6}), whereas \foreach should have {1..6}

or

2) another typical error is indexes running {0..[length-1]} instead of {1..[length]} , which could lead to "unexpected input" as the interpreter tries to move past the last element.