# tikzmark position erratic in overprint environment of beamer

My aim is to highlight a term in an equation, and draw an arrow pointing to another one.

Here's my code

\documentclass{beamer}

\usepackage{tikz}
\usetikzlibrary{arrows,calc,tikzmark}%decorations.markings,shapes,positioning

%% Beamer %%
\usefonttheme{professionalfonts}

%% TikZ %%
\tikzset{>=stealth,%
annotations/.style={overlay,remember picture}
}

\newcommand{\hilitTerm}[2]{\tikz[remember picture,baseline,inner xsep=0pt]\node[fill=red!20,anchor=base] (#1) {#2};}

%% Commands%
\newcommand{\uf}{\boldsymbol{u}}
\renewcommand{\vec}[1]{\boldsymbol{#1}}

\begin{document}

\begin{frame}{Balance of momentum}

\begin{overprint}

\onslide<1-2>
\begin{block}{}
\begin{align*}
\rho(\partial_t \uf + (\uf\cdot\nabla)\uf) =- \tikzmark{pPos}\nabla p + \mu \Delta \uf +  \hilitTerm{bodForce}{$\displaystyle \rho \only<1>{\vec{f}}\only<2>{\vec{g}}$}
\end{align*}
~
\end{block}
\begin{itemize}
\item Body forces\visible<2-3>{: gravity}
\end{itemize}
\begin{tikzpicture}[annotations]
\useasboundingbox (0,0);
\draw<2>[red,->] (bodForce.north) to[bend right=45] ($(pic cs:pPos) + (1em,2ex)$);
\end{tikzpicture}

\end{overprint}

\end{frame}

\end{document}


If there's another slide after drawing the arrow (for example because of the visible command hiding the word "gravity" as set in the example), the arrow points to the lower left hand corner of the slide.

If there is no other slide in the frame after drawing my arrow (for example by restricting the visible command to <2>), then I get what I want.

How do I prevent the arrow from depending whether there are slides following or not? (The same phenomenon happens when the next slide doesn't feature the tikzmark.)

-
When should the arrow appear only on slide 2? Can you put more details about what should happen on 1 and 3 too? –  percusse Apr 30 '13 at 12:00
The first slide has the general vector f, the second turns to the particular case where there's just a gravity force, thus just a vector g. The third slide of my actual presentation is something else altogether (still featuring the equation though), but the error is the same if I continue with onslides in the same overprint environment. Does that help? Should I update the question? –  Christoph B. Apr 30 '13 at 12:06
I ran into the same problem a while ago, sadly I couldn't find a solution in the short time I had then. My workaround was to include everything (including the equation) in the tikz picture, using regular tikz commands to place the mark. Alignment problems were fixed by fiddling with use as bounding box and baseline. –  T. Verron Apr 30 '13 at 12:10

I think I'll need to do some more analysis to figure out what is really going on here, but I have what appears to be a solution for the time being so I'll post this for now. If this doesn't work, I'll have to think a bit more.

The issue is that the \tikzmark is getting called too often. I think it is both the overprint environment and the align* that are calling it too often. Both reset their contents several times (to figure out things like spacing) and when the \tikzmark is called inside a box which is then thrown away then it isn't happy: it records a mark, but that mark has no corresponding coordinate and so the default is used (which, in this case, happens to be in the bottom corner of the page). The real problem here is the overprint environment, I think, as it typesets the equation on slide 3 and throws it away and this is the last time the equation is typeset so that remembered position is the one that wins.

The (temporary) solution is to ensure that the \tikzmark is not invoked on slide 3. The simplest way to do that is to make it overlay aware. Put the following in the preamble:

\renewcommand<>{\tikzmark}[2][]{\only#3{\beameroriginal{\tikzmark}[{#1}]{#2}}}


(This, I think, would make a good addition to the tikzmark package, but I'd like to get to the bottom of this issue before updating.)

Then in your equation, make the \tikzmark call \tikzmark<2>{pPos}. This will ensure that on the third run then it isn't invoked and so doesn't overwrite the position saved on the second run.

Update after a few minutes testing ...

It would seem that the problem with boxes is due to my use of \immediate\write. It would seem that \protected@write works better. The relevant fix will be:

\makeatletter
\tikzset{
save picture id/.code={%
\protected@write\pgfutil@auxout{}{%
\string\savepointas{#1}{\pgfpictureid}}%
},
}
\makeatother


(The \pgfmark macro will need a similar fix.)

I think that the beamer version will be useful as well so I'll put both in.

-
Thanks a million, this works for my current purposes! –  Christoph B. Apr 30 '13 at 12:47