这个问题类似于使用 Beamer 逐步执行用伪代码编写的算法。但并不局限于任何特定的环境。我更喜欢 minted,但任何其他可以实现我想要的类似环境都是可以接受的。
我想在双列框架上逐步执行 Beamer 中的算法。左列应突出显示当前行,右列应显示执行状态。MWE:
\documentclass{beamer}
\usepackage{minted}
\setminted[python]{autogobble}
\begin{document}
\begin{frame}[fragile]{Running code}
\begin{columns}
\begin{column}{0.50\textwidth}
\begin{overprint}
\onslide<1>
\begin{minted}[highlightlines={1}]{python}
N = 5
i = 0
lst = []
while i < N:
lst.append(i)
i = i + 1
\end{minted}
\onslide<2>
\begin{minted}[highlightlines={2}]{python}
N = 5
i = 0
lst = []
while i < N:
lst.append(i)
i = i + 1
\end{minted}
\onslide<3>
\begin{minted}[highlightlines={3}]{python}
N = 5
i = 0
lst = []
while i < N:
lst.append(i)
i = i + 1
\end{minted}
\onslide<4>
\begin{minted}[highlightlines={4}]{python}
N = 5
i = 0
lst = []
while i < N:
lst.append(i)
i = i + 1
\end{minted}
\end{overprint}
\end{column}
\begin{column}{0.50\textwidth}
Defined variables here and explanations of the highlighted line,
etc.
\end{column}
\end{columns}
\end{frame}
\end{document}
虽然上述方法“有效”,但它并不实用,因为它会导致过多的代码膨胀。有没有更好的方法?像这样的方法就很好:
\begin{minted}[highlighted_line_on_beamer_slide={1,2,3,4,5,6,4,5,6,4,5,6}]{python}
N = 5
i = 0
lst = []
while i < N:
lst.append(i)
i = i + 1
\end{minted}
答案1
您可以使用lstlinebgrd
软件包(带有来自https://tex.stackexchange.com/a/451538/36296)
\documentclass{beamer}
\usepackage{listings}
\makeatletter
\let\old@lstKV@SwitchCases\lstKV@SwitchCases
\def\lstKV@SwitchCases#1#2#3{}
\makeatother
\usepackage{lstlinebgrd}
\makeatletter
\let\lstKV@SwitchCases\old@lstKV@SwitchCases
\lst@Key{numbers}{none}{%
\def\lst@PlaceNumber{\lst@linebgrd}%
\lstKV@SwitchCases{#1}%
{none:\\%
left:\def\lst@PlaceNumber{\llap{\normalfont
\lst@numberstyle{\thelstnumber}\kern\lst@numbersep}\lst@linebgrd}\\%
right:\def\lst@PlaceNumber{\rlap{\normalfont
\kern\linewidth \kern\lst@numbersep
\lst@numberstyle{\thelstnumber}}\lst@linebgrd}%
}{\PackageError{Listings}{Numbers #1 unknown}\@ehc}}
\makeatother
\makeatletter
\newcommand*{\slideinframe}{\number\beamer@slideinframe}
\makeatother
\begin{document}
\begin{frame}[fragile]
\begin{lstlisting}[%
language=python,
linebackgroundcolor={%
\ifnum\slideinframe=\value{lstnumber}\color{red}\fi
},
escapechar=@
]
N = 5
i = 0
lst = []
while i < N:
lst.append(i)
i = i + 1 @\pause[\value{lstnumber}]@
\end{lstlisting}
\end{frame}
\end{document}
为了多次显示 while 循环,你可以使用\againframe
宏:
\documentclass{beamer}
\usepackage{listings}
\makeatletter
\let\old@lstKV@SwitchCases\lstKV@SwitchCases
\def\lstKV@SwitchCases#1#2#3{}
\makeatother
\usepackage{lstlinebgrd}
\makeatletter
\let\lstKV@SwitchCases\old@lstKV@SwitchCases
\lst@Key{numbers}{none}{%
\def\lst@PlaceNumber{\lst@linebgrd}%
\lstKV@SwitchCases{#1}%
{none:\\%
left:\def\lst@PlaceNumber{\llap{\normalfont
\lst@numberstyle{\thelstnumber}\kern\lst@numbersep}\lst@linebgrd}\\%
right:\def\lst@PlaceNumber{\rlap{\normalfont
\kern\linewidth \kern\lst@numbersep
\lst@numberstyle{\thelstnumber}}\lst@linebgrd}%
}{\PackageError{Listings}{Numbers #1 unknown}\@ehc}}
\makeatother
\makeatletter
\newcommand*{\slideinframe}{\number\beamer@slideinframe}
\makeatother
\begin{document}
\begin{frame}[label=foo,fragile]
\begin{lstlisting}[%
language=python,
linebackgroundcolor={%
\ifnum\slideinframe=\value{lstnumber}\color{red}\fi
},
escapechar=@
]
N = 5
i = 0
lst = []
while i < N:
lst.append(i)
i = i + 1 @\pause[\value{lstnumber}]@
\end{lstlisting}
\end{frame}
\againframe<4->{foo}
\againframe<4->{foo}
\againframe<4->{foo}
\againframe<4->{foo}
\end{document}