40

I have a small problem with the TikZ \foreach loop whenever the list, over which we loop, is defined my a macro. The following code example will show my problem:

\documentclass{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage{tikz}

\begin{document}
Picture one:

\begin{tikzpicture}
\foreach \x/\y in {1.0/2.0, 3.0/4.0} \node[draw] at (\x,\y) {\x--\y};
\end{tikzpicture}

Picture two:

\newcommand{\mymacro}{1.0/2.0, 3.0/4.0}
\begin{tikzpicture}
\foreach \x/\y in {\mymacro} \node[draw] at (\x,\y) {\x--\y};
\end{tikzpicture}
\end{document}

The expected result is that both images should look the same. But in the second image, I only get one node - and both \x and \y are each time expanded to 1.0/2.0, 3.0/4.0. I hope someone can help.

2

2 Answers 2

31

The \mymacro isn't expanded by the \foreach loop, but only afterwards. You need to remove the braces { } around the macro to make it work:

\documentclass{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage{tikz}

\begin{document}
Picture one:

\begin{tikzpicture}
\foreach \x/\y in {1.0/2.0, 3.0/4.0} \node[draw] at (\x,\y) {\x--\y};
\end{tikzpicture}

Picture two:

\newcommand{\mymacro}{1.0/2.0, 3.0/4.0}
\begin{tikzpicture}
\foreach \x/\y in \mymacro \node[draw] at (\x,\y) {\x--\y};
\end{tikzpicture}
\end{document}

Note that while normally both arguments {\mymacro} and \mymacro are identical, \foreach seems to test for { and expands the argument if it isn't present.

2
  • @slouwrun: As far as I remember this is an explicit feature of the \foreach macro. Feb 25, 2011 at 22:21
  • 2
    Good! I deleted my shorter answer. Btw. the pgf manual says: Still in the easiest case, <list> is either a comma-separated list of values surrounded by curly braces or it is the name of a macro that contain such a list of values.
    – Stefan Kottwitz
    Feb 25, 2011 at 22:43
3

Starting with version 3.1.7 (November 2020), TikZ supports the expand list option for \foreach.

From the TikZ & PGF manual:

/pgf/foreach/expand list={<boolean>} (default false)
If this key is set to true the contents of the list are fully expanded with \edef before further processing. This allows using complex macros which generate a list upon expansion without having to use an intermediate macro.

So this is particularly useful if the macro that produces the list requires multiple expansions.

\documentclass{article}
\usepackage{tikz}

\begin{document}
Picture one:

\begin{tikzpicture}
\foreach \x/\y in {1.0/2.0, 3.0/4.0} \node[draw] at (\x,\y) {\x--\y};
\end{tikzpicture}

Picture two:

\newcommand{\mymacro}{1.0/2.0, 3.0/4.0}
\begin{tikzpicture}
\foreach[expand list] \x/\y in {\mymacro} \node[draw] at (\x,\y) {\x--\y};
\end{tikzpicture}
\end{document}

You must log in to answer this question.

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