1

Is it possible to append something to the body of every frame in beamer?

Specifically, I would like to include \par\unskip right before \end{frame} so that the bottom margin of full slides is the same regardless of whether the slide ends with text, an enumerate environment, or a displayed formula. I am using the metropolis theme, for which the difference is quite noticeable.

enter image description here enter image description here

My two ideas were to either use

\addtobeamertemplate{footline}{\par\unskip}{}

or the standard trick

\let\oldendframe\endframe
\def\endframe{\par\unskip\oldendframe}

The first one doesn't work because \lastskip has been forgotten at that point. The second doesn't' work because \endframe is never actually used. Where it is defined in beamerbaseframe.sty, there's a comment:

% Normally not executed; only in containsverbatim context:
\def\endframe{\egroup\begingroup\def\@currenvir{frame}}

I don't quite understand plain TeX well enough to understand how the body of the frame is processed to figure out where I would need to include the \par\unskip. Does anybody know how one would achieve this? Here is an MWE:

\documentclass{beamer}
\usetheme{metropolis}
\usepackage{lipsum}

\begin{document}

\begin{frame}
\frametitle{This frame ends in text}

\begin{enumerate}
\item \lipsum[1][1]
\item \lipsum[1][2]
\item \lipsum[1][3]
\item \lipsum[1][4-5]
\item \lipsum[1][6]
\end{enumerate}

\lipsum[1][7-13] This is the bottom margin in metropolis.
%\par\unskip % it works if entered manually
\end{frame}

\begin{frame}
\frametitle{This frame ends in a formula}
\begin{enumerate}
\item \lipsum[1][1]
\item \lipsum[1][2]
\item \lipsum[1][3]
\item \lipsum[1][4-5]
\item \lipsum[1][6]
\end{enumerate}

\lipsum[1][7-12]
\[ a + b = c \]
%\par\unskip % it works if entered manually
\end{frame}
\end{document}

If \par\unskip is inserted manually, it looks better to my eyes.

enter image description here enter image description here

2
  • Have you tried executing \usepackage{etoolbox} \AtEndEnvironment{frame}{\par\unskip} in the preamble? (untested)
    – Mico
    Apr 22, 2022 at 8:22
  • 1
    Yes, thank you. It doesn't work for the same reason as above: frame is not a real environment that scans for \endframe. Patching \endframe in any fashion won't work. Btw \AtEndEnvironment is now part of the Latex kernel, so there's no need to say \usepackage{etoolbox} anymore Apr 22, 2022 at 8:27

1 Answer 1

2

Patching the end part of internal environment beamer@frameslide seems to work. This environment is defined as (see beamerbaseframe.sty)

\newenvironment{beamer@frameslide}{%
  % ...
  \global\setbox\beamer@framebox=\vbox\bgroup
    % ...
    \begin{beamer@framepauses}%
      % ...
}{%
      \par
    \end{beamer@framepauses}%
  \egroup
  % ...
}

So we only need to append \unskip right after \par in \endbeamer@frameslide:

\documentclass{beamer}
\usetheme{metropolis}
\usepackage{lipsum}

\makeatletter
\patchcmd\endbeamer@frameslide
  {\par}
  {\par\unskip}
  {}{\PatchFailed}
\makeatother

\begin{document}

\begin{frame}
  \frametitle{This frame ends in text}
  
  \begin{enumerate}
    \item \lipsum[1][1]
    \item \lipsum[1][2]
    \item \lipsum[1][3]
    \item \lipsum[1][4-5]
    \item \lipsum[1][6]
  \end{enumerate}
  
  \lipsum[1][7-13] This is the bottom margin in metropolis.
  %\par\unskip % it works if entered manually
\end{frame}

\begin{frame}
  \frametitle{This frame ends in a formula}
  \begin{enumerate}
  \item \lipsum[1][1]
  \item \lipsum[1][2]
  \item \lipsum[1][3]
  \item \lipsum[1][4-5]
  \item \lipsum[1][6]
  \end{enumerate}
  
  \lipsum[1][7-12]
  \[ a + b = c \]
  %\par\unskip % it works if entered manually
\end{frame}
\end{document}

enter image description here

You must log in to answer this question.

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