# Programming TeX macros so that they output instructions to rerun the compilation

This question is motivated by the behavior of the tikzmark macro created by Andrew Stacey, and a recent discussion with David Carlisle on chat.

I have noticed that LaTeX code using tikzmark typically requires more than one compilation run. After the first run, a picture is drawn, but there is no indication in the LaTeX output that a second run is required. Automated tools and humans too, depend on the LaTeX output to determine whether more recompilations are necessary. David tells me it is possible to add code to a macro so that it outputs a suitable message to the LaTeX logs, saying the code needs to be rerun or similar. I use AucTeX inside emacs, and that certainly uses information from the output to determine whether LaTeX needs to be run again.

I don't know how the tikzmark macro works or how difficult it is to tell when the code needs to be rerun, but does anyone know how to add code to the tikzmark macro to make this happen?

See for example, Peter Grill's solution to How to draw arrows between parts of an equation to show the Math Distributive Property (Multiplication)?

Note: Andrew Stacey has added tikzmark to the tex-sx project on Launchpad. The repository is located at http://bazaar.launchpad.net/~tex-sx/tex-sx/development/files. The actual file is tikzmark.dtx (do tex tikzmark.dtx to generate the files). There's also tikzmark_test.tex which is the test file and which might give some hints as to how to use it.

UPDATE: For AucTeX users, note that AucTeX looks for a very specific string, as noted by Heiko. Changing

