在 beamer 中简洁地逐行查看代码的方法

在 beamer 中简洁地逐行查看代码的方法

这个问题类似于使用 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}

在此处输入图片描述

相关内容