Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I want to highlight some portion of my pseudo codes in my slides during the course of presentation. It's easy in powerpoint and I've made a sample slide:

enter image description here

However, I couldn't manage to get a similar effect with beamer, tikz and algorithm2e package.

So far, I've defined the following command.

\newcommand<>{\myspot}[1]
{
\begin{tikzpicture}
        \node[draw=none,inner sep=0cm] (n1)
        {
            #1
        };
    \uncover#2{
        \draw (n1) node[rectangle,inner sep=0cm, fill=yellow] (n2)
        {
            #1
        };
    }
    \end{tikzpicture}
}

It is very useful, but can only highlight a single line in my code.

\myspot<2>{
$pseudo_code here$
}

How can I make a similar effect shown in the sample slide by using beamer?

share|improve this question
add comment

1 Answer

Use \tikzmark to place auxiliary nodes and the fit library, together with the remember picture, overlay options to place the shadings. A little example:

\documentclass{beamer}
\usepackage[ruled,vlined,linesnumbered]{algorithm2e}
\usepackage{tikz}
\usetikzlibrary{fit,calc}

\newcommand{\tikzmark}[1]{%
  \tikz[overlay,remember picture,baseline] \node [anchor=base] (#1) {};}

\definecolor{mybrown}{RGB}{255,218,195}
\definecolor{myframe}{RGB}{197,122,195}

\begin{document}

\begin{frame}

\begin{columns}
\column{.4\textwidth}
\onslide<2->{
\setlength\fboxsep{6pt}%
\framebox{\begin{tikzpicture}[x=0.8cm,init/.style={circle,fill=green!60!black,inner sep=2pt},
tran/.style={circle,fill=magenta!60!black,inner sep=3pt}]
\node<1,2,3>[init] at (0,0) (p) {};
\node<4>[tran] at (0,0) (p) {};
\node[init] at (1,-1) (q) {};
\node[init] at (3,-1) (r) {};
\node<1,2,4>[init] at (2.5,-2) (s) {};
\node<3>[tran] at (2.5,-2) (s) {};
\node[init] at (3.5,-3) (t) {};
\draw[blue] (p) -- (q) -- (r)  -- (s);
\draw[blue] (r) -- (t);
\end{tikzpicture}}
}

\column{.6\textwidth}
\begin{algorithm}[H]
\SetKwData{Left}{left}\SetKwData{This}{this}\SetKwData{Up}{up}
\SetKwFunction{Union}{Union}\SetKwFunction{FindCompress}{Find}
\SetKwInOut{Input}{input}\SetKwInOut{Output}{output}

\For{$i\leftarrow 2$ \KwTo $l$}
{
\emph{special treatment of $i$}\;
\For{$j\leftarrow 2$ \KwTo $w$}{\label{forins}
\Left$\leftarrow$ \FindCompress{$Im[i,j-1]$}\;
\tikzmark{a}\If(\tcp*[h]{}){\Left compatible \This}{\label{lt}
\lIf{\Left $<3$}{\Union{\Left}}\;
\lElse{\Union{\This,\Left}\tikzmark{b}\;}
}
\tikzmark{c}\If(\tcp*[h]{}){\Left compatible \This}{\label{lt1}
\lIf{\Left $<3$}{\Union{\Left}}\;
\lElse{\Union{\This,\Left}\tikzmark{d}\;}
}
}
\lForEach{element $e$ of the line $i$}{\FindCompress{p}}
}
\caption{disjoint decomposition}\label{algo_disjdecomp}
\end{algorithm}
\end{columns}

\begin{tikzpicture}[remember picture,overlay]
\coordinate (aa) at ($(a)+(0,0.2)$);
\coordinate (bb) at ($(b)+(1.2,0)$);
\node<3>[draw=myframe,line width=1pt,fill=mybrown,opacity=0.4,rectangle,rounded corners,fit=(aa) (bb)] {};
\coordinate (cc) at ($(c)+(0,0.2)$);
\coordinate (dd) at ($(d)+(1.2,0)$);
\node<4>[draw=myframe,line width=1pt,fill=mybrown,opacity=0.4,rectangle,rounded corners,fit=(cc) (dd)] {};
\end{tikzpicture}
\end{frame}

\end{document}

The four resulting slides:

enter image description here enter image description here enter image description here enter image description here


Added by Andrew Stacey

Here's a version using the slightly improved tikzmark which makes it possible to put the boxes behind the text. While I was at it, I also added in overlay-aware styles for those two nodes, and non-jumping pictures because the small jump when the node size changes annoyed me (you need to compile the code to see the effect of this, try commenting out the stop jumping key on the tikzpicture environment). I found that \resetcounteronoverlays{algocf} did work - unless I missed something. On the plus side, I got rid of the dependency on the fit and calc libraries. Here's the full code:

\documentclass{beamer}
% \url{http://tex.stackexchange.com/q/51582/86}
%
% Using code from:
%  http://tex.stackexchange.com/a/6155/86 for overlay-aware styles
%  http://tex.stackexchange.com/a/50054/86 for advanced tikzmark
%  http://tex.stackexchange.com/q/18704/86 for the non-jumping pictures
\usepackage[ruled,vlined,linesnumbered]{algorithm2e}
\usepackage{tikz}
\makeatletter

\newcounter{jumping}
\resetcounteronoverlays{jumping}

\def\jump@setbb#1#2#3{%
  \@ifundefined{jump@#1@maxbb}{%
    \expandafter\gdef\csname jump@#1@maxbb\endcsname{#3}%
  }{%
    \csname jump@#1@maxbb\endcsname
    \pgf@xa=\pgf@x
    \pgf@ya=\pgf@y
    #3
    \pgfmathsetlength\pgf@x{max(\pgf@x,\pgf@xa)}%
    \pgfmathsetlength\pgf@y{max(\pgf@y,\pgf@ya)}%
    \expandafter\xdef\csname jump@#1@maxbb\endcsname{\noexpand\pgfpoint{\the\pgf@x}{\the\pgf@y}}%
  }
  \@ifundefined{jump@#1@minbb}{%
    \expandafter\gdef\csname jump@#1@minbb\endcsname{#2}%
  }{%
    \csname jump@#1@minbb\endcsname
    \pgf@xa=\pgf@x
    \pgf@ya=\pgf@y
    #2
    \pgfmathsetlength\pgf@x{min(\pgf@x,\pgf@xa)}%
    \pgfmathsetlength\pgf@y{min(\pgf@y,\pgf@ya)}%
    \expandafter\xdef\csname jump@#1@minbb\endcsname{\noexpand\pgfpoint{\the\pgf@x}{\the\pgf@y}}%
  }
}

\tikzset{%
  remember picture with id/.style={%
    remember picture,
    overlay,
    save picture id=#1,
  },
  save picture id/.code={%
    \edef\pgf@temp{#1}%
    \immediate\write\pgfutil@auxout{%
      \noexpand\savepointas{\pgf@temp}{\pgfpictureid}}%
  },
  if picture id/.code args={#1#2#3}{%
    \@ifundefined{save@pt@#1}{%
      \pgfkeysalso{#3}%
    }{
      \pgfkeysalso{#2}%
    }
  },
  onslide/.code args={<#1>#2}{%
    \only<#1>{\pgfkeysalso{#2}}%
  },
  alt/.code args={<#1>#2#3}{%
    \alt<#1>{\pgfkeysalso{#2}}{\pgfkeysalso{#3}}%
  },
  stop jumping/.style={
    execute at end picture={%
      \stepcounter{jumping}%
      \immediate\write\pgfutil@auxout{%
        \noexpand\jump@setbb{\the\value{jumping}}{\noexpand\pgfpoint{\the\pgf@picminx}{\the\pgf@picminy}}{\noexpand\pgfpoint{\the\pgf@picmaxx}{\the\pgf@picmaxy}}
      },
      \csname jump@\the\value{jumping}@maxbb\endcsname
      \path (\the\pgf@x,\the\pgf@y);
      \csname jump@\the\value{jumping}@minbb\endcsname
      \path (\the\pgf@x,\the\pgf@y);
    },
  }
}


\def\savepointas#1#2{%
  \expandafter\gdef\csname save@pt@#1\endcsname{#2}%
}

\def\tmk@labeldef#1,#2\@nil{%
  \def\tmk@label{#1}%
  \def\tmk@def{#2}%
}

\tikzdeclarecoordinatesystem{pic}{%
  \pgfutil@in@,{#1}%
  \ifpgfutil@in@%
    \tmk@labeldef#1\@nil
  \else
    \tmk@labeldef#1,\pgfpointorigin\@nil
  \fi
  \@ifundefined{save@pt@\tmk@label}{%
    \tikz@scan@one@point\pgfutil@firstofone\tmk@def
  }{%
  \pgfsys@getposition{\csname save@pt@\tmk@label\endcsname}\save@orig@pic%
  \pgfsys@getposition{\pgfpictureid}\save@this@pic%
  \pgf@process{\pgfpointorigin\save@this@pic}%
  \pgf@xa=\pgf@x
  \pgf@ya=\pgf@y
  \pgf@process{\pgfpointorigin\save@orig@pic}%
  \advance\pgf@x by -\pgf@xa
  \advance\pgf@y by -\pgf@ya
  }%
}
\newcommand\tikzmark[2][]{%
\tikz[remember picture with id=#2] #1;}
\makeatother

\definecolor{mybrown}{RGB}{255,218,195}
\definecolor{myframe}{RGB}{197,122,195}

\resetcounteronoverlays{algocf}

\newcommand<>{\boxto}[1]{%
\only#2{\tikz[remember picture,overlay]
\draw[myframe,line width=1pt,fill=mybrown,,rectangle,rounded corners]
(pic cs:#1) ++(1.4,-.25) rectangle (-.2,0.4)
;}%
}


\begin{document}

\begin{frame}
\begin{columns}
\column{.4\textwidth}
\onslide<2->{
\setlength\fboxsep{6pt}%
\framebox{\begin{tikzpicture}[
      x=0.8cm,
      init/.style={circle,fill=green!60!black,inner sep=2pt},
      tran/.style={circle,fill=magenta!60!black,inner sep=3pt},
      stop jumping
    ]
\node[alt=<4>{tran}{init}] at (0,0) (p) {};
\node[init] at (1,-1) (q) {};
\node[init] at (3,-1) (r) {};
\node[alt=<3>{tran}{init}] at (2.5,-2) (s) {};
\node[init] at (3.5,-3) (t) {};
\draw[blue] (p) -- (q) -- (r)  -- (s);
\draw[blue] (r) -- (t);
\end{tikzpicture}}
}

\column{.6\textwidth}
\begin{algorithm}[H]
\SetKwData{Left}{left}\SetKwData{This}{this}\SetKwData{Up}{up}
\SetKwFunction{Union}{Union}\SetKwFunction{FindCompress}{Find}
\SetKwInOut{Input}{input}\SetKwInOut{Output}{output}

\For{$i\leftarrow 2$ \KwTo $l$}
{
\emph{special treatment of $i$}\;
\For{$j\leftarrow 2$ \KwTo $w$}{\label{forins}
\Left$\leftarrow$ \FindCompress{$Im[i,j-1]$}\;
\boxto<3>{b}\If(\tcp*[h]{}){\Left compatible \This}{\label{lt}
\lIf{\Left $<3$}{\Union{\Left}}\;
\lElse{\Union{\This,\Left}\tikzmark{b}\;}
}
\boxto<4>{d}\If(\tcp*[h]{}){\Left compatible \This}{\label{lt1}
\lIf{\Left $<3$}{\Union{\Left}}\;
\lElse{\Union{\This,\Left}\tikzmark{d}\;}
}
}
\lForEach{element $e$ of the line $i$}{\FindCompress{p}}
}
\caption{disjoint decomposition}\label{algo_disjdecomp}
\end{algorithm}
\end{columns}

\end{frame}

\end{document}

First slide with highlighted code Second slide with highlighted code Third slide with highlighted code Fourth slide with highlighted code

share|improve this answer
    
Gonzalo, thanks a million. It works perfect. However, there is a minor issue. As you can see in the slides, the "Algorithm number" increases as we put more overlays. Is there a way to keep algorithm number constant? Because, we have just one algorithm. Thanks –  Oktay Arslan Apr 11 '12 at 21:00
3  
Hooray for \tikzmark! Incidentally, if you use the new-and-improved version then you can put the code for the block before the code so that it goes under the text rather than over it. –  Andrew Stacey Apr 11 '12 at 21:05
    
@OktayArslan: yes, sorry for that. Unfortunately the obvious solution \resetcounteronoverlays{algocf} does not work, so you will have to add \setcounter{algocf}{3} right after \begin{frame} (this will show the number 4 for the algorithm). Don't forget to accept (by clicking on the tickmark below the vote count) my answer (or possibly another one) that solves your problem ;-) –  Gonzalo Medina Apr 11 '12 at 21:28
4  
Shouldn't the OP click on the tikzmark to accept this answer? –  Andrew Stacey Apr 12 '12 at 6:53
    
I just tried \resetcounteronoverlays{algocf} to see what was going wrong and it worked as I expected it to. What went wrong for you, Gonzalo? –  Andrew Stacey Apr 12 '12 at 7:12
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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