# Why does the node style newcommand not work in tikz-qtree?

To reuse the labeled node style in tikz-qtree, I have defined
\newcommand{\lnode}[3]{\node [label = {#1} : {$#2$}] {#3};}.
However, \lnode does not work as in \Tree [.\lnode{above}{[1,5]}{$x$} ....

How to fix it?

\documentclass[tikz]{standalone}

\usepackage{tikz-qtree}

\newcommand{\lnode}[3]{\node [label = {#1} : {$#2$}] {#3};}

\begin{document}
\begin{tikzpicture}[level distance = 40pt, sibling distance = 30pt,
edge from parent/.style= {
draw, edge from parent path={(\tikzparentnode) -- (\tikzchildnode)}}]
\tikzset{every node/.style = {draw, circle}}

% \lnode works here
\lnode{above}{[1,5]}{$x$}

\begin{scope}[xshift = -2.5cm]
\Tree [.\node[label = above : {$[1,5]$}]{$x$};
[.\node[label = above : {$[1,1]$}] {$y$}; ]
[.\node[label = above : {$[3,5]$}] {$z$}; ]
]
\end{scope}

% \lnode does not work in qtree
% \begin{scope}[xshift = 2.5cm]
%   \Tree [.\lnode{above}{[1,5]}{$x$}
%           [.\lnode{above}{[1,1]}{$y$} ]
%           [.\lnode{above}{[3,5]}{$z$} ]
%         ]
% \end{scope}
\end{tikzpicture}
\end{document}

• There are many possible reasons, one being that the parser really wants to see a \node, or expansion issues. But there is IMHO also not too much point in this, your could just define a style that does the same. You could e.g. do l/.style n args={2}{label={#1}:{$#2$}} and then \Tree [.\node[l={above}{[1,5]}]{$x$}; [.\node[l={above}{[1,1]}]{$y$}; ] [.\node[l={above}{[3,5]}]{$z$}; ] ]. – user121799 Oct 5 '18 at 15:56
• @marmot The parser is indeed looking for an explicit \node. The offending code is in the \@label command: \@label ->\pgfutil@ifnextchar \node {\@litlabel }{\@@label } – Hood Chatham Oct 5 '18 at 16:21
• @HoodChatham Thanks! You may want to write an answer since this answers the question "Why does the node style newcommand not work in tikz-qtree?". (Whether or not it is really desirable to use such new commands here is a different question, and the answer is anyway opinion based.) – user121799 Oct 5 '18 at 16:36
• @HoodChatham Would you mind writing an answer so that I can accept it? – hengxin Oct 6 '18 at 15:25

The tikzqtree parser is indeed looking for an explicit \node. The offending code is in the \@label command: \@label ->\pgfutil@ifnextchar \node {\@litlabel }{\@@label } so \pgfutil@ifnextchar\node checks if the next token is a literal \node token. Any other token in that place will not be processed as a label, and gets expanded later in some strange context. The \node command is specifically undefined at the beginning of the \Tree command so instead of doing something crazy, it just throws an undefined command error.
I determined this by adding a \tracingall before the \Tree command and then analyzing the resulting log file.