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 Answers2

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}
Werner
  • 603,163