Automation – Iterating Over Files in a Directory

automationinput

I have a folder called diary which contains a series of files:

  • 20120101.tex
  • 20120105.tex
  • 20120304.tex
  • etc.

How can I create a single LaTeX document that includes each of these files, in alphabetical order? I'd like to do this within LaTeX, not using LuaTeX or shell operations (to make it portable).

I found a near-solution here, but I can't get it to work properly for this situation.

\documentclass{book}
\usepackage{xifthen}

\begin{document}

% 20120101.tex included here
% 20120105.tex included here
% etc

\end{document}

The code from the near solution linked above for iterating over files that I am trying to modify is:

\foreach \Year in {\StartYear,...,\EndYear}
{   \foreach \Month in {Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec}
    {   \foreach \Day in {1,...,31}
        {   \IfFileExists{\Year/\Month/\Day}
                {   \newread\mysource
                    \openin\mysource=\Year/\Month/\Day.tex
                    \read\mysource to \firstline
                    \closein\mysource
                    \xdef\writetitle{1}
                    \begin{loggentry}{\Year - \Month - \Day}{\firstline}    
                        \xdef\writetitle{0}
                        \input{\Year/\Month/\Day}
                    \end{loggentry} 
        }
        {   % files does not exist, so nothing to do
        }

        }  
    }
}

Here is my failed modification that I want to not look in year/month subdirectories, but read the files as I have listed them above:

\foreach \Year in {\StartYear,...,\EndYear}
{   \foreach \Month in {01,02,03,04,05,06,07,08,09,10,11,12}
    {   \foreach \Day in {01,...,31}
    {   \IfFileExists{{Year}{Month}{Day}}
                {   \newread\mysource
                \openin\mysource={Year}{Month}{Day}.tex
                    \read\mysource to \firstline
                    \closein\mysource
                    \xdef\writetitle{1}
                    \begin{loggentry}{\Year - \Month - \Day}{\firstline}    
                        \xdef\writetitle{0}
                        \input{{YearMonth/\Day}
                    \end{loggentry} 
        }
        {   % files does not exist, so nothing to do
        }

        }  
    }
}

The problem is in concatenating the variables to create the file name instead of subdirectories, which I can't figure out how to do (the above, obviously, doesn't work).

Best Answer

Here is an adaption of my earlier answer from How to iterate through the name of files in a folder:

Notes:

  • This assumes that all the files are named as YYYYMMDD.tex.
  • All the files are ready to be \input.
  • You can adjust the values of \MinYear \MaxYear to suit.
  • There is some overhead here that a check is made for every single day. So unless you are producing a diary over many years this should not really be a problem.
  • If you want to be able to typeset each individually diary entry by itself you should have a look at the standalone package. If your dairy entries are quite small this may not be of much value, but if they are lengthy this would be useful as you can view each day as you go and ensure that everything typesets properly and then simply run the main program at certain intervals.
  • One reason why your attempt failed is that the code \foreach \Day in {01,...,31} yields the sequence:

       01 2 3 ... 9 10 11 ... 30 31
    

    So while the first day is correct the subsequent days 2-9 are not two digits.

References:

Code:

\documentclass{article}
\usepackage{pgffor}%

%\usepackage{filecontents}
\begin{filecontents*}{20120201.tex}
  Feb 1, 2012:
  First day of Feb. Got cold today.
\end{filecontents*}
\begin{filecontents*}{20120202.tex}
  Feb 2, 2012:
  Second day of Feb. Got even colder today.
\end{filecontents*}

\newcommand*{\MinYear}{2012}% Adjust these two settings for your needs.
\newcommand*{\MaxYear}{2013}

% https://tex.stackexchange.com/questions/56207/how-to-convert-a-one-digit-number-to-a-two-digit-number
\newcommand\TwoDigits[1]{%
   \ifnum#1<10 0#1\else #1\fi
}

\begin{document}
\foreach \YYYY in {\MinYear,...,\MaxYear}{%
    \foreach \MM in {1,2,...,12}{%
        \foreach \DD in {1,2,...,31}{%
            \edef\FileName{\YYYY\TwoDigits{\MM}\TwoDigits{\DD}}
            \IfFileExists{\FileName} {%
                \par
                \input{\FileName}%
            }{%
                    % files does not exist, so nothing to do
            }%
        }%
    }%
}%
\end{document}
Related Question