8

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?

Quiggin
  • 83
  • 1
    Welcome! I don't think what you are attempting can possibly be expected to work. The nesting of remember and/or overlay seems deeply problematic. – cfr Feb 21 '17 at 23:39
  • The problem is not related to the use of overlay or remember picture: the error still occurs without them, and does not occur under the article documentclass. – Quiggin Feb 21 '17 at 23:46
  • 1
    Yes, I agree. You get the error anyway. That's because the definitions are changed in the Beamer class. \tikzmark is not the same as \tikzmark usually is. Otherwise, it would not be overlay aware. The remember picture just seems pointless. But the overlay doesn't seem coherent. I don't care if it works - it is completely illogical! – cfr Feb 22 '17 at 00:42

1 Answers1

9

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.

cfr
  • 198,882
  • "\tikzmark creates a TikZ picture. Hence, it should not be used inside a tikzpicture environment." Its creator seems to think otherwise! See the answer to this question ("The syntax inside a tikzpicture is...") http://tex.stackexchange.com/questions/295903/refer-to-a-node-in-tikz-that-will-be-defined-in-the-future-two-passes – Quiggin Feb 21 '17 at 23:27
  • @Quiggin Oh, I see. I didn't know that bit had been added. You still shouldn't use it inside a node, though. That has never been supported. – cfr Feb 21 '17 at 23:35
  • Did you actually read my question? It shouldn't be used inside a node--yes, that's why I also included the latest syntax, \tikzmark{b}{(1,-3)}. As I wrote in my original post, that works in the article document class, but not beamer. – Quiggin Feb 21 '17 at 23:40
  • @Quiggin Your original syntax used \tikzmark inside a node. That was never intended to work, as I understand it. That is, on the basis of what the package's author has said before. What is new is not a new syntax for an existing feature. It is a new feature. That is, now you can use \tikzmark inside a TikZ picture, whereas previously you couldn't. – cfr Feb 21 '17 at 23:45
  • Ok! But the new feature evidently does not work within the beamer documentclass. That's what I'd like an answer to. – Quiggin Feb 21 '17 at 23:50
  • @Quiggin Just email Loopspace the URL for this question/answer if an answer doesn't appear here shortly. – cfr Feb 22 '17 at 00:59
  • thanks. The use of \beameroriginal is, for my purposes, sufficient (I was not aware of that command!). If you think Loopspace will have more to add, I'll wait for his reply; otherwise I'm happy to accept your answer. – Quiggin Feb 22 '17 at 01:08
  • Also I should say: as far as I can tell, I do need all the overlays in the full (non-minimal) code. It's very complicated, but basically I construct an elaborate tikz picture with a \foreach loop over tikzpictures. But then I want to lay down a colored rectangle in the background of just part of it. My solution is to tag the relevant nodes with tikzmarks, and then conceptually afterwards but programmatically prior, overlay the background.

    Thanks again for pointing out \beameroriginal.

    – Quiggin Feb 22 '17 at 01:13
  • @Quiggin Why don't you just use the backgrounds library? If you nest tikzpictures, you need to box them first to be safe. It sounds to me as if you are trying to use tikzmark rather than using layers in a tikzpicture. That is going to make life much harder. Just create the number of layers you need in the picture and draw on those. Then you can define things first and draw under them later. – cfr Feb 22 '17 at 01:49
  • @Quiggin You should wait. This is a hack. Loopspace will have a solution. – cfr Feb 22 '17 at 01:50
  • The backgrounds library is certainly more elegant! That was my original design. But I couldn't get it to work across multiple tikz pictures (which is necessitated by some other, perhaps sub-optimal, design choices I've made). So I abandoned backgrounds for \tikzmarks, inspired by this post: http://tex.stackexchange.com/questions/86693/is-it-possible-to-use-tikz-to-draw-a-background-on-the-printed-page – Quiggin Feb 22 '17 at 04:16
  • Well, nobody can say without knowing more, of course, but it sounds to me as though you've designed a hard life for yourself ;). – cfr Feb 22 '17 at 04:20
  • Thanks, I had the same issue with newer packages. The solution was to simply replace tikzmark with subnode, when used inside nodes inside pictures. – Adama Jan 26 '18 at 08:09