I have been managed to define an environment in which I can draw a
tree with TikZ, which Beamer will uncover, one level at a time. Not
only the text in the nodes will uncover, but also the edges. Here is a
MWE:
\documentclass{beamer}
\mode<presentation>{\setbeamercovered{transparent}}
\usepackage{tikz}
\usetikzlibrary{trees}
\newenvironment{appearingtree}{
\alt<-1>{\tikzstyle overlayed1=[draw=black!30]}{\tikzstyle
overlayed1=[draw=black]}
\alt<-2>{\tikzstyle overlayed2=[draw=black!30]}{\tikzstyle
overlayed2=[draw=black]}
\alt<-3>{\tikzstyle overlayed3=[draw=black!30]}{\tikzstyle
overlayed3=[draw=black]}
\begin{tikzpicture}
[level 1/.style={overlayed1},level 2/.style={overlayed2},level
3/.style={overlayed3}]
}{
\end{tikzpicture}
}
\begin{document}
\frame{
\begin{appearingtree}
\node{root}
child{node{{\onslide<2->{child at level 1}}}
child{node{{\onslide<3->{child at level 2}}}
child{node{{\onslide<4->{child at level 3}}}}
}
}
;
\end{appearingtree}
}
\end{document}
I would like to parametrize the environment on the number of layers
the tree will have, because Beamer will generate slides up to the
highest pausenumber it encounters. So, for example, a tree with 2
levels will have an 'extra' slide (which uncovers nothing), with the
current definition.
I have tried to rewrite the definition, but I don't understand LaTeX's
loops, expansion and things like csname enough to make it work. This
is how far I got (omitting all my fruitless experimenting with
combinations of the aforementioned commands):
\documentclass{beamer}
\mode<presentation>{\setbeamercovered{transparent}}
\usepackage{tikz}
\usetikzlibrary{trees}
\newcount\n
\newcount\z
\newenvironment{appearingtree}[1]{
\n=1%
\z=#1\advance\z by 1%
\loop\ifnum\n<\z%
\alt<-\n>{\tikzstyle overlayed\n=[draw=black!30]}{\tikzstyle
overlayed\n=[draw=black]}%
\advance\n by 1%
\repeat%
\begin{tikzpicture}
[level 1/.style={overlayed1},level 2/.style={overlayed2},level
3/.style={overlayed3}]
}{
\end{tikzpicture}
}
\begin{document}
\frame{
\begin{appearingtree}{3}
\node{root}
child{node{{\onslide<2->{child at level 1}}}
child{node{{\onslide<3->{child at level 2}}}
child{node{{\onslide<4->{child at level 3}}}}
}
}
;
\end{appearingtree}
}
\end{document}
This should make my basic problem clear. Can anyone help me make this
loop work the way I intend?
\newenvironment{appearingtree}[1]{
\n=1%
\z=#1\advance\z by 1%
\loop\ifnum\n<\z%
\edef\tmp{overlayed\the\n}
\alt<-\n>{\tikzstyle \tmp=[draw=black!30]}{\tikzstyle
\tmp=[draw=black]}%
\advance\n by 1%
\repeat%
\begin{tikzpicture}
[level 1/.style={overlayed1},level 2/.style={overlayed2},level
3/.style={overlayed3}]
}{
\end{tikzpicture}
}
Now I just need to the parameters for the tikzpicture environment in a
similar way. Unfortunately, I can't seem to get it to work.
\documentclass{beamer}
\mode<presentation>{\setbeamercovered{transparent}}
\usepackage{tikz}
\usetikzlibrary{trees}
\newcount\n
\newcount\z
\newsavebox{\mybox}
\newenvironment{appearingtree}[1]{
\n=1%
\z=#1\advance\z by 1%
\loop\ifnum\n<\z%
\edef\tmp{overlayed\the\n}
\alt<-\n>{\tikzstyle \tmp=[draw=black!30]}{\tikzstyle
\tmp=[draw=black]}%
\savebox{\mybox}{\unhbox\mybox level \the\n/.style=\{overlayed\the\n
\},}% i.e. append 'level #/.style={overlayed#},' (where # = \n) to the
savebox
\advance\n by 1%
\repeat%
\edef\tmp{\unhbox\mybox}
\begin{tikzpicture}[\tmp] % this does not work
the following may work, but no guarantee (my tikz always complains,
may be too old or somehow broken).
\documentclass{beamer}
\mode<presentation>{\setbeamercovered{transparent}}
\usepackage{tikz}
\usetikzlibrary{trees}
\newcount\n
\newcount\z
\newtoks\mytoken
\newenvironment{appearingtree}[1]{
\n=1%
\z=#1\advance\z by 1%
\mytoken{[}% initialize
%\typeout{Test 0: \the\mytoken}% just for testing
\loop\ifnum\n<\z%
\edef\tmp{overlayed\the\n}
\alt<-\n>{\tikzstyle \tmp=[draw=black!30]}{\tikzstyle \tmp=[draw=black]}%
\ifnum\n>1\mytoken\expandafter{\the\mytoken,}\fi% add ',' after first
option
\edef\tmp{\the\mytoken level \the\n/.style={\tmp}}
\mytoken\expandafter{\tmp}
%\typeout{Test \the\n: \the\mytoken}% just for testing
\advance\n by 1%
\repeat%
\mytoken\expandafter{\the\mytoken]}
%\typeout{Test \the\n: \the\mytoken}% just for testing
\expandafter\calltikzpicture\the\mytoken\nil
}{
\end{tikzpicture}
}
\def\calltikzpicture#1\nil{\begin{tikzpicture}#1}
It works perfectly fine over here. Thank you very much!
For completeness' sake, this is my own final version:
% environment for drawing a tikz tree which uncovers level by level
% #1 = additional options to pass to tikz
% #2 = number of tree levels
\newenvironment{overlaytree}[2][]{%
% declaring variables
\newcount\n
\newcount\z
\newtoks\mytoken
% initializing variables
\n=1%
\z=#2\advance\z by 1%
\mytoken{[text depth=0pt,}%
%\typeout{Test 0: \the\mytoken}
% looping, building up declarations and parameters
\loop\ifnum\n<\z%
\edef\tmp{overlayed\the\n}%
\alt<-\n>{\tikzstyle \tmp=[draw=black!30]}{\tikzstyle
\tmp=[draw=black]}%
\ifnum\n>1\mytoken\expandafter{\the\mytoken,}\fi% add ',' after
first option
\edef\tmp{\the\mytoken level \the\n/.style={\tmp}}%
\mytoken\expandafter{\tmp}%
%\typeout{Test \the\n: \the\mytoken}
\advance\n by 1%
\repeat%
% add additional (optional) parameters
\mytoken\expandafter{\the\mytoken,#1]}%
%\typeout{Test \the\n: \the\mytoken}
% call tikz
\expandafter\tikz\the\mytoken
}{}