2

I would like to modify the overlay specification that is passed to a custom command, but for some reason, < and > are interpreted as ¡ and ¿ when they are included in a new command.

MWE:

\documentclass[12pt,t,aspectratio=169]{beamer}

\usepackage[utf8]{inputenc} % Ensure the correct input encoding
\usepackage{xstring}

% named colors
\definecolor{offwhite}{RGB}{249,242,215}
\definecolor{background}{RGB}{24,24,24}
\definecolor{hilight}{RGB}{255,69,0}

% use those colors
\setbeamercolor{titlelike}{fg=hilight}
\setbeamercolor{normal text}{fg=offwhite,bg=background}
\setbeamercolor{item}{fg=offwhite} % color of bullets

% define macros
\newcommand<>{\hilight}[1]{{\color#2{hilight} \textbf#2{#1}}}
\newcommand<>{\onlyhilight}[1]{%
\StrBetween{#2}{<}{>}[\spec]% Extract the number between < and >
\edef\modifiedspec{<\spec->}% Create the new overlay specification
% \edef\modifiedspec{<3->}% Create the new overlay specification
\only\modifiedspec{{\color#2{hilight} \textbf#2{#1}}}%
}

\newcommand{\test}{<5->}

\begin{document}

    \begin{frame}{\textbf{Introduction}}
    
        \vspace{60pt}
        \begin{itemize}\itemsep10pt
            \item<2-> \hilight<2>{First entry}, \onlyhilight<3>{second entry}, \onlyhilight<4>{third entry}, \onlyhilight<5>{fourth entry} \test
        \end{itemize} 
    \end{frame}

\end{document}
4
  • Can you add some background info why you need to extract the overlay specification? The example in your question could be written as \newcommand<>{\onlyhilight}[1]{\only#2{{\color#2{hilight} \textbf#2{#1}}}} Commented Jun 19 at 8:32
  • Hi, @samcarter_is_at_topanswers.xyz! The overlay specification for \only has to be <#2-> (i.e. appended by a -), because otherwise, the text will disappear again on the following slides. At the same time, #2 cannot include the -, because then, the highlighting won't disappear on the following slides. The overlay specification therefore needs to be modified.
    – mapf
    Commented Jun 19 at 9:23
  • Ah! Thanks for the clarification! I missed the - Commented Jun 19 at 9:25
  • 2
    So \newcommand<>{\onlyhilight}[1]{\temporal#2{}{{\color#2{hilight} \textbf#2{#1}}}{#1}} Commented Jun 19 at 9:27

4 Answers 4

3

It seems unnecessary to parse the overlay specifications, you could instead use \temporal:

\documentclass[12pt,t,aspectratio=169]{beamer}

% named colors
\definecolor{offwhite}{RGB}{249,242,215}
\definecolor{background}{RGB}{24,24,24}
\definecolor{hilight}{RGB}{255,69,0}

% use those colors
\setbeamercolor{titlelike}{fg=hilight}
\setbeamercolor{normal text}{fg=offwhite,bg=background}
\setbeamercolor{item}{fg=offwhite} % color of bullets

\setbeamerfont{frametitle}{series=\bfseries}

% define macros
\newcommand<>{\onlyhilight}[1]{\temporal#2{}{{\color#2{hilight} \textbf#2{#1}}}{#1}}

\begin{document}

    \begin{frame}
    \frametitle{Introduction}
    
        \vspace{60pt}
        \begin{itemize}\itemsep10pt
            \item<2-> \onlyhilight<2>{First entry,} \onlyhilight<3>{second entry,} \onlyhilight<4>{third entry,} \onlyhilight<5>{fourth entry} 
        \end{itemize} 
    \end{frame}

\end{document}

enter image description here

1
  • Nice! I didn't know about \temporal. This may be the cleanest solution.
    – mapf
    Commented Jun 19 at 11:52
3

You can use \NewExpandableDocumentCommand (from recent LaTeX or from xparse) to define the \extractoverlayspecs macro:

\NewExpandableDocumentCommand\extractoverlayspecs{R<>{}m}{\edef#2{#1}}

Your modified MWE:

\documentclass[12pt,t,aspectratio=169]{beamer}

\usepackage[utf8]{inputenc} % Ensure the correct input encoding
\usepackage[T1]{fontenc}
\usepackage{xparse} % use with old LaTeX

% named colors
\definecolor{offwhite}{RGB}{249,242,215}
\definecolor{background}{RGB}{24,24,24}
\definecolor{hilight}{RGB}{255,69,0}

% use those colors
\setbeamercolor{titlelike}{fg=hilight}
\setbeamercolor{normal text}{fg=offwhite,bg=background}
\setbeamercolor{item}{fg=offwhite} % color of bullets

% define macros
\NewExpandableDocumentCommand\extractoverlayspecs{R<>{}m}{\edef#2{#1}}
\newcommand<>{\hilight}[1]{{\color#2{hilight} \textbf#2{#1}}}
\newcommand<>{\onlyhilight}[1]{%
  \extractoverlayspecs#2\spec%
  \edef\modifiedspec{\spec-}% Create the new overlay specification
  \only<\modifiedspec>{{\color#2{hilight} \textbf#2{#1}}}%
}

\newcommand{\test}{<5->}

\begin{document}

    \begin{frame}{\textbf{Introduction}}
    
        \vspace{60pt}
        \begin{itemize}\itemsep10pt
            \item<2-> \hilight<2>{First entry}, \onlyhilight<3>{second entry}, \onlyhilight<4>{third entry}, \onlyhilight<5>{fourth entry} \test
        \end{itemize} 
    \end{frame}

\end{document}

Note: Just to work around ¡ and ¿, add \usepackage[T1]{fontenc}.

5
  • Thank you! Using \usepackage[T1]{fontenc} turns the ¡ ¿ back into < >, however, if you keep them inside \edef\modifiedspec{<\spec->} , \only\modifiedspec is still not handled correctly. So this solution also only works when putting the < > around \modifiedspec. Why is that?
    – mapf
    Commented Jun 19 at 7:59
  • @mapf The \only command (defined in beamerbaseoverlay.sty) explicitly tests whether the next character is <. Commented Jun 19 at 9:11
  • Thank you, I see, but when you use \usepackage[T1]{fontenc}, the next character after \only is <, but it still doesn't work. Or is the proper encoding not yet applied when \modifiedspec is defined?
    – mapf
    Commented Jun 19 at 9:25
  • 2
    @mapf T1 affects only the mapping between a character code and a glyph. The \only command checks if the next token is <. The \modifiedspec token is NOT <. Commented Jun 19 at 9:31
  • Ah, I think I start to understand now. Thanks a lot!
    – mapf
    Commented Jun 19 at 11:48
0

Ok, I just found a simple solution. I only need to move the < > outside \modifiedspec and move them to \only<\modifiedspec>:

\newcommand<>{\onlyhilight}[1]{%
\StrBetween{#2}{<}{>}[\spec]% Extract the number between < and >
\edef\modifiedspec{\spec-}% Create the new overlay specification
\only<\modifiedspec>{{\color#2{hilight} \textbf#2{#1}}}%
}

But I would still like to understand why it doesn't work the other way around.

0

Based on this post, I just came up with another, even better solution using \NewDocumentCommand from the xparse package, which allows to pass on useful optional arguments:

\NewDocumentCommand{\onlyhilight}{ d<> O{} m O{}}{%
    \only<#1->{#2{\color<#1>{hilight} \textbf<#1>{#3}}#4}%
}

MWE:

\documentclass[12pt,t,aspectratio=169]{beamer}

% Only required for older LaTeX versions
% \usepackage[utf8]{inputenc}
% \usepackage{xparse}

% named colors
\definecolor{offwhite}{RGB}{249,242,215}
\definecolor{background}{RGB}{24,24,24}
\definecolor{hilight}{RGB}{255,69,0}

% use those colors
\setbeamercolor{titlelike}{fg=hilight}
\setbeamercolor{normal text}{fg=offwhite,bg=background}
\setbeamercolor{item}{fg=offwhite} % color of bullets

% define macros
\newcommand<>{\hilight}[1]{{\color#2{hilight} \textbf#2{#1}}}
\NewDocumentCommand{\onlyhilight}{ d<> O{} m O{}}{%
    \only<#1->{#2{\color<#1>{hilight} \textbf<#1>{#3}}#4}%
}

\begin{document}

    \begin{frame}{\textbf{Introduction}}
    
        \vspace{60pt}
        \begin{itemize}\itemsep10pt
            \item<2-> \hilight<2>{First entry}\onlyhilight<3>[, ]{second entry}\onlyhilight<4>[, ]{third entry}\onlyhilight<5>[, ]{fourth entry}
        \end{itemize} 
    \end{frame}

\end{document}

I still don't understand though why < > are not correctly interpreted when inside a custom command.

2
  • 1
    xparse is only needed if you have an old latex release, and \usepackage[utf8]{inputenc} is only needed if you have a very old latex release Commented Jun 19 at 11:52
  • Thank you for pointing this out; I wasn't aware. But I guess I leave it in for backwards compatibility.
    – mapf
    Commented Jun 19 at 11:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .