2

I have a document like:

\documentclass{article} 
  \begin{document}
    \begin{itemize}
      \item First
      \item Second
      \item Third
    \end{itemize}
  \end{document}

which I want to fill with different values for \item. That is, generate different documents, with the same layout, but different items.

The items could be loaded from a text file, which could have any easily readable form like:

 #1#First item
 #2#Second item

Or some other light mark-up. How can I set some kind of variables in the Latex document, to import items from the other file?

2

The question is a little bit vague about the content to be loaded.

I've assumed a file name foocontent.txt and a .tex file called foo.tex, the compilation is done this way

pdflatex "\def\filetoload{foocontent.txt}\input{foo}"

on command line (or in a commandline box of those editors)

The code will load the file and read its content line by line using expl3 features and storing it to a \seq variable which is displayed later on with \displayfilecontent within \begin{itemize}...\end{itemize}.

As 'defined' each entry for an \item must appear on a separate line and can be 'any' LaTeX content.

It's the 'quick' way I'm generating lists for many students etc.

\documentclass{article}

\usepackage{xcolor}
\usepackage{xparse}

\ExplSyntaxOn
\ior_new:N \l_local_file_handle
\seq_new:N \g_local_content_seq
\cs_new:Nn \store_content_to_seq:n {%
  \seq_gput_right:Nn \g_local_content_seq {#1}
}

\NewDocumentCommand{\readfromfile}{m}{
  \ior_open:Nn \l_local_file_handle {#1}
  \ior_map_inline:Nn \l_local_file_handle {\store_content_to_seq:n{##1} }
  \ior_close:N \l_local_file_handle
}

\NewDocumentCommand{\displayfilecontent}{}{%
  \seq_map_inline:Nn \g_local_content_seq { \item ##1 }
}
\ExplSyntaxOff

\begin{document}

\readfromfile{\filetoload}

\begin{itemize}
\displayfilecontent
\end{itemize}
\end{document}

Here is foocontent.txt

And
Now
For
Something
Completely
Different
And 
Totally
\textcolor{blue}{Strange}
Things

enter image description here

1

The following example uses datatool to read in a CSV containing two columns (without headers) in the following form:

1,First item
2,Second item
3,Third item

Items are set using the default environment's \item or using the first column entries (\fixedenumerate):

enter image description here

\documentclass{article} 

\usepackage{filecontents,datatool}
\begin{filecontents*}{mylist.csv}
1,First item
2,Second item
3,Third item
\end{filecontents*}

\newif\ifdefaultenumerate
\newcommand{\defaultenumerate}{\defaultenumeratetrue}
\newcommand{\fixedenumerate}{\defaultenumeratefalse}

\newcommand{\processCSV}[1]{%
  \DTLifdbexists{CSVinput}{\DTLgdeletedb{CSVinput}}{}%
  \DTLloaddb[noheader,keys={Number,Text}]{CSVinput}{#1}%
  \DTLforeach{CSVinput}{\Number=Number,\Text=Text}{%
    \ifdefaultenumerate
      \item
    \else
      \item[\Number]
    \fi
    \Text
  }
}

\begin{document}

\begin{itemize}
  \item First
  \item Second
  \item Third
\end{itemize}

\begin{itemize}
  \processCSV{mylist.csv}
\end{itemize}

\begin{enumerate}
  \processCSV{mylist.csv}
\end{enumerate}

\defaultenumerate
\begin{enumerate}
  \processCSV{mylist.csv}
\end{enumerate}

\end{document}

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.