11

I just discovered tikzmark thanks to the blog, and it sounds really promising. I downloaded the files from CTAN and put tikzlibrarytikzmark.code.tex and tikzmarklibrarylistings.code.tex in the same folder as my main .tex file. I'm trying to reproduce the first example from the manual itself, en français.

\documentclass[french]{beamer}

\usepackage{babel}
\usepackage{tikz}
\usetikzlibrary{tikzmark}

\begin{document}

\begin{frame}{Test}

   \[
     \tikzmark{a} \frac{x^2}{n!}
   \]

  Test \tikz[remember picture,overlay,baseline=0pt] \draw[->] (0,1em) to (pic cs:a);

\end{frame}

\end{document}

I guess it has to do with the : colon in the tikzmark specific syntax, right? Any ideas on what to do? This compiles just fine if I replace french with english.

10

It's not the colon, it's a buried non-active semi-colon.

TikZ is super-clever with regard to active semi-colons. When it starts a \tikz command (or a \draw or whatever) then it calls a certain macro to gather in the rest of the command. The rest of the command is everything up to the next semi-colon ("up to" with the usual proviso of TeX groupings). However, as there are popular packages like babel make the semi-colon active then the semi-colon delimiting the TikZ command could be either active or non-active (well, it could be a host of things but those are the most likely) and the two are not equivalent. So TikZ checks the state of the semi-colon before calling the macro and calls a different one depending on the state of the semi-colon.

All very well and good.

Enter the tikzmark. This expands to \tikz <something>;. However, it is defined before the document officially begins. This means that the semi-colon has the status of the preambelic semi-colon. babel only changes the state of the semi-colon at the start of the actual document meaning that this semi-colon is not active. But when the \tikzmark is actually used, TikZ checks the current semi-colon status. So it starts looking for an active semi-colon but doesn't find it, causing it to bail out in confusion.

There are probably a few solutions, but I suspect that the best is for \tikzmark to do its own semi-colonic check and use the Right Semi-Colon^TM (TM = tikzmark).

Here's some code that will do that:

\documentclass[french]{beamer}
%\url{https://tex.stackexchange.com/q/110014/86}

\usepackage{babel}
\usepackage{tikz}
\usetikzlibrary{tikzmark}

\makeatletter

\begingroup
\catcode`\;=\active

\gdef\tikzmark@active#1#2{%
\tikz[remember picture with id=#2] #1;}

\endgroup
\def\tikzmark@nonactive#1#2{%
\tikz[remember picture with id=#2] #1;}

\renewcommand\tikzmark[2][]{%
\ifnum\catcode`\;=\active
\let\@next=\tikzmark@active
\else
\let\@next=\tikzmark@nonactive
\fi
\@next{#1}{#2}}


\makeatother

\begin{document}

\begin{frame}{Test}

   \[
     \tikzmark{a}
 \frac{x^2}{n!}
   \]

  Test \tikz[remember picture,overlay,baseline=0pt] \draw[->] (0,1em) to (pic cs:a);

\end{frame}

\end{document}

Assuming that no-one tells me that this the Wrong Implementation of Catcode Protection^TM then I'll stick this in the tikzmark code an upload it to CTAN.

Added for clarity This is in essence the same as the problem encountered in tikz declare function and babel french option and Unexpected clash between babel and pgf spy. For each of these then I prefer the solution that involves modifying the original code to cope with active semi-colons - which is what I've done above. Figuring out exactly what needs modifying in such cases is a bit different in each case. Those other questions contain other possibilities that don't require this modification and so are easier for someone to implement themselves in a similar situation. However, I would warn that using beamer can cause a few hiccoughs where catcodes are concerned since catcodes are "frozen" inside frames unless you use the fragile option.

  • No need to scan the arguments twice, just do \renewcommand\tikzmark{% \ifnum\catcode'\;=\active \expandafter\tikzmark@active \else \expandafter\tikzmark@nonactive \fi } (after putting the ' back to a backtick) – David Carlisle Apr 22 '13 at 11:32
  • @DavidCarlisle Then I'd need to define \tikzmark@active and \tikzmark@nonactive via \newcommand so that they could deal with the optional argument, no? – Loop Space Apr 22 '13 at 11:35
  • @percusse That would be okay, except it could lead to unexpected behaviour if you put something into the \tikzmark arguments that used a semi-colon since it wouldn't behave the same way as outside. – Loop Space Apr 22 '13 at 11:37
  • @AndrewStacey I don't think that's the case if you prefix the code.. – percusse Apr 22 '13 at 11:38
  • 1
    @ChristophB. I've uploaded it to the TeX-SX Launchpad page (bazaar.launchpad.net/~tex-sx/tex-sx/development/files). – Loop Space Apr 22 '13 at 12:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.