26

Problem

I want to explain C# programming language step by step using overlay in beamer.cls. But it does NOT works as shown in the following figure.

How to solve this problem?


Code Snippet

\documentclass[dvipsnames,cmyk]{beamer}

\usepackage{listings}

\begin{document}

\defverbatim[colored]\Lst{%
\begin{lstlisting}[language={[Sharp]C}]
using System;
public delegate void Foo(object o);
\uncover<1>{public class Foo}
\uncover<2>{\{}
\uncover<3>{public static void Main()}
\end{lstlisting}}

\begin{frame}{MyListing}
\Lst
\end{frame}

\end{document}
Joseph Wright
  • 259,911
  • 34
  • 706
  • 1,036
Display Name
  • 46,933

3 Answers3

47

Even though xpert has already accepted the (frequently given) "use semiverbatim" answer by Herbert, I would like to present my listings-only solution here as well – for those like Tobi, who do not want to give up on syntax coloring and all the other cool features of the listings package.

The first thing to do (similar to Herbert's solution) is to not use beamer's \defverbatim, but to embed the listings inside the frame using the [fragile] option. (The whole point of \defverbatim is that the content is expanded before \begin{frame}, hence overlay specifications just don't work.)

The trick is then to use the moredelim style option of listings to inject the overlay-command into the listing:

\documentclass[dvipsnames,cmyk]{beamer}
\usepackage{listings}
\lstloadlanguages{[Sharp]{C}}

\lstdefinestyle{base}{
  language=[Sharp]{C},
  moredelim=**[is][\only<+>{\color{red}}]{@}{@},
}

\begin{document}

\begin{frame}[fragile]{MyListing 1}
  \begin{lstlisting}[style=base, gobble=4]
    using System;
    public delegate void Foo(object o);
    @public class Foo@
    @{@ 
    @  public static void Main()@
    @}@
  \end{lstlisting}
\end{frame}
\end{document}

Note that I'am using \only instead of \uncover, as the formatting given by \moredelim** is applied additionally to all other formattings of the current line, which means that \uncover has basically no effect here.

To achive not only highlighting of the current line, but also "dimming" of the remaining parts (as in Tobi's solution), we have to play a bit more around with listing styles. The idea is to have one style (base) that renders the listing "dimmed" and another one (highlight) that is applied on top of it in the \moredelim command (using \lstset) to remove the "dimming" for the current line. This works for all style elements, but basicstyle, so we apply the "nondimmed"-version of basicstyle (which here is \color{black}) manually in the moredelim command:

\lstdefinestyle{highlight}{
  keywordstyle=\color{red},
  commentstyle=\color{green},
}
\lstdefinestyle{base}{
  language=[Sharp]{C},
  basicstyle=\color{black!40},
  keywordstyle=\color{red!40},
  commentstyle=\color{green!40},
  moredelim=**[is][\only<+>{\color{black}\lstset{style=highlight}}]{@}{@},
}

\begin{frame}[fragile]{MyListing 2}
  \begin{lstlisting}[style=base, gobble=4]
    using System;
    public delegate void Foo(object o);
    @public class Foo@
    @{@ 
    @  public static void Main()@
    @}@
  \end{lstlisting}
\end{frame}

enter image description here

Daniel
  • 37,517
  • Seems to be a very good idea :-) I’ll keep it in mind. But why don’t you add basicstyle=\color{black} to higlight-style and remove \color{black} from the moredelim-line? – Tobi May 15 '11 at 12:35
  • @Tobi: As explained above (albeit not very clear...) some listing styles apparently cannot be changed "in the middle" of an listing, among them basicstyle and backgroundcolor. Putting them into 'highlight` has just no effect. – Daniel May 15 '11 at 13:25
26

use the semiverbatim environment, it is more flexible in this case. Here is an example how I did it some time ago:

\documentclass{beamer}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage[utf8]{inputenc}

\begin{document}
\begin{frame}[fragile]{Matrixoperationen}{Benutzung von \texttt{semiverbatim}}
\setbeamercolor{alerted text}{fg=blue}
\setbeamerfont{alerted text}{series=\bfseries,family=\ttfamily}
\begin{semiverbatim} \small
\uncover<1->{\alert<0>{\alert<6>{sub \color{red}matrix_row2vector} \{}}
\uncover<2->{\alert<2>{  my $m = shift;    my($rows,$cols) = ($m->[1],$m->[2]);}}
\uncover<2->{\alert<2>{  my $r = shift;   # optional, which column from matrix}}
\uncover<2->{\alert<2>{  croak "Error: matrix hasn't 3D rows" unless ($colsRun also:>{}>3);}}
\uncover<3->{\alert<3>{  if ( defined $r ) \{}}
\uncover<3->{\alert<3>{    croak "Error: matrix hasn't that row" unless ($r < $rows);}}
\uncover<3->{\alert<3>{  \}}}
\uncover<4->{\alert<4>{  else \{}}
\uncover<4->{\alert<4>{    croak "Error: matrix is not a 3D row matrix"}}
\uncover<4->{\alert<4>{           unless ($rowsRun also: >>  1);}}
\uncover<5->{\alert<5>{    $r = 0;}}
\uncover<4->{\alert<4>{  \}}}
\uncover<6->{\alert<6>{  return Math::VectorReal->%
\alert<6>{\color{red}new(@\{$m->[0][$r]\})};}}
\uncover<1->{\alert<1>{\}}}
\end{semiverbatim}

\visible<6>{Beachte den Gebrauch von \alert{\color{red}\texttt{shift}}.}
\end{frame}
\end{document}

If you have a lot of TeX code to show then define something like

\def\Lcs#1{\textbackslash#1}

then it easier to write something like \Lcs{newpage}.

  • 1
    Hi, does anybody know how to use lstlisting to get syntaxhighlighting? – Tobi Apr 26 '11 at 19:20
  • @Tobi: That should have been posted as a fresh question. Buried here in a comment, almost no-one will see it. – Andrew Stacey May 12 '11 at 18:23
  • 1
    @Andrew. Thanks. I would have made an extra question but it wasn’t so important for me. I “solved“ the problem with semi transparent overlay (TikZ) so that I can focus a snippet while keeping the whole code visible. I thinks this is even better than view the code line by line. If someone likes I can make an example as another answer to this question – Tobi May 12 '11 at 18:34
  • 1
    @Tobi: Post it. Sounds useful (I can imagine uses for that in mathematical lectures too). – Andrew Stacey May 12 '11 at 18:38
  • @Andrew: So should I post it here or would you like to ask a new question? – Tobi May 12 '11 at 20:14
  • @Tobi: Post it here. It fits here. (I'd also like to take this opportunity to apologise to Herbert for cluttering up his inbox with irrelevant comments! - Irrelevant to his answer, that is. Tobi, if there's anything more you wish to say or ask on this, we should continue in the chat room.) – Andrew Stacey May 12 '11 at 20:22
  • @Tobi: That is an impressive amount of TikZ hacking - I have learned a thing or two from it! However, for the original purpose it might be a bit over-engineered :-) See my solution below. – Daniel May 15 '11 at 10:22
17

As requested my answer about using TikZ with semi transparent overlays.

Code

\documentclass[handout]{beamer}

% basic packages
\usepackage[latin1]{inputenc}
\usepackage[T1]{fontenc}

% load TikZ to draw the heighlighting areas
\usepackage{tikz}
    \usetikzlibrary{fit,calc,decorations.pathreplacing}
    \newcommand{\tikzref}[1]{% to define an anchor
        \tikz[remember picture]{%
            \coordinate (#1) at (0,0.5ex);%
        }%
    }
    \tikzset{
       transp/.style={
          fill opacity=0.75,fill=white, inner sep=1.5mm,
       },
       reverseclip/.style={
          insert path={(current page.north east) --
            (current page.south east) --
            (current page.south west) --
            (current page.north west) --
            (current page.north east)},
       },
    }

% use listings to show an example how to heighlight code
\usepackage{listings}
    \lstloadlanguages{[LaTeX]TeX}
    \lstset{% 
        language=[LaTeX]TeX, 
        basicstyle=\ttfamily,
        keywordstyle={},
        escapechar={§},% needed to set tikz anchors in listings
    }


\begin{document}

% EXAMPLE A
\begin{frame}{Heighlighting parts of an equation}
% 1.  Set the equation as usual. Add anchors with \tikzmark at the beginning and
%     end of the formular, named bmath and emath in this example, and at the
%     beginning and end of the part you want to heighlight, named bfrac and efrac.
\[
    \tikzref{bmath}f(x) =
        \left(2x^4 + \tikzref{bfrac}\frac{3x^3}{4m}\tikzref{efrac}+
        7x+\pi\right)\cdot\frac{\alpha}{2\gamma\varepsilon_0}\tikzref{emath}
\]
% 2.  Add the code to highlight
% 2.1 The {tikzpicture} shouldn't take space on the frame but 'overlay' it and
%     we make the \tikzref anchors acessible via 'remember picture'.
\begin{tikzpicture}[overlay, remember picture]
% 2.2 Draw the frame around the part that should be heighlighted, i.e. not coverd
%     by the semi-transparent overlay. This path has the 'clip' option meaning
%     that all following path are clipped by that.
    \path [clip] % [A, see Notes]
        ($(bfrac) - (0,5mm)$) -- %
        ($(efrac) - (0,5mm)$) -- %
        ($(efrac) + (0,5mm)$) -- %
        ($(bfrac) + (0,5mm)$) --%
        cycle
         [reverseclip];
% 2.3 Add the semi-transparent overlay to cover the whole equation.
    \node [transp,fit={($(bmath)+(0,5mm)$) ($(emath)-(0,5mm)$)}] {};
\end{tikzpicture}
\end{frame}

% EXAMPLE B
\begin{frame}[fragile]{Heighlighting parts of a code example}
% 1.  Set the code environment as usual and add \tikzref anchors. Here § is used
%     to escape from vermatim back to LaTeX.
    \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
        §\tikzref{z1}§\documentclass[ngerman,11pt]{scrartcl}
        \usepackage[T1]{fontenc}
        \usepackage[latin1]{inputenc}
        \usepackage{babel}
        §\tikzref{z5}§\usepa§\tikzref{pkgcmd}§ckage{list§\tikzref{pkg}§ings}§\tikzref{lst}§
        §\tikzref{z6}§    \lstset{basicstyle=\ttfamily}§\tikzref{lstset}§
        §\tikzref{z7}§    \lstMakeShortInline|§\tikzref{svrb}§
        §\tikzref{z8}§\begin{document}
        Eine \emph{Auszeichnung} und 
        §\tikzref{bvrb}§|verb§\tikzref{verb}§atim|-Text§\tikzref{evrb}§ enthält.
        \dots und eine {unbedeutende Gruppe}.
        % Kommentare erscheinen nicht in der Ausgabe§\tikzref{txt}§
        §\tikzref{z15}§\end{document}
    \end{lstlisting}
% 2.  Add the {tikzpicture} to draw the heiglighting (see example A).
    \begin{tikzpicture}[overlay, remember picture]
        % clipping:
        \begin{scope}% [B, see Notes]
            % cut out 1
            \path [clip] let \p1=(z5), \p2=(z7), \p3=(lstset) in%
                ($(z8) + (0,1ex)$) %
                -- ++(\x3-\x1,0) %
                -- ++($(0,0) + (0,2ex) + (0,\y1-\y2)$)
                -- ++(\x1-\x3,0) %
                -- cycle [reverseclip];
            % cut out 2
            \path [clip] %
                ($(bvrb) - (0,1ex)$) %
                -- ($(evrb) - (0,1ex) $) %
                -- ($(evrb) + (0,1ex) $) %
                -- ($(bvrb) + (0,1ex)$) %
                -- cycle [reverseclip];
            % clip everything without cutted areas
            \node [transp,fit=(z1) (z15) (txt)] {};
        \end{scope}
% 3.  Add some additional text annotations using 'nodes' and the \tikzref anchors.
        \def\ddx{0.15}\def\ddy{1ex}\def\dx{0.7}
        \draw<2-> [<-] ($(lst) + (\ddx,0)$) -- +(\dx,0) node [right, anchor=mid west] {load};
        \draw<3-> [<-] ($(lstset) + (\ddx,0)$) -- +(\dx,0) node [right, anchor=mid west] {mono font};
        \draw<4-> [<-] ($(svrb) + (\ddx,0)$) -- +(\dx,0) node [right, anchor=mid west] {short verb};
        \draw<5-> [<-] ($(verb) + (0,-\ddy)$) |- +(0.3,-0.5) node [right, anchor=mid west] {example};
    \end{tikzpicture}
\end{frame}

\end{document}

Output

output


Notes

  • To get a semi transparent overlay with some cut out areas, I lay a node above the whole relevant part of a frame and clip this. The needed reveseclip-Option was created by Jake at How can I invert a 'clip' selection within TikZ?.

  • While designing this example I’ve found out that the direction of drawing clip path [A] is relevant so try drawing path (counter) clockwise if it doesn’t work.

  • Note that TikZ needs two runs of (pdf)LaTEX to get the right positions.

  • In some cases [B] it seems to be a good idea to limit the clipping to a {scope} to make other drawings which are not effected by it.

  • A problem might be that we need to contaminate the original listing code with the §\tikzref{…}§. Maybe someone has an idea how to export adjusted listing automatically?

Tobi
  • 56,353
  • I just used this idea to make different parts of a slide stand-out at different times. So I was right to get you to post this code! – Andrew Stacey May 23 '11 at 11:25
  • @Tobi can you please post a simpler example? How to animate this in multiple places? – ATOzTOA Mar 02 '13 at 10:37
  • @ATOzTOA: Can you explain, why you need one? I can’t see many options to simplify my example. At least the second frame “Math” contains an easy example I guess. just ignore the first frame … If you tell me what you don’t understand I’ll add more information and appropriate examples. – Tobi Mar 06 '13 at 16:46
  • @Tobi Wow, sorry.... i get it now... kool... – ATOzTOA Mar 06 '13 at 17:50
  • @ATOzTOA: No problem. Your welcome to ask if you got problems with my example ;-) – Tobi Mar 06 '13 at 17:57
  • It is sad the code is hard to make sense for a new comer. :-/ It is amazing how hard it gets from the \step to this case where we want to highlight different portions over different slides :-( – Oeufcoque Penteano Nov 22 '13 at 05:28
  • @OeufcoquePenteano: I’m not sure what you want to cause with your comment ;-) I added some more information/explanation to my code but I think it's not reasonable to add explanations going back to Adam and Eva. If you don't understand a (more or less) specific part of code first try to find an answer in the manual of used packaged and then ask a specific question in a comment and we'd be happy to help further ;-) – Tobi Nov 22 '13 at 10:20
  • Sorry Tobi, was just slight frustrated on Latex :-( In any case, I found out that by deleting the text and leaving empty spaces I could fake your approach. Not as neat as leaving the text faded, but works for a newbie like myself. Thanks for adding more comments, and yes I agree you cant go explaining every single detail! – Oeufcoque Penteano Nov 23 '13 at 11:24