1

I am struggeling with one particular problem for years now. I try to draw arrows from a part of a node in a forest tree. Due to a bug in xelatex this does not work with the tikzmark package and the subnode command.

The topic was discussed here:

tikzmark and xelatex

fixing or replacing tikzmark/pgfmark/subnode within forest

I am too dumb for understanding the solutions. Some solutions seem to be outdated. The underlying bug in xelatex seems to be not fixed and pdflatex seems to have stopped working as well.

What I want to do is to connect all the Vs after the // with double arrows. This should work in a copy and paste-safe way. I can shift the arrows left or right, but when I change the font size, this breaks. Is there any solution to this? Of course the subnode solution would be the preferred one.

\documentclass{article}

\usepackage{forest} \useforestlibrary{linguistics} \forestapplylibrarydefaults{linguistics}

\usetikzlibrary{arrows} \tikzset{ %Define standard arrow tip >=stealth'}

\newcommand{\sliste}[1]{% \mbox{% $\left\langle\mbox{\upshape\scshape #1}\right\rangle$}% }

    \begin{document}


\begin{forest} where n children=0{tier=word}{} [S [{V \sliste{ S$/!/$V }},name=vini [V,name=vlast [liest$_j$] ] ] [{S$/!/$V}, name=sv [NP [Conny] ] [{V$'$$!/!/$V}, name=v1v [NP [das Buch, roof] ] [{V$!/!/$V}, name=vv [_$_j$] ] ] ] ] ] \path[semithick,<->,color=green] (v1v.east) edge [bend left=44] (vv.east); \path[semithick,<->,color=green] (v1v.north east) edge [bend right=44] (sv.east); \path[semithick,<->,color=green] (sv.north) edge [bend right=24] (vini.north); \draw[semithick,<->,color=green] (vini.south) -- (vlast.north); \end{forest}

\end{document}

With a working subnode command, it should look like this:

\documentclass{article}

\usepackage{tikz} \usetikzlibrary{tikzmark}

\usepackage{forest} \useforestlibrary{linguistics} \forestapplylibrarydefaults{linguistics}

\usetikzlibrary{arrows} \tikzset{ %Define standard arrow tip >=stealth'}

\newcommand{\sliste}[1]{% \mbox{% $\left\langle\mbox{\upshape\scshape #1}\right\rangle$}% }

    \begin{document}


\begin{forest} where n children=0{tier=word}{} [S [{V \sliste{ S$/!/$\subnode{vini}{V} }},name=vinix [V,name=vlast [liest$_j$] ] ] [{S$/!/$\subnode{sv}{V}}, name=svx [NP [Conny] ] [{V$'$$!/!/$\subnode{v1v}{V}}, name=v1vx [NP [das Buch, roof] ] [{V$!/!/$\subnode{vv}{V}}, name=vvx [_$_j$] ] ] ] ] ] \path[semithick,<->,color=green] (v1v.east) edge [bend left=44] (vv.east); \path[semithick,<->,color=green] (v1v.north east) edge [bend right=44] (sv.east); \path[semithick,<->,color=green] (sv.north) edge [bend right=24] (vini.north); \draw[semithick,<->,color=green] (vini.south) -- (vlast.north); \end{forest}

\end{document}

Stefan Müller
  • 6,901
  • 3
  • 29
  • 61
  • 2
    If I compile the second lot of code with pdfTeX, I get very strange output which I'm sure isn't what you want. Can you post a picture of the target output? – cfr Jun 29 '23 at 17:30
  • With both pdfTeX and luaTeX, the second lot of code produces unstable output which flip-flops between compilations, but neither of the results looks at all sane. – cfr Jun 29 '23 at 17:34
  • I think it would be better to ask this without the forest complication because the problem is the use of \tikzmark or \subnode in any tikzpicture with XeTeX - it isn't specific to forest. Unless you're specifically asking for some kind of forest work around? – cfr Jun 29 '23 at 19:26
  • If the //V is always the last thing in the node, you could just use an anchor on a named node, for example, but a more general solution probably needs a generic solution i.e. non-forest-specific. – cfr Jun 29 '23 at 19:37
  • Yes, it is a general problem. Ultimately, I would be happy with a forest solution since this is what I work with all day. – Stefan Müller Jun 30 '23 at 08:58
  • The target ouput is approximately what you get from the first example but instead of targeting the whole forest node, the arrows should point to the Vs after //. This could be done with manual shifts, but this is causing manual labor or some kind of distance measuring computations. – Stefan Müller Jun 30 '23 at 09:08
  • Can't you just point to a fixed point on the border of the node, in that case? If the Vs are always last, something like .east? – cfr Jul 01 '23 at 02:46
  • The example is just an instance of a general case. I want to be able to point to portions of nodes. For example, boxed numbers inside a node. This was described here: https://tex.stackexchange.com/questions/229500/tikzmark-and-xelatex – Stefan Müller Jul 01 '23 at 10:34
  • 1
    Then I think you need a non-Forest-specific solution and would be better off asking a more general question. This isn't a criticism of this question: just I think you're more likely to get something useful in response to a more generic one. https://tex.stackexchange.com/a/266743/ is key here. If Forest's author can't offer a Forest-specific solution, I doubt you'll get one. – cfr Jul 01 '23 at 16:12
  • Thanks! But as I said in the question: I am too dumb for this. Would the problem exist when using subnode in normal text? For normal text tixmark may work and subnode may not be needed. The complexity of this problem is above my knowledge of latex. – Stefan Müller Jul 02 '23 at 10:47
  • The problem certainly exists in a simple tikzpicture. As I understand it, you wouldn't use \subnode in normal text. For example, try \documentclass{standalone} \usepackage{tikz} \usetikzlibrary{tikzmark} \begin{document} \begin{tikzpicture}[remember picture] \node {A node with a \subnode{sn}{subnode}}; \end{tikzpicture} \begin{tikzpicture}[remember picture, overlay] \draw [red,<-] (pic cs:sn) -- ++(0pt,25pt); \end{tikzpicture} \end{document} In contrast, \tikzmark seems to work in normal text and in a tikzpicture (provided the appropriate form is used). – cfr Jul 02 '23 at 20:00
  • I think more people will look at an example like that which doesn't involve Forest. Lots more TikZ users than Forest users! See also page 1142 of the TikZ manual, which says your driver has to support position tracking? – cfr Jul 02 '23 at 20:01

1 Answers1

1

After asking the question in a tikz-related form, I was pointed to this solution to a similar problem:

Draw connection between node in forest tree diagram and something outside it

I adapted it to my forest problem. The point I struggled with was that the drawing has to happen outside of forest, since the subnode coordinates seem to work only outside of the tree.

\documentclass{article}

\usepackage[linguistics]{forest}

\forestapplylibrarydefaults{linguistics}

\usetikzlibrary{positioning, tikzmark, arrows}

\tikzset{ %Define standard arrow tip >=stealth'}

% WORKAROUND:
% Definition copied from /usr/share/texlive/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-common-pdf-via-dvi.def % Compare https://tex.stackexchange.com/q/229500 and comments! \makeatletter \def\pgfsys@hboxsynced#1{% {% \pgfsys@beginscope% \setbox\pgf@hbox=\hbox{% \hskip\pgf@pt@x% \raise\pgf@pt@y\hbox{% \pgf@pt@x=0pt% \pgf@pt@y=0pt% \special{pdf: content q}% \pgflowlevelsynccm% \pgfsys@invoke{q -1 0 0 -1 0 0 cm}% \special{pdf: content -1 0 0 -1 0 0 cm q}% translate to original coordinate system \pgfsys@invoke{0 J [] 0 d}% reset line cap and dash \wd#1=0pt% \ht#1=0pt% \dp#1=0pt% \box#1% \pgfsys@invoke{n Q Q Q}% }% \hss% }% \wd\pgf@hbox=0pt% \ht\pgf@hbox=0pt% \dp\pgf@hbox=0pt% \pgfsys@hbox\pgf@hbox% \pgfsys@endscope% }% } \makeatother

\begin{document}

\begin{forest} where n children=0{tier=word}{} [S [{V S$/!/$\subnode{vini}{V} },name=vinix % [V,name=vlast [liest$_j$] ] ] does not work, has to be subnode [\subnode{vlast}{V} [liest$_j$] ] ] [{S$/!/$\subnode{sv}{V}}, name=svx [NP [Conny] ] [{V$'$$!/!/$\subnode{v1v}{V}}, name=v1vx [NP [das Buch, roof] ] [{V$!/!/$\subnode{vv}{V}}, name=vvx [_$_j$] ] ] ] ] ] % \path[semithick,<->,color=green] (v1v.east) edge [bend left=44] (vv.east); % \path[semithick,<->,color=green] (v1v.north east) edge [bend right=44] (sv.east); % \path[semithick,<->,color=green] (sv.north) edge [bend right=24] (vini.north); % \draw[semithick,<->,color=green] (vini.south) -- (vlast.north); \end{forest}

\begin{tikzpicture}[remember picture, overlay] \path[semithick,<->,color=green] (vv.north) edge [bend right=44] (v1v.east); \path[semithick,<->,color=green] (v1v.north) edge [bend right=44] (sv.east); \path[semithick,<->,color=green] (sv.north) edge [bend right=24] (vini.north); \draw[semithick,<->,color=green] (vini.south) -- (vlast.north); \end{tikzpicture}

\end{document}

Note that this solution breaks when multiple trees are in the same document. A solution is to put a tixmark prefix declaration before the image. E.g. \tikzset{tikzmark prefix=fig-German-v2}. This seems to open a new name space.

enter image description here

Stefan Müller
  • 6,901
  • 3
  • 29
  • 61