I will list two LaTeX manuscripts. The first one, which is the example given in the manual to demonstrate the usefulness of the /tikz/graph/parse
key, compiles successfully, whereas the second one fails to compile. After listing the first manuscript and showing its output, I will argue that the second manuscript is equivalent to the first one. Clearly this argument is false, but I don't know why.
Consider the following LaTeX manuscript, which is essentially a copy of the example in the end of subsection 19.3.2 ('Syntax of Group Specifications') of section 19.3 ('Syntax of the Graph Path Command') of chapter 19 ('Specifying Graphs') of the TikZ & PGF manual for version 3.0.1a (p. 265).
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{graphs}
\begin{document}
\def\mychain#1{
\def \mytext{1}
\foreach \i in {2,...,#1} {
\xdef\mytext{\mytext -> \i}
}
}
\tikzgraphsset{my chain/.style={
/utils/exec=\mychain{#1},
parse/.expand once=\mytext}
}
\tikz \graph { [my chain=4] };
\end{document}
The resulting rendered picture is (not to scale)
I'll explain the output as best I understand it.
- The
\tikzgraphsset
command simply executes its keys with the path prefix/tikz/graphs
(the\tikzgraphsset
command is described in p. 262). So the key/tikz/graphs/my chain
becomes an abbreviation that expands to/utils/exec=\mychain{#1}, parse/.expand once=\mytext
. - Next the
\graph ...
command is executed. The only thing to do is to process the group options ([my chain=4]
). The group options are executed with the path prefix/tikz/graphs
(this is described in p. 264). So the key assignment/tikz/graphs/mychain=4
is executed. This expands to/utils/exec=\mychain{4},/tikz/graphs/parse/.expand once=\mytext
. - Now the assignment
/utils/exec=\mychain{4}
is executed. This key simply executes the assigned value (this key is described in p. 893 in the 'Key Management' chapter), so the macro\mychain{4}
gets expanded. - As the last step, the assignment
/tikz/graphs/parse/.expand once=\mytext
is executed. The key handler.expand once
causes\mytext
's replacement text, namely1 -> 2 -> 3 -> 4
, to be assigned to/tikz/graphs/parse
(the.expand once
key handler is described in p. 890 in the chapter 'Key Management' chapter). The effect of assigning to the/tikz/graphs/parse
key is that the assigned value is inserted at the beginning of the current group, as if you had entered it there (/tikz/graphs/parse
is described in p. 265.)
In conclusion, the above manuscript should be equivalent to the following:
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{graphs}
\begin{document}
\def \mychain#1{
\def \mytext{1}
\foreach \i in {2,...,#1} {
\xdef\mytext{\mytext -> \i}
}
}
\tikz \graph { \mychain{4} 1->2->3->4 };
\end{document}
And yet the last manuscript fails to compile, and pdftex
reports the following error message:
ERROR: Undefined control sequence.
--- TeX said ---
\mychain #1-> \def \mytext
{1} \foreach \i in {2,...,#1} { \xdef \mytext {\m...l.11 \tikz \graph { \mychain{4} 1->2->3->4 }
I will appreciate it if someone can explain not only why the second example fails, but, more importantly, how the first example works. I'd like to be able to predict how similar examples will play out.
\mytext
in the graph ? You just defined it\def\mytext{1}
here in the argument. It works in the first case because stuff gets expanded first. If you definemy chain
in the first example asparse=\mychain{#1}
rather than usingexec
, then you have something closer to your second example.\tikz{...}
that does not mean that you can do\tikz{\def\tmp{...}\tmp}
\pgfutil@ifnextchar
conditionals. So the answer is just it's by design.\def
that typically does not work\def\tmp{1}\tmp
will typeset1
but\setcounter{equation}{\def\tmp{1}\tmp}
will not set the counter to 1. whereas\def\tmp{1}\setcounter{equation}{\tmp}
will. the difference is all about where expansion occurs