Beamer alt 命令“喜欢可见”而不是“喜欢仅”

Beamer alt 命令“喜欢可见”而不是“喜欢仅”

如果当前幻灯片在给定的叠加规范内,则命令将插入beamer,否则。它相当于\alt<*overlay specification*>{foo}{bar}foobar

\only<*overlay specification*>{foo}\only<*complementary overlay specification*>{bar}

以下是使用它的示例文档:

\documentclass{beamer}
\begin{document}
\begin{frame}
\begin{align*}
y &= \frac{(x^2+1)\sqrt{x+3}}{x-1} \\
\ln y &= \ln (x^2+1) + \frac{1}{2} \ln(x+3) - \ln(x-1) \\
\frac{1}{y} \frac{dy}{dx}
      &= \frac{2x}{x^2+1} + \frac{1}{2(x+3)} - \frac{1}{x-1}
\end{align*}
So
\[
\begin{split}
\frac{dy}{dx} &= \left(\frac{2x}{x^2+1} + \frac{1}{2(x+3)} - \frac{1}{x-1}
\right)
\alt<2>{\frac{(x^2+1)\sqrt{x+3}}{x-1}}{y}
\end{split}
\]
\end{frame}
\end{document}

这非常有用,可以节省打字时间。但是如果其中一个选项大于另一个,则会导致幻灯片抖动。

我想要的是一个覆盖规范感知命令\altvisible,它会在每张幻灯片上占用相同的空间。因此,它必须插入一个与两者中较大的一个一样大的框,然后设置正确的材料。这样,上面的文档\altvisible\alt不会抖动了。

有谁愿意接受吗?

答案1

继讨论 diabonas 的回答之后,这里是我的建议。使用幻影盒的想法似乎是可行的。这里将两个替代方案装箱,以便可以测量它们。可以改进代码以自行检测模式(文本、数学、显示数学等),并避免幻影命令中发生的重新装箱。

