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.

I'm trying to create a matrix using nested \foreach loops. I tried following the example I found in a previous question, but I keep getting errors.

Here is the code I tried to run:

\documentclass{article}
\usepackage{etoolbox}
\usepackage{tikz}
\usetikzlibrary{matrix}

\begin{document}
\let\mymatrixcontent\empty
\newcommand{\row}[1]{
  \foreach \i in {0,...,5} {
    \xappto\mymatrixcontent{\expandonce{
      \node {\i}; & 
    }}
  }
  \xappto\mymatrixcontent{\\}
}
\row{1}

\begin{tikzpicture}
  \matrix[matrix of nodes]{
    \mymatrixcontent
  };
\end{tikzpicture}
\end{document}

I'm getting an error:

! Undefined control sequence.
\\  ->\let \reserved@e 
                       \relax \let \reserved@f \relax \@ifstar {\let \reserv...
l.16 \row{1}

I noticed that this error occurs only after adding the new row after the \foreach loop. Is there a way to avoid it?

EDIT: I completed the example.

share|improve this question

2 Answers 2

up vote 8 down vote accepted

If you do

\let\mymatrixcontent\empty
\newcommand{\row}{%
  \foreach \i in {0,...,5} {%
    \gappto\mymatrixcontent{\node{\i}; \&}%
    }%
  \gappto\mymatrixcontent{\\}%
}
\row

(using \& is better because of problems with "naked" & tokens; percusse's answer tells how to cope with this when building the matrix) then \mymatrixcontent will expand to

\node{\i}; \& \node{\i}; \& \node{\i}; \& \node{\i}; \& \node{\i}; \&\\

and the current definition of \i will be used, which is "print a dotless i", because \i will expand to the successive values only during the action of \foreach. So what's needed is the expansion of \i during the action of \foreach:

\let\mymatrixcontent\empty
\newcommand{\row}{%
  \foreach \i in {0,...,5} {%
    \begingroup\edef\x{\endgroup
       \noexpand\gappto\noexpand\mymatrixcontent{\noexpand\node{\i}; \&}}\x
    }%
  \gappto\mymatrixcontent{\\}%
}
\row

However one has to pay close attention when using \edef: not all tokens are allowed inside the replacement text and those which we want to get as themselves need to be prefixed by \noexpand. In this particular case, where \i is the only token to be expanded, a different method can be used

\let\mymatrixcontent\empty
\newcommand{\row}{%
  \foreach \i in {0,...,5} {%
    \expandafter\gappto\expandafter\mymatrixcontent\expandafter{%
      \expandafter\node\expandafter{\i} \&}}%
    }%
  \gappto\mymatrixcontent{\\}%
}
\row

because the \expandafter chain will cause the expansion of \i before \gappto is executed.

share|improve this answer
    
I wasn't able to compile your first solution. I got Too many }'s. –  haggai_e Mar 12 '12 at 6:42
    
@haggai_e Fixed the braces, thanks –  egreg Mar 12 '12 at 7:23
1  
Sorry to bother you, but there's still an extra brace in the first solution (the second code segment). I would have deleted it myself, but SO doesn't allow me to do a single character edit. –  haggai_e Mar 12 '12 at 8:12
    
Also, you should mention that if I want to use \node inside the \edef, I'll need to put \noexpand there as well. –  haggai_e Mar 12 '12 at 8:13
    
@haggai_e Without seeing the "real" code, it's difficult to know what you want to append at every cycle. –  egreg Mar 12 '12 at 8:34

As Martin wrote in the linked answer it's working with \gappto command. Here is an example that works for me. I also changed the ampersand since it's always problematic to put a lonely & into the bowels of expanding macros :)

\documentclass{article}
\usepackage{etoolbox}
\usepackage{tikz}
\usetikzlibrary{matrix}

\begin{document}
\let\mymatrixcontent\empty
\newcommand{\row}[1]{
  \foreach \i in {0,...,5} {
    \gappto\mymatrixcontent{\expandonce{
     A  \& 
    }}
  }
  \gappto\mymatrixcontent{\\}
}
\row{1}

\begin{tikzpicture}
  \matrix (a) [matrix of nodes,ampersand replacement=\&]{
    \mymatrixcontent
  };
    \draw (a-1-1) -- (a-1-5);
\end{tikzpicture}

\end{document}

code output

share|improve this answer
    
Thanks! I had an error when I used \gappto at first, but I guess it was unrelated. –  haggai_e Mar 11 '12 at 11:28
    
There's still a problem with this method. For some reason if I put \i after the A, the result is A 1 in all the cells. –  haggai_e Mar 11 '12 at 11:41
    
@haggai_e Hmm, that's not 1 but iota, dotless i character. Apparently, \i becomes a command rather than the argument of foreach loop. I'll try to fix it. –  percusse Mar 11 '12 at 12:01

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.