4

I am designing a slide of Python language and I want to show the execution of algorithm step-by-step (line by line) refreshing the state of variables and simulating the output in any console (simulating a debugger tool).

My problem is that i was faced with a large algorithm that I should be split in two or more frames of beamer. My slide highlight the current line executed. Thus, I have to set in latex the number of frame and the number of line that be colorized.

When the lstlisting is too large (a lot of lines), I have to:

  1. reinsert lstlisting in a new frame (called "frame 2");

  2. set the range of remaining lines of same code that I want to show;

  3. set a line counter of code starting at a first line after the last line of a previous frame;

  4. insert a lot of commands which highlight lines of a snippet of code reinserted in a frame 2;

This way is too much expensive and make me to (roughly) copy a full code of previous frame. There's a way that I implement lstlisting for a only frame and LaTex split automatically the code among frames?

Below, my latex code (lstinputlisting is most important part).

Thanks so much in advance.

\documentclass{beamer}
\usepackage{graphicx,url}
\usepackage[brazil]{babel}   
\usepackage[utf8]{inputenc}
\usepackage{hyperref}

% A CONFIG FILE
\input{config.tex}

\definecolor{ultramarine}{rgb}{0.07, 0.04, 0.56}
\definecolor{ufop-verde}{RGB}{57, 155, 60}

% ALL PACKAGES
\usepackage{graphicx}
\usepackage{verbatim}
\usepackage{floatrow}
\usepackage{sidecap}
\usepackage{scalerel}
\usepackage{listingsutf8}
\usepackage{float}        
\usepackage{pgf, pgffor}
\usepackage{listings}
\usepackage{lstlinebgrd}
\usepackage{tcolorbox}
\usepackage{mdframed}
\usepackage{tabularx}
\usepackage{tikz}
\usepackage{color}
\usepackage{lstlinebgrd}

\newcommand{\numeroaula}{01234}


%% THIS SEQUENCE OS LINES ENABLE THE HIGHLIGHT OF SOURCE CODE INSIDE LSTLISTNGS
\makeatletter
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% \btIfInRange{number}{range list}{TRUE}{FALSE}
%
% Test in int number <number> is element of a (comma separated) list of ranges
% (such as: {1,3-5,7,10-12,14}) and processes <TRUE> or <FALSE> respectively

\newcount\bt@rangea
\newcount\bt@rangeb

