我想让用户可以选择将来自 Beamer 主题 Metropolis 的突出帧从帧计数中排除。只要我将帧选项写为 ,这种方法就有效noframenumbering, standout
。但如果我颠倒顺序并写为 ,standout, noframenumbering
则会出现错误
Package keyval Error: noframenumbering undefined. [ \end{frame}]
在我的 MWE 中(如下)。我应该怎么做才能允许这两个订单?
\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}
答案1
这个答案只有在以下人士的帮助下才有可能@samcarter!
问题是内部\setbeamercolor
使用\setkeys
,并且keyval
不能\setkeys
嵌套,如果嵌套它们,内部调用的键前缀将用于外部调用的其余部分,因此noframenumbering
不会被解析为 的一部分beamerframe
,而是beamerthc
(由 内部使用\setbeamercolor
)。
为了解决这个问题,有两种根本不同的方法:
- 不要使用
\setbeamercolor
直接调用的内部函数。(@samcarter 采取的方法,如果beamer
改变其内部函数,理论上可能会失效) - 修复
\setkeys
后可嵌套。(的一般修复keyval
不应该有不良副作用,但理论上如果某些代码依赖于的这个限制则可能会有\setkeys
)
使用内部\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}
修补\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}