I'm trying to write a code that will draw a tree consisting of 2 children for each node up to a specified depth. The drawing of the tree itself works but applying the styles (which are numbered consecutively in the order the children are drawn) doesn't. I'm incrementing a counter for every child and if I manually write out the code of the tree, all is fine. However there seem to be some subtelties with the foreach operation that I don't understand. Here is an example not very "minimal", since I can't pinpoint the problem. The first bit works as expected, only the specified node is drawn in a different color. But if I request that child to be missing, then it's sibling also disappears. I don't know if it's related to the unexpected result of the third part of the example, which increments another counter only on the second execution of each of the nested foreach loops, yet the counter seems to step by 2, not 1. Any insight into this is much appreciated.
\documentclass{article}
\usepackage{tikz}
\parindent=0pt\relax
\begin{document}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcount\foo
\tikzset{
level distance=2cm,
level/.style={sibling distance=4cm/#1},
inc foo/.code=\global\advance\foo by 1\relax,
left/.style={label=left:\the\foo,inc foo},
right/.style={label=right:\the\foo,inc foo},
s0/.style=blue,
s1/.style=blue,
s2/.style=blue,
s3/.style=blue,
s4/.style=green,
s5/.style=blue,
}
only node 5 should be green\par
\foo=0\relax
\begin{tikzpicture}[grow=up]
\node {A} child[s\the\foo] foreach \x in {right,left} {
node[\x] {} child[s\the\foo] foreach \y in {right,left} {node[\y] {}
}
};
\end{tikzpicture}
\tikzset{s4/.style=missing}
only node 5 should be missing\par
\foo=0\relax
\begin{tikzpicture}[grow=up]
\node {A} child[s\the\foo] foreach \x in {right,left} {
node[\x] {} child[s\the\foo] foreach \y in {right,left} {node[\y] {}
}
};
\end{tikzpicture}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcount\foobar
\tikzset{
s4/.style=missing,
foo/.code args={#1}{\global\advance\foobar by #1\relax},
left/.style={label={left:\the\foo, \the\foobar},inc foo},
right/.style={label={right:\the\foo, \the\foobar},inc foo},
}
second number should go up by 0 on every right child and 1 on every left child\par
\foo=0\relax
\foobar=1\relax
\begin{tikzpicture}[grow=up]
\node {A} child[foo=\n] foreach \x/\n in {right/0,left/1} {
node[\x] {} child[foo=\m] foreach \y/\m in {right/0,left/1} {node[\y] {}
}
};
\end{tikzpicture}
\end{document}
@cfr suggested I use Forest: I will have a look at it. However, I'm not sure to what extent it is useful in my case or how long it would take me to rewrite my code using it. Since the actual example is way more complicated--I have 500 lines of code (almost done) that takes input of the form ::!::!...., and for each path specification of the form rrllrlrl (for move right/left) it sets the lable of the first edge to and the color of all edges to ; if a new path specification is encountered after !, then continue from where the previous path ended (applying label and color to the new path); if a new path is after a coma, then start at the root again. Furthermore, every time a change in direction is encountered, such as when I say rl or r::!l:..., then continue the previous path in the default color. ALSO, unless one of color or label is given, or the edge style has never been set (missing), do not override previous values. Finally, the last path specification (before a coma) should be continued until the top of the tree (i.e. the color should be applied until the end of the edge, on its corresponding side, left or right)... So for example saying rl:a:green!r:s:red,l:a:blue!r:c:red should give (but with the labels midway next to the edge, I just drew that "by hand" now quickly):
child[foo=\n]
isn't within the scope of theforeach
.missing
is implemented. I just noticed the\n
in the last case where you use it.