4

The code provided here (where the workaround for gcd() issue isn't needed anymore, at least in pgfplots 1.18) does:

  • work if the class used is e.g. article,
  • not work if the class used is beamer.

Indeed, the compilation of the following MCE:

\documentclass{beamer}
\usepackage{pgfplots}
\pgfplotsset{compat=1.18}

% Load math library, for \tikzmath \usetikzlibrary{math}

\pgfplotsset{ % Typeset fractions of pi at regular intervals on x axis x axis in pi/.style={ % Make sure the x axis is in radians trig format plots=rad, % Set tick distance from style argument xtick distance={pi/#1}, % Set label style: calculate reduced fraction of pi xticklabel={ \tikzmath{ % Calculate this tick's multiple of pi/#1 int \numorig, \gcd, \num, \denom, \absnum; \numorig = round(\tick*#1/pi); % Calculate reduced fraction for \numorig/#1 \gcd = gcd(\numorig,#1); \num = \numorig / \gcd; \absnum = abs(\num); \denom = #1 / \gcd; % Build label text if \num < 0 then { let \sign = -; } else { let \sign =; }; if \absnum == 1 then { let \numpi = \pi; } else { let \numpi = \absnum\pi; }; if \denom == 1 then { if \num == 0 then { { \strut$0$ }; } else { { \strut$\sign\numpi$ }; }; } else { { \strut$\sign\frac{\numpi}{\denom}$ }; % Other style with all pi symbols same and aligned: % { \strut$\sign\frac{\absnum}{\denom}\pi$ }; }; } }, }, }

\begin{document} \begin{frame} \begin{tikzpicture} \begin{axis}[ x axis in pi=2, % tick distance as fraction of pi ] \addplot {sin(x)}; \end{axis} \end{tikzpicture} \end{frame} \end{document}

fails with the error:

(./test-beamer.nav)
! Missing \endcsname inserted.
<to be read again> 
                   \protect 
l.62 \end{frame}

?

Note that adding the fragile option to the frame environment doesn't help.

Do you understand what's going on?

Denis Bitouzé
  • 9,652
  • 4
  • 27
  • 85

1 Answers1

5

The issue lies in the way the math library handles variable names; in essence for the \gcd-variable it'll try to use it inside of a \csname construct.

Your issue can be reduced to the following MWE:

\RequirePackage{amsmath}
\RequirePackage{tikz}
\usetikzlibrary{math}
\tikzmath{\gcd = 1;}
\stop

The difference lies in LaTeX's standard definition of \gcd (\meaning starts with macro) and the definition in amsmath (\meaning starts with \protected), so we can further reduce our MWE:

\RequirePackage{tikz}
% make \gcd \protected, but don't alter it otherwise
\protected\expandafter\def\expandafter\gcd\expandafter{\gcd}
\usetikzlibrary{math}
\tikzmath{\gcd = 1;}
\stop

Now the math-parser doesn't understand that this is a variable but thinks it's part of a keyword, grabs everything up to the next space (or does it? Not sure here), and tries to build the keyword name of that with \csname which fails badly.

So you can't assign to variables which are already defined \protected in the math library (well, if you use the let keyword you can, so \tikzmath{let \gcd=;} works and afterwards you can use the name \gcd)!

If you change that variable's name (e.g., to \mygcd) everything works again:

\documentclass{beamer}
\usepackage{pgfplots}
\pgfplotsset{compat=1.18}

% Load math library, for \tikzmath \usetikzlibrary{math}

\pgfplotsset{ % Typeset fractions of pi at regular intervals on x axis x axis in pi/.style={ % Make sure the x axis is in radians trig format plots=rad, % Set tick distance from style argument xtick distance={pi/#1}, % Set label style: calculate reduced fraction of pi xticklabel={ \tikzmath{ % Calculate this tick's multiple of pi/#1 int \numorig, \gcd, \num, \denom, \absnum; \numorig = round(\tick*#1/pi); % Calculate reduced fraction for \numorig/#1 \mygcd = gcd(\numorig,#1); \num = \numorig / \mygcd; \absnum = abs(\num); \denom = #1 / \mygcd; % Build label text if \num < 0 then { let \sign = -; } else { let \sign =; }; if \absnum == 1 then { let \numpi = \pi; } else { let \numpi = \absnum\pi; }; if \denom == 1 then { if \num == 0 then { { \strut$0$ }; } else { { \strut$\sign\numpi$ }; }; } else { { \strut$\sign\frac{\numpi}{\denom}$ }; % Other style with all pi symbols same and aligned: % { \strut$\sign\frac{\absnum}{\denom}\pi$ }; }; } }, }, }

\begin{document} \begin{frame} \begin{tikzpicture} \begin{axis}[ x axis in pi=2, % tick distance as fraction of pi ] \addplot {sin(x)}; \end{axis} \end{tikzpicture} \end{frame} \end{document}

Skillmon
  • 60,462