我正在为我的投影仪演示文稿创建一个帧列表,就像我的上一个问题,效果非常好。如果存在 framesubtitle,则会将其放入框架列表中以取代 frametitle。
然而有时 framesubtitle 对于帧列表来说太长了,我想要一个更短的版本,但只有 frametitle 提供此功能:
\frametitle[short]{long}
我已经发现不起作用\insertshortframetitle
,所以我必须使用\beamer@shortframetitle
,结果:
\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}
只要我始终提供一个短框架标题,这种方法就很有效,但我实际上想要的是以下内容:
- 如果定义了 shortframetitle,则使用它
- 如果不使用framesubtitle
- 仅当两者都未定义时才使用 frametitle
问题:shortframetitle
始终被定义,因为如果没有进一步指定,它等于 frametitle。这意味着如果我不定义 shortframetitle,它将显示 frametitle,但在这种情况下,framesubtitle 是首选。我该如何解决这个困境?
我尝试了以下操作:我认为我可以使用 xstring 包并使用字符串比较,如下所示:
\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}%
}
但我却被错误所困扰。正确的做法是什么?
答案1
你的想法是将短框架标题与框架标题进行比较,这似乎很有效——而且Mike 在评论中指出无需软件包即可完成此操作xstring
。
\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}