Is it possible to use a loop to generate a list for a foreach loop? More specifically I want the following:

Consider the following answer to a question I asked some time ago: https://tex.stackexchange.com/a/38793/4011

It worked very well except if I define \alist as follows:

    \foreach \i in {1,2,3}{

I get the following error:

ERROR: Undefined control sequence.

--- TeX said ---
\foreach ...reach \let \pgffor@assign@before@code 
                                                  =\pgfutil@empty \let \pgff...
l.38   \rectDiv{7}{5}{(1,1)}{(4,3)}{\alist}

Is there any way to fix this?


Full example:

  \def\rectDiv#1#2#3#4#5{%#columns, #rows, rectangle start, rectangle end, list of elements to fill
      \draw #3 rectangle #4;
      \path #3;
      \path #4;
      \foreach \x in {1,...,#1}{
        \draw ($#3 +\x*(\myxstep,0)$) -- ($#3 +(0,\ydiff) +\x*(\myxstep,0)$);
      \foreach \y in {1,...,#2}{
        \draw ($#3 +\y*(0,\myystep)$) -- ($#3 +(\xdiff,0) +\y*(0,\myystep)$);
      \edef\temp{\noexpand\foreach \noexpand\i/\noexpand\j in {#5}}
        \path[fill=blue!20,draw] ($#3 + (\i*\myxstep,\j*\myystep)$) rectangle ($#3 + (\i*\myxstep,\j*\myystep) + (\myxstep,\myystep)$);



    \foreach \i in {1,2,3}{


   \rectDiv{7}{5}{(1,1)}{(4,3)}{\alist}  %this doesn't  work


1 Answer 1


Your problem is that you wrote

\edef\temp{\noexpand\foreach \noexpand\i/\noexpand\j in {#5}}

% Here is what #5 is in \temp:
\foreach \i in {1,2,3}{

which requires that the stuff in the braces be "fully expandable". Alas, \foreach is not expandable, and it is part of \alist. So when \temp is defined, it expands "as much as possible" and hits some non-expandable part of the code of \foreach, which in this case is \let \pgffor@assign@before@code = ...; \let is an assignment, and not expandable, so is not changed by \edef. Thus, the assignment is not actually performed, and \edef goes on to try to interpret the following control sequence \pgffor@assign@before@code directly. Not surprisingly, it is not defined, since it was the \let that is supposed to define it, so you get an error.

To do this, you have to create a macro that contains the output of \alist. For example,

\foreach \i in {1,2,3} {
 \xdef\alist{\alist \i/1,}
\xdef\alist{\alist 4/1}

Then you can use \alist directly instead of \temp. (I have used global assignments for \alist because \foreach executes its contents in a group.)

  • Is there a way to do this without using global macros?
    – Adam Crume
    Oct 18, 2013 at 4:32
  • Not with \foreach. It acts in a group, so you have to break out with global macros.
    – Ryan Reich
    Oct 18, 2013 at 11:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .