Document ClassesImprove Relative Beamer Overlays

Information and discussion about specific document classes and how to create your own document classes.
Post Reply
sefie
Posts: 2
Joined: Thu Mar 12, 2015 6:56 pm

Improve Relative Beamer Overlays

Post by sefie »

I asked a similar question on stackexchange[1]. There however, the abstract goal was not yet clear.

When I create a presentation with `beamer` using relative overlays sometimes is difficult. Especially, when the order overlays should appear in is different from the order the `tex` code is parsed.

Consider the following example. It is not easy to understand the order of appearance, and neither is it easy to come up with the code to achieve the desired order. With more complicated code things become very unwieldy.

Code: Select all

\documentclass{beamer}
    \usepackage{tikz}
    \begin{document}
    \begin{frame}
    \begin{itemize}
    \item<+(2)-> First item, appears third
    \item<+(-1)-.(1)> Second item, appears first, stays 2 slides
    \item<+(1)-> Third item, appears fourth
    \item<+(-2)> Fourth item, appears second, stays 1 slide
    \end{itemize}
    \setcounter{beamerpauses}{1}
    \begin{tikzpicture}
    \node<+-.(2)> (foo1) [draw] {For second item};
    \node<+> (foo2) [draw, below of=foo1] {For fourth item};
    \node<+-> (foo3) [draw, right of=foo1, node distance=3.5cm] {For first item};
    \node<+-> (foo4) [draw, below of=foo3] {For third item};
    \end{tikzpicture}
    \end{frame}
    \end{document}
The reason seems to be that with e.g. '\item<+(2)->' we refer to the overlay number the item should appear on. I was wondering whether it would be easier to define relative overlay orders when we assign to each overlay element an identifier. Then we use these identifiers to define the order. See the following (not working) example. There we assign identifiers to the overlay elements and define the order with '\setorderuncover'.

Code: Select all

\documentclass{beamer}
    \usepackage{tikz}
    \begin{document}
    \begin{frame}
    \setorderuncover{ {seconditem-2, secondnode-2}, {fourthitem, fourthnode}, {firstitem-, firstnode-}, {thirditem-, thirdnode-} }
    \begin{itemize}
    \item<firstitem> First item, appears third
    \item<seconditem> Second item, appears first
    \item<thirditem> Third item, appears fourth
    \item<fourthitem> Fourth item, appears second
    \end{itemize}
    \begin{tikzpicture}
    \node<firstnode> (foo1) [draw] {For second item};
    \node<secondnode> (foo2) [draw, below of=foo1] {For fourth item};
    \node<thirdnode> (foo3) [draw, right of=foo1, node distance=3.5cm] {For first item};
    \node<fourthnode> (foo4) [draw, below of=foo3] {For third item};
    \end{tikzpicture}
    \end{frame}
    \end{document}
Do you know whether this exists? If not, do you have suggestions on how this could be implemented?


[1]: http://tex.stackexchange.com/questions/ ... -in-beamer

Recommended reading 2024:

LaTeXguide.org • LaTeX-Cookbook.net • TikZ.org

NEW: TikZ book now 40% off at Amazon.com for a short time.

User avatar
Stefan Kottwitz
Site Admin
Posts: 10320
Joined: Mon Mar 10, 2008 9:44 pm

Improve Relative Beamer Overlays

Post by Stefan Kottwitz »

Welcome to the forum!

I'm not aware of such a feature. Mh, it could make beamer even more complicate. ;)

Generally, I would not make presentations too sophisticated, as the true stars are you as the presenter and the content.

I hope your next question would not be so hard. ;-)
The beamer class maintainer Joseph Wright is a moderator of this LaTeX-Community.org forum, so we of course also like beamer topics. See you later,

Stefan
LaTeX.org admin
sefie
Posts: 2
Joined: Thu Mar 12, 2015 6:56 pm

Improve Relative Beamer Overlays

Post by sefie »

After some time I got the 'setorder' command working, which makes the example relatively easy to define. I will try to use it and see whether its useful.

Code: Select all

\documentclass{beamer}
\usepackage{xstring}
\usepackage{etoolbox}
\usepackage{tikz}
\newcounter{mycounter}%
%\newcount\mycounter

