When writing Beamer slides for a talk, I find that I often want to have some text (usually math) visible on a group of slides and be alerted on only the first slide in the group. For example, I can achieve this with $1 + 1 = \action<visible@+- | alert@+>{2}$, $2 + 2 = \action<visible@.(-1)- | alert@.(-1)>{4}$, etc.
However, it would be more maintainable and readable if these actions could be combined into one alertvisible action. Using a simple macro, it's easy to handle the case where the group of slides has the form <slide number>-:
\documentclass{beamer}
\newcommand{\alertvisible}[1]{visible@#1- | alert@#1}
\begin{document}
\begin{frame}{Frame Title}
Facts:\pause
\begin{itemize}
\item $1 + 1 = \action<visible@+- | alert@+>{2}$
\item $2 + 2 = \action<\alertvisible{+}>{4}$
\item $3 + 3 = \action<\alertvisible{.(-1)}>{6}$
\item $4 + 4 = \action<\alertvisible{+}>{8}$
\end{itemize}
\end{frame}
\end{document}
Unfortunately, this simple solution does not handle the general case. For example, I might want to have a single alertvisible action so that \action<alertvisible@+,+(2)-+(3)> is equivalent to \action<visible@+,+(2)-+(3) | alert@+>. This would seem to require a way, say \firstslideof, to extract the logically first slide in a group so that one could define
\newenvironment<>{alertvisibleenv}%
{\begin{visibleenv}#1\begin{alertenv}\firstslideof{#1}}%
{\end{alertenv}\end{visibleenv}}
Is there some way to define \firstslideof to allow this sort of general definition of alertvisibleenv?
Edit:
I am attempting to use the xparse and xstring packages to build \firstslideof, which, for some reason, I decided to rename as \extract. The basic idea is to parse out the left endpoint of each range in the slide specification and evaluate it to a numeric value. The slide specification with the smallest value should be returned as the "first-slide-of". For example, \extract<+-+(1), 3, +, +(-2)-8> should return +(-2) when the value of beamerpauses is smaller than 5, and 3 otherwise.
Here is the code that I have so far:
\documentclass{beamer}
\usepackage{etoolbox}
\usepackage{etextools}
\usepackage{xparse}
\usepackage{xstring}
\makeatletter
\NewDocumentCommand{\extract}{>{\SplitList{,}}r<>}{%
% Initially set the minimum slide spec to something large
\def\beamer@extract@min{+(1000)}%
\ProcessList{#1}{\beamer@extract}%
}
\newcommand*{\beamer@extract}[1]{%
% Substitute \beamer@extract@groupplus for each +
\saveexpandmode
\expandarg
\StrSubstitute{#1}{+}{\noexpand\beamer@extract@groupplus}[\@tmpa]%
\restoreexpandmode
%
% Once \@tmpa is fully expanded, each occurrence of
% a possibly shifted + will be surrounded with { }.
% The { } are used to prevent \beamer@@extract from
% incorrectly splitting +(-1) as +( and 1).
%
%% How do I fully expand \@tmpa here? Is this right?
\ExpandNext{\beamer@@extract}{\@tmpa}%
}
\NewDocumentCommand{\beamer@@extract}{>{\SplitArgument{1}{-}}m}{%
% Use \SplitArgument and \@firstoftwo to get left endpoint
% of range.
Found: `\@firstoftwo#1'\par
%
% Evaluate the prospective and current minima to
% a numeric value and store the result in \@tmpa
% and \@tmpb, respectively.
\beamer@@extract@eval{\@tmpa}{\@firstoftwo#1}%
\beamer@@extract@eval{\@tmpb}{\beamer@extract@min}%
%
% If the prospective minimum is smaller, then
% make it the current minimum.
\ifnumless{\@tmpa}{\@tmpb}{%
\expandnext{\def\beamer@extract@min}{\@firstoftwo#1}%
Updated
}{%
Not Updated
}%
Minimum: \meaning\beamer@extract@min\par
}
\newcommand*{\beamer@@extract@eval}[2]{%
% Substitute \beamer@@extract@evalplus for each occurrence of
% + in #2, storing the fully expanded result in #1.
\saveexpandmode
\expandarg
\StrSubstitute{#2}{+}{\noexpand\beamer@@extract@evalplus}[#1]%
\restoreexpandmode
%% How do I fully expand #1 here?
}
\NewDocumentCommand{\beamer@@extract@evalplus}{r()}{%
\value{beamerpauses}+#1%
}
\NewDocumentCommand{\beamer@extract@groupplus}{D(){0}}{%
{+(#1)}%
}
\makeatother
\begin{document}
\begin{frame}{Test Frame}
% The following should set \beamer@extract@min to
% +(-2) if beamerpauses < 5
% 3 if beamerpauses >= 5
\extract<+-+(1), 3, +, +(-2)-8>
\end{frame}
\end{document}
Unfortunately, when I run the code, I get an error: You can't use \numexpr in horizontal mode. \ifnumcomp ...\ifnum \numexpr #1\relax #2\numexpr #3\relax \expandafter \@fi.... My guess is that this error comes from expansion problems at the lines marked above with %%.
Question:
Is the problem indeed related to expansion? If so, how can I fix it?

\only,\temporal, etc., that can select the first slide in a range, one would have to mimic the structure of the overlay specification parser inbeamerbasedecode.sty. Which looks complicated... – Matthew Leingang Jul 09 '12 at 15:40\only,\temporal, etc. that works. Instead of mimickingbeamerbasedecode.sty, I wonder if there is some way to leverage thexparsepackage to make things (partly) easier. – Henry DeYoung Jul 17 '12 at 16:57visibleaction works by displacing its contents a large amount for slides where the contents should be invisible. This means that it is still processed making it a little tricky to determine the point at which it is actually printed on the page. – Andrew Stacey Jul 25 '12 at 22:18alertvisible", I don't think I need that generality; isn't it enough to expand+s and.s and find the smallest slide in that set? (I've been working on code along this line, now that I've learned more about TeX programming. I'm running into expansion bugs; after I try some more, I will post an edit or separate question.) Maybe I'm missing your point, though? – Henry DeYoung Jul 26 '12 at 21:16\onlyyou could have some flag that was set the first time it was processed since the argument to\onlyis thrown away on the slides where it doesn't appear. But since\visiblealways processes its argument, that wouldn't work. Just thinking aloud, as it were. – Andrew Stacey Jul 26 '12 at 21:52