4

I try to automate some things with tikz, and I am running into a problem that I do not understand. Nesting scopes with shifts defined as commands does not work as I was expecting.

For example, this works perfectly :

\begin{tikzpicture}
\def\coord{(1,0)}
\begin{scope}[shift={\coord}]
\end{scope}
\begin{scope}[shift={\coord}]
\end{scope}
\end{tikzpicture}

and it works correctly, as one can see by adding some \node[fill,circle] at (0,0) {}; inside and outside the scopes

but the following fails :

\begin{tikzpicture}
\def\coord{(1,0)}
\begin{scope}[shift={\coord}]
  \begin{scope}[shift={\coord}]
  \end{scope}
\end{scope}
\end{tikzpicture}

However, this

\begin{tikzpicture}
\def\coord{(1,0)}
\begin{scope}[shift={(1,0)}]
  \begin{scope}[shift={(1,0)}]
  \end{scope}
\end{scope}
\end{tikzpicture}

indeed works. I do not understand what is happening. pdflatex returns

Package tikz Error: Cannot parse this coordinate.
See the tikz package documentation for explanation. ...

in the problematic case. The question is why does this happen ? I probably did something wrong, but I really do not see what.

Notice that adding length units does not fix the problem. However, a similar problem with xshift and yshift does not seem to happen. Also notice that I tried to simplify the code as much as possible ; that's why it draws nothing.

Thanks,

2
  • 2
    TikZ needs to expand \coord on its own. The algorithm that is used to parse a coordinate does this if it encounters something that is did not expect (here it does expect a ( but doesn’t find it). Each expansion counts down a counter, if this counter reaches zero, TikZ gives up and presents you this error message. On a path, this counter is usually initialized with 100. This is not the case on a scope. You can observe the same behavior if you use shift=\ccoord with \def\ccoord{\coord}. — Best is to give TikZ the coordinate already expanded and do shift/.expanded=coord. Commented Sep 14, 2013 at 14:58
  • @Qrrbrbirlbel well I cannot accept your comment as an answer, but it was exactly what I needed (the solution as well as the explanation). Thanks. Commented Sep 14, 2013 at 20:07

1 Answer 1

3

As qrrbrbirlbel noted TikZ works with parsing letter-by-letter the command stream. It is a blessing and sometimes a curse depending on the context and when key value system is mixed with macros and literal text. So you can give a hand to TikZ to understand what it should read. So changing your definition without the parentheses is enough for it to go, oh, that must be a coordinate then

Also notice that braces are needed to hide the commas and brackets in the options and you can remove them here, so this doesn't cost you extra typing.

\begin{tikzpicture}
\draw[style=help lines] (0,-1) grid[step=1cm] (4,1);
\def\coord{1,0}
\begin{scope}[shift=(\coord)]
  \begin{scope}[shift=(\coord)]
      \begin{scope}[shift=(\coord)]
        \begin{scope}[shift=(\coord)]
        \node (a) at (0,0) {a};
        \end{scope}
      \end{scope}
  \end{scope}
\end{scope}
\end{tikzpicture}

enter image description here

0

You must log in to answer this question.

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