[Tex/LaTex] using \tikzmark in beamer: new versions of packages break old functionality

beamernodestikz-pgftikzmark

UPDATE (08/03/18): This issue has been fixed in the latest version of the tikzmark package. The workaround proposed by cfr, using \beameroriginal to redefine the \tikzmark inside beamer environments, has now been incorporated into the tikzmark package. So this question now serves only a historical purpose.


Formerly, this worked, including with pgf version 3.0.1a:

\documentclass{beamer}
%\documentclass{article}
\usepackage{tikz,pgfplots}
\usetikzlibrary{positioning,calc,tikzmark}

\begin{document}

\begin{frame}\frametitle{A SLIDE}
meaningless filler\tikzmark{a}

\begin{tikzpicture}[overlay,>=latex,shorten >=1pt,->,remember picture]
    % old preferred syntax for using tikz marks inside tikz pictures
    \node (foo) at (1,-3) {\tikzmark{b}};

    % new preferred syntax for using tikz marks inside tikz pictures
    % \tikzmark{b}{(1,-3)}
\end{tikzpicture}

\begin{tikzpicture}[overlay,>=latex,shorten >=1pt,->,remember picture]
    \draw[black] (pic cs:a) -- (4,-3);
    \draw[black] (pic cs:b) -- (4,-3);
\end{tikzpicture}

\end{frame} 

\end{document}

Now I've updated some packages–presumably including beamer–and it fails with the error "Cannot parse this coordinate." A little searching the interweb shows that the preferred way to use \tikzmark inside a tikzpicture is now \tikzmark{b}{(1,-3)}. Yet this fails also with the same error:

\documentclass{beamer}
%\documentclass{article}
\usepackage{tikz,pgfplots}
\usetikzlibrary{positioning,calc,tikzmark}

\begin{document}

\begin{frame}\frametitle{A SLIDE}
meaningless filler\tikzmark{a}

\begin{tikzpicture}[overlay,>=latex,shorten >=1pt,->,remember picture]
    % old preferred syntax for using tikz marks inside tikz pictures
    % \node (foo) at (1,-3) {\tikzmark{b}};

    % new preferred syntax for using tikz marks inside tikz pictures
    \tikzmark{b}{(1,-3)}
\end{tikzpicture}

\begin{tikzpicture}[overlay,>=latex,shorten >=1pt,->,remember picture]
    \draw[black] (pic cs:a) -- (4,-3);
    \draw[black] (pic cs:b) -- (4,-3);
\end{tikzpicture}

\end{frame} 

\end{document}

On the other hand, the problem seems to be local to beamer, because this works:

%\documentclass{beamer}
\documentclass{article}
\usepackage{tikz,pgfplots}
\usetikzlibrary{positioning,calc,tikzmark}

\begin{document}

%\begin{frame}\frametitle{A SLIDE}
meaningless filler\tikzmark{a}

\begin{tikzpicture}[overlay,>=latex,shorten >=1pt,->,remember picture]
    % old preferred syntax for using tikz marks inside tikz pictures
    % \node (foo) at (1,-3) {\tikzmark{b}};

    % new preferred syntax for using tikz marks inside tikz pictures
    \tikzmark{b}{(1,-3)}
\end{tikzpicture}

\begin{tikzpicture}[overlay,>=latex,shorten >=1pt,->,remember picture]
    \draw[black] (pic cs:a) -- (4,-3);
    \draw[black] (pic cs:b) -- (4,-3);
\end{tikzpicture}

%\end{frame} 

\end{document}

(And finally, for completeness, using \node (foo) at (1,-3) {\tikzmark{b}}; in the article class, but with the new packages, also fails, perhaps as expected.)

I dread trawling through the beamer class files. Is there something "obvious" I'm missing first?

Best Answer

Nested TikZ pictures are unsupported. Period. Sometimes they work, but they are expected to break.

\tikzmark creates a TikZ picture. Although it can now be used inside tikzpicture environments, it should not be used inside nodes inside tikzpicture environments.

The tikzmark library provides \subnode{}{} for such cases.

\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{tikzmark}
\begin{document}
\begin{frame}\frametitle{A SLIDE}
  meaningless filler\tikzmark{a}

  \begin{tikzpicture}[overlay,>=latex,shorten >=1pt,->,remember picture]
    % this has never been preferred: \tikzmark shouldn't be used inside a tikzpicture with any syntax
    \node (foo) at (1,-3) {\subnode{b}{}};
  \end{tikzpicture}

  \begin{tikzpicture}[overlay,>=latex,shorten >=1pt,->,remember picture]
    \draw[black] (pic cs:a) -- (4,-3);
    \draw[black] (b) -- (4,-3);
  \end{tikzpicture}
\end{frame}
\end{document}

subnode

However, you don't really need a \subnode{}{} because there is nothing else inside your main \node {}.

So you can just use

\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{tikzmark}
\begin{document}
\begin{frame}\frametitle{A SLIDE}
  meaningless filler\tikzmark{a}

  \begin{tikzpicture}[overlay,>=latex,shorten >=1pt,->,remember picture]
    % this has never been preferred: \tikzmark shouldn't be used inside a tikzpicture with any syntax
    \node (foo) at (1,-3) {};
  \end{tikzpicture}

  \begin{tikzpicture}[overlay,>=latex,shorten >=1pt,->,remember picture]
    \draw[black] (pic cs:a) -- (4,-3);
    \draw[black] (foo) -- (4,-3);
  \end{tikzpicture}
\end{frame}
\end{document}

I've used \node ... as it gives exactly the same result. But obviously \coordinate would be a more obvious choice here in most cases.

The use of \tikzmark inside TikZ pictures is, moreover, presumably not intended for use in pictures using the remember picture, overlay options. Note that the example in the manual does not include these options. In particular, overlay over overlay doesn't make any sense. You overlay the picture containing the mark and then overlay that with a picture referring to it. But the whole point of marks is their specific location, isn't it?

In any case, I can't get the inside syntax to work without those options either ....

EDIT

I don't think the new syntax is designed to work in conjunction with the special code used for Beamer.

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

The library does this to make \tikzmark overlay-specification aware. It also then needs to ensure that \tikzmarks are tied to one particular slide within a Beamer frame

tikzmark suffix=-\the\beamer@slideinframe

and something goes wrong with the expansion so that TikZ tries to parse something like {[} as a node name ....

If your frames do not use overlay specifications, so that a frame has only one slide (at least where you want to use this), you can use

\begin{frame}\frametitle{A SLIDE}
  meaningless filler\tikzmark{d}

  \begin{tikzpicture}[>=latex,shorten >=1pt,->,remember picture,overlay]
    \beameroriginal{\tikzmark}{e}{(1,-3)}
  \end{tikzpicture}

  \begin{tikzpicture}[overlay,>=latex,shorten >=1pt,->,remember picture]
    \draw[black] (pic cs:d) -- (4,-3);
    \draw[black] (pic cs:e) -- (4,-3);
  \end{tikzpicture}
\end{frame}

However, this may break in the future since it is not, as far as I can tell, documented as an end-user macro.

I don't really see, though, how it can make sense to use overlay when creating a mark. It makes the mark disembodied. Maybe I don't see why this would be useful. Yes. But I don't see even how it might be coherent.

The examples in the manual make sense, because they don't do this. But, here, you are overlaying stuff on overlaid stuff in a way which I just don't understand.