1

I would like to make it optional to exclude the standout frames from the beamer theme Metropolis from the frame count. This works as long as I write my frame options as noframenumbering, standout. But if I reverse the order and write standout, noframenumbering then I get an error

Package keyval Error: noframenumbering undefined. [  \end{frame}]

in my MWE (below). What should I do to allow both orders?

\documentclass{beamer}
% Standout frame code from [Metropolis' inner theme](https://github.com/matze/mtheme/blob/master/source/beamerinnerthememetropolis.dtx)
\usepackage{keyval}
\makeatletter
\define@key{beamerframe}{c}[true]{% centered
  \beamer@frametopskip=0pt plus 1fill\relax%
  \beamer@framebottomskip=0pt plus 1fill\relax%
  \beamer@frametopskipautobreak=0pt plus .4\paperheight\relax%
  \beamer@framebottomskipautobreak=0pt plus .6\paperheight\relax%
  \def\beamer@initfirstlineunskip{}%
}
\providebool{metropolis@standout}
\define@key{beamerframe}{standout}[true]{%
  \booltrue{metropolis@standout}
  \begingroup
    \setkeys{beamerframe}{c}
    \setbeamertemplate{frame numbering}{}
    % \setkeys{beamerframe}{noframenumbering}
    \ifbeamercolorempty[bg]{palette primary}{
      \setbeamercolor{background canvas}{
        use=palette primary,
        bg=-palette primary.fg
      }
    }{
      \setbeamercolor{background canvas}{
        use=palette primary,
        bg=palette primary.bg
      }
    }
  \centering
  \usebeamercolor[fg]{palette primary}
  \usebeamerfont{standout}
}
\pretocmd{\beamer@reseteecodes}{%
  \ifbool{metropolis@standout}{
    \endgroup
    \boolfalse{metropolis@standout}
  }{}
}{}{}
\makeatother
\begin{document}
  \begin{frame}[standout]
    standout
  \end{frame}

  \begin{frame}[noframenumbering, standout]
    noframenumbering, standout
  \end{frame}

  % This frame produces the error message
  \begin{frame}[standout, noframenumbering]
    standout, noframenumbering
  \end{frame}
\end{document}
3
  • Why do you need to this in the first place? It is normal that some keys aren't commutative. And do you really want to change the definitions of the metropolis theme?
    – Skillmon
    Aug 6, 2021 at 19:41
  • @Skillmon I'm working on a stripped down version on Metropolis without a lot of the bells and whistles. I like the standout frames and would like to include them in the frame count. That is, unless the frame options contain noframenumbering. And I would prefer not having to think about which order I enter the options.
    – Fredrik P
    Aug 6, 2021 at 20:05
  • 1
    This turns out to be really weird. The lines creating this problem are the \setbeamercolor{background canvas} instructions inside the standout code. But they don't immediately undefine the noframenumbering key (directly afterwards the key still exists), and the key also exists inside a frame environment which uses the standout option. Furthermore, it doesn't depend on the colour you change (e.g., use \setbeamercolor{something unrelated} instead), and even if nothing is changed (empty second argument) the error shows up. This looks like a strange beamer bug.
    – Skillmon
    Sep 8, 2021 at 21:33

1 Answer 1

2

This answer was only possible due to the kind help of @samcarter!

The issue is that \setbeamercolor uses \setkeys internally, and keyval's \setkeys can't be nested, if you nest them the key prefix of the inner call is used for the remainder of the outer call, so noframenumbering isn't parsed as part of beamerframe, but beamerthc (which is used internally by \setbeamercolor).

To fix this you have two fundamentally different approaches:

  1. Don't use \setbeamercolor but the internals this would call directly. (approach taken by @samcarter, could theoretically break if beamer changed its own internals)
  2. Fix \setkeys to be nestable. (general fix for keyval, shouldn't have evil side effects, but theoretically could if some code relies on this limitation of \setkeys)

Using internals of \setbeamercolor

\documentclass{beamer}

% Standout frame code from [Metropolis' inner theme](https://github.com/matze/mtheme/blob/master/source/beamerinnerthememetropolis.dtx)
%\usepackage{keyval}
\makeatletter
\define@key{beamerframe}{c}[true]{% centered
  \beamer@frametopskip=0pt plus 1fill\relax%
  \beamer@framebottomskip=0pt plus 1fill\relax%
  \beamer@frametopskipautobreak=0pt plus .4\paperheight\relax%
  \beamer@framebottomskipautobreak=0pt plus .6\paperheight\relax%
  \def\beamer@initfirstlineunskip{}%
}
\providebool{metropolis@standout}
\define@key{beamerframe}{standout}[true]{%
  \booltrue{metropolis@standout}%
  \begingroup
    \setkeys{beamerframe}{c}%
    \setbeamertemplate{frame numbering}{}%
    % \setkeys{beamerframe}{noframenumbering}%
    \def\beamer@temp{background canvas}%
    \expandafter\def\csname beamer@thcuse@\beamer@temp\endcsname{%
        \@for\@temp:={palette primary}\do{\expandafter\beamer@thc@usecolor\expandafter{\@temp}}}%
    \ifbeamercolorempty[bg]{palette primary}{%
       \expandafter\def\csname beamer@thcbg@\beamer@temp\endcsname{\def\beamer@thc@bg{-palette primary.fg}}%
    }{%
       \expandafter\def\csname beamer@thcbg@\beamer@temp\endcsname{\def\beamer@thc@bg{palette primary.bg}}%
    }%
  \centering
  \usebeamercolor[fg]{palette primary}%
  \usebeamerfont{standout}%
}
\pretocmd{\beamer@reseteecodes}{%
  \ifbool{metropolis@standout}{%
    \endgroup
    \boolfalse{metropolis@standout}%
  }{}%
}{}{}
\makeatother

\begin{document}
  \begin{frame}[standout]
    standout
  \end{frame}

  \begin{frame}[noframenumbering, standout]
    noframenumbering, standout
  \end{frame}

  % This frame produces the error message
  \begin{frame}[standout, noframenumbering]
    standout, noframenumbering
  \end{frame}
  
  \begin{frame}
  content...
  \insertframenumber
  \end{frame}
\end{document}

Patching \setkeys

\documentclass{beamer}
% Standout frame code from [Metropolis' inner theme](https://github.com/matze/mtheme/blob/master/source/beamerinnerthememetropolis.dtx)
%\usepackage{keyval} % loaded by beamer

\makeatletter
% patch \setkeys to be nestable:
\NewCommandCopy\my@setkeys@orig\setkeys
\def\setkeys{\expandafter\my@setkeys@aux\expandafter{\KV@prefix}}
\long\def\my@setkeys@aux#1#2#3{\my@setkeys@orig{#2}{#3}\def\KV@prefix{#1}}

\define@key{beamerframe}{c}[true]{% centered
  \beamer@frametopskip=0pt plus 1fill\relax
  \beamer@framebottomskip=0pt plus 1fill\relax
  \beamer@frametopskipautobreak=0pt plus .4\paperheight\relax
  \beamer@framebottomskipautobreak=0pt plus .6\paperheight\relax
  \def\beamer@initfirstlineunskip{}%
}
\providebool{metropolis@standout}
\let\KV@beamerframe@cx\KV@beamerframe@c
\let\KV@beamerframe@cx@default\KV@beamerframe@c@default
\define@key{beamerframe}{standout}[true]{%
  \booltrue{metropolis@standout}%
  \begingroup
    \setkeys{beamerframe}{cx}%
    \setbeamertemplate{frame numbering}{}%
    % \setkeys{beamerframe}{noframenumbering}%
    \ifbeamercolorempty[bg]{palette primary}{%
      \setbeamercolor{unrelated beamer color}{%
        use=palette primary,
        bg=-palette primary.fg
      }%
    }{%
      \setbeamercolor{unrelated beamer color}{%
        use=palette primary,
        bg=palette primary.bg
      }%
    }%
  \centering
  \usebeamercolor[fg]{palette primary}%
  \usebeamerfont{standout}%
}
\pretocmd{\beamer@reseteecodes}{%
  \ifbool{metropolis@standout}{%
    \endgroup
    \boolfalse{metropolis@standout}%
  }{}%
}{}{}
\makeatother

\begin{document}
  \begin{frame}[standout]
    standout
  \end{frame}

  \makeatletter
  \begin{frame}[noframenumbering, standout]
    noframenumbering, standout
  \end{frame}

  % This frame produces the error message
  \begin{frame}[standout, noframenumbering]
      %\show\KV@beamerframe@noframenumbering
    standout, noframenumbering
  \end{frame}

  \begin{frame}
    normal
    \insertframenumber
  \end{frame}
\end{document}

You must log in to answer this question.

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