Use for loop to input files

inputloops

Suppose I am writing a book with 45 chapters (in separate files 1.tex 2.tex etc) and I want to input them into main.tex. How can I write a for loop for this?

Best Answer

As it is about inputting files containing chapters of a LaTeX-document I suppose the \include-command is the appropriate command for inputting files. But you can easily replace instances of \include by instances of \input if you prefer.


Edit: As a leftover from when I switched from \input to \include, I erroneously left the filename-extension ".tex" as ⟨tokens after number-component of filename⟩. Unlike with \input with \include you don't provide the extension .tex—the extension .tex is added automatically by the \include-command. This is now rectified.


Probably a tail-recursive loop does the trick.

Here a loop where filenames are specified:

\newcommand\noneofone[1]{}%
\newcommand\firstofone[1]{#1}%
\newcommand\includeloop[2]{%
  \ifx\relax#2\expandafter\noneofone\else\expandafter\firstofone\fi
  {\include{#1#2}\includeloop{#1}}%
}%
\includeloop{./chapters/}{filename1}{filename2}{filename3}{filename4}{filename5}%
            {filename6}{filename7}{filename8}{filename9}{filename10}%
            {filename11}{filename12}{filename13}{filename14}{filename15}%
            {filename16}{filename17}{filename18}{filename19}{filename20}%
            {filename21}{filename22}{filename23}{filename24}{filename25}%
            {filename26}{filename27}{filename28}{filename29}{filename30}%
            {filename31}{filename32}{filename33}{filename34}{filename35}%
            {filename36}{filename37}{filename38}{filename39}{filename40}%
            {filename41}{filename42}{filename43}{filename44}{filename45}\relax

In case all filenames are of same pattern, you can have a loop based on counting:

Syntax:

\includepatternloop{⟨lower bound of number range⟩}%
                   {⟨upper bound of number range⟩}%
                   {⟨tokens before number-component of filename⟩}%
                   {⟨tokens after number-component of filename⟩}%
                   {⟨directory/file-path⟩}%

yields a sequence of

\include{%
  ⟨directory/file-path⟩%
  ⟨tokens before number-component of filename⟩%
  ⟨number-component of filename⟩%
  ⟨tokens after number-component of filename⟩%
}

The code

\newcommand\exchange[2]{#2#1}%
\newcommand\includepatternloop[5]{%
  \include{#5#3#1#4}%
  \ifnum#1<\expandafter\exchange\expandafter{\number#2}{} %
     \exchange{\expandafter\includepatternloop\expandafter{\number\numexpr#1+1\relax}{#2}{#3}{#4}{#5}}%
  \fi
}%
\includepatternloop{1}{45}{File}{of45Files}{./chapters/}%

gets you a sequence:

\include{./chapters/File1of45Files}%
\include{./chapters/File2of45Files}%
...
\include{./chapters/File45of45Files}%

If you don't want \ifnum#1<\expandafter\exchange\expandafter{\number#2}{} % you can introduce another macro which applies \number for normalizimg things before actually starting the loop:

\newcommand\exchange[2]{#2#1}%
\newcommand\includepatternloop[2]{%
  \expandafter\exchange\expandafter{\expandafter{\number#2}}{\includepatternloopinternal{#1}}%
}%
\newcommand\includepatternloopinternal[5]{%
  \include{#5#3#1#4}%
  \ifnum#1<#2 %
     \exchange{\expandafter\includepatternloopinternal\expandafter{\number\numexpr#1+1\relax}{#2}{#3}{#4}{#5}}%
  \fi
}%
\includepatternloop{1}{45}{File}{of45Files}{./chapters/}%
Related Question