4

I am trying to write a template to automatically load files inside directories formatted in a certain way, and I want to print something every time a new file is found in a directory previously empty.

My code looks like this:

\documentclass[11pt,twoside,a4paper]{article}
\usepackage{tikz}
\usepackage{etoolbox}

\usepackage[utf8]{inputenc}



\begin{document}


\foreach \Year in {2016,...,2020}
{
  \newtoggle{mytoggle}
  \toggletrue{mytoggle}

  \foreach \Month in {Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec}
  {   \foreach \Day in {1,...,31}
    { \IfFileExists{\Year/\Month/\Day}
      {
        \iftoggle{mytoggle}{
          \togglefalse{mytoggle}
          true
        }{
          false
        }

        \input{\Year/\Month/\Day.tex}
      }
    }
  }
}
\end{document}

I would expect that the true branch is called only once, however it is called every time. What am I doing wrong?

Thanks

Mimo
  • 325
  • Using \newtoggle in the loop over and over again looks weird –  Mar 24 '16 at 08:25
  • You can use \InputIfFileExists as well, this combines the test for the existince of the file and the input –  Mar 24 '16 at 08:29

1 Answers1

4

A \foreach forms a group, thus you need to apply \global before a \toggletrue or \togglefalse within a \foreach.

Result of the MEW below without the \global

enter image description here

and with the \global:

enter image description here

Notes:

  • No need to declare the \newtoggle within the \foreach.

  • Be careful of the space following the foreach { as this can add up. See Tex Capacity Exceeded (if remove % after use of macro).

  • Also, with macros such as \IfFileExists, make sure that you cover both the true and false case. Use {} for the case that you don't need anything executed. This was missing in the code you provided.

  • The filecontents package was used to set up a file to read for this test case. It is not needed in you actual use case. Also, to simplify the MWE, the file naming was altered to not require additional directories.

Code:

\begin{filecontents}{2016-Mar-24.tex}
content for file 2016-Mar-24\par
\end{filecontents}
\begin{filecontents}{2016-Jul-10.tex}
content for file 2016-Jul-10\par
\end{filecontents}
\begin{filecontents}{2017-Dec-31.tex}
content for file 2017-Dec-31\par
\end{filecontents}

\documentclass[11pt,twoside,a4paper]{article} \usepackage{tikz} \usepackage{etoolbox}

\newtoggle{mytoggle}

\begin{document} \foreach \Year in {2016,...,2020} {% \global\toggletrue{mytoggle}% % \foreach \Month in {Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec} {%
\foreach \Day in {1,...,31} {% \IfFileExists{\Year-\Month-\Day.tex}{% \iftoggle{mytoggle}{% true \global\togglefalse{mytoggle}% }{% false \global\toggletrue{mytoggle}% }% \input{\Year-\Month-\Day.tex} }{}% }% foreach \Day }% foreach \Month }% \end{document}

Peter Grill
  • 223,288
  • In order to build a file name from the input stream, the primitive \input absorbs and expands tokens until finding an unexpandable token that can't be interpreted as being part of a file name (implementation dependent); so \input{\Year/\Month/\Day} does the same as the indirect path with \edef you propose. – egreg Mar 24 '16 at 10:27
  • @egreg: Thanks for pointing that out and have removed that comment regarding an \edef. I know I have had issues with similar use of file names but perhaps it was not with \input. – Peter Grill Mar 24 '16 at 11:21
  • It works perfectly well and for providing all the explanations needed! – Mimo Mar 24 '16 at 22:43