tikzmark 和 xelatex 似乎存在问题。xetex 列表中的 Ulrike Fischer 帮助追踪了这个问题。以下代码在使用 xelatex 编译时不起作用,但在使用 pdflatex 编译时会产生预期结果:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{tikzmark}
\begin{document}
x\pgfmark{tA}some text \pgfmark{tB} some text
\begin{tikzpicture}[remember picture]
\draw (0,0)node (A){A} rectangle (1,1)node (B){B};
\end{tikzpicture}
\begin{tikzpicture}[remember picture]
\draw (0,0)node {\pgfmark{nA}} rectangle (1,1)node {\pgfmark{nB}};
\end{tikzpicture}
\vspace{3cm}\centering
\begin{tikzpicture}[overlay,remember picture]
\draw[red,->] (0,0)--(pic cs:tA) (0,0)--(pic cs:tB);
\draw[blue,->](0,0)--(pic cs:nA) (0,0)--(pic cs:nB); %nB faulty
\draw[green,->](0,0)--(A) (0,0)--(B);
\end{tikzpicture}
\end{document}
有快速修复方法吗?从 texlive 2013 升级到 texlive 2014 后出现了此问题。
编辑:原始代码使用过\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{forest}
[V
[\subnode{ap2}{AP}
[ungewaschen]]
[V{[\subnode{arg21}{1} ]}]]
\end{forest}
\begin{tikzpicture}[overlay,remember picture]
%% this works with tikzmark
%% \draw[->, bend angle=40, bend left] ($(pic cs:ap1)+(1ex,2ex)$) to($(pic cs:arg11)+(1ex,2.5ex)$);
%% \draw[->, bend angle=40, bend left] ($(pic cs:ap1)+(1ex,2ex)$) to($(pic cs:arg12)+(1ex,2.5ex)$); % 1ex links, 2ex hoch
%% %
%% this used to work with subnode in texlive 2013 but is broken now
%% \draw[->, bend angle=40, bend left] ($(pic cs:ap2)+(1ex,2ex)$) to($(pic cs:arg21)+(1ex,2.5ex)$);
\draw[->, bend angle=40, bend left] (ap1.north) to (arg11.north);
\draw[->, bend angle=40, bend left] (ap1.north) to (arg12.north);
%
\draw[->, bend angle=40, bend left] (ap2.north) to (arg21.north);
\end{tikzpicture}
\end{document}
AP 应该分别连接到 1 和 2,但箭头却朝上。
答案1
感谢@UlrikeFischer 和@AkiraKakuto 的评论。
在 PGF 中,该命令\pgfsys@hboxsynced
用于将一些文本放置在指定位置。有两种方法可以做到这一点:
\hskip
和一起努力\raise
;告诉 PDF 渲染器为您完成这些脏活。
当使用 LaTeX 时,通过第一种方法pgfsys-pdftex.def
实现\pgfsys@hboxsynced
。并且正如 @AkiraKakuto 所建议的,中的实现pgfsys-common-pdf-via-dvi.def
也使用第一种方法。
但是,当使用 XeLaTeX 时, 中的实现pgfsys-common-pdf-via-dvi.def
会被 覆盖pgfsys-dvipdfmx.def
,后者使用第二种方法。现在,所有文本都连同一些定位信息一起放在原点。PDF 渲染器将识别这些信息并将这些文本移到正确的位置。但是,\tikzmark
和任何其他标记宏将不再起作用,因为您标记的是原点。
尽管我们可以\pgfsys@hboxsynced
自己实现,但这需要大量有关 XeLaTeX 的知识,我们也可以尝试定位信息。
注意,定位信息由 处理\pgfsys@transformcm
。因此我们可以尝试
\let\temp=\pgfsys@transformcm
\def\pgfsys@transformcm#1#2#3#4#5#6{
\rememberxshift{#5}
\rememberyshift{#6}
\temp{#1}{#2}{#3}{#4}{#5}{#6}
}
然后我们可以\tikzmark
根据信息修复或任何标记宏。
更多技术细节
\pgf@pt@x
是 x 移的维度。- 所以
\hskip\pgf@pt@x
属于第一种方法。 - 另一方面,任何诸如
\pgflowlevelsynccm
、、、\pgfsys@invoke
之类的东西都\special
与第二种方法相关。 - 一个简单的例子是
\tikz[overlay]\node[xshift=100]{Some \pgfmark{X} Text}; \tikz[overlay,remember picture]\draw(pic cs:X)circle(.1);
- 一个更简单的例子是(我们甚至不在
pgfpicture
)\newbox\mybox \setbox\mybox=\hbox{Some \pgfmark{Y} Text 2} \pgftransformxshift{100} \pgfsys@hboxsynced\mybox \tikz[overlay,remember picture]\draw(pic cs:Y)circle(.1);