![仅限、发现和可见的 Beamer 覆盖代码块内的命令](https://linux22.com/image/468948/%E4%BB%85%E9%99%90%E3%80%81%E5%8F%91%E7%8E%B0%E5%92%8C%E5%8F%AF%E8%A7%81%E7%9A%84%20Beamer%20%E8%A6%86%E7%9B%96%E4%BB%A3%E7%A0%81%E5%9D%97%E5%86%85%E7%9A%84%E5%91%BD%E4%BB%A4.png)
我想在演示文稿中使用 Beamer 的覆盖图在 Minted 代码块中解释一段复杂的 LaTeX 代码。我发现现有的解决方案不够完善,主要有两个问题:
- 我需要非线性地揭示代码,因此简单的
\pause
s 是不够的 - 我不希望代码逐行显示,但有时也只希望显示部分代码,因此我无法将代码块拆分成多个不同的铸造块
为了简单起见,这有点像我想要解释的复杂代码(真正的块有点长):
Let \(x,y \in \mathbb{R}\).
\begin{align*}
x + y &= y + x\\
&= x + y
\end{align*}
这就是我想要显示代码的方式:
Let \(x,y \in \mathbb{R}\).
\uncover<2->{\begin{align*}}
\uncover<3->{x + y} \uncover<4->{&= y + x\\}
\uncover<5->{&= x + y}
\uncover<2->{\end{align*}}
(请注意,此代码本身实际上不会编译,但我想演示逐字代码显示的顺序)
我尝试了以下方法:
\documentclass{beamer}
\usepackage{minted}
\setminted{autogobble=true}
\begin{document}
% approach 1
\begin{frame}[fragile]{\LaTeX{} Example}
\begin{minted}[escapeinside=||,beameroverlays=true]{latex}
Let \(x,y \in \mathbb{R}\).
|\uncover<2->{|\begin{align*}|}|
|\uncover<3->{|x + y|}| |\uncover<4->{|&= y + x\\|}|
|\uncover<5->{|&= x + y|}|
|\uncover<2->|\end{align*}|}|
\end{minted}
\end{frame}
% approach 2
\begin{frame}[fragile]{\LaTeX{} Example}
\begin{minted}[escapeinside=||,beameroverlays=true]{latex}
Let \(x,y \in \mathbb{R}\).
|\uncover<2->{\begin{align*}}|
|\uncover<3->{x + y}| |\uncover<4->{&= y + x\\}|
|\uncover<5->{&= x + y}|
|\uncover<2->{\end{align*}}|
\end{minted}
\end{frame}
% approach 3
% same as appraoch 2, but this time with \mintinline inside the escaped blocks
\begin{frame}[fragile]{\LaTeX{} Example}
\begin{minted}[escapeinside=||,beameroverlays=true]{latex}
Let \(x,y \in \mathbb{R}\).
|\uncover<2->{\mintinline{latex}{\begin{align*}}}|
|\uncover<3->{\mintinline{latex}{x + y}}| |\uncover<4->{\mintinline{latex}{&= y + x\\}}|
|\uncover<5->{\mintinline{latex}{&= x + y}}|
|\uncover<2->{\mintinline{latex}{\end{align*}}}|
\end{minted}
\end{frame}
% appraoch 4
\begin{frame}[fragile]{\LaTeX{} Example}
\begin{minted}[escapeinside=||,beameroverlays=true]{latex}
Let \(x,y \in \mathbb{R}\).
|\onslide<2->|\begin{align*}
|\onslide<3->|x + y |\onslide<4->|&= y + x\\
|\onslide<5->|&= x + y
|\onslide<2->|\end{align*}
\end{minted}
\end{frame}
\end{document}
方法 1 和 2 可以编译,但会出现错误,并且无法获得预期结果。方法 3 根本无法编译。方法 4 可以编译并获得预期结果。
显然,方法 4 是可行的,但我发现它相当丑陋。\onslide
在没有给出文本的情况下使用变体会导致代码块后面的所有内容出现问题。例如,当\onslide<2->
放入tcolorbox
环境中时,由于某种原因,beamer 的脚注线在第一张幻灯片中会变得不可见(请注意,可以通过\onslide<1->
在 minted 块后插入来修复此问题)。此外,虽然可以使用\onslide
切换到命令的等效项,但不能切换到 的等效项。在这种情况下,我不需要命令,但如果我需要,方法 4 将不起作用。\visible
\onslide+
\only
\only
方法 1 可能不起作用,因为转义块都是单独处理的。方法 2 无论如何都不会给出所需的结果,因为转义块内的所有内容都将呈现为普通 LaTeX,而不是逐字呈现。因此,我尝试使用\mintinline
方法 3 将它们包装到命令中,但为什么无法编译对我来说绝对是个谜。坦率地说,我不明白方法 3 的 LaTeX 错误消息。我认为,即使方法 3 可以编译,它仍然会导致问题,因为每个转义部分都将被视为自己的 LaTeX 代码,这可能会弄乱上下文相关的突出显示。
方法 4 是仅有的实现我想要的方法?如果我真的想要一个\only
命令,我该怎么办?显然,您可以随时复制整个代码块,无论您需要多少次,然后使用onlyenv
,但这是一个相当肮脏的解决方案(实际上会导致代码块大小不一致)。有没有其他方法可以在铸造的代码块中使用\uncover
(以及\only
和)?\visible
答案1
您无法单独转义参数的开始和结束。\onslide
对于您的用例,我会使用及其变体。
另外,您可以使用 tikzmarks 库来标记代码中元素的开始和结束,然后在适当的覆盖层上使用背景颜色的矩形覆盖各个部分。
% !TeX program = txs:///arara
% arara: pdflatex: {synctex: on, interaction: nonstopmode, shell: yes}
\documentclass{beamer}
\usepackage{minted}
\setminted{autogobble=true}
\usepackage{tikz}
\usetikzlibrary{tikzmark}
\begin{document}
\begin{frame}[fragile]{\LaTeX{} Example}
\begin{minted}[escapeinside=||]{latex}
LLet \(x,y \in \mathbb{R}\).
|\tikzmark{bar}|\begin{align*}|\tikzmark{foo}|
\end{minted}
\begin{tikzpicture}[remember picture,overlay]
\fill<-2>[bg] ([yshift=-1ex]pic cs:bar) rectangle ([yshift=2ex]pic cs:foo);
\fill<3-4>[bg,opacity=0.85] ([yshift=-1ex]pic cs:bar) rectangle ([yshift=2ex]pic cs:foo);
\end{tikzpicture}
\pause[5]
\end{frame}
\end{document}