2

Notice: that question has been answered here, posted to be useful to the general public.

I am struggling to write a macro to use in circuitikz to apply the change to arrow tips you can see here (which will be in 3.1.11) to work with older versions of TikZ.

I managed to separate the 3 values of the version, and to make a simple check with \ifnum, but I find the thing not so elegant:

\documentclass[]{article}
\usepackage[T1]{fontenc}
\usepackage{tikz}
\usetikzlibrary{arrows.meta}

\makeatletter
\def\ctikz@@pgfpgfversionsplit#1.#2.#3\ctikz@@pgfstop{\xdef\ctikz@@pgfmayor{#1}\xdef\ctikz@@pgfminor{#2}\xdef\ctikz@@pgfminorminor{#3}}
\expandafter\ctikz@@pgfpgfversionsplit\pgfversion\ctikz@@pgfstop
\xdef\mycheck{Not patched}

\ifnum\ctikz@@pgfmayor<3 \else % wrong, just the idea
    %% more nested ifs here
    \xdef\mycheck{Patching}
    %% Henri Menke's code, see https://github.com/pgf-tikz/pgf/pull/1352
    \pgfkeys{/pgf/arrow keys/fill/.code={%
        \def\pgf@temp{#1}%
        \ifx\pgf@temp\pgf@nonetext%
          \pgfarrowsaddtooptions{\pgfarrowopentrue}%
        \else\ifx\pgf@temp\pgfkeysnovalue@text%
          \pgfarrowsaddtooptions{\pgfarrowopenfalse}%
        \else
          \pgfarrowsaddtooptions{\pgfarrowopenfalse\def\pgf@arrows@fill@color{#1}}%
        \fi\fi
    }}%
    %% this does not work
    \pgfkeys{/pgf/arrow keys/fill/.value required=false}%
\fi

\makeatother
\begin{document}

\makeatletter
    Check-\ctikz@@pgfmayor-\ctikz@@pgfminor-\ctikz@@pgfminorminor-:\mycheck
\makeatother

\end{document}

Is there a more elegant way to check it? Notice that the code does load TikZ, and so PGF, but it could be used also in ConTeXt, so it must be basically plain TeX.

If you want to know how to "undo" \pgfkeys{/pgf/arrow keys/fill/.value required} look at this comment by @muzimuzhi...

2 Answers 2

3

A somewhat elegant test for your use case which supports a hardcoded number of 3 digits, and uses your split result. I also used the \pgfutil@ since you're loading pgf anyway and that provides \@firstoftwo etc. for every format.

\documentclass[]{article}
\usepackage[T1]{fontenc}
\usepackage{tikz}
\usetikzlibrary{arrows.meta}

\makeatletter
\def\ctikz@@ifpgfatleast@auxi#1#2%
  {%
    \ifnum#1
      \ctikz@@ifpgfatleast@auxii{#2}%
    \fi
  }
\def\ctikz@@ifpgfatleast@auxii#1\fi#2\ctikz@@ifpgfatleast#3{\fi#1}
\def\ctikz@@ifpgfatleast#1.#2.#3#%
  {%
    \ctikz@@ifpgfatleast@auxi{\ctikz@@pgfmayor>#1}\pgfutil@firstoftwo
    \ctikz@@ifpgfatleast@auxi{\ctikz@@pgfmayor<#1}\pgfutil@secondoftwo
    \ctikz@@ifpgfatleast@auxi{\ctikz@@pgfminor>#2}\pgfutil@firstoftwo
    \ctikz@@ifpgfatleast@auxi{\ctikz@@pgfminor<#2}\pgfutil@secondoftwo
    \ctikz@@ifpgfatleast@auxi{\ctikz@@pgfminorminor<#3}\pgfutil@secondoftwo
    \pgfutil@gobble\ctikz@@ifpgfatleast\pgfutil@firstoftwo
  }
\def\ctikz@@pgfpgfversionsplit#1.#2.#3\ctikz@@pgfstop{\xdef\ctikz@@pgfmayor{#1}\xdef\ctikz@@pgfminor{#2}\xdef\ctikz@@pgfminorminor{#3}}
\expandafter\ctikz@@pgfpgfversionsplit\pgfversion\ctikz@@pgfstop
\xdef\mycheck{Not patched}

\ctikz@@ifpgfatleast3.1.11% <- no space should be here
  {%
    %% more nested ifs here
    \xdef\mycheck{Patching}
    %% Henri Menke's code, see https://github.com/pgf-tikz/pgf/pull/1352
    \pgfkeys{/pgf/arrow keys/fill/.code={%
        \def\pgf@temp{#1}%
        \ifx\pgf@temp\pgf@nonetext%
          \pgfarrowsaddtooptions{\pgfarrowopentrue}%
        \else\ifx\pgf@temp\pgfkeysnovalue@text%
          \pgfarrowsaddtooptions{\pgfarrowopenfalse}%
        \else
          \pgfarrowsaddtooptions{\pgfarrowopenfalse\def\pgf@arrows@fill@color{#1}}%
        \fi\fi
    }}%
    %% this does not work
    \pgfkeys{/pgf/arrow keys/fill/.value required=false}%
  }
  {} % false case, do nothing

\makeatother

\begin{document}

\makeatletter
    Check-\ctikz@@pgfmayor-\ctikz@@pgfminor-\ctikz@@pgfminorminor-:\mycheck
\makeatother

\end{document}
1

This here implements a general loop which compares two different version numbers. The following syntax is supported:

  • Parts of the version number are separated by a dot.
  • In the expected version number you can use x to ignore a part of a version number.
  • If the expected version has fewer places than the encountered version and every digit was fine until then <true> is returned
  • If the encountered version has fewer places than the expected version and every digit was fine until then <false> is returned
\begingroup
\catcode`\@=11
\unexpanded{\endgroup
\long\def\@firstoftwo#1#2{#1}
\long\def\@secondoftwo#1#2{#2}
\def\ifversionatleast#1#2%
  {%
    % #1: real version
    % #2: minimum version which shall be met
    % #3: if minimum version is met
    % #4: if real version is smaller than minimum version
    \ifversionatleast@loop#1.\stop.#2.\stop.%
    \ifversionatleast@loop@end
  }
\def\ifversionatleast@loop#1\stop.#2.%
  {%
    \ifversionatleast@ifstop#2\ifversionatleast@done\@firstoftwo\stop
    \ifversionatleast@loop@{#2}#1\stop.%
  }
\def\ifversionatleast@loop@#1#2.%
  {%
    \ifversionatleast@ifstop#2\ifversionatleast@done\@secondoftwo\stop
    \ifversionatleast@ifx\mark#1\mark{}\mark x\mark
      {%
        \ifnum#1<#2
          \ifversionatleast@afterfi{\ifversionatleast@done\@firstoftwo}%
        \fi
        \ifnum#1>#2
          \ifversionatleast@afterfi{\ifversionatleast@done\@secondoftwo}%
        \fi
      }%
    \stop
    \ifversionatleast@loop
  }
\def\ifversionatleast@ifstop#1\stop{}
\def\ifversionatleast@afterfi#1\fi{\fi#1}
\def\ifversionatleast@done#1#2\ifversionatleast@loop@end{#1}
\def\ifversionatleast@ifx#1\mark x\mark#2#3\stop{#2}
}

\def\unittestAux#1#2{\ifversionatleast{#1}{#2}{T}{F}}
\def\unittest#1#2#3%
  {%
    \if\unittestAux{#1}{#2}#3%
    \else
      \message
        {Unit test failed: {#1}{#2} => \unittestAux{#1}{#2} (expected #3)^^J}%
    \fi
  }
\message{^^J}
\unittest{4.0.0}{3.2.1}T
\unittest{3.3.0}{3.2.1}T
\unittest{3.2.2}{3.2.1}T
\unittest{3.2.1}{3.2.1}T
\unittest{3.2.1}{3.x.1}T
\unittest{3.1.1}{3.x.1}T
\unittest{3.2.1}{x.2.1}T
\unittest{2.2.1}{x.2.1}T
\unittest{3.2.1}{3.2.x}T
\unittest{3.2.1}{3.2}T

\unittest{2.2.1}{3.2.1}F
\unittest{3.1.1}{3.2.1}F
\unittest{3.2.0}{3.2.1}F
\unittest{3.2.0}{3.x.1}F
\unittest{3.1.0}{3.x.1}F
\unittest{3.2.0}{x.2.1}F
\unittest{2.2.0}{x.2.1}F
\unittest{3.2}{3.2.1}F

\stop

Applied to your problem:

\begingroup
\catcode`\@=11
\unexpanded{\endgroup
\long\def\@firstoftwo#1#2{#1}
\long\def\@secondoftwo#1#2{#2}
\def\ifversionatleast#1#2%
  {%
    % #1: real version
    % #2: minimum version which shall be met
    % #3: if minimum version is met
    % #4: if real version is smaller than minimum version
    \ifversionatleast@loop#1.\stop.#2.\stop.%
    \ifversionatleast@loop@end
  }
\def\ifversionatleast@loop#1\stop.#2.%
  {%
    \ifversionatleast@ifstop#2\ifversionatleast@done\@firstoftwo\stop
    \ifversionatleast@loop@{#2}#1\stop.%
  }
\def\ifversionatleast@loop@#1#2.%
  {%
    \ifversionatleast@ifstop#2\ifversionatleast@done\@secondoftwo\stop
    \ifversionatleast@ifx\mark#1\mark{}\mark x\mark
      {%
        \ifnum#1<#2
          \ifversionatleast@afterfi{\ifversionatleast@done\@firstoftwo}%
        \fi
        \ifnum#1>#2
          \ifversionatleast@afterfi{\ifversionatleast@done\@secondoftwo}%
        \fi
      }%
    \stop
    \ifversionatleast@loop
  }
\def\ifversionatleast@ifstop#1\stop{}
\def\ifversionatleast@afterfi#1\fi{\fi#1}
\def\ifversionatleast@done#1#2\ifversionatleast@loop@end{#1}
\def\ifversionatleast@ifx#1\mark x\mark#2#3\stop{#2}
}

\documentclass[]{article}
\usepackage[T1]{fontenc}
\usepackage{tikz}
\usetikzlibrary{arrows.meta}

\makeatletter
\def\ctikz@@pgfpgfversionsplit#1.#2.#3\ctikz@@pgfstop{\xdef\ctikz@@pgfmayor{#1}\xdef\ctikz@@pgfminor{#2}\xdef\ctikz@@pgfminorminor{#3}}
\expandafter\ctikz@@pgfpgfversionsplit\pgfversion\ctikz@@pgfstop
\xdef\mycheck{Not patched}

\expandafter\ifversionatleast\expandafter{\pgfversion}{3.1.11}
  {%
    %% more nested ifs here
    \xdef\mycheck{Patching}
    %% Henri Menke's code, see https://github.com/pgf-tikz/pgf/pull/1352
    \pgfkeys{/pgf/arrow keys/fill/.code={%
        \def\pgf@temp{#1}%
        \ifx\pgf@temp\pgf@nonetext%
          \pgfarrowsaddtooptions{\pgfarrowopentrue}%
        \else\ifx\pgf@temp\pgfkeysnovalue@text%
          \pgfarrowsaddtooptions{\pgfarrowopenfalse}%
        \else
          \pgfarrowsaddtooptions{\pgfarrowopenfalse\def\pgf@arrows@fill@color{#1}}%
        \fi\fi
    }}%
    %% this does not work
    \pgfkeys{/pgf/arrow keys/fill/.value required=false}%
  }
  {}

\makeatother

\begin{document}

\makeatletter
    Check-\ctikz@@pgfmayor-\ctikz@@pgfminor-\ctikz@@pgfminorminor-:\mycheck
\makeatother

\end{document}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .