6

This question is directly related to Foreach inside a TikZ matrix. But I can't expand it with a macro inside, such that:

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

\begin{document}
\newcommand{\somecommand}[1]{#1}
\begin{tikzpicture}
  \let\mymatrixcontent\empty
  \foreach \c in {a,b,c}{%
    \expandafter\gappto\expandafter\mymatrixcontent\expandafter{\somecommand{\c} \\}%
    % or
    % \xappto\mymatrixcontent{\expandonce{\somemacro{\c}\\}}
  }
  \matrix [matrix of nodes,ampersand replacement=\&] {
    \mymatrixcontent
  };
\end{tikzpicture}

\end{document}

I get the error: ERROR: Missing } inserted.

aagaard
  • 943

2 Answers2

7

If you add \show\mymatrixcontent before \matrix, you can see that the expansion is

\c  \\\c  \\\c  \\

which is not what you want. You have to expand \c before feeding it as an argument to \somecommand. You can do it by

\newcommand{\somecommand}[1]{#1}
\begin{tikzpicture}
  \let\mymatrixcontent\empty
  \def\gapptoaux#1{\gappto\mymatrixcontent{\somecommand{#1} \\}}
  \foreach \c in {a,b,c}{
    \expandafter\gapptoaux\expandafter{\c}
  }
  \matrix [matrix of nodes,ampersand replacement=\&] {
    \mymatrixcontent
  };
\end{tikzpicture}
egreg
  • 1,121,712
4

I have had exactly the same problem in a different context (the loop counter not being expanded in a table cell). To practice my understanding of how the expansion works I tried to fix the problematic line in the original code directly (commented in the code below) - two more \expandafters do the job.

Egreg's solution looks nicer and cleaner but the crude way might be easier to understand for those like me who have only just met \expandafter. Hope this helps someone.

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

\begin{document}
\newcommand{\somecommand}[1]{#1}
\begin{tikzpicture}
  \let\mymatrixcontent\empty
  \foreach \c in {a,b,c}{%
  %------------------------------
    % original code:
    %\expandafter\gappto\expandafter\mymatrixcontent\expandafter{\somecommand{\c} \\}%
    % changed to:
    \expandafter\gappto\expandafter\mymatrixcontent\expandafter{\expandafter\somecommand\expandafter{\c} \\}%
  %------------------------------
    % or
    % \xappto\mymatrixcontent{\expandonce{\somemacro{\c}\\}}
  }
  \matrix [matrix of nodes,ampersand replacement=\&] {
    \mymatrixcontent
  };
\end{tikzpicture}

\end{document}
lockstep
  • 250,273
PetrH
  • 141