Conditional compilation of code based on package version [duplicate]

I am working on a document with a colleague and we have different versions of PGF/Tikz installed -- I have version 3 and he has version 2.10. This is causing a problem for compilation on our two platforms because the syntax for defining matrices in tikz changed slightly from version 2.1 to 3.0.

What I would like to do is add code at the beginning of my document which checks the version of pgf/tikz that is being used at compilation. Based on that, I want certain blocks of code to be executed which matches the proper syntax for that version.

Is this possible?

-

marked as duplicate by Werner, Malipivo, Christian Hupfer, T. Verron, Martin SchröderJul 17 at 18:35

–  Joseph Wright Jul 16 at 6:23

You could define your own conditional, say \ifTikZVthree and use

\ifTikZVthree
% <TikZ version 3 stuff>
\else
% <TikZ version pre-3 stuff>
\fi


in your document to define separate version 3/pre-3 stuff. The following minimal example defines \checkTikZversion that checks the version of tikz via the macro \ver@tikz.sty - defined whenever a package is loaded. In nature, it's very similar to \@ifpackagelater (see Which package version am I using?), including discussions in Detecting which version of the LaTeX format is in use.

\documentclass{article}
\usepackage{tikz}
\makeatletter
\let\@xp\expandafter
\newif\ifTikZVthree
\def\@extractTikZversion#1 v#2 (#3){#2}
\newcommand{\checkTikZversion}{
\@xp\@xp\@xp\@xp\@xp\@xp\@xp\ifnum
\@xp\@xp\@xp\@xp\@xp\@xp\@xp\pdfstrcmp
\@xp\@xp\@xp\@xp\@xp\@xp\@xp
{\@xp\@xp\@xp\@extractTikZversion\csname ver@tikz.sty\endcsname}{ 3.0.0}=1
\TikZVthreetrue
\fi
}
\makeatother

\checkTikZversion% Check the current TikZ version
\begin{document}

\makeatletter
TikZ version: \@xp\@xp\@xp\strip@prefix\@xp\meaning\csname ver@tikz.sty\endcsname% Show current TikZ version
\makeatother

\ifTikZVthree
TikZ version: 3.0.0% You are running TikZ version 3.0.0
\else
Not TikZ version: 3.0.0% You are not running TikZ version 3.0.0
\fi

\end{document}


Here's how the \expandafter/\@xps work within \checkTikZversion:

\@xp\@xp\@xp\@xp\@xp\@xp\@xp\ifnum
\@xp\@xp\@xp\@xp\@xp\@xp\@xp\pdfstrcmp
\@xp\@xp\@xp\@xp\@xp\@xp\@xp
{\@xp\@xp\@xp\@extractTikZversion\csname ver@tikz.sty\endcsname}{ 3.0.0}=1
\TikZVthreetrue
\fi


After the first batch of processing \@xps, you're left with

\@xp\@xp\@xp\ifnum
\@xp\@xp\@xp\pdfstrcmp
\@xp\@xp\@xp
{\@xp\@extractTikZversion\ver@tikz.sty}{ 3.0.0}=1
\TikZVthreetrue
\fi


where \ver@tikz.sty is the expanded construction of \csname ver@tikz.sty\endcsname. The second round produces

\@xp\ifnum
\@xp\pdfstrcmp
\@xp
{\@extractTikZversion 2013/12/13 v3.0.0 (rcs-revision 1.142)}{ 3.0.0}=1
\TikZVthreetrue
\fi


where \ver@tikz.sty has been expanded to the full version of tikz (on my machine). The next expansion strips out the version via \@extractTikZversion:

\ifnum
\pdfstrcmp
{ 3.0.0}{ 3.0.0}=1
\TikZVthreetrue
\fi


where the actual comparison is made (via e-TeX's \pdfstrcmp). Depending on the output, \ifTikZVthree is set to either true of false. Note the specific use of space before the version number.

-
Instead of \@xa you could use the more popular \@xp. –  Manuel Jul 17 at 0:24
Look ma'! Just one \expandafter! –  egreg Jul 17 at 9:00
@Manuel: \@xp is specifically defined and used by AMS (defined in amsgen.dtx. I've updated accordingly. –  Werner Jul 17 at 14:15

When you do \usepackage{tikz} you have the macro \pgfversion available. We actually want to compare the main version number only, so we can do

\documentclass{article}
\usepackage{tikz}

\newif\iftikziii
\begingroup
\def\getmainversion#1.#2\getmainversion{#1}
\ifnum\expandafter\getmainversion\pgfversion\getmainversion=3
\global\tikziiitrue
\fi
\endgroup

\begin{document}
We have version \iftikziii 3\else 2\fi
\end{document}


You can use in your document

\iftikziii
<code for TikZ 3>
\else
<code for TikZ 2>
\fi


If you prefer a double argument (pseudo)conditional, add the code

\makeatletter
\newcommand{\tikziiiorii}{%
\iftikziii
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi}
\makeatletter


so the above document can become

\documentclass{article}
\usepackage{tikz}

\newif\iftikziii
\begingroup
\def\getmainversion#1.#2\getmainversion{#1}
\ifnum\expandafter\getmainversion\pgfversion\getmainversion=3
\global\tikziiitrue
\fi
\endgroup
\makeatletter
\newcommand{\tikziiiorii}{%
\iftikziii
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi}
\makeatletter

\begin{document}
We have version \tikziiiorii{3}{2}
\end{document}


and the general format is

\tikziiiorii{<code for version 3>}{<code for version 2>}

-

The first link was exactly what I was looking for:

Which package version am I using?

There is a LaTeX kernel function \@ifpackagelater which serves my purpose by testing the date of a package release:

\makeatletter
\@ifpackagelater{tikz}{2013/10/01}
{
% Code which runs if the package date is 2013/10/01 or later
}
{
% Code which runs if the package date is older than 2013/10/01
}
\makeatother