1

This question is similar to Using Beamer to step through an algorithm written in pseudocode. but not tied to any particular environment. I prefer minted, but any other similar environment that can accomplish what I want is acceptable.

I want to step through an algorithm in beamer on a two-column frame. The left column should highlight the current line and the right column should show the execution state. 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}

While the above method "works", it is unpractical because it causes way too much code bloat. Is there a better method? Something like this would be nice:

\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 Answer 1

2

You could use the lstlinebgrd package (with a patch from 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}

enter image description here

For showing the while loop multiple times, you could use the \againframe macro:

\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}

enter image description here

3
  • Can you get the while loop to run multiple times? Feb 1, 2023 at 18:12
  • @BjörnLindqvist See my edit Feb 1, 2023 at 19:18
  • This is quite nice but the idea is that I have a two-column layout with the code in one column and the execution state in the other. I don't think \againframe works for this purpose since the execution state will be different the next time a particular line in a loop is executed. Feb 16, 2023 at 14:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .