我想在 Beamer 中定义一个框架选项来“反转”背景、前景和结构的颜色,我可以通过定义来实现
\documentclass{beamer}
\BeforeBeginEnvironment{frame}{%
\setbeamercolor{normal text}{fg=black, bg=white}%
\setbeamercolor{structure}{fg=blue}%
\usebeamercolor[fg]{normal text}%
}
\makeatletter
\define@key{beamerframe}{bg}[true]{%
\setbeamercolor{normal text}{fg=white, bg=black}%
\setbeamercolor{structure}{fg=red}%
\usebeamercolor[fg]{normal text}%
}
\makeatother
\begin{document}
\begin{frame}
\frametitle{Normal}
\end{frame}
\begin{frame}[bg]
\frametitle{Inverted}
A statement
\end{frame}
\end{document}
然而,给框架分配一个标签
\begin{frame}[bg, label=test]
\frametitle{Inverted}
A statement
\end{frame}
导致错误
Package keyval Error: label undefined \end{frame}
现在这已经是一个问题了,但我们可以说这只是一个小问题,因为可以通过先贴上标签来规避它。
当我想重复使用框架时,事情真的开始失去控制
\begin{document}
\begin{frame}<1>[label=test, bg]
\frametitle{Inverted}
\only<1>{A statement}
\only<2>{Another statement}
\only<3>{Third statement}
\end{frame}
\againframe<2>{test}
\begin{frame}
\frametitle{Normal}
\end{frame}
\againframe<3>{test}
\end{document}
不知何故,框架选项会影响所有连续的框架,但如果中间有一个“正常”框架则不会影响。
我期望看到的行为是,反转将不是影响重复的帧,而是需要再次传递帧选项。但是,这样做
\againframe<3>[bg]{test}
导致错误
Package keyval Error: relabel undefined
如果只改变框架背景如下https://tex.stackexchange.com/a/395429/199342,标签顺序问题就消失了,无法将选项传递给的问题也消失了\againframe
。尽管如此,即使不传递选项,frame 选项仍然会影响连续的帧,但传递它也不会导致任何错误。
\documentclass{beamer}
\defbeamertemplate*{background canvas}{mydefault}{%
\ifbeamercolorempty[bg]{background canvas}{}{\color{bg}\vrule width\paperwidth height\paperheight}%
}
\defbeamertemplate*{background canvas}{bg}{%
\color{black}\vrule width\paperwidth height\paperheight%
}
\BeforeBeginEnvironment{frame}{%
\setbeamertemplate{background canvas}[mydefault]%
}
\makeatletter
\define@key{beamerframe}{bg}[true]{%
\setbeamertemplate{background canvas}[bg]%
}
\makeatother
\begin{document}
\begin{frame}<1>[bg, label=test]
\frametitle{Inverted}
\only<1>{First point}
\only<2>{Second point}
\only<3>{Third point}
\end{frame}
\againframe<2>{test}
\begin{frame}
\frametitle{Normal}
\end{frame}
\againframe<3>[bg]{test}
\end{document}
但我真的希望框架选项也能改变字体颜色。有什么方法可以实现我想要的功能吗?
答案1
这个问题和Metropolis 的突出框架中没有框架编号您正在嵌套\setkeys
不可嵌套的调用。因此,label
键不会被解析为 的可选参数的一部分frame
,而是 所用集合的一部分\setbeamercolor
。
顺便说一句,这个问题还包含一个解决颜色泄漏问题的方法。您尝试使用 恢复颜色\BeforeBeginEnvironment
,但frame
环境未被使用,\againframe
因此您的重置代码不会被执行。修复方法是在bg
应用框架的末尾恢复颜色(通过使用\begingroup
...对其进行范围限定\endgroup
,并使用条件来跟踪它)。
以下补丁\setkeys
可嵌套并实现对您的颜色设置的修复。
\documentclass{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}}
\newif\ifbgframe
\define@key{beamerframe}{bg}[true]{%
\bgframetrue
\begingroup
\setbeamercolor{normal text}{fg=white, bg=black}%
\setbeamercolor{structure}{fg=red}%
\usebeamercolor[fg]{normal text}%
}
\pretocmd{\beamer@reseteecodes}{%
\ifbgframe
\endgroup
\bgframefalse
\fi
}{}{}
\makeatother
\begin{document}
\begin{frame}<1>[bg, label=test]
\frametitle{Inverted}
\only<1>{A statement}
\only<2>{Another statement}
\only<3>{Third statement}
\end{frame}
\againframe<2>{test}
\begin{frame}
\frametitle{Normal}
\end{frame}
\againframe<3>{test}
\end{document}
\begin{document}
\begin{frame}
\frametitle{Normal}
\end{frame}
\begin{frame}[bg]
\frametitle{Inverted}
A statement
\end{frame}
\end{document}