7

I am using forest to construct trees. I have one (minor but persistent) issue: sometimes I would like to place a node at a point that is a proper part of (e.g.) a leaf, in particular so that I can draw movement arrows targeting proper parts of nodes. Here is an example of what I'm after:

movement from inside a node

One low-tech option is to simply name the entire node (here, John see x) and then tweak the arrow's origin on a case-by-case basis (which is how I made the tree above). But that's pretty annoying to do multiple times in a single document, or (gasp) if the tree's layout ever needs to change substantially.

User cfr defined a nice workaround here. However, it is not obvious to me how to turn this into a general solution:

  • For example, this solution only allows for one such sub-part to be targeted. It's straightforward enough to modify cfr's code to handle e.g. the case where there are two adjacent sub-parts, but in the general case, the regions of interest may be non-adjacent, or there may be more than two.

  • In addition, the linked solution makes use of a "global" length \sourcetextaddwidth, which prevents one from reusing the code multiple times in a single document without repeated manual adjustments.

  • Finally (most importantly for me), one may wish to shape the arrow in certain ways, but the linked approach locates the arrow drawing inside the move style/"macro", which doesn't allow for this. Again, achieving the desired effect requires repeated manual adjustments.

What I think would be preferable is a reusable macro/forest style that allows one to create a tikz node at a sub-part of a forest tree node. Then, one can simply use those nodes to draw movement arrows (or whatever) in the usual way. I am not sure whether this is possible, but if it is, it's certainly beyond my pay grade.

Edited to add a MWE with a simple tree for folks to play around with (no arrows, per the nature of the question). The hope is to have an arrow relating the two occurrences of B:

\documentclass{article}
\usepackage{forest}
\begin{document}
\begin{forest}
  [A
    [B]
    [C
      [D]
      [E B F]
    ]
  ]
\end{forest}
\end{document}
SEC
  • 761

1 Answers1

8

You could use the tikzmark library. Using \subnode{<name>}{<content>} you can place some marks around designated elements and then use those marks and the node anchors to easily place the arrows:

\documentclass{article}
\usepackage{forest}
\usetikzlibrary{tikzmark}

\begin{document}

\begin{forest} for tree={s sep=20pt} [A t\subnode{endc}{e}st text [B [\subnode{enda}{C}, ] ] [D [\subnode{endb}{E} ] [\subnode{startc}{F} [G ] [H [\subnode{startb}{Johh} see \subnode{starta}{x} ] ] ] ] ] \end{forest}

\begin{tikzpicture}[ remember picture, overlay, >=latex ] \draw[cyan,thick,->] (starta.south) -- ++(0pt,-10pt) -| (enda.south); \draw[red!80!black,thick,->] (startb.south) -- ++(0pt,-5pt) -| (endb.south); \draw[green!80!black,thick,->] (startc) to[out=60,in=90,looseness=1.4] (endc.north); \end{tikzpicture}

\end{document}

enter image description here

Update

The previous solution won't work with current version of xetex; there seems to be a problem with the drivers? This problem has been noticed in tikzmark and xelatex and there, in a comment, user Akira Kakuto suggested a workaround that seems to work here:

\documentclass{article}
\newcount\pdftexversion 
\pdftexversion140 \def\pgfsysdriver{pgfsys-dvipdfm.def}
\usepackage{forest}
\usetikzlibrary{tikzmark}

\begin{document}

\begin{forest} for tree={s sep=20pt} [A t\subnode{endc}{e}st text [B [\subnode{enda}{C}, ] ] [D [\subnode{endb}{E} ] [\subnode{startc}{F} [G ] [H [\subnode{startb}{Johh} see \subnode{starta}{x} ] ] ] ] ] \end{forest}

\begin{tikzpicture}[ remember picture, overlay, >=latex ] \draw[cyan,thick,->] (starta.south) -- ++(0pt,-10pt) -| (enda.south); \draw[red!80!black,thick,->] (startb.south) -- ++(0pt,-5pt) -| (endb.south); \draw[green!80!black,thick,->] (startc) to[out=60,in=90,looseness=1.4] (endc.north); \end{tikzpicture}

\end{document}

The result, using xelatex:

enter image description here

I have no advanced knowledge of xelatex, so use this with precaution. Since internal calculations are involved, the code needs two or three runs for the arrows to land on their final places.

Gonzalo Medina
  • 505,128