附录

附录
  • 当您allowframebreaks在 beamer 中使用该选项时,如果内容对于一帧来说太高,那么您就会获得额外的帧。
  • 使用列表(逐项列举、枚举、描述)时,垂直间距会受到干扰,例如,请参见以下动画。我使用了选项t(对于框架的对齐方式为“op 对齐”。

在此处输入图片描述

\documentclass[aspectratio=169]{beamer}


\begin{document}

\begin{frame}[t,allowframebreaks]
\frametitle{Frame Title}
\setlength{\mylength}{\baselineskip}
\begin{itemize}
\item Test
\item Test
\item Test
\item Test
\item Test
\item Test
\item Test
\item Test
\item Test
\item Test
\item Test
\item Test
\item Test
\item Test
\item Test
\item Test
\item Test
\end{itemize}

\end{frame}

\begin{frame}[t,allowframebreaks]
\frametitle{Frame Title}

Text\\
Text\\
Text\\
Text\\
Text\\
Text\\
Text\\
Text\\
Text\\
Text\\
Text\\
Text\\
Text\\
Text\\
Text\\
Text\\
Text\\
Text\\
Text\\
Text\\
Text\\
Text\\
Text\\
Text\\
Text\\

\end{frame}

\end{document}
  • 当我读到问题他们如何解释列表中的不同长度。
  • 主要思想是检查当前帧是否不是帧延续的第一帧并添加所需的垂直空间。
  • 我认为这\topsep就是所需的长度但显然不太正确。
  • 它几乎是完美的,但它仍然有点“跳舞”。
  • 我需要多长的额外长度?
  • 这是动画和使用的代码。

在此处输入图片描述

\documentclass[aspectratio=169]{beamer}

\setbeamertemplate{frametitle continuation}{%
    (\insertcontinuationcount)%
    \ifnum\insertcontinuationcount>1%
    \vspace*{\topsep}%
    \else%
    %
    \fi%
}

\begin{document}

\begin{frame}[t,allowframebreaks]
\frametitle{Frame Title}

\begin{itemize}
\item Test
\item Test
\item Test
\item Test
\item Test
\item Test
\item Test
\item Test
\item Test
\item Test
\item Test
\item Test
\item Test
\item Test
\item Test
\item Test
\item Test
\end{itemize}

\end{frame}

\end{document}

有关的

\itemize的定义beamer

beamerbaselocalstructure.sty发现

\renewcommand{\itemize}[1][]{%
  \beamer@ifempty{#1}{}{\def\beamer@defaultospec{#1}}%
  \ifnum \@itemdepth >2\relax\@toodeep\else
    \advance\@itemdepth\@ne
    \beamer@computepref\@itemdepth% sets \beameritemnestingprefix
    \usebeamerfont{itemize/enumerate \beameritemnestingprefix body}%
    \usebeamercolor[fg]{itemize/enumerate \beameritemnestingprefix body}%
    \usebeamertemplate{itemize/enumerate \beameritemnestingprefix body begin}%
    \list
      {\usebeamertemplate{itemize \beameritemnestingprefix item}}
      {\def\makelabel##1{%
          {%
            \hss\llap{{%
                \usebeamerfont*{itemize \beameritemnestingprefix item}%
                \usebeamercolor[fg]{itemize \beameritemnestingprefix item}##1}}%
          }%
        }%
      }
  \fi%
  \beamer@cramped%
  \raggedright%
  \beamer@firstlineitemizeunskip%
}

但我不明白导致“舞蹈”的不同类型的空间是如何定义的。

投影机中的“邪恶”元素

受到@cfr 评论的启发,我在beamer文档中搜索了“邪恶”的东西——这是我发现的(beamer 指南版本 3.41):

  • 不要使用subsubsections,它们是邪恶的
  • 永远不要使用邪恶的选项shrink
  • 再次使用此shrink选项非常邪恶的
  • 此 [ ] 选项的用途allowframebreaks邪恶的

答案1

区别来自于以下场景:

\documentclass{article}


\begin{document}


%\baselineskip0pt
%\lineskip0pt


\vbox{Case1: a vbox}
and then a natural paragraph


\bigskip


\newbox\tempvbox
\setbox\tempvbox=\vbox{and then some vbox content}
\vbox{Case2: a vbox}
\box\tempvbox


\bigskip


\setbox\tempvbox=\vbox{and then some unboxed content}
\vbox{Case3: a vbox}
\unvbox\tempvbox


\end{document}

前两种情况,行间距由 决定\baselineskip。通过改变 ,\baselineskip你可以看到间距的变化。

第三种情况,基本没有空间,两个箱子并排摆放。看起来就像和\baselineskip\lineskip为零时一样。


转到 beamer。在环境定义中beamer@frameslide,有一个\vbox

\vskip-\parskip\vbox{}% 

这与上面的\vbox{Case1//相对应。23: a vbox}

接下来\vbox是框架的内容。在本例中,有一个\itemize。因此第一页看起来很完美。

从第二页开始,内容被以下行提取

\setbox\@tempboxa=\vsplit\beamer@framebox to\beamer@autobreakfactor\textheight%

并放回页面

\ifbeamer@slidehaszoom\box\beamer@framebox\else\unvbox\beamer@framebox\fi%

这对应于上面的第三种情况。因此从第二页开始,页面顶部的空间就不够了。


附录

涉及这些宏。

\beamer@collect@@body

  • #1是框架的内容。也就是说,介于\begin{frame}和之间的任何内容\end{frame}
  • #2应该是字符串frame。如果你有嵌套环境,事情会变得有点紧张。
  • \beamer@envbody是一个tokenlist,根据第五行,它会存储你的frame的内容。
\long\def\beamer@collect@@body#1\end#2{%
  \def\test{#1}%
  \edef\beamer@begin@stack{\beamer@push@begins#1\begin\end \expandafter\@gobble\beamer@begin@stack}%
  \ifx\@empty\beamer@begin@stack % This will be true; I do not know what is this for
      \global\beamer@envbody\expandafter{\the\beamer@envbody#1}%
    \def\reserved@a{#2}
    \ifx\reserved@a\beamer@frametext%
      \endgroup%
      \let\@next=\beamer@process@envbody % A little tricky! Note the grouping
      \@checkend{#2}%
    \else%
      % ok, just expand it, presumably it will generate the desired \end{frame}
      \let\@next=\beamer@process@expander%
    \fi
  \else
    \global\beamer@envbody\expandafter{\the\beamer@envbody#1\end{#2}}%
    \let\@next=\beamer@process@envbody%
  \fi
  \@next
}

\beamer@autobreakframe

beamer读到之后[allowframebreak]就会知道该如何处理这一帧,这个宏就是beamer接下来要做的事情。

之后\begin{beamer@frameslide},您添加的任何内容都将出现在幻灯片顶部,标题下方。(前提是您有一个标题)

\def\beamer@autobreakframe{%
  \beamer@slideinframe=1\relax%
  \advance\beamer@autobreakcount by1\relax%
  \begin{beamer@frameslide}\relax%
    % if you add anything here, it will appear at the top of the slide
    \bgroup%
    \aftergroup\beamer@endautobreak%
    \afterassignment\beamer@checkframetitle%
    \let\beamer@next% gobble opening brace
  }

\beamer@endautobreak

如果你在 之前添加任何内容\end{beamer@frameslide},它将出现在幻灯片的末尾。(但为时已晚)

\def\beamer@endautobreak{\end{beamer@frameslide}%
  \beamer@writeslidentry%
  \ifvoid\beamer@splitbox%
    \let\beamer@next=\beamer@reseteecodes%
  \else%
    \let\beamer@next=\beamer@continueautobreak%
  \fi%
  \beamer@next%
}

\beamer@autobreakframebox

这是 beamer 用于将长内容分割成几页的算法。

在此宏之前,\beamer@framebox存储很长的内容。在此宏之后,\beamer@splitbox存储适合幻灯片/页面的内容。

\def\beamer@autobreakframebox{%
  \global\setbox\beamer@splitbox=\box\voidb@x%
  \ifbeamer@autobreak%
    % Ok, frame was overful -> split it!
    \setbox\@tempboxa=\vsplit\beamer@framebox to\beamer@autobreakfactor\textheight% NOTICE THIS LINE
    \global\setbox\beamer@splitbox=\box\beamer@framebox%
    \@tempdima=\ht\beamer@splitbox%
    \ifdim\@tempdima<\beamer@autobreaklastheight%
      \global\beamer@autobreaklastheight=\@tempdima\relax%
    \else%
      \setbox\@tempboxa=\vbox{\unvbox\@tempboxa\unvbox\beamer@splitbox}%
      \global\setbox\beamer@splitbox=\box\voidb@x%
    \fi%
    \setbox\beamer@framebox=\vbox to\textheight{\unvbox\@tempboxa%
      \vskip\beamer@framebottomskipautobreak%
      \ifvoid\beamer@splitbox%
        \ifvoid\beamer@footins%
        \else%
          \begingroup
            \usebeamercolor*[fg]{footnote}%
            \footnoterule%
            \unvbox \beamer@footins%
            \global\setbox\beamer@footins=\box\voidb@x%
          \endgroup  
        \fi%
      \fi%
      \beamer@exitcode%
    }%
  \else%
    \setbox\beamer@framebox=\vbox to\textheight{\unvbox\beamer@framebox%
      \vskip\beamer@framebottomskip%
      \ifvoid\beamer@footins%
      \else%
        \begingroup
          \usebeamercolor*[fg]{footnote}%
          \footnoterule%
          \unvbox \beamer@footins%
          \global\setbox\beamer@footins=\box\voidb@x%
        \endgroup 
      \fi%
      \beamer@exitcode}%
    \global\setbox\beamer@footins=\box\voidb@x%
  \fi%
  }

\beamer@continueautobreak

这是将内容打印到单个幻灯片/页面的宏。请注意\unvbox倒数第二行中的。

\def\beamer@continueautobreak{%
  \refstepcounter{framenumber}%
  \expandafter\beamer@frametitletoks\expandafter{\beamer@frametitle}%
  \expandafter\beamer@framesubtitletoks\expandafter{\beamer@shortframetitle}%
  \edef\beamer@callframetitle{\noexpand\frametitle[\the\beamer@framesubtitletoks]{\the\beamer@frametitletoks}}%
  \expandafter\expandafter\expandafter\beamer@autobreakframe
  \expandafter\expandafter\expandafter{%
    \expandafter\beamer@callframetitle%
    \expandafter\framesubtitle\expandafter{\insertframesubtitle}%
    \unvbox\beamer@splitbox}% NOTICE THIS LINE
}

beamer@frameslide

\newenvironment{beamer@frameslide}{%
  \ifbeamer@autobreak\else%
    \ifx\beamer@againname\@empty%
      {\let\@elt\beamer@restorecounter\beamer@overlaycounterresets}%
    \else%
      {\let\@elt\beamer@labelrestorecounter\beamer@overlaycounterresets}%
    \fi%
  \fi%
  \global\c@beamerpauses=1\relax%
  \expandafter\beamer@ifempty\expandafter{\beamer@framestartpage}{%
    \stepcounter{subsectionslide}%
    \xdef\beamer@framestartpage{\the\c@page}% only first time
  }{\clearpage\beamer@notesactions}% cleanup from previous slide
  \hypersetup{pdfpagetransition=R}%
  \hypersetup{pdfpageduration=}%
  \@ifundefined{thispdfpagelabel}{}{%
  \thispdfpagelabel{\insertframenumber}}%
  \xdef\beamer@frameendpage{\the\c@page}% every time
  \beamer@setuplinks%
  \beamer@displaybreak%
  \global\setbox\beamer@zoombox=\box\voidb@x%
  \def\beamer@zoomer{}%
  \beamer@slidehaszoomfalse%
  \gdef\insertframetitle{}%
  \gdef\insertframesubtitle{}%
  \gdef\beamer@frametitle{}%
  \gdef\beamer@shortframetitle{}%
  \gdef\beamer@framesubtitle{}%
  \let\beamer@startcomment=\beamer@startcommentinframe%
  % Start slide:
  \beamer@framenotesbegin%
    \global\setbox\beamer@framebox=\vbox\bgroup%
    \beamer@inframetrue%
    \let\frame=\framelatex% inside frames, use LaTeX's \frame command
    \begin{beamer@framepauses}%
      \refcounter{framenumber}%use frame number for  \label
      \ifbeamer@shrink%
        \hsize=\beamer@shrinkfactorinv\hsize%
        \textwidth=\beamer@shrinkfactorinv\textwidth%
        \linewidth=\beamer@shrinkfactorinv\linewidth%
      \fi%
      % Insert labels if necessary:
      \ifx\beamer@againname\@empty\else%
        \nointerlineskip\vbox to0pt{\vss%
        \label<\the\beamer@slideinframe>{\beamer@againname<\the\beamer@slideinframe>}%
        \ifnum\beamer@slideinframe=1\relax%
          \label<1>{\beamer@againname}%
        \fi%
        }\nointerlineskip%
      \fi%
      \ifx\beamer@framehypertargets\@empty\else%
        \nointerlineskip\vbox to0pt{\vss%
          \beamer@framehypertargets%
          \global\let\beamer@framehypertargets\@empty%
        }\nointerlineskip%
      \fi%
      \vskip-\parskip\vbox{}% NOTICE THIS LINE
      \ifbeamer@plainframe\nointerlineskip\fi%
    \beamer@checkframetitle}%

在这一行之前是框架(不是幻灯片)。请注意从底部开始的第三行。

此行之后是框架(不是幻灯片)。

    {\par
    \end{beamer@framepauses}%
  \egroup%
  \ifx\beamer@frametitle\@empty%
    \setbox\beamer@frametitlebox=\box\voidb@x%
  \else%
    \setbox\beamer@frametitlebox=\vbox{%
      \vbox{}%
      {\parskip0pt\usebeamertemplate***{frametitle}\vskip0.25em}%
    }%
  \fi%
  \ifbeamer@plainframe%
    \beamer@frametextheight=\paperheight%
  \else%
    \beamer@frametextheight=\textheight%
  \fi%
  \advance\beamer@frametextheight by-\ht\beamer@frametitlebox%
  \advance\beamer@frametextheight by-\dp\beamer@frametitlebox%
  \advance\beamer@frametextheight by-\beamer@frametopskip%
  \ifbeamer@shrink%
    \beamer@shrinkframebox%
  \fi%
  \ifx\beamer@zoomer\@empty
    \setbox\beamer@framebox=\vbox{%
      \nobreak\vbox{}\nobreak\par\nobreak\beamer@entrycode\nobreak%
      \nointerlineskip\unvbox\beamer@frametitlebox%
      \nobreak%
      \ifbeamer@autobreak%
        \vskip\beamer@frametopskipautobreak%
      \else%
        \vskip\beamer@frametopskip%
      \fi%
      \nobreak%
      \nointerlineskip\box\beamer@zoombox\nointerlineskip%
      \nobreak%
      \ifbeamer@slidehaszoom\box\beamer@framebox\else\unvbox\beamer@framebox\fi%
      % bottom skip is added in autobreakframebox
    }%
    \beamer@autobreakframebox%
  \else%
    \beamer@zoomer%
  \fi%
  \beamer@undolabels%
  \beamer@framenotesend%
  \box\beamer@framebox}

相关内容