2

I'm creating a list of frames for my beamer presentation as in my previous question, which works like a charm. If a framesubtitle exists, it will be put into the list of frames in favor of the frametitle.

However sometimes the framesubtitle is too long for the list of frames and I want a shorter version, but only the frametitle offers this feature:

\frametitle[short]{long}

I already found out that the \insertshortframetitle does not work and I have to use \beamer@shortframetitle, resulting in:

\documentclass{beamer}

\usepackage{hyperref}

\makeatletter
\newcommand\listofframes{\@starttoc{lbf}}
\makeatother

\makeatletter
\addtobeamertemplate{frametitle}{}{%
    \mode<presentation>
    {
    \only<1>{
    \hypertarget{\insertframetitle}{}%
          \addcontentsline{lbf}{section}{\protect\makebox[2em][l]{%
          \protect\usebeamercolor[fg]{structure}\scriptsize\insertframenumber\hfill}%
          \ifx\beamer@shortframetitle\@empty%
              \ifx\insertframesubtitle\@empty%
                  \scriptsize\protect\hyperlink{F\insertframestartpage}{\insertframetitle}%
              \else%
                  \scriptsize\protect\hyperlink{F\insertframestartpage}{\insertframesubtitle}%
              \fi
          \else
              \scriptsize\protect\hyperlink{F\insertframestartpage}{\beamer@shortframetitle}%
          \fi%
          \par}%
    }
    }
}
\makeatother  

\newcommand{\sectioninlbf}{
\addcontentsline{lbf}{section}{%
        \vspace{0.3\baselineskip}
        \protect\footnotesize%
        \secname\par}%
}

\begin{document}

\begin{frame}
\frametitle{General outline}
\tableofcontents[hideallsubsections]
\end{frame}

\begin{frame}
\frametitle{List of Frames}
\listofframes
\end{frame}

\section{Test section one}\sectioninlbf

\begin{frame}
\frametitle{Title Frame One}
\framesubtitle{Subtitle Frame One}
test
\end{frame}

\section{Test section two}\sectioninlbf
\begin{frame}
\frametitle[Short Subtitle Frame Two]{Title Frame Two}
\framesubtitle{Subtitle Frame Two}
test
\end{frame}
\begin{frame}
\frametitle{Title Frame Three}
\framesubtitle{Subtitle Frame Three}
\uncover<1->{test}
\uncover<2->{test}
\uncover<3->{test}
\end{frame}

\end{document}

This works great as long as I always provide a shortframetitle, but I actually want the following:

  • if shortframetitle is defined, use it
  • if not use framesubtitle
  • only if both are undefined use frametitle

The problem: shortframetitle is always defined, as it equals the frametitle if not further specified. That means if I don't define a shortframetitle it will show the frametitle, but in this case the framesubtitle is preferred. How can I solve this dilemma?


I tried the following: I thought I could use the xstring package and use a string comparison as follows:

\IfStrEq{\beamer@shortframetitle}{\beamer@frametitle}{
    \ifx\insertframesubtitle\@empty%
        \scriptsize\protect\hyperlink{F\insertframestartpage}{\insertframetitle}%
    \else%
        \scriptsize\protect\hyperlink{F\insertframestartpage}{\insertframesubtitle}%
    \fi
  }{
   \scriptsize\protect\hyperlink{F\insertframestartpage}{\beamer@shortframetitle}%
}

But I get bombed with errors. What would be the right way to do is?

enter image description here

  • off-topic: you don't need to load the hyperref package with beamer – samcarter is at topanswers.xyz May 22 '18 at 21:04
  • 1
    You should also change \hypertarget{\insertframetitle}{} to \hypertarget{F\insertframestartpage}{} to make the links work. – Mike May 22 '18 at 21:54
  • @Mike thanks! I actually do that already, but as I copied my old mwe, that improvement got lost. – thewaywewalk May 23 '18 at 8:08
3

Your idea to compare the short frametitle with the frametitle seems to work just fine -- and as Mike pointed out in his comment this can be done without the xstring package.

\documentclass{beamer}

\makeatletter

\newcommand\listofframes{\@starttoc{lbf}}

\addtobeamertemplate{frametitle}{}{%
    \mode<presentation>{%
        \only<1>{%
            \hypertarget{\insertframetitle}{}%
            \ifx\beamer@shortframetitle\beamer@frametitle
                \ifx\insertframesubtitle\@empty%
                    %frametitle - prioritate 3
                    \addcontentsline{lbf}{section}{\protect\makebox[2em][l]{\protect\usebeamercolor[fg]{structure}\scriptsize\insertframenumber\hfill}\insertframetitle\par}%
                \else
                    %framesubstitle - prioritate 2
                    \addcontentsline{lbf}{section}{\protect\makebox[2em][l]{\protect\usebeamercolor[fg]{structure}\scriptsize\insertframenumber\hfill}\insertframesubtitle\par}%
                \fi
            \else
                %short title - prioritaet 1
                \addcontentsline{lbf}{section}{\protect\makebox[2em][l]{\protect\usebeamercolor[fg]{structure}\scriptsize\insertframenumber\hfill}\beamer@shortframetitle\par}%
            \fi
        }%
    }%
}
\makeatother  

\newcommand{\sectioninlbf}{%
    \addcontentsline{lbf}{section}{%
        \vspace{0.3\baselineskip}
        \protect\footnotesize%
        \secname\par%
    }%
}

\begin{document}

\begin{frame}
\frametitle{General outline}
\tableofcontents[hideallsubsections]
\end{frame}

\begin{frame}
\frametitle{List of Frames}
\listofframes
\end{frame}

\section{Test section one}\sectioninlbf

\begin{frame}
\frametitle{Title Frame One}
\framesubtitle{Subtitle Frame One}
test
\end{frame}

\section{Test section two}\sectioninlbf

\begin{frame}
\frametitle[Short Subtitle Frame Two]{Title Frame Two}
\framesubtitle{Subtitle Frame Two}
test
\end{frame}

\begin{frame}
\frametitle{Title Frame Three}
\framesubtitle{Subtitle Frame Three}
\uncover<1->{test}
\uncover<2->{test}
\uncover<3->{test}
\end{frame}

\end{document}

enter image description here

  • Simply replacing \ifx\beamer@shortframetitle\@empty with \ifx\beamer@shortframetitle\beamer@frametitle would have worked too, no need for xstring. – Mike May 22 '18 at 21:52
  • @Mike Thanks for the suggestion, that is indeed much simpler! If you'd like to post this as your own answer, I will happily revert my edit. – samcarter is at topanswers.xyz May 22 '18 at 21:59
  • Ah well, you were faster, so I'll leave it there. – Mike May 22 '18 at 22:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.