# macro for empty nodes in tikz-qtree

I'm trying to define a macro for writing empty nodes in a binary tree using tikz-qtree. Referring to the code below, I want the string \missing in my code to be replaced by \edge[draw=none]; {} as-is (just like if I simply did a find and replace in my code).

Is this possible and how can it be done? I don't want to paste \edge[draw=none]; {} every time there is an empty node in my binary tree.

\documentclass{article}
\usepackage{tikz}
\usepackage{tikz-qtree}

\newcommand{\missing}{ \edge[draw=none]; {} }
%intended usage inside tikzpicture enviornment:
%\Tree  [.3  1
%               \missing ]
%To producce the same result as code below but
%it gave me an error:
%! Undefined control sequence.
%\missing -> \edge
%                  [draw=none]; {}

\begin{document}

\begin{tikzpicture}
\Tree  [.3  1
\edge[draw=none]; {} ]
\end{tikzpicture}

\end{document}

• Welcome to TeX.sx! A tip: You can use backticks  to mark your inline code as I did in my edit. :) – Paulo Cereda Jun 7 '12 at 21:35
• Unfortunately \edge is not a real command, but a sentinel; if there is, then tikz-qtree is able to do its business. But you can't hide it in a macro. – egreg Jun 7 '12 at 22:54

You need to encourage \missing to expand at the right time:

\documentclass{article}
\usepackage{tikz}
\usepackage{tikz-qtree}
\makeatletter

\let\old@@children\@@children
\def\@@children{\futurelet\my@next\my@@children}
\def\my@@children{%
\ifx\my@next\missing\else
\expandafter\@gobble
\fi
\expandafter\old@@children}

\makeatother

\newcommand{\missing}{ \edge[draw=none]; {} }
%intended usage inside tikzpicture enviornment:
%\Tree  [.3  1
%               \missing ]
%To producce the same result as code below but
%it gave me an error:
%! Undefined control sequence.
%\missing -> \edge
%                  [draw=none]; {}

\begin{document}

\begin{tikzpicture}

\Tree  [.3  1 \missing ]
\end{tikzpicture}

\end{document}

• You are my hero. – Richard Dec 19 '12 at 10:27

If you are drawing trees, I urge you to look at forest which is extremely powerful and uses a similar syntax to tikz-qtree/qtree. It also has a built in style for missing nodes:

\documentclass[tikz]{standalone}
\usepackage{forest}

\begin{document}

\begin{forest}
[3
[1
]
[,phantom
]
]
\end{forest}

\end{document}


If you want to just pass a missing to the relevant node and have the phantom constructed, you can do something like this, which will have the same output as the code above:

\documentclass[tikz,multi,varwidth]{standalone}
\usepackage{forest}

\begin{document}

\forestset{
missing/.style={
before typesetting nodes={
append={[, phantom]},
},
},
}
\begin{forest}
[3, missing
[1
]
]
\end{forest}

\end{document}


This can be used for non-binary trees where nodes may have more than 2 children. If you might sometimes want to add your missing node in the middle of a node's children in such a tree, you can adapt missing to take an argument equal to the number of the children occurring before the missing node.

For example:

\documentclass[tikz,multi,varwidth]{standalone}
\usepackage{forest}

\begin{document}

\forestset{
missing/.style={
for children={
if n=#1{
before typesetting nodes={
insert after={[, phantom]},
},
}{},
},
},
}
\begin{forest}
[3, missing=3
[1
]
[2
]
[3
]
[4
]
]
\end{forest}

\end{document}


Something slightly more complex is needed if you might want the first child to be missing i.e. if missing=0 is a possibility:

\documentclass[tikz,multi,varwidth]{standalone}
\usepackage{forest}

\begin{document}

\forestset{
missing/.style={
if={equal(#1,0)}{
before typesetting nodes={
prepend={[, phantom]},
},
}{
for children={
if n=#1{
before typesetting nodes={
insert after={[, phantom]},
},
}{},
},
},
},
}
\begin{forest}
[0
[1
]
[2, missing=0
[2
]
[3
]
]
[3, missing=1
[1
]
[3
]
]
[4
]
]
\end{forest}

\end{document}


This might also be useful in binary trees since you can use 0 for left child missing and 1 for right child missing:

\documentclass[tikz,multi,varwidth]{standalone}
\usepackage{forest}

\begin{document}

\forestset{
missing/.style={
if={equal(#1,0)}{
before typesetting nodes={
prepend={[, phantom]},
},
}{
for children={
if n=#1{
before typesetting nodes={
insert after={[, phantom]},
},
}{},
},
},
},
}
\begin{forest}
[0
[1, missing=1
[1
]
]
[2, missing=0
[2
]
]
]
\end{forest}

\end{document}
`