我想要在我的 Beamer 演示文稿中添加图表列表。
我花了一些时间在网上寻找解决方案,却只发现绝望的人告诉别人这是不可能的,即这里或者这里(德语)。
我也做了一些自己的实验,即“滥用” tocloft 来完成这项工作。然而,这甚至\usepackage{tocloft}
会导致 pdflatex 失败! LaTeX Error: \l@section undefined.
(并且通过预先将命令定义为空来欺骗 tocloft 也没有任何好处)。
我真的不明白为什么在 beamer 中制作图表列表会这么困难,因为 \tableofcontents 可以完美地运行。
我并不害怕自己编写一些代码,但我对 TeX 的了解还不够深入,无法真正理解“图表列表”、“目录”等背后的魔力。
有没有人能提供建议或链接来帮助我解决这个问题?
\documentclass{beamer}
% uncomment the following line
% to get the error message
% `! LaTeX Error: \l@section undefined.`
%\usepackage{tocloft}
% uncomment the following lines INSTEAD
% to lie to tocloft
% and get the next error message
%\makeatletter
%\newcommand\l@section{}
%\makeatother
%\usepackage{tocloft}
\begin{document}
\begin{frame}{A frame}
\begin{figure}
\mbox{A}
\caption{An 'A'}
\end{figure}
\end{frame}
\begin{frame}{List of Figures}
\listoffigures
\end{frame}
\end{document}
编辑:解决方案
从 Marco Daniels 对我的问题的回答开始,我修改了他的代码以反映我的需求。以下是我想到的。请随意评论、改进和重复使用。
\RequirePackage{ifthen}
\makeatletter
\AtEndDocument{%
\clearpage
\beamer@tempcount=\c@page\advance\beamer@tempcount by -1%
\if@filesw
\newwrite\tf@lof
\immediate\openout\tf@lof\jobname.lof\relax
\newwrite\tf@lot
\immediate\openout\tf@lot\jobname.lot\relax
\fi
}
\long\def\beamer@makecaption#1#2#3#4{%
\def\insertcaptionname{\csname#1name\endcsname}%
\def\insertcaptionnumber{\csname the#1\endcsname}%
\edef\insertframenumber{\theframenumber}%
\ifthenelse{\equal{#3}{\empty}}{%
\def\insertlistcaption{#2}%
}{%
\def\insertlistcaption{#3}%
}
\def\insertsource{#4}%
\def\insertcaption{#2}%
\ifthenelse{\equal{#1}{figure}}{%
\addtocontents{lof}{\protect\listoffigureformat{\insertcaptionnumber}{\insertlistcaption}{\insertframenumber}{\insertsource}}{}{}%
}{}
\ifthenelse{\equal{#1}{table}}{%
\addtocontents{lot}{\protect\listoftableformat{\insertcaptionnumber}{\insertlistcaption}{\insertframenumber}}{}{}%
}{}
\nobreak\vskip\abovecaptionskip\nobreak
\sbox\@tempboxa{\usebeamertemplate**{caption}}%
\ifdim \wd\@tempboxa >\hsize
\usebeamertemplate**{caption}\par
\else
\global \@minipagefalse
\hb@xt@\hsize{\hfil\box\@tempboxa\hfil}%
\fi
\nobreak\vskip\belowcaptionskip\nobreak%
}
\def\listoffigureformat#1#2#3#4{%
\makebox[2ex][r]{#1}%
\hspace{1ex}%
{\usebeamercolor[fg]{bibliography entry author} #2}%
\ifthenelse{\equal{#4}{\empty}}{}{ -- #4}%
\dotfill%
\makebox[2ex][r]{#3}\par%
}
\def\listoffigures{%
\setlength{\leftskip}{3ex}
\setlength{\parindent}{-3ex}
\@starttoc{lof}%
}
\def\listoftableformat#1#2#3{\makebox[2ex][r]{#1}\hspace{1ex}#2\dotfill\makebox[2ex][r]{#3}\par}
\def\listoftables{%
\setlength{\leftskip}{3ex}
\setlength{\parindent}{-3ex}
\@starttoc{lot}%
}
\long\def\@caption#1[#2]#3{
\par\nobreak
\begingroup
\@parboxrestore
\if@minipage
\@setminipage
\fi
\beamer@makecaption{#1}{\ignorespaces #3}{\ignorespaces #3}{\ignorespaces #2}\par\nobreak
\endgroup}
\makeatother
答案1
以下代码是一个起点,可以根据个人设置进行修改。
首先解释一下。要提供图片或表格列表,您需要一个额外的文件来保存标题。这相当于toc
所需的文件tableofcontents
。beamer
使用特殊方式创建目录。原因很简单——这是设置如此多用户选项的唯一方法。但是以下部分只是基础。具有所有beamer
功能的完整实现将导致一个新包。到目前为止,我认为拥有图片列表之类的东西没什么用。
首先,我们确保beamer
打开一个文件来保存所有标题条目,并以图形列表(lof)和表格列表(lot)分隔。
\AtEndDocument{%
\clearpage
\beamer@tempcount=\c@page\advance\beamer@tempcount by -1%
\if@filesw
\immediate\write\@auxout{\string\@writefile{lof}%
{\noexpand\headcommand{\noexpand\beamer@partpages{\the\beamer@partstartpage}{\the\beamer@tempcount}}}}%
\newwrite\tf@lof
\immediate\openout\tf@lof\jobname.lof\relax
\immediate\write\@auxout{\string\@writefile{lot}%
{\noexpand\headcommand{\noexpand\beamer@partpages{\the\beamer@partstartpage}{\the\beamer@tempcount}}}}%
\newwrite\tf@lot
\immediate\openout\tf@lot\jobname.lof\relax
\fi
}
下一步是告知beamer
所有标题必须写入lof
或文件中。因此必须更改lot
内部命令。新部分是:\beamer@makecaption
\def\@tempa{#1}
\def\@tempb{figure}
\ifx\@tempa\@tempb
\addtocontents{lof}{\protect\listoffigureformat{\insertcaptionnumber}{\insertcaption}}{}{}%
\else
\addtocontents{lot}{\protect\listoffigureformat{\insertcaptionnumber}{\insertcaption}}{}{}%
\fi%
这是一个简单的测试,测试输入是数字还是其他东西。当然这个测试也可以更清晰地测试其他类型。
完整的重新定义如下:
\long\def\beamer@makecaption#1#2{%
\def\insertcaptionname{\csname#1name\endcsname}%
\def\insertcaptionnumber{\csname the#1\endcsname}%
\def\insertcaption{#2}%
\def\@tempa{#1}
\def\@tempb{figure}
\ifx\@tempa\@tempb
\addtocontents{lof}{\protect\listoffigureformat{\insertcaptionnumber}{\insertcaption}}{}{}%
\else
\addtocontents{lot}{\protect\listoffigureformat{\insertcaptionnumber}{\insertcaption}}{}{}%
\fi%
\nobreak\vskip\abovecaptionskip\nobreak
\sbox\@tempboxa{\usebeamertemplate**{caption}}%
\ifdim \wd\@tempboxa >\hsize
\usebeamertemplate**{caption}\par
\else
\global \@minipagefalse
\hb@xt@\hsize{\hfil\box\@tempboxa\hfil}%
\fi
\nobreak\vskip\belowcaptionskip\nobreak}
现在内容将使用命令写入外部文件中
\addtocontents{lot}{\protect\listoffigureformat{\insertcaptionnumber}{\insertcaption}}{}{}%
因此命令\listoffigureformat
目前未定义。因此我定义了命令来格式化输出listoffigures
:
\def\listoffigureformat#1#2{#1:~#2\par}
您看这非常简单。
最后一步是定义\listoffigures
使用内部命令\@starttoc
来读取文件\jobname.lof
。
\def\listoffigures{%
\frame{
\frametitle{List of Figures}
\@starttoc{lof}%
}
}
现在是完整的例子。
\documentclass{beamer}
\makeatletter
\AtEndDocument{%
\clearpage
\beamer@tempcount=\c@page\advance\beamer@tempcount by -1%
\if@filesw
\immediate\write\@auxout{\string\@writefile{lof}%
{\noexpand\headcommand{\noexpand\beamer@partpages{\the\beamer@partstartpage}{\the\beamer@tempcount}}}}%
\newwrite\tf@lof
\immediate\openout\tf@lof\jobname.lof\relax
\immediate\write\@auxout{\string\@writefile{lot}%
{\noexpand\headcommand{\noexpand\beamer@partpages{\the\beamer@partstartpage}{\the\beamer@tempcount}}}}%
\newwrite\tf@lot
\immediate\openout\tf@lot\jobname.lof\relax
\fi
}
\long\def\beamer@makecaption#1#2{%
\def\insertcaptionname{\csname#1name\endcsname}%
\def\insertcaptionnumber{\csname the#1\endcsname}%
\def\insertcaption{#2}%
\def\@tempa{#1}
\def\@tempb{figure}
\ifx\@tempa\@tempb
\addtocontents{lof}{\protect\listoffigureformat{\insertcaptionnumber}{\insertcaption}}{}{}%
\else
\addtocontents{lot}{\protect\listoffigureformat{\insertcaptionnumber}{\insertcaption}}{}{}%
\fi%
\nobreak\vskip\abovecaptionskip\nobreak
\sbox\@tempboxa{\usebeamertemplate**{caption}}%
\ifdim \wd\@tempboxa >\hsize
\usebeamertemplate**{caption}\par
\else
\global \@minipagefalse
\hb@xt@\hsize{\hfil\box\@tempboxa\hfil}%
\fi
\nobreak\vskip\belowcaptionskip\nobreak}
\def\listoffigureformat#1#2{#1:~#2\par}
\def\listoffigures{%
\frame{\frametitle{List of Figures}
\@starttoc{lof}%
}
}
\makeatother
\begin{document}
\listoffigures
\begin{frame}
\color{blue}
\begin{figure}
\rule{3cm}{3cm}
\caption{fig 1}
\end{figure}
\end{frame}
\begin{frame}
\begin{figure}
\color{green}
\rule{3cm}{3cm}
\caption{fig 2}
\end{figure}
\end{frame}
\begin{frame}
\begin{figure}
\color{blue}
\rule{3cm}{3cm}
\caption{fig 3}
\end{figure}
\end{frame}
\begin{frame}
\begin{figure}
\color{yellow}
\rule{3cm}{3cm}
\caption{fig 4}
\end{figure}
\end{frame}
\end{document}