4

Thanks to Marc van Dongen there is a template of a "step by step" programming tutorial (with a sample layout in his question): How to create step by step annotated programming tutorial in LaTeX? .

I wonder if it is possible to achieve similar functionality with source highlighting ?

Simply changing environment from semiverbatim to lstlisting , does not work (as is easy to guess).

%Generate with : `pdflatex filename`
\documentclass{beamer}
\usepackage{listings}
\lstset{
    language=C++,
    basicstyle=\small,
    numbers=left,
    numberstyle=\tiny\color{gray},
}
\begin{document}
\begin{frame}[fragile]%
%\begin{semiverbatim}
\begin{lstlisting}[language=C++,caption={C++ as C++ TexTests},label=cppascpptextests]
\only<1-2>{\frametitle{General program structure}}
\only<3>{\frametitle{Variables}}
\only<4>{\frametitle{Reading numbers from standard input}}
\only<5>{\frametitle{Printing results on standard output}}
\only<6>{\frametitle{Assigning results of computation}}
\only<7>{\frametitle{Working example :)}}
\only<8>{\frametitle{Enjoy programming :)}}
\only<4>{(4)How to include needed header file?}\only<5->{\#include <cstdio>}
\only<1>{(1) How to construct main function ?}\only<2->{int main() \{}
   \only<3>{(3) How to declare variables?}\only<4->{long a,b,c;}
   \only<4>{(4) How to read data?}\only<5->{scanf("\%ld\%ld", \&a, \&b);}
   \only<6>{(6) How to compute result?}\only<7->{c = a * b;}
   \only<5>{(5) How to print result?}\only<6->{printf("\%ld\textbackslash n", c);}
   \only<2>{(2) How to exit program correctly?}\only<3->{return 0;}
\only<2->{\}}
\end{lstlisting}
%\end{semiverbatim}
\end{frame}

\end{document}
5
  • Not yet the time for a real answer: The general advice here is to use the escapechar= option in your listing settings to escape to LaTeX inside the listing. This can be used to bring in the \only commands. The problem is, though, that the stuff inside the LaTeX code does not get syntax highlighting. A more elegant way is to use moredelims= to hide this stuff in a listings style, take tex.stackexchange.com/a/18266/3751 for an inspiration.
    – Daniel
    Feb 19, 2012 at 8:59
  • (Continued...) The tricky part in your case is that you do not only want lines of your listing to appear and disappear, but want the comments to be replaced. I might be a lot easier if the comments could remain (e.g., by turning them to EOL-Comments, like long a,b,c; // (3) How to declare variables?) with the comment being allowed to stay after slide 3.
    – Daniel
    Feb 19, 2012 at 9:04
  • @Daniel - Questions can be as comments, and other modifications are welcome. Above example is idea, about general shape. What about possible solutions - the idea that come to my mind is to get whole source code listed, and then to hide lines and program fragments by painting on them with rectangles of color of background. However, I have no idea how to do this. Feb 19, 2012 at 9:26
  • Please don't get me wrong but you are only a little far from including all into seperate frames and using the power of lstlistings independently.
    – percusse
    Feb 19, 2012 at 13:40
  • Grzegorz: If the given answer has solved your problem, please consider accepting it. If not, you might want to update your MWE to show the particular deficiencies, so the community could improve the answer.
    – Daniel
    Mar 14, 2012 at 8:03

1 Answer 1

3

The following is a possible solution approach for combining beamer overlays with lstlisting:

\documentclass{beamer}
\usepackage{listings}
\usepackage{beramono}
\usepackage{pgf,pgffor}
\lstset{
    language=C++,
    basicstyle=\small,
    numbers=left,
    numberstyle=\tiny\color{gray},
}

\lstdefinestyle{highlight}{
  keywordstyle=\bfseries,
}
\lstdefinestyle{base}{
  language=C++,
  basicstyle=\color{white},
  keywordstyle=\color{white},
  commentstyle=\sffamily\scriptsize\color{white},
  moredelim=**[is][\only<1->{\color{black}\lstset{style=highlight}}]{@1}{@},
  moredelim=**[is][\only<2->{\color{black}\lstset{style=highlight}}]{@2}{@},
  moredelim=**[is][\only<3->{\color{black}\lstset{style=highlight}}]{@3}{@},
  moredelim=**[is][\only<4->{\color{black}\lstset{style=highlight}}]{@4}{@},
  moredelim=**[is][\only<5->{\color{black}\lstset{style=highlight}}]{@5}{@},
  moredelim=**[is][\only<6->{\color{black}\lstset{style=highlight}}]{@6}{@},
  moredelim=**[is][\only<7->{\color{black}\lstset{style=highlight}}]{@7}{@},
  moredelim=**[is][\only<8->{\color{black}\lstset{style=highlight}}]{@8}{@},
  moredelim=**[is][\only<9->{\color{black}\lstset{style=highlight}}]{@9}{@},
  texcl=true,escapebegin=\hskip-6cm\color{red}
}


\begin{document}
\begin{frame}[fragile]%

  \foreach \o/\t in {%
    1-2/{General program structure},
    3/{Variables},
    4/{Reading numbers from standard input}
  }{
    \only<\o>{\expandafter\frametitle\expandafter{\t}}%
  }

\begin{lstlisting}[style=base,caption={C++ as C++ TexTests},label=cppascpptextests]
  @2int main() {@            // \only<1>{(1) How to construct main?}
    @4long a,b,c;@           // \only<3>{(3) How to declare variables?}
    @5scanf("%ld%ld",&a,&b);@// \only<4>{(3) How to read data?}
    @3return 0;@             // \only<2>{(2) How to exit correctly?}
  @3}@  
\end{lstlisting}
\end{frame}

\end{document}

Remarks:

I took the freedom to simplify your \frametitle specifications using a \foreach loop from the pgffor package. However, that is not the point here. The main idea is to have two different listing styles.

  • Style base basically "hides" the listing by rendering all elements in white.
  • Style highlight applies the real formatting.
  • The trick is then to use the moredelim option of lstlisting to inject the style highlight only on given slides. Unfortunately it is not possible to pass an argument to moredelim, so I defined a series of delimiters @1, @2 and so on.

For the "comments" I use another trick. The comments are always rendered in white (which is the reason you cannot see the comment delimiters //), but use the texcl option to automatically escape to LaTeX for the content of the comment. As we are in LaTeX land after the //, we can use \only<> to implement the overlay specifications. With escapebegin we give additional commands that are inserted by lstlisting before typesetting the comment contents. Here, I also use it to (kind of brutally) move the insertion position to the left, so that the comment appears close to the begin of the source line.

Outcome:

enter image description here

enter image description here

5
  • Hello. Look great ! I believe it will save a lot of my lifetime :). One more thing : here we see "?" of whole lines, what about parts of line ? Is it possible to do sequence like: int main( ??, ?? ){ -> int main(int argc, ??){ -> int main(int argc, char **argv}{. If it would need complete rebuild of your solution, please leave it as it is -> short&sweet :). If it's just another "trick" to do and you have an idea, please share it :). Feb 21, 2012 at 8:32
  • (P.S. I need a little bit of time to understand this, so I need time to decide whether is to "solution") Feb 21, 2012 at 22:46
  • @GrzegorzWierzowiecki: Thats perfectly okay; you should also allow some time for other answers to show up – early acceptance of the only answer might demotivate other potential contributors and their solutions might be better. (I usually wait a week or so before accepting some answer).
    – Daniel
    Feb 22, 2012 at 8:43
  • I encountered problem with your solution. When sum of lengths of code line and comment is longer then width of slide, line gets broken and comment appears in next line, instead of the same. Any clue how to fix it ? Mar 5, 2012 at 10:47
  • @GrzegorzWierzowiecki: Please update your question with a MWE that demonstrates this particular problem.
    – Daniel
    Mar 5, 2012 at 11:20

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