tikzmark y xelatex

tikzmark y xelatex

Parece haber un problema con tikzmark y xelatex. Ulrike Fischer, de la lista xetex, ayudó a localizarlo. El siguiente código no funciona cuando se compila con xelatex pero produce el resultado esperado cuando se compila con 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} 

¿Existe una solución rápida para esto? El problema apareció después de actualizar de texlive 2013 a texlive 2014.

Editar:Se utilizó el código original \subnodepero tampoco funciona:

\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}

El AP debe estar conectado a 1 y 2 respectivamente, pero las flechas están en el aire.

ingrese la descripción de la imagen aquí

Respuesta1

Gracias al comentario de @UlrikeFischer y @AkiraKakuto.


En PGF, el comando \pgfsys@hboxsyncedse usa para colocar texto en una posición específica. Hay dos maneras de hacerlo:

  • trabajar duro con \hskipy \raise;

  • Dígale a los procesadores de PDF que hagan el trabajo sucio por usted.


Cuando se utiliza LaTeX, pgfsys-pdftex.defse implementa \pgfsys@hboxsyncedmediante el primer método. Y como sugirió @AkiraKakuto, la implementación pgfsys-common-pdf-via-dvi.deftambién utiliza el primer método.

Sin embargo, cuando se utiliza XeLaTeX, la implementación pgfsys-common-pdf-via-dvi.defse sobrescribe con pgfsys-dvipdfmx.def, que utiliza el segundo método. Ahora todos los textos se colocan en el origen junto con alguna información de posicionamiento. Los procesadores de PDF reconocerán esta información y trasladarán esos textos al lugar correcto. Sin embargo \tikzmark, cualquier otra macro de marcado ya no funcionará porque lo que estás marcando es el origen.


Aunque podemos implementarlo \pgfsys@hboxsyncednosotros mismos, lo que requiere muchos conocimientos sobre XeLaTeX, podemos jugar con la información de posicionamiento.

Observe que la información de posicionamiento es procesada por \pgfsys@transformcm. Así que podríamos intentarlo

\let\temp=\pgfsys@transformcm
\def\pgfsys@transformcm#1#2#3#4#5#6{
    \rememberxshift{#5}
    \rememberyshift{#6}
    \temp{#1}{#2}{#3}{#4}{#5}{#6}
}

Y luego podemos arreglar la \tikzmarkmacro de marcado o cualquier otra mediante la información.


Más detalles técnicos

  • \pgf@pt@xes la dimensión para el desplazamiento x.
  • entonces \hskip\pgf@pt@xpertenece al primer método.
  • por otro lado, algo como \pgflowlevelsynccm, \pgfsys@invoke, \special, está relacionado con el segundo método.
  • Un ejemplo mínimo es
    \tikz[overlay]\node[xshift=100]{Some \pgfmark{X} Text};
    \tikz[overlay,remember picture]\draw(pic cs:X)circle(.1);
    
  • Un ejemplo cada vez más sencillo es (ni siquiera estamos dentro de un 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);
    

información relacionada