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 have two-column slides where there is a tikz figure on the left, and itemization on the right. There is >10 overlays due to pauses in the itemization, and some pieces of the tikz picture are added/removed/modified accordingly (with \only<>) as are the items uncovered.

It is easy to break the code by adding one \pause, because all numbers have to be rewritten.

Is there a way (no hint in Beamer Manual, chap. 9) to assign the value of beamerpause counter to symbolic names, at the point when that part gets uncovered for the first time, something like (needs multiple passes to be resolved) the following?

\begin{column}{..}
   \only</bar->{...}  % <2-> (use e.g. / to reference labels)
   \only<-/baz>{...}  % <-3>
\end{column}
\begin{column{..}
   \begin{itemize}
      \item foo \pause
      \item bar \firstUncoveredLabel{bar}\pause % assign 2 to label /bar
      \item baz \pause[baz]       % nicer syntax; assign 3 to label /baz
      \item end
   \end{itemize}
\end{column}

EDIT: minimal working example:

\documentclass{beamer}
\usepackage{tikz}
\begin{document}
   \begin{frame}
      \begin{columns}
         \begin{column}{.5\textwidth}
            \tikz{
               \draw< -3>        (0,0) grid (3,3);
               \draw<2-3>[red]   (0,0) -- (3,1);
               \draw<3- >[green] (0,0) -- (3,2);
               \draw<4  >[blue]  (0,0) -- (3,3);
            }
         \end{column}
         \begin{column}{.5\textwidth}
            \begin{itemize}
               %%%% uncomment this item and all numbers above have to be shifted :-(
               % \item important remark at the beginning \pause 
               \item grid \pause
               \item grid, red \pause
               \item grid, red, green \pause
               \item green, blue
            \end{itemize}
         \end{column}
      \end{columns}
   \end{frame}
\end{document}

and this is what I dream of (does not compile):

\documentclass{beamer}
\usepackage{tikz}
\begin{document}
   \begin{frame}
      \begin{columns}
         \begin{column}{.5\textwidth}
            \tikz{
               %% use symbolic names for overlay specificaiton
               \draw<-/gridRedGreen>                (0,0) grid (3,3);
               \draw</gridRed-/gridRedGreen>[red]   (0,0) -- (3,1);
               \draw</gridRedGreen->        [green] (0,0) -- (3,2);
               \draw</last>                 [blue]  (0,0) -- (3,3);
            }
         \end{column}
         \begin{column}{.5\textwidth}
            \begin{itemize}
               %%%% uncomment and overlays are still correct :-)
               % \item important remark at the beginning \pause 
               \item grid                \pause[grid]
               \item grid, red           \pause[gridRed]
               \item grid, red, green    \pause[gridRedGreen]
               \item green, blue      
            \end{itemize}
         \end{column}
      \end{columns}
   \end{frame}
\end{document}
share|improve this question

1 Answer 1

Here's a possible way to reference overlays by name:

\makeatletter
\DeclareRobustCommand*{\savepause}[1]{\only<1>{\immediate\write\@auxout{\string\pauseentry{\the\c@framenumber}{#1}{\the\c@beamerpauses}}}}
\newcommand*{\usepause}[1]{\@ifundefined{pauses@\the\c@framenumber @#1}{1}{\@nameuse{pauses@\the\c@framenumber @#1}}}
\newcommand*{\pauseentry}[3]{\global\@namedef{pauses@#1@#2}{#3}}
\makeatother

Include this code somewhere into the preamble of your document, i. e. between \documentclass{beamer} and \begin{document}. It defines two userlevel commands, \savepause and \usepause:

  • \savepause{overlayname} saves the current value of the counter beamerpauses as overlayname. Issue it immediatly before the \pause command.
  • \usepause{overlayname} refers to the previously saved value of overlayname, so if you e.g. used \savepause{overlayname} on the third overlay, \usepause{overlayname} will expand to 3.

As the values will be saved to the auxiliary file, this needs at least two LaTeX runs to produce a stable output.

You can't use the syntax \pause[overlayname] to save the value as you suggested because the optional argument is already used by beamer itself. However, you can define your own command for convenience:

\newcommand*{\mypause}[1]{\savepause{#1}\pause}

which would be used like \mypause{overlayname}.

Example code:

\documentclass{beamer}
\makeatletter
\DeclareRobustCommand*{\savepause}[1]{\only<1>{\immediate\write\@auxout{\string\pauseentry{\the\c@framenumber}{#1}{\the\c@beamerpauses}}}}
\newcommand*{\pauseentry}[3]{\global\@namedef{pauses@#1@#2}{#3}}
\newcommand*{\usepause}[1]{\@ifundefined{pauses@\the\c@framenumber @#1}{1}{\@nameuse{pauses@\the\c@framenumber @#1}}}
\makeatother
\usepackage{tikz}
\begin{document}
   \begin{frame}
      \begin{columns}
         \begin{column}{.5\textwidth}
            \tikz{
               %% use symbolic names for overlay specificaiton
               \draw<-\usepause{gridRedGreen}>                (0,0) grid (3,3);
               \draw<\usepause{gridRed}-\usepause{gridRedGreen}>[red]   (0,0) -- (3,1);
               \draw<\usepause{gridRedGreen}->        [green] (0,0) -- (3,2);
               \draw<\usepause{last}>                 [blue]  (0,0) -- (3,3);
            }
         \end{column}
         \begin{column}{.5\textwidth}
            \begin{itemize}
               %%%% uncommented and overlays are still correct :-)
               \item important remark at the beginning \pause 
               \item grid                \savepause{grid}\pause
               \item grid, red           \savepause{gridRed}\pause
               \item grid, red, green    \savepause{gridRedGreen}\pause
               \item green, blue      
            \end{itemize}
         \end{column}
      \end{columns}
  \savepause{last} 
  \end{frame}
\end{document}

Output after two LaTeX runs (click on the image to see it full size):

output of the example code (five frames)

share|improve this answer
    
Very nice and usable. I tried to remove the \pauses from your example using [<+->] as an argument to the enumeration instead. Now the reference always points a frame too late. As I did not completely understand the effects of many commands in your solution, I failed to decrement he value before saving. Can you think of a way to use \item<+-> Lorem ipsum \savepause{a} so that something marked with \usepause{a} will show up exactly at the same time the item does? –  XZS Oct 25 '13 at 14:02
1  
@XZS The problem with [<+->] is that the counter beamerpauses is increased at the beginning of the \item and not at the end. Unfortunately I can't think of a way to detect this automatically, but but I can offer you a workaround: Replace the definition of \savepause above by \DeclareRobustCommand*{\savepause}[2][0]{\only<1>{\advance\c@beamerpauses by#1\relax\immediate\write\@auxout{\string\pauseentry{\the\c@framenumber}{#2}{\t‌​he\c@beamerpauses}}\advance\c@beamerpauses by-#1\relax}} and use \savepause[-1]{a} in the itemize environment, like this will refer to the correct overlay. –  diabonas Oct 25 '13 at 14:54
    
Very handy. Could the optional offset also be applied to the \usepause command? Then, one could write \usepause[2]{grid} as equivalent to \usepause{gridRedGreen}` to make ranges more intuitive. –  XZS Oct 25 '13 at 15:32
    
@XZS Sure, you can define \def\usepauseoffset[#1]#2{\number\numexpr\usepause{#2}+#1\relax} to be used like \usepauseoffset[2]{grid}. The different name is necessary as normal macros with an optional argument unfortunately don't work in overlay specifications due to the way beamer internally processes them. –  diabonas Oct 25 '13 at 18:07

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.