5

I am trying to define a node inside a curly braces {}:

\documentclass{article}

\usepackage{tikz}
\usepackage{tikz-qtree}

\begin{document}

\begin{tikzpicture}
\Tree [.CP \node(y){here}; [.C$'$ C [.TP \edge[roof]; {Some text \node(x){here};} ]]]
\end{tikzpicture}

\end{document}

I need to define the node x inside the {} environment since I want tikz-qtree to treat the string 'Some text here' as a single unit. However, if I place the semicolon after the first or second closing bracket, it does not work.

Alenanno
  • 37,338
Andy
  • 53
  • 1
    Please provide a Minimal Working Example, that has all the necessary to be compiled (from \documentclass{} ... \begin{document} ... \end{document) but with only the code that is relevant to your question. You should also apply the code formatting in your question. There is a button that looks like {} in the editor. Select the code and press that button. – Alenanno Apr 20 '15 at 15:25
  • You mean you want an image like this one? If not, could you do an example image of what you want to achieve? I'm not sure I understand your question. – Alenanno Apr 20 '15 at 15:41
  • You cannot access tikz commands inside the text field of a node. You might use something like {Some text \tikz[remember picture]{\node(x){here};}} – John Kormylo Apr 20 '15 at 15:45
  • I tried the solution @JohnKormylo proposed which gives me this - I suppose I can anchor the text to the base somehow? What I am aiming for is the result that you get when you do not try and define a node in the {}, which looks like this – Andy Apr 20 '15 at 15:59
  • There is always [anchor=base] (p 229 of manual). – John Kormylo Apr 20 '15 at 16:04

2 Answers2

7

Since the text inside the roofed node is a node itself internally and you can't embed nodes within nodes, you need to attack this problem in a slightly different way. The basic idea is to make the parent node of the roofed node the named node instead. Then if you want to show, e.g. an arrow from each of the nodes you have to offset the starting point of the arrow relative to the parent node. Here's an example:

\documentclass{article}

\usepackage{tikz}
\usepackage{tikz-qtree}

\begin{document}

\begin{tikzpicture}
\Tree [.CP \node(y){here}; [.C$'$ C [.\node(x){TP}; \edge[roof];  {Some text here} ]]]
\draw [->] (x.south)++(.9,-1) to[out=-90,in=-90,looseness=2] (y.south); 
\end{tikzpicture}

\end{document}

An alternative method (which is perhaps a bit simpler) is to define the roof text itself as a node, and then just use the [xshift] parameter to shift the start point of the arrow to the desired spot:

\documentclass{article}

\usepackage{tikz}
\usepackage{tikz-qtree}

\begin{document}

\begin{tikzpicture}
\Tree [.CP \node(y){here}; [.C$'$ C [.TP \edge[roof];  \node(x){Some text here}; ]]]
\draw [->] ([xshift=2.5em]x.south) to[out=-90,in=-90,looseness=2] (y.south); 
\end{tikzpicture}

\end{document}

output of code

Alan Munn
  • 218,180
  • @AlanMunn, this kind of manual positioning is what I've resorted to doing in cases like this where I want to draw from single words under a roof/triangle (whether in tikz-qtree or forest). In tikz in general you can nest nodes using a matrix (http://tex.stackexchange.com/q/1003/42880), but I haven't been able to make the node at the bottom of a roof/triangle a matrix. Any ideas why? I might post a separate question about this, but it seems like a matrix-based solution to @Andy's question would be nice to avoid the manual positioning. – Jason Zentz Apr 20 '15 at 16:45
  • @AlanMunn, wouldn't it make more sense for this example to label the node below the triangle like you did in this answer? Then you only have to adjust on the x-axis (e.g. ([xshift=2.5em]x.south) could be the origin of the arrow). – Jason Zentz Apr 20 '15 at 16:50
  • @JasonZentz Thanks, I've added that solution too. (I'd forgotten about my previous answer). As for the matrix based solution, the linked answer says "abuse" the matrix command, so I think that as a general solution it won't work. – Alan Munn Apr 20 '15 at 17:19
  • @AlanMunn, I think it was called "abuse" in the context of that question, where the proposed solution is to use a matrix with only a single node. But here we would be using a whole row of nodes (only 2 would be necessary to isolate "here" in this MWE, but you could imagine drawing arrows between several words below the triangle, in which case you'd want more nodes in the matrix), which is a perfectly normal use of a matrix. – Jason Zentz Apr 20 '15 at 17:32
  • 1
    (+1) even though it doesn't use forest... ;). – cfr Apr 20 '15 at 23:26
6

Just in case it had escaped anybody's notice, I tend to prefer forest when drawing trees.

This solution does not require manually repeating the word 'here' or manually adjusting the positioning of the start of the arrow. It is based on an example from page 20 of the manual, though I may have mangled it a little.

  • triangle is used for the roof
  • a style, move={}{} is defined which takes 2 arguments: the first specifies the node to which the content should be copied; the second specifies additional text to add to the current node.

I'm assuming that you may not want to do exactly this, so this is more by way of illustration than a ready-to-use solution. In the example you gave, you would put move={<specification of target node>}{Some text} and you would specify the content of the source node as here.

The source node would then end up containing Some text here, the target node would end up containing here and an arrow would be drawn between a point just below here in the source node and one just below here in the target node.

I've used a 'relative node walk' to specify the target node. However, you could equally add , name=target to your target node and then just put move={target}{Some text}, which is probably simpler in most cases. I've added this alternative as commented code in the tree to demonstrate the idea.

\documentclass[tikz,border=5pt]{standalone}
\usepackage{forest}
\begin{document}
  \newlength{\sourcetextaddwidth}
  \begin{forest}
    for tree={
      parent anchor=south,
      child anchor=north,
      fit=rectangle
    },
    move/.style n args=2{% page 20 of forest manual
      before typesetting nodes={
        TeX={
          \settowidth{\sourcetextaddwidth}{#2}
        },
        #1.content={##1},
        content={#2 ##1},
        tikz={
          \draw[->] (.south) +(.5\sourcetextaddwidth,0) to [out=south west, in=south] (#1);
        },
      },
    },
    [CP
      [this is the target node to which text will be moved%, name=target
      ]
      [C$'$
        [C
        ]
        [TP
          [here, triangle, move={!r1}{Some text}% move={target}{Some text}
          ]
        ]
      ]
    ]
  \end{forest}
\end{document}

automated tree

cfr
  • 198,882