3

I'm struggling to make the following code work:

\documentclass{minimal}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}

\foreach \point in {(0,0),(0,2),(2,0),(2,2)} {
    \begin{scope}[shift={\point}]
        \fill (0,0) circle (0.1) ;
    \end{scope}
}

\end{tikzpicture}

\end{document}

The log contains

Package tikz Error: Cannot parse this coordinate.

See the tikz package documentation for explanation. Type H for immediate help. ...
l.11 } This error message was generated by an \errmessage command, so I can't give any explicit help. Pretend that you're Hercule Poirot: Examine all clues, and deduce the truth by order and method.

Missing character: There is no ( in font nullfont!

Missing character: There is no 0 in font nullfont!

Missing character: There is no , in font nullfont!

Missing character: There is no 0 in font nullfont!

Missing character: There is no ) in font nullfont!

Is there a way to make use of these coordinates directly, or should I resort to the X/Y style?

Update: (to address the claim that () solves the problem). I have fully updated the Miktex installation through console. However, the following lines (directly connected to the usage of shift + ()) still appear:

File: epstopdf-sys.cfg 2021/03/18 v2.0 Configuration of epstopdf for MiKTeX ))

Missing character: There is no ) in font nullfont!

Missing character: There is no ) in font nullfont!

Missing character: There is no ) in font nullfont!

Missing character: There is no ) in font nullfont!

[1]

Exactly one brace for each coordinate in the list (checked with a different number of points).

8
  • 1
    it works with [shift={(\point)}] >>> ( ) is added
    – Black Mild
    Commented May 12, 2022 at 9:08
  • I agree that it partially works. However, it still complains on the bunch of Missing character: There is no ) in font nullfont!. So, I supposed this is not the solution.
    – dEmigOd
    Commented May 12, 2022 at 9:17
  • Do you have an updated MikTeX? \documentclass[tikz]{standalone} \begin{document} \begin{tikzpicture} \foreach \point in {(0,0),(0,2),(2,0),(2,2)} \fill[shift={(\point)}] (0,0) circle (0.1) ; \end{tikzpicture} \end{document}
    – Black Mild
    Commented May 12, 2022 at 9:20
  • 1
    Your error has nothing with \foreach loop. After correcting error in MWE, as pointed @Black Mild in his comment, your MWE works fine (no errors, no warnings, no bad boxes. I tested with recent MiKTeX bundle. SO, it seems that your installation of LaTeX is outdated.
    – Zarko
    Commented May 12, 2022 at 9:31
  • 1
    \expanded{\noexpand\begin{scope}[shift={\point}]} works for me…
    – egreg
    Commented May 12, 2022 at 11:10

1 Answer 1

3

When the TikZ parser (which is also used to parse the shift coordinate) finds something it doesn't understand, it usually tries to expand what's in front of it.

This is why

\fill \point circle (0.1);

works without a hitch.

In case the user writes wrong syntax TikZ has a fail-safe as it decrements an internal counter and only tries the expansion tactic until this counter reaches 0. This counter start usually at 100 and gets decremted by 1 or 10 depending on the case.

At certain places, this counter is reset to 100, for example at the start of a path (which is why

\fill[shift=\point] (0,0) circle (0.1) ;

works) or when the parser successfully finds a valid path specification. It does not get reset at the start of the picture or at the start of a scope. And since it is still the default and initialized-with 0 at that point, the parsing throws an error.

Using shift=(\point) works because there is another expansion of everything happening but it will lead to warnings of

Missing character: There is no ) in font nullfont!

This is because it now tries to parse

((0,0))
and what happens is that the parser recognizes (0 as the x value for the coordinate and the second 0 as the y value. But it leaves the very last ) on the TeX input stream, similar as if you would have done:

\path;
Foo
\path;

Now, why doesn't (0 raise any errors? As with many things in PGF/TikZ this will be fed to PGFmath and evaluated … and PGFmath doesn't have a problem with it. Try

\pgfmathparse{(((((1}\pgfmathresult

or even

\pgfmathparse{1))))}\pgfmathresult

Instead of using \expanded and \noexpand as suggested in the comments I'd recommend using the .expanded key handler which will instruct PGFkeys to expand the value before given it to the key.

(Or we patch either the scope environment or the shift key or just manually reset the counter but using the key handler works always in other places very well when TikZ does no expansion on its own.)

Code

\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
\foreach \point in {(0,0),(0,2),(2,0),(2,2)} {
  \begin{scope}[shift/.expanded=\point]
    \fill (0,0) circle[radius=.1];
  \end{scope}
}
\end{tikzpicture}
\end{document}

You must log in to answer this question.

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