Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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
share|improve this question

3 Answers 3

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
share|improve this answer
    
Thanks! That worked perfectly. –  user839768 Jul 26 '11 at 17:48
1  
If this answers your question, accept it as the answer. –  Werner Jul 26 '11 at 19:06

If you use etoolbox, you are supposed to use \whileboolexpr. And maybe use \newcounter{X}, \value{X} instead of \newcount\X, \X. Thus:

\documentclass{minimal}
\usepackage{etoolbox}
\begin{document}
\newcounter{X}
\newcounter{Y}

\newtoggle{even}
\toggletrue{even}

\setcounter{X}{0}
\whileboolexpr{test {\ifnumcomp{\value{X}}<6} }{%
  \stepcounter{X}
  \setcounter{Y}{0}
  \whileboolexpr{test {\ifnumcomp{\value{Y}}<3} }{%
    \stepcounter{Y}
    \arabic{X}, \arabic{Y}:
    \iftoggle{even}%
      {EVEN\togglefalse{even}}%
      {ODD\toggletrue{even}}\par
  }%
}

\end{document}

I removed the extra group of inner loop, just reset \Y=0 and it will work. You'll find it looks like common for-loops in other programming languages.

share|improve this answer

You have to write \global in front of \togglefalse{even} and \toggletrue{even}.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.