\immediate\write\@auxout{Rerun Latex tikz mark #1 changed}


to

\immediate\write\@auxout{LaTeX Warning: Label(s) may have changed. Rerun to get cross-references right.}


in David's example makes AucTeX notice, and force a rerun of LaTeX.

As regards Heiko's solution, you can find instructions about detaching hopgf.dtx from hopgf-1.0.pdf in section 4.5 of the PDF file hopgf-1.0.pdf. I could not figure out how to use Acrobat Reader to detach the file, but the alternative

pdftk hopgf-1.0.pdf unpack_files output .


works. The style file hopgf.sty is then extracted with

tex hopgf.dtx


Then just putting \usepackage{hopgf} in any example using \tikzmark, like Peter Grill's example linked to earlier in this question, will make the usual LaTeX warning

LaTeX Warning: Label(s) may have changed. Rerun to get cross-references right.


appear, as Heiko says. This works, because, as cyberSingularity mentioned in the comments, \tikzmark works by writing \pgfsyspdfmark to the aux file, and hopgf.sty, if I understand correctly, rewrites this macro to output this warning. This seems like a good general solution, and I hope Heiko's patches can be incorporated in PGF/TikZ.

-
This isn't really a problem specific to tikzmark, but rather the remember picture feature of tikz that it uses. Could you add a link to some tikzmark examples? Probably the rerunfilecheck package could be employed here. – cyberSingularity Nov 9 '12 at 11:04
@cyberSingularity: done. – Faheem Mitha Nov 9 '12 at 11:06
In the example you linked to, it works by writing \pgfsyspdfmarks to the aux file. Therefore normal tools for checking if the aux file has changed are suitable for determining if another run is needed, but LaTeX itself doesn't issue any notifications about this. – cyberSingularity Nov 9 '12 at 11:10
It seems to be enough to add \usepackage[aux=true]{rerunfilecheck}. – cyberSingularity Nov 9 '12 at 11:13
@cyberSingularity: Add this to the macro? But this creates a dependency on rerunfilecheck, yes? I see the warning if I add that, but auctex ignores it, regardless. Sigh. – Faheem Mitha Nov 9 '12 at 11:17

I have written a new package hopgf, where I try to collect some fixes for PGF/TikZ. Also the missing rerun warning is addressed. It is solved by using LaTeX's \@newl@bel that does the work for LaTeX's reference system. By using pgf@sys@df@mark@pos as reference class no new internal macros are needed for the reference.

If the positioning labels of PGF change, then the usual LaTeX warning is given:

LaTeX Warning: Label(s) may have changed. Rerun to get cross-references right.


The package is currently available as hopgf-1.0.pdf and will be put on CTAN at the next time I update my bundle. The .dtx is attachted to the PDF file and running tex (not latex) extracts the package file hopgf.sty.

Comments and other suggestions what can be added to the package are welcome. It would be even better, of course, if the fixed and features can be added upstream in PGF/TikZ.

-
ah I wondered about just re-using label in the above answer but decided not to in the end. Of course making the same message exactly also has the advantage of increasing the chance that external tools just looking for the label warning notice the message. – David Carlisle Nov 9 '12 at 13:32
@DavidCarlisle: This is the case with LyX - it recompiles based on explicit output messages. Not that one would be doing TikZ-related graphics in LyX... :-/ – Werner Nov 9 '12 at 14:39
I would be very pleased to merge those probably high quality fixes in pgf CVS version, if you wish @Heiko Oberdiek. – cjorssen Nov 10 '12 at 13:30
@cjorssen Many thanks, if you can do it. Ask me, if something is unclear. – Heiko Oberdiek Nov 10 '12 at 16:03
@HeikoOberdiek Thanks for your answer. I downloaded the PDF, but could not figure out how to extract the .dtx file. Could you point to a repository or a download site for the code or file? It seems like a good idea to output the standard LaTeX warning in this case, since it makes it more likely tools like AucTeX will take notice of it. Do you know how to write a standalone tikzmark macro that will produce "the usual LaTeX warning"? If so, could you post it here? – Faheem Mitha Nov 12 '12 at 19:19

Taking the posted example, adding the following check seems to work

\documentclass{article}
\usepackage{amsmath}

\usepackage{tikz}
\usetikzlibrary{calc,shapes}

\makeatletter
\AtEndDocument{%
\let\oldpgfsyspdfmark\pgfsyspdfmark
\def\pgfsyspdfmark#1#2#3{%
\expandafter\let\expandafter\tmp\csname pgf@sys@pdf@mark@pos@#1\endcsname
\oldpgfsyspdfmark{#1}{#2}{#3}%
\expandafter\ifx\csname pgf@sys@pdf@mark@pos@#1\endcsname\tmp\else
\immediate\write\@auxout{Rerun Latex tikz mark #1 changed}%
\fi
}}

\newcommand{\tikzmark}[1]{\tikz[overlay,remember picture] \node (#1) {};}
\newcommand{\DrawBox}[4]{%
\begin{tikzpicture}[overlay,remember picture,-latex,shorten >=5pt,shorten <=5pt,out=70,in=130]
\draw[distance=0.45cm,#1] (a.north) to (b.north);
\draw[distance=0.65cm,#2] (a.north) to (c.north);
\draw[distance=0.9cm, #3] (a.north) to (d.north);
\draw[distance=1.1cm, #4] (a.north) to (e.north);
\end{tikzpicture}
}
\begin{document}
\begin{gather*}
(\tikzmark{a}l_{1}) \vee \big( (p \vee\tikzmark{b} q) \wedge (\neg p \vee\tikzmark{c} q) \wedge (p \vee\tikzmark{d} \neg q) \wedge (\neg p \vee\tikzmark{e} \neg q)\big) \DrawBox{red}{blue}{green}{orange}\\
(l_{1} \vee p \vee q) \wedge (l_{1} \vee \neg p \vee q) \wedge (l_{1} \vee p \vee \neg q) \wedge (l_{1} \vee \neg p \vee \neg q)
\end{gather*}
\end{document}


On the first run you get

$grep Rerun tk93.log Rerun Latex tikz mark pgfid7 changed Rerun Latex tikz mark pgfid8 changed Rerun Latex tikz mark pgfid9 changed Rerun Latex tikz mark pgfid10 changed Rerun Latex tikz mark pgfid11 changed Rerun Latex tikz mark pgfid12 changed  on the second run $ grep Rerun tk93.log


If you would rather the first run just had a single message change

  \immediate\write\@auxout{Rerun Latex tikz mark #1 changed}%


to

  \let\pgfsyspdfmark\oldpgfsyspdfmark
\immediate\write\@auxout{Rerun Latex tikz marks changed}%


so after the first warning the macro is restored to its original definition and no further checks are made.

-