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 9 '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