Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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}
share|improve this question
    
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

2 Answers 2

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}
share|improve this answer
    
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}

forest tree with phantom node

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}

more elaborate missing

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}

more elaborate still

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}

binary missings

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.