修复或替换森林中的 tikzmark/pgfmark/subnode

修复或替换森林中的 tikzmark/pgfmark/subnode

我尝试将forest树中节点的某些部分连接到节点的其他部分。这在 texlive 2013 中有效。我找到了问题的答案,该答案也记录在有两个森林图形并使用 tikzmark.后来我得到了一个解决方案subnode

\documentclass{article}
\usepackage{forest}

\usetikzlibrary{tikzmark}


\begin{document}


\begin{forest}
[V
[\subnode{ap1}{AP}
[ungewaschen]]
[V{[ \subnode{arg11}{1}, \subnode{arg12}{2} ]}
[isst]]]
\end{forest}
\begin{tikzpicture}[overlay,remember picture]
\draw[->, bend angle=40, bend left] (ap1.north) to (arg11.north);
\draw[->, bend angle=40, bend left] (ap1.north) to (arg12.north); 
\end{tikzpicture}

\end{document}

在此处输入图片描述

但这些解决方案在 texlive 2014 和 2015 中均不起作用。我现在得到了另一个需要 tex live 2015 的问题的答案,因此我陷入了困境。所以问题是是否有一个库或其他东西允许在forest节点内有节点?我想这对语言学来说真的很重要。forest手册中有一些用于绘制箭头的代码,但没有用于节点子部分的代码。

pdflatex 可以正确显示,但是 xelatex 会生成以下图片:

在此处输入图片描述

答案1

问题的根源似乎是 PGF 使用\pgfpositionnodelater和的延迟节点定位(PGF 手册 102.2.3) \pgfpositionnodenow,如下例所示。(Forest 使用延迟节点定位来放置所有节点!)

pdflatex使用和运行示例xelatex。在示例中,两个节点(A 和 B)以延迟方式在同一张图片中创建。pgfpositionnodenow但是 将它们定位在不同的位置。示例的设置使得 PdfLaTeX 清楚地为页面左下角的节点 A 生成正确的结果 (0,0)。XeLaTeX 错误地为两个节点生成相同的结果(我猜是因为\pgfpositionnodenow在相同的当前点使用,但我无法弄清楚结果维度的含义)。

我希望有人能指点如何解决这个问题。恐怕我不擅长这种低级的事情。

\documentclass{article}
\usepackage[margin=0pt]{geometry}
\parindent 0pt
\usepackage{tikz}
\usepackage{etoolbox}
\newbox\alaterbox
\newbox\blaterbox
\def\asavelaternode{%
  \global\setbox\alaterbox=\box\pgfpositionnodelaterbox
  \global\let\alatername\pgfpositionnodelatername
  \global\let\alaterminx\pgfpositionnodelaterminx
  \global\let\alaterminy\pgfpositionnodelaterminy
  \global\let\alatermaxx\pgfpositionnodelatermaxx
  \global\let\alatermaxy\pgfpositionnodelatermaxy
}
\def\bsavelaternode{%
  \global\setbox\blaterbox=\box\pgfpositionnodelaterbox
  \global\let\blatername\pgfpositionnodelatername
  \global\let\blaterminx\pgfpositionnodelaterminx
  \global\let\blaterminy\pgfpositionnodelaterminy
  \global\let\blatermaxx\pgfpositionnodelatermaxx
  \global\let\blatermaxy\pgfpositionnodelatermaxy
}
\def\arestorelaternode{%
  \setbox\pgfpositionnodelaterbox=\box\alaterbox
  \let\pgfpositionnodelatername\alatername
  \let\pgfpositionnodelaterminx\alaterminx
  \let\pgfpositionnodelaterminy\alaterminy
  \let\pgfpositionnodelatermaxx\alatermaxx
  \let\pgfpositionnodelatermaxy\alatermaxy
}
\def\brestorelaternode{%
  \setbox\pgfpositionnodelaterbox=\box\blaterbox
  \let\pgfpositionnodelatername\blatername
  \let\pgfpositionnodelaterminx\blaterminx
  \let\pgfpositionnodelaterminy\blaterminy
  \let\pgfpositionnodelatermaxx\blatermaxx
  \let\pgfpositionnodelatermaxy\blatermaxy
}
\gdef\pgfsyspdfmark#1#2#3{\csgdef{#1}{(#2 sp, #3 sp)}}
\begin{document}
\makeatletter
\tikzset{every node/.style={inner sep=0, outer sep=0, anchor=north west}}%
\tikz{%
  \pgfpositionnodelater{\asavelaternode}\node(a){\pgfsys@markposition{posa}A};
  \pgfpositionnodelater{\bsavelaternode}\node(b){\pgfsys@markposition{posb}B};
}%
\vfill
A: \csuse{posa}

B: \csuse{posb}

\tikz{%
  \arestorelaternode\pgfpositionnodenow{\pgfqpoint{1cm}{2cm}}%  
  \brestorelaternode\pgfpositionnodenow{\pgfqpoint{5cm}{4cm}}%
}%
\end{document}

PdfLaTeX 结果:

A: (0 sp, 0 sp)
B: (7458720 sp, 3729360 sp)

XeLaTeX 结果:

A: (-1864679 sp, -3281531 sp)
B: (-1864679 sp, -3281531 sp)

答案2

如果预先计算偏移量,则可以指向字符串中的特定字母。我应该提到,这取决于 [inner sep] 使用的森林。

\documentclass{article}
\usepackage{forest}

\usetikzlibrary{calc}
\newlength{\offset}

\begin{document}

\settowidth{\offset}{V[1,2}

\begin{forest}
[V
[AP,name=ap1
[ungewaschen]]
[V{[1,2]},name=arg1]
[isst]]]
tikz={\draw[->, bend angle=40, bend left] (ap1.north) to ($(arg1.north west)+(\offset,0)$);}
\end{forest}

\end{document}

相关内容