2

Many times I reuse help coordinate names in tikz pictures. Normally, they are overwritten. Now I have found an instance where they are maintained.

\documentclass{article}
\usepackage{tikz}

\begin{document}

Reuse of coordinate names overwrites them:

\begin{tikzpicture} \foreach \x in {1,...,5} \node (A) at (\x,0){.}; \draw[red] (A) circle(2pt); \end{tikzpicture}

When placed in a macro also:

\def\overwritecoords{% \foreach \x in {1,...,5} \node (A) at (\x,0){.};}

\begin{tikzpicture} \overwritecoords \draw[green] (A) circle(2pt); \end{tikzpicture}

But when the \verb|\foreach| uses a macro, not:

\def\placecoord{\node (A) at (\x,0){.};} \def\keepcoords{% \foreach \x in {1,...,5} \placecoord}

\begin{tikzpicture} \keepcoords \draw[blue] (A) circle(2pt); \end{tikzpicture}

Although, they can only be used once:

\begin{tikzpicture} \keepcoords \draw[blue] (A) circle(2pt); \draw[->] (A)--++(0,-1); \end{tikzpicture}

\begin{tikzpicture} \keepcoords \draw[->] (A)--++(0,-1); \draw[blue] (A) circle(2pt); \end{tikzpicture}

If the same name is reused again, the previous ones are lost, as usual:

\begin{tikzpicture} \keepcoords \node (A) at (6,0){.}; \draw[orange] (A) circle(2pt); \end{tikzpicture}

\end{document}

I could not find a description of this behaviour but, since the manual is so extensive, I might have overlooked it. I do not understand why and how should tikz maintain a list of coordinates with the same name, when normally they are overwritten. I am a bit worried that at some point, in such a set-up, tikz might pick the wrong help coordinate, or more than one, for drawing my picture. Could that happen? Is there a way to avoid the accumulation of coordinates with the same name?

On the other hand, if I use this behaviour for some purpose, would that be stable in new updates of the package?

enter image description here

  • The \draw command in your \keepcoords is being drawn in to the \foreach loop. I don't know enough about how \foreach should be delimited to know why this is happening, but placing a semi-colon after \placecoord in \keepcoords stops this, as does writing \keepcoords;. – Andrew Stacey Feb 16 '21 at 17:12
  • I did a bit more digging ... – Andrew Stacey Feb 16 '21 at 17:22
  • Consider also that coordinate names are global in TikZ --- https://tex.stackexchange.com/questions/459492/local-scoped-coordinate-names-in-tikz – Rmano Feb 16 '21 at 18:32
  • @Rmano Yes, I am aware that the node names are global. The thing is that, since they are a TeX macro in the end, \pgf@sh@ns@, how can there be more than one. Especially when they are global – Raoul Kessels Feb 16 '21 at 22:19
  • Somewhat related; https://tex.stackexchange.com/questions/570640/can-tikz-matrices-be-forgotten – John Kormylo Feb 16 '21 at 23:16

1 Answers1

1

The PGF manual explains how \foreach figures out the body of its loop in Section 88 "Repeating Things: The Foreach Statement":

Syntax for the commands. Let us move on to a more complicated setting. The first complication occurs when the are not some text in curly braces. If the \foreach statement does not encounter an opening brace, it will instead scan everything up to the next semicolon and use this as .

(bold-emphasis mine)

A key part of this is that the scan does not expand as it goes. So the semi-colon inside \placecoord is not seen and the \foreach takes everything up to the semi-colon at the end of the \draw command. Thus the \draw is dragged into the \foreach loop.

To block this behaviour (assuming that this is what you want to do) then you need to ensure that TikZ/PGF encounters the semi-colon at the right place without expansion.

One option is to put it in after \keepcoords:

\begin{tikzpicture}
  \keepcoords;
  \draw[blue] (A) circle(2pt);
\end{tikzpicture}

Another is to put it inside \keepcoords:

\def\keepcoords{%
  \foreach \x in {1,...,5}
    \placecoord;}

Yet another is to use braces to delimit the body of the loop.

\def\keepcoords{%
  \foreach \x in {1,...,5}
  {\placecoord}}

As for your question about relying on this behaviour, I would say "It's documented, so it's likely to stay.". But from how you write about it then I'm not sure it's behaving how you think it is behaving - in particular, TikZ/PGF is not maintaining a list of nodes defined with the same label, each overwrites the previous one, but rather the \draw is being used as each one is defined. So if this is what you want, then you can rely on it (as much as anything).

Andrew Stacey
  • 153,724
  • 43
  • 389
  • 751
  • Thank you for showing how to overwrite the previous names, which is what I was intending to do. I will definitely do it like that to avoid problems. But how is it even possible that the names are maintained, especially when there is not a list of node names. As far as I am aware, the names are ultimately a TeX macro \pgf@sh@ns@. How can there be more than one? – Raoul Kessels Feb 16 '21 at 22:14
  • The names aren't maintained. It is that the \draw command is executed just after each node is defined and before it is overwritten with the next one. – Andrew Stacey Feb 16 '21 at 22:54
  • But the \draw is way after naming the nodes. The second one, I mean the one with the circles – Raoul Kessels Feb 16 '21 at 22:57
  • It is inside the iteration? Ok, that makes sense. – Raoul Kessels Feb 16 '21 at 22:58
  • 1
    The \keepcoords does not finish with a semicolon, so it is the semicolon of the \draw which does it and is used every iteration. Therefore, all the coordinates are drawn with a circle – Raoul Kessels Feb 16 '21 at 23:03