重复投影仪演示中的前一个图形

重复投影仪演示中的前一个图形

我希望在后面的帧中重新出现一个特定的图形,以便我可以更多地谈论它,最好保留原始的图形计数器数字。在这两种情况下,都会有一些文本或其他内容伴随图形。

这个问题类似于或这个。第一个链接中的解决方案似乎过于手动,第二个看起来不错,但我无法将其编译到 beamer 文档中,第三个仅涉及图形计数器的问题。我尝试使用环境lrbox来保存图形的内容,但这似乎也不起作用:

\documentclass{beamer}
\usepackage{tikz}
\setbeamertemplate{caption}{{\small\bfseries\MakeUppercase{\insertcaptionname~\insertcaptionnumber}}\quad\insertcaption}
\newsavebox{\myfigurebox}

\begin{document}
\begin{frame}{First Frame}
  \begin{lrbox}{\myfigurebox}
    \begin{tikzpicture}
      \draw (0,0) -- ++(75:1 cm) -- ++(-75:1 cm);
    \end{tikzpicture}
  \end{lrbox}

  \begin{figure}
    \centering
    \usebox{\myfigurebox}
    \caption{Description.}
  \end{figure}
  Some text.
\end{frame}
\begin{frame}{Other Frame}
  \begin{figure}
    \centering
    \usebox{\myfigurebox}
    \caption{Description (again).}
  \end{figure}
  More text.
\end{frame}
\end{document}

还尝试了其他变化,例如用 包围figure环境lrbox、移到lrbox外面frame等等,但这些也没有起作用。

现在,我唯一接近的解决方案是使用覆盖规范和\againframe,但这会弄乱方程式数字或其他计数器。

\documentclass{beamer}
\usepackage{tikz}
\setbeamertemplate{caption}{{\small\bfseries\MakeUppercase{\insertcaptionname~\insertcaptionnumber}}\quad\insertcaption}

\begin{document}
\begin{frame}<1>[label=myframe]
\frametitle<1>{First Frame}
\frametitle<2>{Other Frame}
  \begin{figure}
    \centering
    \begin{tikzpicture}
      \draw (0,0) -- ++(75:1 cm) -- ++(-75:1 cm);
    \end{tikzpicture}
    \caption{Description.}
  \end{figure}
\begin{overprint}
\onslide<1>
  Some text. 
\onslide<2>
  More text. % imagine there are some equations or other counters here; the equation numbering would be wrong
\end{overprint}
\end{frame}
% later...
\againframe<2>{myframe}
\end{document}

如果同一个数字重复很多次,这种“黑客”方式可能会失控……

答案1

  • \begin{lrbox}在 a 中拥有etcframe使它成为 的局部frame,因此以后无法调用它,除非定义一个globallrbox环境并使用它。这样的定义可以通过

    \usepackage{etoolbox}
    \usepackage{letltxmacro}
    \LetLtxMacro{\globallrbox}{\lrbox}
    \LetLtxMacro{\endgloballrbox}{\endlrbox}
    \patchcmd{\globallrbox}{\setbox}{\global\setbox}{}{\showtokens{patching globallrbox failed}}
    
  • 图形编号会有所不同,因为\caption命令负责分配编号,而您有两个\caption命令。尝试将整个figure环境放在一个框中可能并不容易(而且您也不能caption在没有环境的情况下将 放在框中figure),并且不允许您第二次将文本“(再次)”附加到标题,所以最好摆弄标签/计数器,就像我下面所做的那样,扩展示例以显示在中间放置其他图形的效果。

在下文中,我避免使用环境,并将框架globallrbox移到外部,以便更好地说明各种方法。您可以通过提供用于保存和调用图形的附加宏/环境来进一步整理它。lrbox

\documentclass{beamer}

\usepackage{tikz}
\setbeamertemplate{caption}{{\small\bfseries\MakeUppercase{\insertcaptionname~\insertcaptionnumber}}\quad\insertcaption}
\newsavebox{\myfigurebox}

