# foreach LaTeX input file, output a PDF file

I have a bunch of tables saved in separate files and folders which I have compiled with a master file, commenting the name of each file in the master file one by one and tediously renaming the resulting PDF output.

I have over one hundred tables produced over several months. Now I would like to recompile them all in a different style, so I'm looking for a way to automate the process.

Below is an unsuccessful attempt that builds on several suggestions found on this site, particularly this question.

To summarise in words what I tried to do in the code below:

1. create files a.tex and b.tex to be used as inputs (these are my tables);
2. define a command to store the file names as a list, a and b (no need to automate file naming);
3. a foreach loop (package pgffor) to call each input file a.tex and b.tex inside a basic document header/preamble (standalone class) and save it with the name temp.tex;
4. followed by a call to \immediate\write18{pdflatex... to run pdflatex on temp.tex;
5. the intended output is two PDF files named a.pdf and b.pdf. I'm running this with shell-escape enabled.

Needless to say it's not working and help is appreciated!

% !TeX TXS-program:compile = txs:///pdflatex/[--shell-escape]
\documentclass{article}
\usepackage{pgffor}% \foreach
\usepackage{filecontents}
\begin{filecontents*}{a.tex}
First file (a table without preamble)
\end{filecontents*}

\begin{filecontents*}{b.tex}
Second file (a table without preamble)
\end{filecontents*}

\newcommand*{\ListOfFiles}{a,b}

\foreach \x in \ListOfFiles{%
\begin{filecontents*}{temp.tex}%
\documentclass{standalone}%
%\usepackage{stylesforalltables}
\begin{document}%
\input{\x}
\end{document}%
\end{filecontents*}%
\immediate\write18{pdflatex -jobname=\x\space temp}
}%

• why do you need to make a loop in tex? if I had a directory full of tex files I'd just write for i in *.tex; do pdflatex $i;done and get a directory full of pdf. (That's bash but you could do the same in any commandline . – David Carlisle Mar 17 '17 at 18:55 • @DavidCarlisle - it seems the tables are not actually complete documents. So, he needs a way to process each table as a document fragment. Maybe for file in table*.tex; do ln -s$file temp.tex; pdflatex template.tex; mv template.pdf $(file%.tex).pdf; done. This assumes that names of all table source files start with table, and that the template.tex file sets up the desired document format and contains \input{temp} in the document body. – Michael Palmer Mar 17 '17 at 20:36 • Please 1) don't use filecontents as argument of a command 2) don't use % at the end of line with \begin{filecontents*}{temp.tex}% 3) try \input{\jobname} instead of \input{\x}. – touhami Mar 17 '17 at 22:34 • @DavidCarlisle, a bash/commandline solution would be perfectly acceptable for a one-off, but I'm also interested in a cross-platform solution that would be easy to explain to my co-authors (in this project I do not have co-authors, but in other cases I do, so I'm interested in learning of other ways). Thanks for the comment. – PatrickT Mar 18 '17 at 6:27 • @MichaelPalmer, your interpretation is correct, thanks for the solution! – PatrickT Mar 18 '17 at 6:39 ## 2 Answers You can't use filecontents in the argument to another command. But you can define the master file in a separate filecontents environment. Call this compileall.tex (or whatever) \documentclass{article} \usepackage{pgffor}% \foreach \usepackage{filecontents} \begin{filecontents*}{master.tex} \documentclass{standalone} %\usepackage{stylesforalltables} \begin{document} \input{\jobname} \end{document} \end{filecontents*} \begin{filecontents*}{a.tex} First file (a table without preamble) \end{filecontents*} \begin{filecontents*}{b.tex} Second file (a table without preamble) \end{filecontents*} \newcommand*{\ListOfFiles}{a,b} \foreach \x in \ListOfFiles{% \immediate\write18{pdflatex -jobname=\x\space master} } \stop  However, it's simpler to have master.tex written as above and do, from the command line (assuming bash) for i in {a,b}; do pdflatex -jobname=$i master; done

• Thanks! I prefer the non-command line solution, as I tend to edit documents with texstudio and compile them by pressing on the F12 key (my shortcut), plus I use MacOS, Linux, Windows almost indifferently (depending on whether I'm at home, the office, etc) and shell commands are not always cross-platform. But it's certainly good to have as a reference. – PatrickT Mar 18 '17 at 6:54
• Note to self: As I have my tables saved in folders with the same name, I wrote \input{\jobname/\jobname} and it worked. – PatrickT Mar 18 '17 at 7:45

Here is a solution (with simple \write).

\documentclass{article}
\usepackage{pgffor}% \foreach
\usepackage{filecontents}

\begin{filecontents*}{a.tex}
First file (a table without preamble)
\end{filecontents*}

\begin{filecontents*}{b.tex}
Second file (a table without preamble)
\end{filecontents*}

\newcommand*{\ListOfFiles}{a,b}

\newwrite\temp
\foreach \x in \ListOfFiles{
\immediate\openout\temp=temp.tex
\immediate\write\temp{
\string\documentclass{standalone}
\string\begin{document}
\string\input{\x}
\string\end{document}
}
\immediate\closeout\temp
\immediate\write18{pdflatex -jobname=\x\space temp}
}%

\begin{document}
foo
\end{document}


Or (shorter) with \unexpanded

\immediate\write\temp{\unexpanded{%
\documentclass{standalone}
\begin{document}
\input{\jobname}
\end{document}}

• Excellent, thanks! I like the second solution better, with \unexpanded, as it makes it easier to type a longer preamble. – PatrickT Mar 18 '17 at 6:50