使用以下代码我可以将 ToC 行放在中心beamer
:
\begin{frame}
\begin{center}
\tableofcontents
\end{center}
\end{frame}
但是如何使这些 ToC 行左对齐并且仍然位于中心?
答案1
一个小的计算就可以充分提高边距以获得居中和左对齐的\tableofcontents
显示。
\documentclass{beamer}% http://ctan.org/pkg/beamer
\newsavebox{\longestsec}% Box to save longest sectional heading
\begin{document}
\begin{frame}
\frametitle{Table of contents}
\begin{lrbox}{\longestsec}Last section in the presentation\end{lrbox}% Capture longest title
\setlength{\leftskip}{\dimexpr.5\textwidth-.5\wd\longestsec\relax}% Advance left margin accordingly
\tableofcontents
\end{frame}
\section{First section}
\begin{frame}
\frametitle{First slide}
This is a slide.
\end{frame}
\section{Last section in the presentation}% Longest sectional title
\begin{frame}
\frametitle{Another slide}
This is another slide
\end{frame}
\end{document}
之所以要绕这么远,是因为beamer
在放置\tableofcontents
或minipage
(varwidth
从varwidth
包裹)。
以下是自动捕获最长部分宽度的方法:
\documentclass{beamer}% http://ctan.org/pkg/beamer
\usepackage{etoolbox}% http://ctan.org/pkg/etoolbox
\makeatletter
\newlength{\secnamelength}
\newsavebox{\longestsec}% Box to save longest sectional heading
\patchcmd{\beamer@section}% <cmd>
{\beamer@savemode}% <search>
{\begin{lrbox}{\longestsec}#1\end{lrbox}%
\ifdim\wd\longestsec>\secnamelength\relax\setlength{\secnamelength}{\wd\longestsec}\fi%
\beamer@savemode}% <replace>
{}{}% <success><failure>
\AtEndDocument{% http://tex.stackexchange.com/q/137495/5764
\immediate\write\@auxout{\global\secnamelength=\the\secnamelength}%
}
\makeatother
\begin{document}
\begin{frame}
\frametitle{Table of contents}
\setlength{\leftskip}{\dimexpr.5\textwidth-.5\secnamelength\relax}% Advance left margin accordingly
\tableofcontents
\end{frame}
\section{First section}
\begin{frame}
\frametitle{First slide}
This is a slide.
\end{frame}
\section{Last section in the presentation}% Longest sectional title
\begin{frame}
\frametitle{Another slide}
This is another slide
\end{frame}
\end{document}
上面的代码存储了最长部分的长度,\secnamelength
该部分被写入.aux
文档末尾。\beamer@section
etoolbox
有必要获取部分名称的最大长度并将其放入其中,.aux
\AtEndDocument
以便可以在后续运行中检索它。
答案2
通过修补\beamer@sectionintoc
命令,我可以使用varwidth
内部center
环境使 ToC 行左对齐并位于中心。
这个解决方案的唯一限制是 ToC 行不能换行。
\documentclass{beamer}
\usepackage{varwidth}
\usepackage{etoolbox}
\makeatletter
%\patchcmd{\beamer@sectionintoc}{\vskip1.5em}{\vskip0.5em}{}{}
\patchcmd{\beamer@sectionintoc}{%
\hbox{\vbox{%
\def\beamer@breakhere{\\}%
\beamer@tocact{\ifnum\c@section=#1\beamer@toc@cs\else\beamer@toc@os\fi}{section in toc}}}%
}{%
\hbox{%
\def\beamer@breakhere{}%
\beamer@tocact{\ifnum\c@section=#1\beamer@toc@cs\else\beamer@toc@os\fi}{section in toc}}%
}{}{}
\makeatother
\setbeamertemplate{section in toc}[sections numbered]
\begin{document}
\begin{frame}
\frametitle{Table of contents}
\begin{center}
\begin{varwidth}{\textwidth}
\tableofcontents[sectionstyle=show,subsectionstyle=hide]
\end{varwidth}
\end{center}
\end{frame}
\section{First section}
\begin{frame}
\frametitle{First slide}
This is a slide.
\end{frame}
\section{Second section in the presentation}
\begin{frame}
\frametitle{Another slide}
This is another slide.
\end{frame}
\section{Last section}
\begin{frame}
\frametitle{Last slide}
This is the last slide.
\end{frame}
\end{document}
答案3
正如我在评论中指出的,如果你有短名称(例如 beamer slide headlines),Werner 提供的自动化功能可能会有问题\section[shortName]{longName}
。它总是采用第一个参数,也就是短名称。
我现在实现了一个快速解决方案(使用etoolbox
和ifthen
),如果提供,它将采用第二个参数:
\makeatletter
\newlength{\secnamelength}
\newsavebox{\longestsec}% Box to save longest sectional heading
\patchcmd{\beamer@section}% <cmd>
{\beamer@savemode}% <search>
{
\ifstrempty{#2}{%
\begin{lrbox}{\longestsec}#1\end{lrbox}
\ifthenelse{
\wd\longestsec > \secnamelength
}{
\setlength{\secnamelength}{\wd\longestsec}
}{}%else
}{
\begin{lrbox}{\longestsec}#2\end{lrbox}
\ifthenelse{
\wd\longestsec > \secnamelength
}{
\setlength{\secnamelength}{\wd\longestsec}
}{}%else
}
\beamer@savemode
}% <replace>
{}{}% <success><failure>
\AtEndDocument{% http://tex.stackexchange.com/q/137495/5764
\immediate\write\@auxout{\global\secnamelength=\the\secnamelength}%
}
\makeatother