\makeatletter
\newcommand*{\localsetcounter}[2]{% same as LaTeX's \setcounter, but removed the \global
    \@ifundefined {c@#1}{\@nocounterr {#1}}%
    {\csname c@#1\endcsname #2\relax}%
}

\newcommand*{\reusefigurecounter}[1]{%only use this within your figure environment to keep the changes local to that environment, and before the \caption command!
    \localsetcounter{figure}{\getrefnumber{#1}}%
    \let\refstepcounter\@gobble
}
\makeatother

\setcounter{errorcontextlines}{\maxdimen}

\begin{document}

  \begin{lrbox}{\myfigurebox}% the lrbox is outside any frames, but after \begin{document} so that the right fonts and things are set up, and before we first want to use it
    \centering
    \begin{tikzpicture}
      \draw (0,0) -- ++(75:1 cm) -- ++(-75:1 cm);
    \end{tikzpicture}
  \end{lrbox}

\begin{frame}{First Frame}
  \begin{figure}
    \usebox{\myfigurebox}
    \caption{Description.}
    \label{myfigure}
  \end{figure}
  Some text.
\end{frame}

\begin{frame}{Another Frame}
  \begin{figure}
    something else
    \caption{Description.}
  \end{figure}
  Some text.
\end{frame}

\begin{frame}{Other Frame}
  \begin{figure}
    \centering
    \usebox{\myfigurebox}
    \reusefigurecounter{myfigure}
    \caption{Description (again).}
  \end{figure}
  More text.
\end{frame}


\begin{frame}{Another Frame}
  \begin{figure}
    something else entirely
    \caption{Description.}
  \end{figure}
  Some text.
\end{frame}
\end{document}

更新:界面稍微好一点?

使用此版本,savefigure在您希望显示该图形的第一个副本之前的任何位置使用环境,在第一个参数中提供一个标签,以便稍后调用它。然后使用\figurefirstuse\reusefigure命令调用或调用该图形,具体取决于它是否已经显示。这些命令的参数是标签名称和标题,对于同一图像的所有调用,它们不必相同。它目前不会自动保存任何以前使用的标题。

不确定这些东西是否必要或优雅,但似乎有效,现在也有覆盖层。请注意,至少在错误处理方面存在一些限制。很难自动确定图形是否是第一次使用,因为在重新处理多张幻灯片的帧(即覆盖和暂停)时beamer会重置figure计数器,因此我暂时放弃尝试这样做。

还有一个figureandsave环境,它保存图形并在同一位置显示它,内部调用上述命令。\figurefirstuse在这种情况下采用与相同的参数。

我保留了上面的旧版本,因为这样可能更清楚实际发生了什么。希望下面的示例比我的描述能更好地说明新界面。

\documentclass{beamer}

\usepackage{tikz}
\setbeamertemplate{caption}{{\small\bfseries\MakeUppercase{\insertcaptionname~\insertcaptionnumber}}\quad\insertcaption}

\makeatletter
\newcommand*{\localsetcounter}[2]{% same as LaTeX's \setcounter, but removed the \global
    \@ifundefined {c@#1}{\@nocounterr {#1}}%
    {\csname c@#1\endcsname #2\relax}%
}

\newcommand*{\reusefigurecounter}[1]{%#1=label, only use this within your figure environment to keep the changes local to that environment, and before the \caption command!
    \localsetcounter{figure}{\getrefnumber{#1}}%
    \let\refstepcounter\@gobble
}

\usepackage{etoolbox}
\usepackage{letltxmacro}
\LetLtxMacro{\globallrbox}{\lrbox}
\LetLtxMacro{\endgloballrbox}{\endlrbox}
\patchcmd{\globallrbox}{\setbox}{\global\setbox}{}{\showtokens{patching globallrbox failed}}

\newenvironment{figureandsave}[2]{% parameters #1=label name,#2=caption
    \def\currsavefigurecaption{#2}%
    \def\currsavefigurename{#1}%
    \begin{savefigure}{#1}}%
    {\end{savefigure}%
    \figurefirstuse{\currsavefigurename}{\currsavefigurecaption}%
    }

% can use savefigure within or outside of a frame, but always after \begin{document}
\newenvironment*{savefigure}[1]{% parameters #1=label name
    \expandafter\newbox\expandafter{\csname savedfigure#1box\endcsname}%use \newbox instead of \newsavebox as we have to allow beamer to process the same figure multiple times if a frame contains multiple slides
    \begin{globallrbox}{\csname savedfigure#1box\endcsname}%
    }
    {\end{globallrbox}}

% use \figurefirstuse the first time you want to show the figure
\newcommand\figurefirstuse[2]{% parameters #1=label name,#2=caption
    \@ifundefined{savedfigure#1box}{\errmessage{figure #1 hasn't been saved yet}}{%
    % calling this multiple times for the same figure will result in it having multiple numbers assigned to it and multiply defined label issues
    \begin{figure}%
        \usebox{\csname savedfigure#1box\endcsname}%
        \caption{#2}%
        \label{savedfigure#1}%
    \end{figure}}}

% use \reusefigure if the figure has already been shown, and you want to show it again
\newcommand\reusefigure[2]{% parameters #1=label name, #2=new caption
    \@ifundefined{savedfigure#1box}{\errmessage{figure #1 hasn't been saved yet}}{%
    % no easy way to test if the figure has been used or not yet, but will be numbered Figure 0 if not!
    \begin{figure}%
        \usebox{\csname savedfigure#1box\endcsname}%
        \reusefigurecounter{savedfigure#1}%
        \caption{#2}%
    \end{figure}}}
\makeatother


\begin{document}

\begin{savefigure}{test}
    World.
\end{savefigure}

\begin{frame}{First Frame}
    \begin{figureandsave}{myfigure}{Description.}
        \centering
        \begin{tikzpicture}
            \draw (0,0) -- ++(75:1 cm) -- ++(-75:1 cm);
        \end{tikzpicture}
    \end{figureandsave}
    \pause
    Some text after a pause.
\end{frame}

\begin{frame}{In between}
    \begin{figure}
        A different figure
        \caption{For testing}
    \end{figure}

    \pause
    \figurefirstuse{test}{Hello}
    \reusefigure{test}{Hello again}
\end{frame}

\begin{frame}{Other Frame}
    \reusefigure{myfigure}{Description (again).}

    \begin{figure}
        A second figure on the same frame.
        \caption{With a number}
    \end{figure}

    More text.
\end{frame}

\end{document}

相关内容