% #1 is of the form <name>[=-|n], e.g. foo=- or foo=10 or foo
% Stores in #2 the overlay specification for <name> s.t. it can be appended to the content of <name>
\newcommand*{\getNewOverlayContent}[2]{%
	\getItemSpec{#1}{itemSpec}%
	\IfStrEq{\itemSpec}{-}{%
		\csedef{#2}{\arabic{beamerpauses}-}%
	}{%
		\IfStrEq{\itemSpec}{}{%
			\csedef{#2}{\arabic{beamerpauses}}%
		}{%
			\IfInteger{\itemSpec}{%
%				\mycounter=\
				\setcounter{mycounter}{\arabic{beamerpauses}}%
				\addtocounter{mycounter}{\itemSpec}%
				\addtocounter{mycounter}{-1}%
				\csedef{#2}{\arabic{beamerpauses}-\arabic{mycounter}}%
			}{%
				\PackageError{setorder}{Argument has illegal format}{Argument was #1}%
			}%
		}%
	}%
%	input: #1, itemspec:\itemSpec, beamervalue: \arabic{beamerpauses}, content: \csuse{#2} \\
}
% #1 is of the form 'foo=1' or 'foo=-' or 'foo'. 
% #2 Is the name of the macro which should hold the result
% This macro stores the part infront '=' (the name) in #2.
\newcommand*{\getItemName}[2]{%	
	\IfSubStr{#1}{=}{%
		\StrBefore{#1}{=}[\tmp]%
		\csdef{#2}{\tmp}%
	}{%
		\csdef{#2}{#1}%	
	}%
}
% #1 is of the form 'foo=1' or 'foo=-' or 'foo'. 
% #2 Is the name of the macro which should hold the result
% This macro stores the part behind '=' (the overlay spec) in #2. The stored part is empty iff there is no '=' in #1
\newcommand*{\getItemSpec}[2]{%
	\StrBehind{#1}{=}[\tmp]%
	\csdef{#2}{\tmp}%
}
% #2 is the name where content should be appended. 
% It has been ensured previously that #2 is a defined macro
% #1 is the content to append
% Depending on whether #2 is empty or not a (,) is added 
% before appending #1
\newcommand*{\appendToOverlaySpecification}[2]{%
	\IfStrEq{\csexpandonce{#2}}{}{%
		% #1 i.e. <name> is empty
		\cseappto{#2}{\csname#1\endcsname}%
	}{%
		\cseappto{#2}{,\csname#1\endcsname}%
	}%
}

\newcommand*{\setorderItem}[1]{%
	\getNewOverlayContent{#1}{overlaycontent}%
	\getItemName{#1}{cmdname}%
	\appendToOverlaySpecification{overlaycontent}{\cmdname}%
}

\newcommand*{\setorderList}[1]{%
	\forcsvlist{\setorderItem}{#1}%
	\stepcounter{beamerpauses}%
}
\newcommand*{\setorder}[1]{%	
	\clearNamesListofLists{#1}%
	\forcsvlist{\setorderList}{#1}%
}

% takes a list of lists of the form: {foo=1, bla},{gar=-} and then defines empty macros for each name
\newcommand*{\clearNamesListofLists}[1]{%
	\forcsvlist{	\clearNamesList}{#1}%
}
\newcommand*{\clearNamesList}[1]{%
	\forcsvlist{	\clearName}{#1}%
}
\newcommand*{\clearName}[1]{%
	\getItemName{#1}{cmdname}%
	\csdef{\cmdname}{}%	
}
\begin{document}
\begin{frame}{Each overlay one item}
\setorder{{seconditem},{fourthitem},{firstitem},{thirditem}}

\begin{itemize}
\item<\firstitem> First item, appears third
\item<\seconditem> Second item, appears first
\item<\thirditem> Third item, appears fourth
\item<\fourthitem> Fourth item, appears second
\end{itemize}
\end{frame}

\begin{frame}{More complex example}
\setorder{{seconditem=2},{fourthitem},{firstitem=-},{thirditem=-}}
\begin{itemize}
\item<\firstitem> First item, appears third, does not disappear
\item<\seconditem> Second item, appears first, stays 2 slides
\item<\thirditem> Third item, appears fourth, does not disappear
\item<\fourthitem> Fourth item, appears second, stays 1 slide
\end{itemize}
\begin{tikzpicture}
\node<\seconditem> (foo1) [draw] {For second item};
\node<\fourthitem> (foo2) [draw, below of=foo1] {For fourth item};
\node<\firstitem> (foo3) [draw, right of=foo1, node distance=3.5cm] {For first item};
\node<\thirditem> (foo4) [draw, below of=foo3] {For third item};
\end{tikzpicture}
\end{frame}
\end{document}
Post Reply