\newcommand\btIfInRange[2]{%
    \global\let\bt@inrange\@secondoftwo%
    \edef\bt@rangelist{#2}%
    \foreach \range in \bt@rangelist {%
        \afterassignment\bt@getrangeb%
        \bt@rangea=0\range\relax%
        \pgfmathtruncatemacro\result{ ( #1 >= \bt@rangea) && (#1 <= \bt@rangeb) }%
        \ifnum\result=1\relax%
            \breakforeach%
            \global\let\bt@inrange\@firstoftwo%
        \fi%
    }%
    \bt@inrange%
}
\newcommand\bt@getrangeb{%
    \@ifnextchar\relax%
        {\bt@rangeb=\bt@rangea}%
        {\@getrangeb}%
}
\def\@getrangeb-#1\relax{%
    \ifx\relax#1\relax%
        \bt@rangeb=100000%   \maxdimen is too large for pgfmath
    \else%
        \bt@rangeb=#1\relax%
    \fi%
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% \btLstHL<overlay spec>{range list}
%
% TODO BUG: \btLstHL commands can not yet be accumulated if more than one overlay spec match.
% 
\newcommand<>{\btLstHL}[1]{%
  \only#2{\btIfInRange{\value{lstnumber}}{#1}{\color{orange!25}\def\lst@linebgrdcmd{\color@block}}{\def\lst@linebgrdcmd####1####2####3{}}}%
}%
\makeatother
%% THES SEQUENCE ABOVE ENABLE THE HIGHLIGHT OF SOURCE CODE INSIDE LSTLISTNGS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


\batchmode

\usepackage{amsmath,amssymb,enumerate}
\usepackage{epsfig,bbm,calc,color,ifthen,capt-of}

\usetheme{Madrid}
\usecolortheme{senac}

%-------------------------Titulo/Autores/Orientador------------------------------------------------
\title[Comando de decisão IF]{\small{BCC 701 - Programação de Computadores I}\\\LARGE{\textbf{Comando de decisão IF}}}
\date{\dataPT  -  Aula \numeroaula}
\author[DECOM]{Universidade Federal de Ouro Preto - UFOP\\Departamento de Computação - DECOM\\Material Didático Unificado\\\url{www.decom.ufop.br/bcc701}}

%-------------------------Logo na parte de baixo do slide------------------------------------------
\pgfdeclareimage[height=1.0cm]{ufop-logo}{ufop-logo.pdf}
\logo{\pgfuseimage{ufop-logo}\hspace*{0.5cm}}

%-------------------------Este código faz o menuzinho bacana na parte superior do slide------------
\iffalse
\AtBeginSection[]
{
  \begin{frame}<beamer>
    \frametitle{Outline}
    \tableofcontents[currentsection]
  \end{frame}
}
\fi
\beamerdefaultoverlayspecification{<+->}
% ------------------------------------------------------------------------------
\begin{document}
% -----------------------------------------------------------------------------

%---Gerador de Sumário---------------------------------------------------------
\frame{\titlepage}
\section[]{}
\begin{frame}{Sumário}
  \tableofcontents
\end{frame}
%---Fim do Sumário------------------------------------------------------------

% -----------------------------------------------------------------------------
\section{Exemplo (passo a passo)}
\begingroup

    %% THE MOST IMPORTANTE CODE IS BELOW.           <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    %% THE MOST IMPORTANTE CODE IS BELOW.           <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    %% THE MOST IMPORTANTE CODE IS BELOW.           <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    %% THE MOST IMPORTANTE CODE IS BELOW.           <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

%% FRAME 1
 \begin{frame}[fragile]{Exemplo (passo-a-passo)}
\vbox{
    \begin{minipage}[t][0.5\textheight][t]{\textwidth}
        %\lstinputlisting[language=Python, frame=single, linebackgroundcolor={%
        \lstinputlisting[language=Python, firstline=1, lastline=15, firstnumber=1, linebackgroundcolor={% %% HERE I SET MAX OF LINES VISIBLE IN FRAME 1 AND A FIRST NUMBER IN A COLUMN OS LINE COUNTERS
    \btLstHL<1>{1}% on slide 1, highlight lines 1-3
    \btLstHL<2>{2}% on slide 2, highlight lines 6 and 9
    \btLstHL<3,4,5>{4}% on slide 3,4,5, highlight line 4
    \btLstHL<6>{5}}% on slide 6, highlight line 5
  }]{bhaskara.py} %% THIS IS THE PYTHON CODE.
enter code here


% IF THIS PYTHON CODE IS LARGE, I HAVE TO CREATE A NEW FRAME COPYING 
% ALL LATEX CODE POSTED HERE, SET THE LINE WHERE I WANNA START PYTHON CODE 
% AND RECREATE A LIST OF \btLstHL TAGS ABOVE INSERTING THE CORRECT LINES 
% OF A SNIPPET OF CODE

\end{minipage}

    %% THE MOST IMPORTANTE CODE IS ABOVE. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% THE MOST IMPORTANTE SNIPPET IS ABOVE


    \nointerlineskip
    \begin{minipage}[b][0.5\textheight][t]{\textwidth}
        \vspace{0.4in}
        \begin{minipage}[t]{0.55\linewidth}

\end{minipage}\hfill
\begin{minipage}[t]{0.4\linewidth}

\end{minipage}
    \end{minipage}
}

\end{frame}
%% END OF FRAME 1

\endgroup


\end{document}
1
  • 2
    There is a whole bunch of stuff in your code that is not needed for this issue (only around the end do we see THE MOST IMPORTANT CODE IS BELOW). You can really trim down the example to be minimal (and working) yet still representative. And we don't even have bhaskara.py. How about reading this: I've just been asked to write a minimal example, what is that?
    – Werner
    Jun 8 '17 at 2:21
3

So what you want to do is to highlight step-by-step all lines of a code on beamer slides, and "scroll" the code according to what is your current line. Here is a very simple solution that solves this specific problem (but is not very flexible).

The idea is to have a command \mylisting that takes four arguments:

  • the slide number
  • the start and end line of the code to be displayed
  • the line number to be highlighted

The command then inserts a \lstinputlisting inside an \only with the appropriate arguments. You then simply need to put \mylisting in your frame as many times as you have lines to highlight.

At the start of the frame, you just need to redefine the commands \mycode and \mycolor to have the code to be includecd and the color for highlighting. Thus, you can use this in different frames to display different codes (if needed).

For this example, I took a sample Python code from here.

\documentclass{beamer}
\usetheme{Madrid}

\usepackage{listings}
\usepackage{lstlinebgrd}
\lstset{language=Python, numbers=left, xleftmargin=2em}

\usepackage{filecontents}
\begin{filecontents*}{\jobname.py}
import datetime

now = datetime.datetime.now()

print
print "Current date and time using str method of datetime object:"
print str(now)

print
print "Current date and time using instance attributes:"
print "Current year: %d" % now.year
print "Current month: %d" % now.month
print "Current day: %d" % now.day
print "Current hour: %d" % now.hour
print "Current minute: %d" % now.minute
print "Current second: %d" % now.second
print "Current microsecond: %d" % now.microsecond

print
print "Current date and time using strftime:"
print now.strftime("%Y-%m-%d %H:%M")
\end{filecontents*}

\def\mycode{}
\def\mycolor\color{green}
\def\mylisting<#1>#2#3#4{\only<#1>{\lstinputlisting[firstline=#2, lastline=#3, firstnumber=#2, linebackgroundcolor={\ifnum\value{lstnumber}=#4\mycolor\fi}]{\mycode}}}

\begin{document}

\begin{frame}
    \renewcommand{\mycode}{\jobname.py}
    \renewcommand{\mycolor}{\color{yellow!30!white}}
    \mylisting<1>{1}{15}{1}
    \mylisting<2>{1}{15}{3}
    \mylisting<3>{1}{15}{6}
    \mylisting<4>{5}{20}{10}
    \mylisting<5>{5}{20}{11}
    \mylisting<6>{5}{20}{12}
\end{frame}

\end{document}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.