Make ToC in the center and left aligned in beamer
A small calculation could advance the margins sufficiently to obtain the centered & left-aligned \tableofcontents
display.
\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}
The reason for this round-about way is because beamer
collapses the spacing when putting \tableofcontents
within a minipage
or varwidth
(from the varwidth
package).
Here is an automated way of capturing the width of the longest section:
\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}
The above stores the length of the longest section in \secnamelength
that is written to the .aux
at the end of the document. A patch of \beamer@section
(with the aid of etoolbox
is necessary to grab the maximum length of a section name and drop it into the .aux
\AtEndDocument
so it can be retrieved in a successive run.
By patching \beamer@sectionintoc
command, I could use varwidth
inside center
environment to make ToC lines left aligned and in the center.
The only limitation of this solution is, ToC lines could not be wrapped.
\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}
As shown in my comment, the automatism provided by Werner can be problematic if you have short names like \section[shortName]{longName}
e.g. for beamer slide headlines. It always takes the first argument, which would then be the short name.
I implemented a quick solution now (with etoolbox
and ifthen
), which will take the second argument if provided:
\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