# Problem using macros to define tree substructures

Relatively simple problem: I want to use macros to define substructures of a tree. In the following example for illustration, I want to define some children (left and right) to be used several times in a tree.

\documentclass{article}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}

\newcommand{\leftchildren}{%
child{node[circle,draw] {l}} child{node[circle,draw] {l}} %
}%

\newcommand{\rightchildren}{%
child{node[circle,draw] {r}} child{node[circle,draw] {r}} %
}%

\node[circle,draw] (root) {}  \leftchildren \rightchildren;
\end{tikzpicture}
\end{document}


The problem is

• Without the label (root) it does not even compile (Why?)

• The macros are not expanded on the same level: the right children become children of the left children

• Using more macros, or nesting them, makes it worse.

This is a very simplified version of what I want to do. Often I want to be able to add other children by hand (without using macro). I also would like to be able to define entire subtrees as macros, for example a long chain, as a macro.

I think there is a problem with the expansion of the macros, but I was not able to figure it out myself. Help please.

Cheers, Oliver

-
Your suspicion is right, the macros should be expanded before node starts to read. From the manual: When a node operation like node {X} is followed by child, TikZ starts counting the number of child nodes that follow the original node {X}. For this, it scans the input and stores away each child and its arguments until it reaches a path operation that is not a child. –  percusse Jun 13 '12 at 11:41
And indeed, \expandafter\leftchildren\rightchildren does what I would expect your code to produce. –  Loop Space Jun 13 '12 at 11:45
Which suggests to me that the right strategy would be to have a "tree building" command which expanded all the pieces before feeding it to TikZ. How complicated are your trees? Are there any macros in, say, the node texts? In the example one could do \edef\children{\leftchildren\rightchildren} but that wouldn't work if there was fancy stuff going on. –  Loop Space Jun 13 '12 at 11:47
Oh, and for your first comment: the root node needs to have a name otherwise there's no way for TikZ to connect it to its children. The root node is processed before TikZ knows that it is constructing a tree so it doesn't know that that node is going to be used later and therefore it doesn't know to assign it a name automatically. With the internal nodes, TikZ knows that they are part of a tree so knows to give them names (if they don't already have them). –  Loop Space Jun 13 '12 at 11:50
(And you now have enough reputation to post pictures. That's always helpful.) –  Loop Space Jun 13 '12 at 11:50

This is similar to

macro for empty nodes in tikz-qtree

You need to pre-expand macros so the tikz parser sees them:

\documentclass{article}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}

\node[circle,draw] (root) {}  child{node[circle,draw] {l}} child{node[circle,draw] {l}} child{node[circle,draw] {r}} child{node[circle,draw] {r}};

\end{tikzpicture}

aaaaaaaaaaaaaaaaa

\begin{tikzpicture}

\newcommand{\leftchildren}{%
child{node[circle,draw] {l}} child{node[circle,draw] {l}} %
}%

\newcommand{\rightchildren}{%
child{node[circle,draw] {r}} child{node[circle,draw] {r}} %
}%

\node[circle,draw] (root) {}  \leftchildren \rightchildren;
\end{tikzpicture}

bbbbbbbbbbbbbbbbbbbbbbbbbbbb

\makeatletter

\let\mypgfutil@ifnch\pgfutil@ifnch
\def\pgfutil@ifnch{%
\let\x@next\@empty
\ifx\pgfutil@let@token\leftchildren\let\pgfutil@let@token c\let\x@next\expandafter\fi
\ifx\pgfutil@let@token\rightchildren\let\pgfutil@let@token c\let\x@next\expandafter\fi
\x@next\mypgfutil@ifnch}

\makeatother

\newcommand{\leftchildren}{%
child{node[circle,draw] {l}} child{node[circle,draw] {l}} %
}%

\newcommand{\rightchildren}{%
child{node[circle,draw] {r}} child{node[circle,draw] {r}} %
}%

\begin{tikzpicture}

\node[circle,draw] (root) {}  \leftchildren \rightchildren;
\end{tikzpicture}

\end{document}

-
Thank you very much David. That is exactly what I suspected, but I was not able to achieve this expansion. To be honest, I understand almost nothing of the solution code you use to force the expansion ;-). But that is also not that important. I just need to understand what I need to do for more macros. I guess just adding a new line for each macro? Cheers, –  Oliver Jun 13 '12 at 12:59
yes the c in that line is the first token of the expansion, first letter of child in each case here. (It would be possible to rejig things so you didn't need to do that but....) –  David Carlisle Jun 13 '12 at 13:06
OK, I see. That is no problem. By the way, will this solution also work when the macros have parameters? –  Oliver Jun 13 '12 at 13:44
probably it'll work, if my understanding of what tikz is doing here is correct. I have almost no knowledge of tikz though:-) –  David Carlisle Jun 13 '12 at 14:09
Just an update from my side. David's solution also works for macros with parameters. Great! Thanks Ahmed for your suggestion, but I understand even less ;-). Never mind, I can live with the c character. (Even though it is easy to forget to change when you change the macro, happened already). Oliver –  Oliver Jun 14 '12 at 9:05

The character c is required to be always present in Master David Carlisle's approach. Here is an approach that I sometimes use.

\documentclass{article}
\usepackage{tikz}
\makeatletter
\newcommand*\tikzcommands{%
% Collect your tikz commands here, otherwise they will be expanded
% prematurely:
\do\begin\do\end\do\coordinate\do\path\do\draw\do\node
}
\def\xtikzpicture{\@ifnextchar'{\@firstoftwo{\xtikz@picture{00}}}%
{\xtikz@picture{01}}}
\def\xtikz@picture#1#2\end#3{%
\def\reserved@a{#3}\def\reserved@b{xtikzpicture}%
\ifx\reserved@a\reserved@b
\def\endxtikzpicture{}%
\end{xtikzpicture}%
\else
\fi
\let\this@relax\relax
\def\reserved@a##1\this@relax{}%
\if#1\expandafter\reserved@a\fi
\begingroup
\def\do##1{\let##1\relax}\tikzcommands
\protected@edef\x{\endgroup
\begin{tikzpicture}#2\end{tikzpicture}%
}\x
\this@relax
}
\makeatother

\def\leftchildren{%
child{node[circle,draw] {left}}
child{node[circle,draw] {left}}
}
\def\rightchildren{%
child{node[circle,draw] {\textcolor{blue}{right}}}
child{node[circle,draw] {\textcolor{blue}{right}}}
}

\begin{document}
\begin{xtikzpicture}' % ignored
xx
\end{xtikzpicture}

\begin{xtikzpicture}[level distance=10mm,
every node/.style={fill=red!40,circle,inner sep=1pt}]
% Maybe someone can tell me why the circle on 'root' has no effect:
\node {root} [grow'=up,circle,draw]
\leftchildren \rightchildren
child {node {parent}
child {node {child}}
child {node {child}}
};
\end{xtikzpicture}
\end{document}


-

You can also force expansion of your macro with \edef :

\edef\tmp{\leftchildren \rightchildren}
\node[circle,draw] (root) {} \tmp;

-
Welcome to TeX.sx! –  henrique Dec 14 '12 at 19:18