\documentclass{beamer}
\newcommand<>\Alt[2]{{%
    \sbox0{$\displaystyle #1$}%
    \sbox1{$\displaystyle #2$}%
    \alt#3%
        {\rlap{\usebox0}\vphantom{\usebox1}\hphantom{\ifnum\wd0>\wd1 \usebox0\else\usebox1\fi}}%
        {\rlap{\usebox1}\vphantom{\usebox0}\hphantom{\ifnum\wd0>\wd1 \usebox0\else\usebox1\fi}}%
}}

\begin{document}
\begin{frame}
\begin{align*}
y &= \frac{(x^2+1)\sqrt{x+3}}{x-1} \\
\ln y &= \ln (x^2+1) + \frac{1}{2} \ln(x+3) - \ln(x-1) \\
\frac{1}{y} \frac{dy}{dx}
      &= \frac{2x}{x^2+1} + \frac{1}{2(x+3)} - \frac{1}{x-1}
\end{align*}
So
\[
\begin{split}
\frac{dy}{dx} &= \left(\frac{2x}{x^2+1} + \frac{1}{2(x+3)} - \frac{1}{x-1}
\right)
\Alt<2>{\frac{(x^2+1)\sqrt{x+3}}{x-1}}{y}
\end{split}
\]
\end{frame}
\end{document}

这是自动检查模式和数学样式的版本。它适用于所有数学和文本模式:

\documentclass{beamer}

\makeatletter
% Detect mode. mathpalette is used to detect the used math style
\newcommand<>\Alt[2]{%
    \begingroup
    \ifmmode
        \expandafter\mathpalette
        \expandafter\math@Alt
    \else
        \expandafter\make@Alt
    \fi
    {{#1}{#2}{#3}}%
    \endgroup
}

% Un-brace the second argument (required because \mathpalette reads the three arguments as one
\newcommand\math@Alt[2]{\math@@Alt{#1}#2}

% Set the two arguments in boxes. The math style is given by #1. \m@th sets \mathsurround to 0.
\newcommand\math@@Alt[3]{%
    \setbox\z@ \hbox{$\m@th #1{#2}$}%
    \setbox\@ne\hbox{$\m@th #1{#3}$}%
    \@Alt
}

% Un-brace the argument
\newcommand\make@Alt[1]{\make@@Alt#1}

% Set the two arguments into normal boxes
\newcommand\make@@Alt[2]{%
    \sbox\z@ {#1}%
    \sbox\@ne{#2}%
    \@Alt
}

% Place one of the two boxes using \rlap and place a \phantom box with the maximum of the two boxes
\newcommand\@Alt[1]{%
    \alt#1%
        {\rlap{\usebox0}}%
        {\rlap{\usebox1}}%
    \setbox\tw@\null
    \ht\tw@\ifnum\ht\z@>\ht\@ne\ht\z@\else\ht\@ne\fi
    \dp\tw@\ifnum\dp\z@>\dp\@ne\dp\z@\else\dp\@ne\fi
    \wd\tw@\ifnum\wd\z@>\wd\@ne\wd\z@\else\wd\@ne\fi
    \box\tw@
}

\makeatother

\begin{document}

% Test the different modes and math styles
\begin{frame}
Display:
\[
\begin{split}
\frac{dy}{dx} &= \left(\frac{2x}{x^2+1} + \frac{1}{2(x+3)} - \frac{1}{x-1}
\right)
\Alt<2>{\frac{(x^2+1)\sqrt{x+3}}{x-1}}{y}.
\end{split}
\]

In-Text:
\(
\frac{dy}{dx} = \left(\frac{2x}{x^2+1} + \frac{1}{2(x+3)} - \frac{1}{x-1}
\right)
\Alt<2>{\frac{(x^2+1)\sqrt{x+3}}{x-1}}{y}.
\)

Subscript:
\(
\frac{dy}{dx} = \left(\frac{2x}{x^2+1} + \frac{1}{2(x+3)} - \frac{1}{x-1}
\right) X_{\Alt<2>{\frac{(x^2+1)\sqrt{x+3}}{x-1}}{y}}.
\)
\[
\frac{dy}{dx} = \left(\frac{2x}{x^2+1} + \frac{1}{2(x+3)} - \frac{1}{x-1}
\right) X_{\Alt<2>{\frac{(x^2+1)\sqrt{x+3}}{x-1}}{y}}.
\]

Sub-Subscript:
\(
\frac{dy}{dx} = \left(\frac{2x}{x^2+1} + \frac{1}{2(x+3)} - \frac{1}{x-1}
\right) X_{X_{\Alt<2>{\frac{(x^2+1)\sqrt{x+3}}{x-1}}{y}}}.
\)
\[
\frac{dy}{dx} = \left(\frac{2x}{x^2+1} + \frac{1}{2(x+3)} - \frac{1}{x-1}
\right) X_{X_{\Alt<2>{\frac{(x^2+1)\sqrt{x+3}}{x-1}}{y}}}.
\]

Text-mode:
XXXX  \Alt<2>{aaaaa}{Ag}.


\end{frame}
\end{document}

末尾的点仅用于可视化恒定的宽度。

结果

答案2

第二条\Alt命令Martin Scharrer 的回答非常棒;但是,与 Beamer 的增量叠加规范(例如)一起使用时,可能会出现问题。这是因为 Martin 的实现使用<+>调用了底层命令。内部使用,它实际上先排版了四种数学样式中给出的内容,然后再决定在最终输出中使用哪一种。\alt\mathpalette\mathpalette\mathchoice

问题示例

\documentclass{beamer}

% [Paste Martin's second set of `\Alt` macros here.]

\begin{document}

\begin{frame}
  \begin{itemize}
    \item Some stuff\dots

      \pause

    \item An equation I'll reveal in pieces:
      \[
        \frac{-4}{2} + \frac{9}{3} =
        \Alt<+>{
          \vcenter{\hbox{ ?\thinspace?}}
        }{
          \frac{-4 + 9}{2 + 3} = 1.
        }
      \]

      \pause

    \item Some more stuff\dots
  \end{itemize}
\end{frame}

\end{document}

编译此代码将产生一个包含七张幻灯片而不是所需的四张幻灯片的文档,因为 TeX 正在执行 Beamer\alt宏(从而将beamerpauses计数器增加四次而不是一次)。

解决问题

将调用移到/\alt之外。不幸的是,这意味着新命令的参数将被排版八次(宏的两个参数各排版四次),而不是像 Martin 的代码中那样排版四次,但增加的开销似乎是必要的,以使行为与增量覆盖相同。\mathpalette\mathchoice\Alt\alt\Alt\alt

另外,这是一件小事,但\leavevmode在排版之前添加\Alt内容框似乎会使命令在某些情况下表现得不那么令人惊讶,例如在列表项的开头。

修订代码(支持增量覆盖)

\usepackage{etoolbox} % For `\ifbool`, `\ifnumcomp`.

\makeatletter
\newcommand*\Alt{\alt{\Alt@branch0}{\Alt@branch1}}

\newcommand\Alt@branch[3]{%
  \begingroup
  \ifbool{mmode}{%
    \mathchoice{%
      \Alt@math#1{\displaystyle}{#2}{#3}%
    }{%
      \Alt@math#1{\textstyle}{#2}{#3}%
    }{%
      \Alt@math#1{\scriptstyle}{#2}{#3}%
    }{%
      \Alt@math#1{\scriptscriptstyle}{#2}{#3}%
    }%
  }{%
    \sbox0{#2}%
    \sbox1{#3}%
    \Alt@typeset#1%
  }%
  \endgroup
}

\newcommand\Alt@math[4]{%
  \sbox0{$#2{#3}\m@th$}%
  \sbox1{$#2{#4}\m@th$}%
  \Alt@typeset#1%
}

\newcommand\Alt@typeset[1]{%
  \ifnumcomp{\wd0}{>}{\wd1}{%
    \def\setwider   ##1##2{##2##1##2 0}%
    \def\setnarrower##1##2{##2##1##2 1}%
  }{%
    \def\setwider   ##1##2{##2##1##2 1}%
    \def\setnarrower##1##2{##2##1##2 0}%
  }%
  \sbox2{}%
  \sbox3{}%
  \setwider2{\wd}%
  \setwider2{\ht}%
  \setwider2{\dp}%
  \setnarrower3{\ht}%
  \setnarrower3{\dp}%
  \leavevmode
  \rlap{\usebox#1}%
  \usebox2%
  \usebox3%
}
\makeatother

答案3

作为对马丁·沙勒的bcat 的漂亮的答案,这里有一个版本,允许人们指定较大框中较小文本的位置( lc或):r

\usepackage{etoolbox}
\usepackage{mathtools}

\makeatletter
% Detect mode. mathpalette is used to detect the used math style
\newcommand<>\Alt[3][l]{%
  \begingroup
    \providetoggle{Alt@before}%
    \alt#4{\toggletrue{Alt@before}}{\togglefalse{Alt@before}}%
    \ifbool{mmode}{%
      \expandafter\mathpalette
      \expandafter\math@Alt
    }{%
      \expandafter\make@Alt
    }%
    {{#1}{#2}{#3}}%
  \endgroup
}

% Un-brace the second argument (required because \mathpalette reads the three arguments as one
\newcommand\math@Alt[2]{\math@@Alt{#1}#2}

% Set the two arguments in boxes. The math style is given by #1. \m@th sets \mathsurround to 0.
\newcommand\math@@Alt[4]{%
  \setbox\z@ \hbox{$\m@th #1{#3}$}%
  \setbox\@ne\hbox{$\m@th #1{#4}$}%
  \@Alt{#2}%
}

% Un-brace the argument
\newcommand\make@Alt[1]{\make@@Alt#1}

% Set the two arguments into normal boxes
\newcommand\make@@Alt[3]{%
  \sbox\z@ {#2}%
  \sbox\@ne{#3}%
  \@Alt{#1}%
}

% Place one of the two boxes using \rlap and place a \phantom box with the maximum of the two boxes
\newcommand\@Alt[1]{%
  \setbox\tw@\null
  \ht\tw@\ifnum\ht\z@>\ht\@ne\ht\z@\else\ht\@ne\fi
  \dp\tw@\ifnum\dp\z@>\dp\@ne\dp\z@\else\dp\@ne\fi
  \wd\tw@\ifnum\wd\z@>\wd\@ne\dimexpr\wd\z@/2\relax\else\dimexpr\wd\@ne/2\relax\fi
  %
  \ifstrequal{#1}{l}{%
    \rlap{\iftoggle{Alt@before}{\usebox\z@}{\usebox\@ne}}%
    \copy\tw@
    \box\tw@
  }{%
    \ifstrequal{#1}{c}{%
      \copy\tw@
      \clap{\iftoggle{Alt@before}{\usebox\z@}{\usebox\@ne}}%
      \box\tw@
    }{%
      \ifstrequal{#1}{r}{%
        \copy\tw@
        \box\tw@
        \llap{\iftoggle{Alt@before}{\usebox\z@}{\usebox\@ne}}%
      }{%
      }%
    }%
  }%
}
\makeatother

与 bcat 的宏不同,我\mathpalette通过切换内部的标志来使用和避免 Martin 答案中的错误;该标志表示是否应该设置\alt的第一个或第二个参数。\Alt

这是我第一次尝试编写涉及纯 TeX 的非平凡宏,因此如果有更好的风格实践应该使用,请告诉我。

答案4

alt这里是的定义beamerbaseoverlay.sty

\def\alt{\@ifnextchar<{\beamer@alt}{\beamer@alttwo}}
\long\def\beamer@alttwo#1#2{\beamer@ifnextcharospec{\beamer@altget{#1}{#2}}{#1}}
\long\def\beamer@altget#1#2<#3>{%
  \def\beamer@doifnotinframe{#2}\def\beamer@doifinframe{#1}%
  {\beamer@masterdecode{#3}}\beamer@donow}
\long\def\beamer@alt<#1>#2#3{%
  \def\beamer@doifnotinframe{#3}\def\beamer@doifinframe{#2}%
  {\beamer@masterdecode{#1}}\beamer@donow}

奇怪的是,\uncover的定义如下\alt

\newcommand{\uncover}{\alt{\beamer@fakeinvisible}{\beamer@makecovered}}

所以我怀疑在类似 的定义中将\beamer@fakeinvisible和放在某个位置应该可以吗?但我不知道该把它放在哪里。\beamer@makeuncovered\alt

相关内容