使用宏中的计数器来管理 Beamer 覆盖

使用宏中的计数器来管理 Beamer 覆盖

我有一个非常复杂的 Tikz 图形,在演示过程中需要逐个显示。在调整演示文稿时,我决定更改显示顺序,但由于 \onslide 命令数量众多,因此很难将其正确显示。为了解决这个问题,我尝试创建以下两个宏:

\newcommand*{\BeamerCounter}[1]{%
  \@ifundefined{c@#1}{%
    \newcounter{#1}}{}}

\newcommand*{\BeamerNext}[2]{%
  \@ifundefined{#1#2}{%
    \stepcounter{#1}   
    \newcommand*{#1#2}{\the#1}}{}}

我的想法是,在我的文档的顶层我会做类似的事情:

\BeamerCounter{Fig}
\BeamerNext{Fig}{Part1}
\BeamerNext{Fig}{Part2}

因此在我的图中我可以使用:

\onslide<\FigPart1>{ .. }
\onslide<\FigPart2>{ .. }
\onslide<\FigPart1, \FigPart2>{ .. }

最小(非)工作示例:

\documentclass{beamer}

\newcommand*{\BeamerCounter}[1]{%
  \@ifundefined{c@#1}{%
    \newcounter{#1}}{}}

\newcommand*{\BeamerNext}[2]{%
  \@ifundefined{#1#2}{%
    \stepcounter{#1}
    \newcommand*{#1#2}{\the#1}}{}}

\BeamerCounter{Fig}
\BeamerNext{Fig}{Part1}
\BeamerNext{Fig}{Part2}

\begin{document}
\begin{frame}
  \begin{itemize}
    \item<FigPart1-> item1
    \item<FigPart2-> item2
  \end{itemize}
\end{frame}
\end{document}

这会产生以下错误:

t.tex:12: You can't use `\spacefactor' in vertical mode.
t.tex:12: leading text: \BeamerCounter{Fig}
t.tex:12: Missing $ inserted.
t.tex:12: leading text: \BeamerCounter{Fig}
t.tex:12: Missing \begin{document}.
t.tex:12: leading text: \BeamerCounter{Fig}
t.tex:13: You can't use `\spacefactor' in math mode.
t.tex:13: leading text: \BeamerNext{Fig}{Part1}
t.tex:13: Missing number, treated as zero.
t.tex:13: leading text: \BeamerNext{Fig}{Part1}
t.tex:13: Missing control sequence inserted.
t.tex:13: leading text: \BeamerNext{Fig}{Part1}
t.tex:13: You already have nine parameters.
t.tex:13: leading text: \BeamerNext{Fig}{Part1}
t.tex:13: You can't use `the letter F' after \the.
t.tex:13: leading text: \BeamerNext{Fig}{Part1}
t.tex:14: You can't use `\spacefactor' in math mode.
t.tex:14: leading text: \BeamerNext{Fig}{Part2}
t.tex:14: Missing number, treated as zero.
t.tex:14: leading text: \BeamerNext{Fig}{Part2}
t.tex:14: Missing control sequence inserted.
t.tex:14: leading text: \BeamerNext{Fig}{Part2}
t.tex:14: You already have nine parameters.
t.tex:14: leading text: \BeamerNext{Fig}{Part2}
t.tex:14: You can't use `the letter F' after \the.
t.tex:14: leading text: \BeamerNext{Fig}{Part2}
t.tex:15: Missing $ inserted.

答案1

您的代码有几个弱点。

  1. 您想使用宏\@ifundefined,因此代码必须被 和 包围\makeatletter\makeatother\makeatletter 和 \makeatother 起什么作用?

  2. \newcommand*{#1#2}{\the#1}出于多种原因,这是错误的;假设你这样做\BeamerNext{Fig}{Part1};那么 TeX 会尝试

    \newcommand*{FigPart1}{\the Fig}
    
  3. 当然\newcommand*{FigPart1}是非法的,但是你不能通过\newcommand*{\#1#2}在定义中说来解决这个问题,因为这也是非法的:\#是一个令牌的名称。

  4. \the#1不会提及\theFig,因为\the已经是一个标记。

  5. 你无论如何都不想\theFig,但是当前的的价值\theFig

  6. 即使这有效,\item<FigPart2->也不会达到您所期望的效果,因为FigPart2这不是命令的名称。

这是修订版本。

\documentclass{beamer}

\makeatletter
\newcommand*{\BeamerCounter}[1]{%
  \@ifundefined{c@#1}{%
    \newcounter{#1}}{}}

\newcommand*{\BeamerNext}[2]{%
  \@ifundefined{#1#2}{%
    \stepcounter{#1}%
    % \edef to get the current value
    \expandafter\edef\csname#1#2\endcsname{\the\value{#1}}}{}%
}
\newcommand{\BC}[1]{\@nameuse{#1}} % for using the newly defined command
\makeatother

\BeamerCounter{Fig}
\BeamerNext{Fig}{Part1}
\BeamerNext{Fig}{Part2}


\begin{document}
\begin{frame}
  \begin{itemize}
    \item<\BC{FigPart1}-> item1
    \item<\BC{FigPart2}-> item2
  \end{itemize}
\end{frame}
\end{document}

在此处输入图片描述

相关内容