[Tex/LaTex] TeX Nested Loops With \iftoggle

conditionalsetoolboxgroupingloops

This forum has helped me understand how to use nested loops in TeX, but now I am having trouble using \iftoggle (from the etoolbox package) with loops. My goal is to have a toggle that can keep track of an "even" or "odd" state as the loops are progressing, where the state is updated by the code inside the loops. However, the example shown below does not work as I expect, as the toggle seems to get set to "even" every time it gets back out into the outer loop. Why does this happen, and how can I prevent it / what is a better way to achieve this functionality?

\documentclass{book}
\usepackage{etoolbox}
\begin{document}
\newcount\X
\newcount\Y

\newtoggle{even}
\toggletrue{even}

\loop
\Y = 0
\advance \X by 1
{%
  \loop
  \advance \Y by 1
  \message{\the\X,\the\Y}
  \iftoggle{even}{%
    \message{EVEN}%
    \togglefalse{even}%
  }{%
    \message{ODD}%
    \toggletrue{even}%
  }%
  \ifnum \Y < 3
  \repeat
}%
\ifnum \X < 6
\repeat
\end{document}

Output (notice the repeated EVENs):

1,1 EVEN 1,2 ODD 1,3 EVEN 2,1 EVEN 2,2 ODD 2,3 EVEN 3,1 EVEN 3,2 ODD 3,3 EVEN 4,1 EVEN 4,2 ODD 4,3 EVEN 5,1 EVEN 5,2 ODD 5,3 EVEN 6,1 EVEN 6,2 ODD 6,3 EVEN

Best Answer

This has to do with the scoping of your toggles. That is, in the inner loop, the call to \toggletrue and \togglefalse is valid, but ignored once completed, reverting back to the original definition \toggletrue{even}. That is why then output is EVEN for the start of every one of the inner loops. For these redefinitions to hold across the entire scope, prepend the toggle switches with \global:

...
\global\togglefalse{even}%
...
\global\toggletrue{even}%
...

This is the output I get when I make the above change:

1,1 EVEN 1,2 ODD 1,3 EVEN 2,1 ODD 2,2 EVEN 2,3 ODD 3,1 EVEN 3,2 ODD 3,3 EVEN 4, 1 ODD 4,2 EVEN 4,3 ODD 5,1 EVEN 5,2 ODD 5,3 EVEN 6,1 ODD 6,2 EVEN 6,3 ODD
Related Question