diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/beamersubframe/beamersubframe.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/beamersubframe/beamersubframe.dtx | 2354 |
1 files changed, 2354 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/beamersubframe/beamersubframe.dtx b/Master/texmf-dist/source/latex/beamersubframe/beamersubframe.dtx new file mode 100644 index 00000000000..d6698dd3caf --- /dev/null +++ b/Master/texmf-dist/source/latex/beamersubframe/beamersubframe.dtx @@ -0,0 +1,2354 @@ +% \iffalse meta-comment +% +% Package beamersubframe +% Copyright (c) 2011 Mike Kaufmann, all rights reserved +% +% This program is provided under the terms of the +% LaTeX Project Public License distributed from CTAN +% archives in directory macros/latex/base/lppl.txt. +% +% Author: Mike Kaufmann +% m.km@gmx.de +% \fi +%% \CharacterTable +%% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z +%% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z +%% Digits \0\1\2\3\4\5\6\7\8\9 +%% Exclamation \! Double quote \" Hash (number) \# +%% Dollar \$ Percent \% Ampersand \& +%% Acute accent \' Left paren \( Right paren \) +%% Asterisk \* Plus \+ Comma \, +%% Minus \- Point \. Solidus \/ +%% Colon \: Semicolon \; Less than \< +%% Equals \= Greater than \> Question mark \? +%% Commercial at \@ Left bracket \[ Backslash \\ +%% Right bracket \] Circumflex \^ Underscore \_ +%% Grave accent \` Left brace \{ Vertical bar \| +%% Right brace \} Tilde \~} +%% +% \CheckSum{922} +% +% \iffalse meta-comment +% +%<*package> +%% +\def\fileversion{0.2} +\def\filedate{2011/08/07} + +%</package> +% +%<*driver> +\documentclass{ltxdoc} +\usepackage{hypdoc} +\usepackage{graphicx} +%\usepackage[pdfborder=0,colorlinks,linkcolor=blue]{hyperref} +\usepackage[all]{hypcap} +\setcounter{IndexColumns}{2} +\EnableCrossrefs +\CodelineIndex +%\RecordChanges +%\OnlyDescription +\makeatletter +% new, like ...Env... commands from doc.sty) +\let\PrintDescribeOpt\PrintDescribeEnv +\let\PrintOptName\PrintEnvName +\def\DescribeOpt{\leavevmode\@bsphack\begingroup\MakePrivateLetters + \Describe@Opt} +\def\Describe@Opt#1{\endgroup + \marginpar{\raggedleft\PrintDescribeOpt{#1}}% + \SpecialOptIndex{#1}\@esphack\ignorespaces} +\def\SpecialOptIndex#1{\@bsphack + \index{#1\actualchar{\protect\ttfamily#1} + (option)\encapchar usage}% + \index{options:\levelchar#1\actualchar{\protect\ttfamily#1}\encapchar + usage}\@esphack} +% new (like \SpecialEnvIndex from hypdoc.sty) +\let\HDorg@SpecialOptIndex\SpecialOptIndex +\renewcommand*\SpecialOptIndex[1]{% + \@bsphack + \begingroup + \HD@target + \let\HDorg@encapchar\encapchar + \edef\encapchar usage{% + \HDorg@encapchar hdclindex{\the\c@HD@hypercount}{usage}% + }% + \HDorg@SpecialOptIndex{#1}% + \endgroup + \@esphack +} +% redefinition (from doc.sty) +\def\macro{\begingroup + \catcode`\\12 + \MakePrivateLetters \m@cro@ \z@} +\def\environment{\begingroup + \catcode`\\12 + \MakePrivateLetters \m@cro@ \@ne} +% new, environment 'option', like 'environment', but index entries with +% '(option)' +\def\option{\begingroup + \catcode`\\12 + \MakePrivateLetters \m@cro@ \tw@} +% redefinition (from doc.sty) +\long\def\m@cro@#1#2{\endgroup \topsep\MacroTopsep \trivlist + \edef\saved@macroname{\string#2}% + \def\makelabel##1{\llap{##1}}% + \if@inlabel + \let\@tempa\@empty \count@\macro@cnt + \loop \ifnum\count@>\z@ + \edef\@tempa{\@tempa\hbox{\strut}}\advance\count@\m@ne \repeat + \edef\makelabel##1{\llap{\vtop to\baselineskip + {\@tempa\hbox{##1}\vss}}}% + \advance \macro@cnt \@ne + \else \macro@cnt\@ne \fi + \edef\@tempa{\noexpand\item[% + \ifcase #1% + \noexpand\PrintMacroName + \or + \noexpand\PrintEnvName + \or + \noexpand\PrintOptName + \fi + {\string#2}]}% + \@tempa + \global\advance\c@CodelineNo\@ne + \ifcase #1% + \SpecialMainIndex{#2}\nobreak + \DoNotIndex{#2}% + \or + \SpecialMainEnvIndex{#2}\nobreak + \or + \SpecialMainOptIndex{#2}\nobreak + \fi + \global\advance\c@CodelineNo\m@ne + \ignorespaces} +% new +\let\endoption\endmacro +\def\SpecialMainOptIndex#1{\@bsphack\special@index{% + #1\actualchar + {\string\ttfamily\space#1} + (option)% + \encapchar main}% + \special@index{options:\levelchar#1\actualchar{% + \string\ttfamily\space#1}\encapchar + main}\@esphack} +\makeatother +\begin{document} +\DocInput{beamersubframe.dtx} +\end{document} +%</driver> +% +%<*package> +% \fi +% +% \DoNotIndex{\^} +% \DoNotIndex{\@auxout} +% \DoNotIndex{\@@end,\@empty} +% \DoNotIndex{\@gobble,\@gobbletwo} +% \DoNotIndex{\@ifclassloaded,\@ifnextchar,\@ifundefined} +% \DoNotIndex{\@makeother} +% \DoNotIndex{\@nameuse} +% \DoNotIndex{\@tempa,\@tempb,\@tempcnta,\@tempcntb} +% \DoNotIndex{\@writefile,\@nameuse} +% \DoNotIndex{\advance,\active,\addtocontents,\addtocounter} +% \DoNotIndex{\AtBeginDocument,\AtEndDocument} +% \DoNotIndex{\begin,\begingroup} +% \DoNotIndex{\beamer@endpageofdocument,\beamer@endpageofframe} +% \DoNotIndex{\beamer@endpageofpart,\beamer@endpageofsection} +% \DoNotIndex{\beamer@endpageofsubsection} +% \DoNotIndex{\beamer@frameendpage,\beamer@framepages,\beamer@framestartpage} +% \DoNotIndex{\beamer@startpageofpart,\beamer@startpageofsection} +% \DoNotIndex{\beamer@startpageofsubsection,\beamer@subsectionstartpage} +% \DoNotIndex{\beamer@partstartpage,\beamer@sectionstartpage} +% \DoNotIndex{\beamer@ifempty,\beamer@notesactions,\beamer@tempcount} +% \DoNotIndex{\c@framenumber,\c@page,\c@part} +% \DoNotIndex{\c@section,\c@subsection,\c@subsectionslide} +% \DoNotIndex{\catcode,\clearpage,\closeout,\csname} +% \DoNotIndex{\DeclareOption,\def,\do,\dospecials} +% \DoNotIndex{\edef,\else,\end,\endgroup,\endcsname,\endinput,\ExecuteOption} +% \DoNotIndex{\expandafter,\ExecuteOptions} +% \DoNotIndex{\fi,\filedate,\fileversion} +% \DoNotIndex{\gdef,\global} +% \DoNotIndex{\headcommand,\hyperlink} +% \DoNotIndex{\if@filesw} +% \DoNotIndex{\if,\ifcase,\ifcat,\ifdim,\ifnum,\ifx,\InputIfFileExists} +% \DoNotIndex{\immediate,\input} +% \DoNotIndex{\insertpartheadnumber,\insertsectionhead,\insertsubsectionhead} +% \DoNotIndex{\insertsectionheadnumber,\insertsubsectionheadnumber} +% \DoNotIndex{\jobname} +% \DoNotIndex{\let,\lastsubsection} +% \DoNotIndex{\MessageBreak} +% \DoNotIndex{\NeedsTeXFormat,\newcommand,\newcount,\newdimen,\newif} +% \DoNotIndex{\newenvironment,\newtoks,\newwrite,\noexpand} +% \DoNotIndex{\openout} +% \DoNotIndex{\PackageError,\PackageWarning,\PackageInfo} +% \DoNotIndex{\ProcessOptions,\ProvidesPackage} +% \DoNotIndex{\protect} +% \DoNotIndex{\relax,\RequirePackage} +% \DoNotIndex{\setcounter,\slideentry,\space,\string} +% \DoNotIndex{\the} +% \DoNotIndex{\verbatim@,\verbatim@line,\verbatim@processline} +% \DoNotIndex{\write} +% \DoNotIndex{\xdef,\z@} +% +% \changes{0.1}{2011/06/29}{initial release} +% \changes{0.2}{2011/08/07}{proper package, manual and documentation} +% \changes{0.2}{2011/08/07}{appendix tested} +% \changes{0.2}{2011/08/07}{fixed navigation bar} +% \changes{0.2}{2011/08/07}{total number of frames not counting appended frames} +% \changes{0.2}{2011/08/07}{new environment lastframe} +% \changes{0.2}{2011/08/07}{subslideentry} +% \changes{0.2}{2011/08/07}{inserttotalframenumberwithsub} +% \changes{0.2}{2011/08/07}{new option nominiframes} +% \changes{0.2}{2011/08/07}{defaults for bsf@sub...page... macros} +% \changes{0.2}{2011/08/07}{checking .sfp file} +% +% \newcommand{\BSF}{\textsf{BeamerSubFrame}} +% +% \title{The \BSF\ Package\\[1ex] +% Reordering frames in the PDF file without reordering the source} +% \author{Mike Kaufmann\\\href{mailto:m.km@gmx.de}{\texttt{m.km@gmx.de}}} +% \date{\filedate\ (v\fileversion)} +% ^^A-------------------------------------------------------------------------- +% \maketitle +% \begin{abstract} +% The \BSF\ package provides a method to reorder frames in the +% PDF file without reordering the source. Mainly, it is meant to embed or +% append frames with details on some subject. +% \end{abstract} +% +% \tableofcontents +% +% ^^A-------------------------------------------------------------------------- +% \section{Introduction} +% \subsection{Why this Package} +% Of course, usually a presentation is prepared for one occasion. +% But sometimes a presentation is used more then once, and the audience +% and/or the available time differs. +% +% For me, there are two kinds of audience. The first group are the +% sales people, who for the most part only want to know the features +% of a new product I developed. And the second group are the technicians, +% who want to know everything. +% +% So basically, on one time I have to give a presentation in half an hour, +% covering only the basics. But there might be questions, where I need to +% show some details. In this case it's nice to have the necessary frames. +% And an another time, I have to give a presentation in one hour, covering +% also the details. +% +% In both cases, it would be nice to have a presentation, where normally +% only the cursor keys are needed for navigation, and without the necessity +% of clicking on links. +% +% With Beamer, one would have to create two presentation. One with the +% frames containing details at the end, and another one with the details +% between the other frames. +% +% Now here the \BSF\ package comes in handy. After some changes to the source +% of the presentation with the details embedded, both version can be compiled +% out of the same source. To select the version, only one option must be +% changed. +% +% ^^A--------------------------------------------- +% \subsection{A Warning} +% This package is in an early state of development (it's version +% \fileversion). It is already useful, but there are some restrictions (see +% \autoref{sec:restrictions}). And although it's not planned, the user +% interface may change in the future. +% +% ^^A--------------------------------------------- +% \subsection{Feeback and Testing} +% Because this package is very new and still under development, any feedback +% is appreciated. A good location for a discussion would be the newsgroup +% \texttt{comp.text.tex} (or \texttt{de.comp.text.tex}). +% +% And since Beamer offers a lot of features and it is hard to test the +% \BSF\ package with all of them, it would be nice, if some people would +% do some additional testing and/or provide some presentation for testing. +% +% ^^A--------------------------------------------- +% \subsection{Dependencies} +% The \BSF\ package can only be used with the Beamer class (article mode +% is not supported yet). +% +% Additionally, it needs the |verbatim| package. +% +% ^^A--------------------------------------------- +% \subsection{Legal Stuff} +% This program is provided under the terms of the +% \LaTeX\ Project Public License distributed from CTAN +% archives in directory macros/latex/base/lppl.txt. +% +% ^^A-------------------------------------------------------------------------- +% \section{Using the Packages} +% \subsection{Package Options} +% The \BSF\ package has three options. +% +% \DescribeOpt{embed} +% The option |embed| is used to put frames with details between the other +% frames. +% +% \DescribeOpt{append} +% The option |append| is used to remove the frames with details from the other +% frames and append them at the end of the PDF file. +% +% If none of these two options is given, |embed| is used as default. Both +% options are mutually exclusive. If both are given, the last one wins. +% +% \DescribeOpt{nominiframes} +% In themes with miniframes, there are also frame symbols for appended frames +% with details by default. If the option |nominiframes| is given, these frame +% symbols will disappear. This option has only an effect, if the |append| option +% is given too. +% +% ^^A--------------------------------------------- +% \subsection{The \texttt{subframe} Environment} +% \DescribeEnv{subframe} +% For frames which should be embedded or appended contitionally (i.e.\ frames +% with details), the |subframe| environment must be used instead of the |frame| +% environment. Basically, it works the same way as the |frame| environment, +% i.e.\ it has the same options and arguments. +% +% For typesetting, the |frame| environment is used internally. In embed mode +% (i.e.\ the |embed| option is given) it inserts the option |environment=subframe| +% to enable the use of verbatim material in the frames. In append mode the contents +% of the frame is written to a file. Before the contents, |\begin{frame}|, with +% all arguments of the |subframe| environment appended, is inserted. And after +% the contents |\end{frame}| is inserted. +% +% For copying the contents, the |verbatim| package is used. So in append mode +% the |subframe| environment is treated as a |verbatim| +% environment,\footnote{Because of this, the phrase \texttt{\bslash +% end\{subframe\}} cannot be used in a \texttt{subframe} environment.} but +% without typesetting anything. +% +% There should be no parts, sections, or subsections only containing subframes, +% because in append mode, they would have no contents. Since it is not the +% intention of the \BSF\ package, to move parts, sections, or subsections, this +% was not even tested. +% +% ^^A--------------------------------------------- +% \subsection{Appending Frames} +% \DescribeMacro\appendsubframes +% To append the subframes, the macro |\appendsubframes| must be called before +% |\end{document}|. In embed mode, the command simply does nothing. In append +% mode it inputs the file written by the |subframe| environments. +% +% The command is only allowed once and it can only appear right before +% |\end{document}|.\footnote{Both restrictions are not tested by the package yet.} +% Disregarding this may lead to some strange errors. +% +% The command can be omitted to remove the subframes from the PDF file in append +% mode. But links to them will then produce warnigs and will lead somewhere else. +% In themes with miniframes, the links of the miniframe symbols for subframes +% will lead to page 1. +% +% ^^A--------------------------------------------- +% \subsection{Conditional Execution} +% \DescribeMacro\ifappend +% To execute some macros or insert some text according to the mode of the +% \BSF\ package, the marco |\ifappend| can be used. It has two arguments. +% +% \vspace{1ex} +% |\ifappend{|\meta{material for append mode}|}{|\meta{material for embed mode}|}| +% +% \vspace{1ex} +% \noindent +% The first argument is inserted only in append mode and the second one only in +% embed mode. +% +% The macro is intended for conditional links in frames and subframes. It can +% be used in own macros. To do something only in one mode, the argument for the +% other mode can be left empty. +% +% ^^A--------------------------------------------- +% \subsection{The \texttt{lastframe} Environment} +% \DescribeEnv{lastframe} +% Normally, a presentation has a last frame, containing something like ``Thanks +% for listening'' (at least I learned it this way). But using a |frame| +% environmet, the navigation (sidebar, miniframes, and so on) appears as if the +% frame belongs to the last (sub)section. +% +% Using the |lastframe| environment, the navigation has the same appearance as +% on the title frame. +% +% It has the same options and arguments as the |frame| environment, which is +% used internally with all given arguments.. To enable the use of verbatim +% contents, it additionally inserts the option |environment=lastframe|. +% +% The |lastframe| environment must be used only for the last frame (before the +% |\appendsubframes| command), because it sets the counters for parts, sections, +% and subsections to 0. So after a ``lastframe'', sectioning will not work +% properly anymore. +% +% ^^A--------------------------------------------- +% \subsection{Inserts} +% \DescribeMacro\inserttotalframenumber +% Beamers |\inserttotalframenumber| was changed. In append mode it now contains +% the number of frames without the subframes. In embed mode it contains the +% number of frames as usual. +% +% \DescribeMacro\inserttotalframenumberwithsub +% Additionally, the insert |\inserttotalframenumberwithsub| is available. It +% inserts the total number of frames including appended subframes in append mode. +% It is also defined in embed mode. Then it just contains the total number of +% frames (so the same as |\inserttotalframenumber|). +% +% ^^A--------------------------------------------- +% \subsection{Files written} +% The \BSF\ package writes two files. +% \begin{description} +% \item[\texttt{\bslash jobname.sfr}] contains the contents of all subframes. +% The package inputs this file before the end of the document with the +% |\appendsubframes| command. The file is written regardless of |\nofiles|. +% \item[\texttt{\bslash jobname.sfp}] contains the information necessary for +% miniframes. It is written indirectly, using the |.aux| file. So if +% |\nofiles| is used, the |.sfp| file is not written too. +% \end{description} +% Both files are only written and used in append mode. +% +% ^^A--------------------------------------------- +% \subsection{Warnings and Errors} +% Currently, there is one warning and one error in the \BSF\ package. +% +% When loading the package, it checks, if the Beamer class is loaded. If not, +% an error message will be displayed and the package is not loaded. Disregarding +% this error will therefore lead to additional errors. +% +% The |.sfp| file is checked at the end of the document. If it is missing, +% corrupted or incomplete, a warning is given out. In this case some links of +% miniframe symbols for subframes will lead to page 1. Of course this applies +% only to themes with miniframes. +% +% ^^A--------------------------------------------- +% \subsection{Conditional Execution (2)} +% \DescribeMacro\ifsubframe +% This macro is intended to be used in themes, to make things appear differently +% on normal frames and subframes. This could be used to set some marker on +% subframes.\footnote{There is an example in the example file, which can be +% generated from \texttt{beamersubframe.dtx}.} The command works regardless of +% the mode. +% +% \vspace{1ex} +% |\ifsubframe{|\meta{material for subframes}|}{|\meta{material for normal frames}|}| +% +% \vspace{1ex} +% \noindent +% The first argument is inserted only in subframes and the second one only in +% normal frames. An unused argument may be left empty. +% +% ^^A--------------------------------------------- +% \subsection{The \texttt{subslideentry}} +% \label{sec:man-subse} +% \DescribeMacro\subslideentry +% This is not a macro for normal users. It may be useful for people who want to +% write their own theme, willing to do more, then defining and using templates. +% If you are not one of these people, just skip this section. +% +% In append mode, the \BSF\ package writes a |\subslideentry| instead of a +% |\slideentry| for subframes to the |.nav| file. The |\subslideentry| has the +% same arguments as the |\slideentry|. By default, it just passes its arguments +% to |\slideentry|. This way it does the same as |\slideentry|, independent of +% the used theme. By redefining |\subslideentry|, it is possible to, for example, +% make miniframes for subframes appear differently form miniframes for normal +% frames. +% +% ^^A-------------------------------------------------------------------------- +% \section{The Look and Feel} +% \subsection{In Embed Mode} +% In embed mode, the frames containing details are between the other frames. +% And navigation (navigation bar, sidebar and so on) behaves the same way, as +% it would without the \BSF\ package. Of course the highlighting of section +% and subsection names is the same too. +% +% ^^A--------------------------------------------- +% \subsection{In Append Mode} +% In apend mode, the frames containing details are at the end of the PDF file. +% +% The navigation in the main part (the part of the PDF without the details) +% behaves as if the frames with details are not part of the PDF. And for the +% total number of frames, the frames with details are not counted (leading to +% something like ``41 / 29'' for the subframes in themes with a footline like +% AnnArbor). +% +% In themes with miniframes there are also frame symbols for the frames with +% details. Clicking on the symbols leads to these frames. But if the option +% |nominiframes| is given, the frame symbols will disappear and the symbol for +% the normal frame before the frame with details is highlighted on the frame +% with details. +% +% The navigation bar in the appended part (the part of the PDF with frames +% containing details) behaves as follows +% \begin{description} +% \item[slide and frame symbol:] behave as if the appended frames where at the +% end of the source, so leading to the next or previous slide or frame in +% the PDF (arrows), or leading to the last or first slide of a frame. +% \item[section and subsection symbol:] are always leading to the appropriate +% slides in the main part of the PDF. +% \item[presentation symbol:] leads to the first frame of the presentation or +% the last frame of the main part (before a possible appendix). +% \item[appendix symbol:] leads to the first or last frame of the appendix. +% \end{description} +% +% The links for sections and subsections in the sidebar and others lead to the +% first slide of the section or subsetion. +% +% In the navigation part of appended frames, the section and subsection names +% are the same and the highlighting is done as if the frames where embedded. +% +% ^^A-------------------------------------------------------------------------- +% \section{A practical Approach} +% \subsection{The Order of Frames} +% If a presentation contains details on some items, there are two ways to +% insert them. +% \begin{enumerate} +% \item The details can be inserted right after the according item. This is +% useful, if it is planned to present the details. +% \item The details can be inserted at the end. This is useful, if it is not +% planned to present the details, but they might be needed to answer +% question. +% \end{enumerate} +% +% In both cases, links can be useful. In the first case, these are links to +% skip the details. And in the second case, these are links to jump to and +% return from the details. +% +% The first case is shown in \autoref{fig:embed} and the second in +% \autoref{fig:append}. In both pictures the black lines denote the +% transitions using the cursor keys, and the blue lines the transitions +% using links. The dashed black lines are transitions by cursor keys, which +% are normally not needed. +% +% \begin{figure}[htb] +% \includegraphics[width=\textwidth]{beamersubframe-embed.pdf} +% \caption{Frame Order with Details embedded}\label{fig:embed} +% \end{figure} +% +% \begin{figure}[htb] +% \includegraphics[width=\textwidth]{beamersubframe-append.pdf} +% \caption{Frame Order with Details appended}\label{fig:append} +% \end{figure} +% +% Of course, the way the links are arranged in the picuters is only an example. +% There are hundreds of possibilities. And how the links are arranged the best +% way, depends on the presentation \emph{and} on the person giving the +% presentation. For this section, let's consider the links in the pictures +% the ideal way. +% +% To use the \BSF\ package, in the source the frames must be arranged as shown +% in \autoref{fig:embed}. By default, the frames in the PDF file are arranged +% the same way. By just using the option |append|, the frames in the PDF file +% will be arragned as shown in \autoref{fig:append}. +% +% ^^A--------------------------------------------- +% \subsection{Basic Changes to the Source} +% To use the \BSF\ package, a few changes to the source of a presentaion must +% be applied. In the example below, the left side shows the source before the +% changes and the right side the source after them. +% +% \noindent +% \begin{minipage}{0.49\textwidth} +% \footnotesize +% \begin{verbatim} +% \begin{frame}{Frame on Foo} +% material on foo +% \end{frame} +% +% \begin{frame} +% {Details on Foo Item b} +% details for item b +% \end{frame} +% +% \begin{frame}{Another Frame} +% other material +% \end{frame} +% +% \end{document} +% \end{verbatim} +% \end{minipage} +% \hfill +% \begin{minipage}{0.49\textwidth} +% \footnotesize +% \begin{verbatim} +% \begin{frame}{Frame on Foo} +% material on foo +% \end{frame} +% +% \begin{subframe} +% {Details on Foo Item b} +% details for item b +% \end{subframe} +% +% \begin{frame}{Another Frame} +% other material +% \end{frame} +% \appendsubframes +% \end{document} +% \end{verbatim} +% \end{minipage} +% +% Here, the |frame| environment for the frame with details was changed to the +% |subframe| environment, and the command |\appendsubframes| was inserted +% before |\end{document}|. This is the minimum of changes necessary. +% +% It is not necessary, to change the arguments of subframes. Also, there is no +% need to change the contents of subframes. Even the |fragile| option (for +% verbatim material) will work, because the |subframe| environment automatically +% adds the option |environment=subframe|. +% +% ^^A--------------------------------------------- +% \subsection{Conditional Links} +% \label{sec:clinks} +% How links are used and arranged, it totally up to the user, because this is +% highly individual. But nevertheless, links in embed mode should be different +% from links in append mode. For example, a link on a frame before a subframe +% (or a group of subframes) with details should skip them in embed mode, while +% in append mode the same link should lead to the subframe (or the first +% subframe of the group). +% +% Let's stay with the examples shown in \autoref{fig:embed} and +% \autoref{fig:append}. +% +% The link ``Skip Details'' on slide 2 of ``frame on foo'' in embed mode is +% replaced by a link ``Goto Details'' in append mode. In the first case the +% destination is slide 3 of ``frame on foo'' and in the second case it is +% slide 1 of ``details on foo item b''. +% +% Let's say, ``frame on foo'' has a label ``lfoo'', given as option |label=lfoo| +% to the |frame| environment (this is also necessary, if the \BSF\ package is +% not used). For append mode a label must be added to the subframe ``details +% on foo item b''. Let's call it ``ldfoob''. +% +% For embed mode the link can be realised with +% \begin{verbatim} +% \uncover<2>{\hyperlink{lfoo<3>}{\beamerskipbutton{Skip Details}}} +% \end{verbatim} +% and for append mode with +% \begin{verbatim} +% \uncover<2>{\hyperlink{ldfoob}{\beamergotobutton{Goto Details}}} +% \end{verbatim} +% +% In order to make the link work as expected in both modes, without the need to +% change the source, |\ifappend| can be used like this: +% \begin{verbatim} +% \ifappend{\uncover<2>{\hyperlink{ldfoob}% +% {\beamergotobutton{Goto Details}}}}% +% {\uncover<2>{\hyperlink{lfoo<3>}% +% {\beamerskipbutton{Skip Details}}}} +% \end{verbatim} +% +% The link to return from the frames with details can then be done this way: +% \begin{verbatim} +% \ifappend{\uncover<4>{\hyperlink{lfoo<3>}% +% {\beamerreturnbutton{Return from Details}}}}{} +% \end{verbatim} +% This has the disatvantage, that in embed mode there is no link, and therefore +% the layout will differ between embed mode and append mode. But this can be +% fixed by adding an invisible button like this: +% \begin{verbatim} +% \ifappend{\uncover<4>{\hyperlink{lfoo<3>} +% {\beamerreturnbutton{Return from Details}}}}% +% {\visible<0>{\beamerreturnbutton{Return from Details}}} +% \end{verbatim} +% +% Typing all this every time can be a bit exhausting. So let's define some macros. +% +% For skipping or going to the details, a macro called |\linkdetail| can be +% defined as +% \begin{verbatim} +% \newcommand<>{\linkdetail}[4]{% +% \ifappend{\uncover#5{\hyperlink{#3}{\beamergotobutton{#4}}}}% +% {\uncover#5{\hyperlink{#1}{\beamerskipbutton{#2}}}} +% } +% \end{verbatim} +% +% The command is overlay-aware and it has four arguments: +% \begin{description} +% \item[\texttt{\#1}] is the label for the destination to go to in order to skip +% the details. +% \item[\texttt{\#2}] is the text for the link to skip the details. +% \item[\texttt{\#3}] is the label for the destination to go to in order to jump +% to the details. +% \item[\texttt{\#4}] is the text for the link to go to the details. +% \end{description} +% Now the link on the frame before the subframe can be written as +% \begin{verbatim} +% \linkdetails<2>{lfoo<3>}{Skip Details}{ldfoob}{Goto Details} +% \end{verbatim} +% +% For returning from the details, a macro called |\returndetail| can be +% defined as +% \begin{verbatim} +% \newcommand<>{\returndetail}[2]{% +% \ifappend{\uncover#3{\hyperlink{#1}{\beamerreturnbutton{#2}}}}% +% {\visible<0>{\beamerreturnbutton{#2}}} +% } +% \end{verbatim} +% +% The command is also overlay-aware and it has two arguments: +% \begin{description} +% \item[\texttt{\#1}] is the label for the destination to go to in order to return +% from details. +% \item[\texttt{\#2}] is the text for the link to return from details. +% \end{description} +% And the link on the subframe can be written as +% \begin{verbatim} +% \returndetails<4>{lfoo<3>}{Return from Details} +% \end{verbatim} +% +% Of course, these are only examples. How links are done, is up to the user. +% And therefore, it is also up to the user, how commands like |\linkdetail| and +% |\returndetail| are defined. +% +% Another example: I like my links to be active only on the slide, they are +% needed. On all other slides, they should be covered and inactive. So I definded +% the macros a bit different: +% \begin{verbatim} +% \newcommand<>{\linkdetail}[4]{% +% \ifappend{\uncover#5{\alt#5{\hyperlink{#3}{\beamergotobutton{#4}}}% +% {\beamergotobutton{#4}}}}% +% {\uncover#5{\alt#5{\hyperlink{#1}{\beamerskipbutton{#2}}}% +% {\beamerskipbutton{#2}}}} +% } +% \newcommand<>{\returndetail}[2]{% +% \ifappend{\uncover#3{\alt#3{\hyperlink{#1}{\beamerreturnbutton{#2}}}% +% {\beamerreturnbutton{#2}}}}{} +% } +% \end{verbatim} +% +% ^^A--------------------------------------------- +% \subsection{An Example} +% \subsubsection{Without \BSF} +% As an example, let's realise frames in the order shown in \autoref{fig:embed} +% and \autoref{fig:append}. To show the difference of the source with and +% without using the \BSF\ package, first the order shown in \autoref{fig:embed} +% is realised without \BSF. +% +% \begin{verbatim} +% \documentclass{beamer} +% \usepackage{lmodern} +% \usepackage[T1]{fontenc} +% +% \begin{document} +% \begin{frame}{some frame} +% \begin{itemize}[<+->] +% \item there is foo +% \item foo is good +% \item and there is bar +% \item bar is good too +% \end{itemize} +% \end{frame} +% +% \begin{frame}<1-2>[label=lfoo]{frame on foo} +% \begin{itemize}[<+->] +% \item item a +% \item item b \uncover<2>{\hyperlink{lfoo<3>}% +% {\beamerskipbutton{Skip Details}}} +% \item item c +% \item item d +% \end{itemize} +% \end{frame} +% +% \begin{frame}{details on foo item b} +% \begin{itemize}[<+->] +% \item item b.1 +% \item item b.2 +% \item item b.3 +% \item item b.4 +% \end{itemize} +% \end{frame} +% +% \begin{frame} +% \frametitle{more details on foo item b} +% \begin{itemize}[<+->] +% \item item b.5 +% \item item b.6 +% \item item b.7 +% \item item b.8 +% \end{itemize} +% \end{frame} +% +% \againframe<3->{lfoo} +% +% \begin{frame}{frame on bar} +% \begin{itemize}[<+->] +% \item item w +% \item item x +% \item item y +% \item item z \uncover<4>{\hyperlink{lother}% +% {\beamerskipbutton{Skip Details}}} +% \end{itemize} +% \end{frame} +% +% \begin{frame} +% \frametitle{details on bar item z} +% \begin{itemize}[<+->] +% \item item z.1 +% \item item z.2 +% \item item z.3 +% \item item z.4 +% \end{itemize} +% +% \vspace{2ex} +% \uncover<4>{\hyperlink{lother}{\beamerskipbutton{Skip further Details}}} +% \end{frame} +% +% \begin{frame}{more details on bar item z} +% \begin{itemize}[<+->] +% \item item z.5 +% \item item z.6 +% \item item z.7 +% \item item z.8 +% \end{itemize} +% \end{frame} +% +% \begin{frame}[label=lother]{another frame} +% \begin{itemize}[<+->] +% \item conclusion 1 +% \item conclusion 2 +% \item conclusion 3 +% \item conclusion 4 +% \end{itemize} +% \end{frame} +% \end{document} +% \end{verbatim} +% +% ^^A------------------------- +% \subsubsection{With \BSF} +% And now the same order of frames, but this time using the \BSF\ package and +% with some comments. +% \begin{verbatim} +% \documentclass{beamer} +% \usepackage{lmodern} +% \usepackage[T1]{fontenc} +% \end{verbatim} +% Here, the option |embed| has to be changed to |append|, to get the order as +% shown in \autoref{fig:append}. +% \begin{verbatim} +% \usepackage[embed]{beamersubframe} +% \end{verbatim} +% The two commands, as explained in \autoref{sec:clinks}. +% \begin{verbatim} +% \newcommand<>{\linkdetail}[4]{% +% \ifappend{\uncover#5{\hyperlink{#3}{\beamergotobutton{#4}}}}% +% {\uncover#5{\hyperlink{#1}{\beamerskipbutton{#2}}}} +% } +% \newcommand<>{\returndetail}[2]{% +% \ifappend{\uncover#3{\hyperlink{#1}{\beamerreturnbutton{#2}}}}% +% {\visible<0>{\beamerreturnbutton{#2}}} +% } +% \end{verbatim} +% The next command realises a link with the same destination (argument |#1|) for +% both modes, but different texts (|#2| for embed mode and |#3| for append mode. +% \begin{verbatim} +% \newcommand<>{\linkdifftext}[3]{% +% \ifappend{\uncover#4{\hyperlink{#1}{\beamergotobutton{#3}}}}% +% {\uncover#4{\hyperlink{#1}{\beamerskipbutton{#2}}}} +% } +% \end{verbatim} +% The template defined below is an example for the use of |\ifsubframe|. It puts +% the text ``detail'' in the lower left corner of subframes and ``main part'' in +% the lower left corner of normal frames. Careful: it replaces a sidebar, so +% this will not work with themes like Berkeley. +% \begin{verbatim} +% \defbeamertemplate*{sidebar left}{bsf test}[1][50] +% { +% \vfill% +% \rlap{\hskip0.1cm\hbox{\color{fg!#1!bg}\tiny{\ifsubframe{detail}{main part}}}}% +% \vskip2pt% +% } +% +% \begin{document} +% \begin{frame}{some frame} +% \begin{itemize}[<+->] +% \item there is foo +% \item foo is good +% \item and there is bar +% \item bar is good too +% \end{itemize} +% \end{frame} +% +% \begin{frame}<1-2>[label=lfoo]{frame on foo} +% \begin{itemize}[<+->] +% \item item a +% \end{verbatim} +% Here, the link was changed. +% \begin{verbatim} +% \item item b \linkdetail<2>{lfoo<3>}{Skip Details}{ldfoob}{Goto Details} +% \item item c +% \item item d +% \end{itemize} +% \end{frame} +% \end{verbatim} +% For the next two frames the environment was changed to |subframe|. And for the +% first, the label |ldfoob| was added. +% \begin{verbatim} +% \begin{subframe}[label=ldfoob]{details on foo item b} +% \begin{itemize}[<+->] +% \item item b.1 +% \item item b.2 +% \item item b.3 +% \item item b.4 +% \end{itemize} +% \end{subframe} +% +% \begin{subframe} +% \frametitle{more details on foo item b} +% \begin{itemize}[<+->] +% \item item b.5 +% \item item b.6 +% \item item b.7 +% \item item b.8 +% \end{itemize} +% +% \vspace{2ex} +% \end{verbatim} +% The link to return from details was added. Because there was no link in the +% version without \BSF\ the layout of the frame is now changed compared to that +% version. But it doesn't change from one mode to the other, because of the way +% |\returndetails| was definded. +% \begin{verbatim} +% \returndetail<4>{lfoo<3>}{Return from Details} +% \end{subframe} +% +% \againframe<3->{lfoo} +% +% \begin{frame}{frame on bar} +% \begin{itemize}[<+->] +% \item item w +% \item item x +% \item item y +% \end{verbatim} +% Again, the link was changed here. +% \begin{verbatim} +% \item item z \linkdetail<4>{lother}{Skip Details}{ldbarz}{Goto Details} +% \end{itemize} +% \end{frame} +% \end{verbatim} +% For the next two frames the environment was changed to |subframe| also. And +% for the first, the label |ldbarz| was added. +% \begin{verbatim} +% \begin{subframe}[label=ldbarz] +% \frametitle{details on bar item z} +% \begin{itemize}[<+->] +% \item item z.1 +% \item item z.2 +% \item item z.3 +% \item item z.4 +% \end{itemize} +% +% \vspace{2ex} +% \end{verbatim} +% This link was changed, so the text differs between modes. But it would have +% been possible here, to leave the link unchanged. +% \begin{verbatim} +% \linkdifftext<4>{lother}{Skip further Details}{Return from Details} +% \end{subframe} +% +% \begin{subframe}{more details on bar item z} +% \begin{itemize}[<+->] +% \item item z.5 +% \item item z.6 +% \item item z.7 +% \item item z.8 +% \end{itemize} +% +% \vspace{2ex} +% \end{verbatim} +% Again, the link was added here, resulting also in a change off layout compared +% to the first version. +% \begin{verbatim} +% \returndetail<4>{lother}{Return from Details} +% \end{subframe} +% +% \begin{frame}[label=lother]{another frame} +% \begin{itemize}[<+->] +% \item conclusion 1 +% \item conclusion 2 +% \item conclusion 3 +% \item conclusion 4 +% \end{itemize} +% \end{frame} +% \end{verbatim} +% And finally, the |\appendsubframes| command was inserted here. +% \begin{verbatim} +% \appendsubframes +% \end{document} +% \end{verbatim} +% +% The source of the second version is available as example file, which can be +% generated from |beamersubframe.dtx|. +% +% ^^A-------------------------------------------------------------------------- +% \section{Restrictions} +% \label{sec:restrictions} +% Since this is an early version of the \BSF\ package, there are some +% restrictions. +% +% \begin{itemize} +% \item The package was only tested with Beamer mode |beamer|. Using other +% modes may lead to strange errors. +% \item Supporting material, like notes, is not tested yet. +% \item Lectures are not tested yet. +% \item There is no support for subsubsections (not even tested). And it is not +% planned at all. +% \item There is no |\subframe| command. +% \item There is no |\againsubframe| command. +% \end{itemize} +% +% ^^A-------------------------------------------------------------------------- +% \section{Testing} +% For testing the \BSF\ package the following themes were used: +% \begin{itemize} +% \item Dresden +% \item Darmstadt +% \item Berkeley +% \item Montpellier +% \item Malmoe +% \item AnnArbor +% \end{itemize} +% +% The themes were used without options. They where choosen to cover all types of +% navigation possible with the themes delivered with Beamer. If I missed +% something and this doesn't work, please let me know. If there are other things +% not working (e.g.\ some inserts), please let me know too. In both cases, a +% file for testing would be nice. +% +% ^^A-------------------------------------------------------------------------- +% \section{ToDo} +% Although the \BSF\ package is already useful, there are a lot of things left +% to do: +% \begin{description} +% \item[testing] Beamer has a lot of features, an many of them are still +% not tested. +% \item[Beamer modes] I have to admit, I didn't even test them. +% \item[notes] The same here. +% \item[lectures] And again, not tested. +% \item[macros] There are commands, which would be nice to have, like +% |\subframe|, |\againsubframe|, and |\subnote| (to get notes between +% frames moved too) +% \item[levels] With multiple levels of subframes, it would be possible, to have +% details on details (on details on \dots). And then, one could embed the +% first $n$ levels of details, and append the others. +% \end{description} +% +% The list is not complete. If someone has an item to add, please let me know. +% +% ^^A-------------------------------------------------------------------------- +% \StopEventually{\newpage\PrintIndex} +% ^^A \PrintChanges} +% +% ^^A-------------------------------------------------------------------------- +% \newpage +% \section{The Code} +% \subsection{The Usual} +% First the usual things. +% \begin{macrocode} +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{beamersubframe}[\filedate\space + v\fileversion\space reordering beamer frames] +% \end{macrocode} +% +% ^^A--------------------------------------------- +% \subsection{Check the Class} +% Since the \BSF\ package only works with the Beamer class and article mode is +% not supported yet, check for the Beamer class. If it is not loaded, throw an +% error message and stop loading the package. +% \begin{macrocode} +\@ifclassloaded{beamer}{}{% + \PackageError{beamersubframe}{% + The package works only with the beamer class,\MessageBreak + therefore it is not loaded. + }{% + The package is not loaded, because it needs the\MessageBreak + beamer class. Continuing may lead to additional\MessageBreak + errors because of undefined commands. + } + \endinput +} +% \end{macrocode} +% +% ^^A--------------------------------------------- +% \subsection{``Variables''} +% \begin{macro}{\if@bsf@append} +% First there is the main flag to distinguish between append mode and embed mode. +% \begin{macrocode} +\newif\if@bsf@append +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\if@bsf@miniframes} +% This flag is true by default. It is set to false by the option |nominiframes|. +% \begin{macrocode} +\newif\if@bsf@miniframes +\@bsf@miniframestrue +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\if@bsf@subframe} +% This flag is set to true for subframes in both modes. For normal frames it is +% false. +% \begin{macrocode} +\newif\if@bsf@subframe +\@bsf@subframefalse +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\if@bsf@nosfnum} +% This flag is used for checking the |.sfp| file. +% \begin{macrocode} +\newif\if@bsf@nosfnum +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\if@bsf@firstline} +% This flag is needed to write |\begin{frame}| in front of the arguments of a +% |subframe| environment to the |.sfr| file in append mode. +% \begin{macrocode} +\newif\if@bsf@firstline +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\if@bsf@firstpart} +% This flag is needed by |\bsfrestorepart| to initialize some macros used as +% variables instead of writing the |\bsf@partpages| entry to the |.nav| file. +% \begin{macrocode} +\newif\if@bsf@firstpart +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\if@bsf@firstsection} +% This flag is needed by |\bsfrestoresection| to initialize some macros used as +% variables instead of writing the |\bsf@sectionpages| entry to the |.nav| file. +% \begin{macrocode} +\newif\if@bsf@firstsection +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\if@bsf@firstsubsection} +% This flag is needed by |\bsfrestoresubsection| to initialize some macros used +% as variables instead of writing the |\bsf@subsectionpages| entry to the |.nav| +% file. +% \begin{macrocode} +\newif\if@bsf@firstsubsection +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\if@bsf@nosubsection} +% This flag is used by |\bsfrestoresection| and |\bsfrestoresubsection| to +% determine, if a section contains any subsections. +% \begin{macrocode} +\newif\if@bsf@nosubsection +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\if@bsf@prevnosubsection} +% This flag contains the final state of |\if@bsf@nosubsection| for the previous +% section. +% \begin{macrocode} +\newif\if@bsf@prevnosubsection +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bsf@frame@param} +% This token register is used to store the first three arguments of the +% |subframe| environment in embed mode, after adding the option +% |environmet=subframe|. The contents is passed to the |frame| environmet as +% its first three arguments. +% \begin{macrocode} +\newtoks\bsf@frame@param +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bsf@sfrout} +% The stream used to write the |.sfr| file. It holds the contents of all +% subframes. The file is only written and used in append mode. +% \begin{macrocode} +\newwrite\bsf@sfrout +% \end{macrocode} +% \end{macro} +% +% ^^A--------------------------------------------- +% \subsection{Options and Packages} +% \begin{option}{embed} +% The options are rather simple. The option |embed| just sets |\if@bsf@append| +% to false. +% \begin{macrocode} +\DeclareOption{embed}{\@bsf@appendfalse} +% \end{macrocode} +% \end{option} +% \begin{option}{append} +% And |append| sets |\if@bsf@append| to true. +% \begin{macrocode} +\DeclareOption{append}{\@bsf@appendtrue} +% \end{macrocode} +% \end{option} +% \begin{option}{nominiframes} +% The option |nominiframes| sets |\if@bsf@miniframes| to false. +% \begin{macrocode} +\DeclareOption{nominiframes}{\@bsf@miniframesfalse} +% \end{macrocode} +% \end{option} +% The default is set and the options are processed. +% \begin{macrocode} +\ExecuteOptions{embed} +\ProcessOptions*\relax +% \end{macrocode} +% And the verbatim package is loaded. +% \begin{macrocode} +\RequirePackage{verbatim} +% \end{macrocode} + +% ^^A--------------------------------------------- +% \subsection{Navigation} +% \subsubsection{Sidebar and Headline} +% To get the highlighting of sections and subsections on appened subframes as if +% the frames were embedded, some counters must be restored to the values, they +% had at the point, the subframe appeared in the source. Additionally, for the +% headline some inserts must be restored. +% +% To achieve this, the |subframe| environment writes a macro with all necessary +% arguments to the |.sfr| file. This is done for each subframe, before its +% contents, embedded in a |frame| environmet, is written to the file (see +% \autoref{sec:code-subframe}). +% +% \begin{macro}{\bsfrestore} +% The macro is called |\bsfrestore|. It is executed, when the |.sfr| file is +% loaded. It restores the counters for part (|#1|), section (|#2|), and +% aubsection (|#3|). It also restores the counter subsectionslide (|#4|), which +% is needed for miniframes. +% +% Then |\insertsectionhead| and |\insertsubsectionhead| are restored to their +% meanings at the point, the subframe appeard in the source. These meanings were +% stored to the two macros |\bsf@sectionhead|\meta{part}|.|\meta{section} and +% |\bsf@subsectionhead|\meta{part}|.|\meta{section}|.|\meta{subsection} by the +% |subframe| environment (see \autoref{sec:code-subframe}). +% +% After that, the inserts for the part, section, and subsection numbers are +% restored. +% +% The macro is also used by the |lastframe| environment (see +% \autoref{sec:code-lastframe}). +% \begin{macrocode} +\newcommand{\bsfrestore}[4]{% + \setcounter{part}{#1}% + \setcounter{section}{#2}% + \setcounter{subsection}{#3}% + \setcounter{subsectionslide}{#4}% + \expandafter\let\expandafter\insertsectionhead + \csname bsf@sectionhead\the\c@part.\the\c@section\endcsname + \expandafter\let\expandafter\insertsubsectionhead + \csname bsf@subsectionhead\the\c@part.\the\c@section.\the\c@subsection\endcsname + \def\insertpartheadnumber{#1}% + \def\insertsectionheadnumber{#2}% + \def\insertsubsectionheadnumber{#3}% +} +% \end{macrocode} +% \end{macro} +% +% ^^A------------------------- +% \subsubsection{Miniframes} +% \label{sec:code-miniframes} +% To typset miniframes, Beamer writes a |\slideentry| with the necessary +% arguments to the |.nav| file. Because miniframes should appear, as if the +% subframes are embedded, the |subframe| environment has to write such an entry +% at the point, the subframe appears in the source. But instead of a +% |\slideentry|, \BSF\ writes a |\subslideentry| (see \autoref{sec:man-subse}). +% +% Argument |#4| of |\slideentry| contains the start page and the end page of the +% frame. Unfortunately, for subframes these numbers are unknown, until the +% |.sfr| file was loaded by |\appendsubframes|. +% +% To get around this, for each subframe two macros are used. Their names \linebreak +% are +% |\bsf@substartpage|\meta{part}|.|\meta{section}|.|\meta{subsection}|.|\meta{subsectionslide} +% and \linebreak +% |\bsf@subendpage|\meta{part}|.|\meta{section}|.|\meta{subsection}|.|\meta{subsectionslide}. +% Here \meta{part}, \meta{section} and so on are the numbers. +% +% Now at the point where the subframe appears in the souce, the |\subslideentry| +% is written. Instead of the unknown frame numbers, it contains the sequence +% |{\bsf@usenum{bsf@substartpage...}/\bsf@usenum{bsf@subendpage...}}| as argument +% |#4|. After a subframe was typeset by loading the |.sfr| file, the necessary +% information is written to the |.sfp| file. In the next \TeX\ run, when loading +% the |.sfp| file at the beginning of the document (see \autoref{sec:code-beginend}), +% these macros are all defined. +% +% \begin{macro}{\bsf@subnum} +% The first macro involved is just a shortcut to get the numbers. +% \begin{macrocode} +\def\bsf@subnum{% + \the\c@part.\the\c@section.\the\c@subsection.\the\c@subsectionslide +} +% \end{macrocode} +% \end{macro} +% +% Beamer uses the macro |\beamer@writeslidentry| to write the |\slideentry| and +% the |\beamer@framepages| entry (used for the navigation bar) to the |.nav| +% file. For subframes this is split into two macros. +% +% \begin{macro}{\beamer@writeslidentry@miniframes} +% The |\subslideentry| is written by |\beamer@writeslidentry@miniframes|. The +% macro is called directly by the |subframe| environment (see +% \autoref{sec:code-subframe}). +% \begin{macrocode} +\def\beamer@writeslidentry@miniframes{% + \addtocontents{nav}% + {\protect\headcommand{% + \protect\subslideentry{\the\c@section}{\the\c@subsection}% + {\the\c@subsectionslide}% + {\protect\bsf@usenum{bsf@substartpage\bsf@subnum}/% + \protect\bsf@usenum{bsf@subendpage\bsf@subnum}}% + {\lastsubsection}{\the\c@part}}}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\beamer@writeslidentry@navbar} +% The |\beamer@framepages| entry is written by |\beamer@writeslidentry@navbar|. +% And it also writes the |\bsfsubframepages| entry to the |.sfp| file. +% +% This macro is used to replace |\beamer@writeslidentry|, before the |.sfr| file +% is loaded. This is done in |\appendsubframes| (see \autoref{sec:code-appendsub}). +% \begin{macrocode} +\def\beamer@writeslidentry@navbar{% + \expandafter\beamer@ifempty\expandafter{\beamer@framestartpage}{}% does not happen normally + {%else + \addtocontents{nav}% + {\protect\headcommand{% + \protect\beamer@framepages{\beamer@framestartpage}{\beamer@frameendpage}}}% + \addtocontents{sfp}{% + \protect\bsfsubframepages{\the\c@part}{\the\c@section}{\the\c@subsection}% + {\the\c@subsectionslide}{\beamer@framestartpage}{\beamer@frameendpage}}% + \clearpage\beamer@notesactions% + }% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\subslideentry} +% The |\subslideentry| is initialized in a way that it does the same as the +% |\slideentry|. Because |\slideentry| is refedined by some themes, |\let| can +% not be used here. +% \begin{macrocode} +\def\subslideentry{\slideentry} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bsfsubframepages} +% The |.sfp| file contains one |\bsfsubframepages| entry for each subframe. The +% arguments are the part number (|#1|), the section number (|#2|), the subsection +% number (|#3|), the subsectionslide number (|#4|), and the first (|#5|) and the +% last page of the subframe (|#6|). +% +% When the |.sfp| file is loaded, each |\bsfsubframepages| defines two macros +% |\bsf@substartpage...| and |\bsf@subendpage...| used by the |\subslideentry|. +% \begin{macrocode} +\def\bsfsubframepages#1#2#3#4#5#6{% + \expandafter\def\csname bsf@substartpage#1.#2.#3.#4\endcsname{#5}% + \expandafter\def\csname bsf@subendpage#1.#2.#3.#4\endcsname{#6}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bsf@usenum} +% The macro |\bsf@usenum|, used in the |\subslideentry|, sets a default in case +% the |\bsf@substartpage...| and |\bsf@subendpage...| macros are not defined due +% to a missing, corrupted or incomplete |.sfp| file. Without this, there could +% be errors which would persist on every subsequent run of \TeX. +% \begin{macrocode} +\def\bsf@usenum#1{% + \@ifundefined{#1}{1}{\csname #1\endcsname}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bsf@checksfp} +% In order to warn the user about a missing, corrupted or incomplete |.sfp| file, +% the file is checked. This is done indirectly by checking, if all +% |\bsf@substartpage...| and |\bsf@subendpage...| macros in the current |.nav| +% file are defined. +% +% For this all commands in the |.nav| file are executed using Beamers |\dohead| +% command. Because some of the commands would typeset something, they are +% disabled and everything is done in a group to keep the changes local. +% +% The macro |\bsf@usenum| is also redefined to set the flag |\if@bsf@nosfnum| to +% true in case one of the checked macros is undefined. +% \begin{macrocode} +\def\bsf@checksfp{% + \begingroup + \@bsf@nosfnumfalse + \def\bsf@usenum##1{% + \@ifundefined{##1}{\@bsf@nosfnumtrue}{}} + \def\slideentry##1##2##3##4##5##6{}% + \def\partentry##1##2{}% + \def\sectionentry##1##2##3##4##5{}% + \def\beamer@subsectionentry##1##2##3##4##5{}% + \def\subslideentry##1##2##3##4##5##6{% + \bsf@checksfnum(##4)}% + \dohead + \if@bsf@nosfnum + \PackageWarningNoLine{Beamer SubFrame}{% + Missing, incomplete or corrupted file\MessageBreak + \jobname.sfp! Links for miniframes of\MessageBreak + subframes may be wrong. Please run TeX\MessageBreak + again} + \fi + \endgroup +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bsf@checksfnum} +% The macro |\bsf@checksfnum| is just used by |\bsf@checksfp| to get rid of the +% slash in argument |#4| of the |\subslideentry|. +% \begin{macrocode} +\def\bsf@checksfnum(#1/#2){#1#2} +% \end{macrocode} +% \end{macro} +% +% ^^A------------------------- +% \subsubsection{Navigation Bar} +% Getting the navigation bar right takes some effort. First lets take a look, +% what Beamer does to get the necessary information for the navigation bar. +% +% \paragraph{How Beamer does it}~\\ +% Beamer writes several different entries to the |.nav| file. +% \begin{description} +% \item[\texttt{\bslash beamer@framepages}] with the first and the last page of +% the frame as arguments. It is written for every frame at its end. +% \item[\texttt{\bslash beamer@subsectionpages}] with the first and the last +% page of the subsection as arguments. It is written by the |\subsection| +% command for the previous subsection, as well as by |\section| and +% |\part| and the end of the document for the last subsection. +% \item[\texttt{\bslash beamer@sectionpages}] with the first and the last page +% of the section as arguments. It is written by the |\section| command for +% the previous section, as well as by |\part| and the end of the document +% for the last section. +% \item[\texttt{\bslash beamer@partpages}] with the first and the last page of +% the part as arguments. It is written by the |\part| command for the +% previous part and the end of the document for the last part. +% \item[\texttt{\bslash beamer@documentpages}] with the last page of the +% documnet as argument. It is written at the end of the document. +% \end{description} +% +% The macros in the |.nav| file are executed once for every page (i.e.\ slide). +% By this the entry |\beamer@framepages| sets the macro |\beamer@startpageofframe| +% to its first argument and |\beamer@endpageofframe| to its second argument, but +% only if the current page is $\ge$ than the first argument and $\le$ than the +% second one. Similar macros are set the same way by the other entries. +% +% The frame icon is then typeset in a way, that +% \begin{itemize} +% \item the left arrow points to page |\beamer@startpageofframe| $-1$, +% \item the left part of the frame symbol points to page |\beamer@startpageofframe|, +% \item the right part of the frame symbol points to page |\beamer@endpageofframe|, +% \item and the right arrow points to page |\beamer@endpageofframe| $+1$. +% \end{itemize} +% The arrows are limited 1 or |\beamer@endpageofdocument| respectively. The icons +% for subsections and sections are typeset in a similar way. +% +% The right part of the presentation symbol or (if there is an appendix) of the +% appendix symbol will point to page |\beamer@endpageofdocument|. + +% \paragraph{How \BSF\ does it}~\\ +% The frame icon should point to the previous or next frame or subframe in the +% PDF file. This is simply achieved by writing the |\beamer@framepages| entry +% with |\beamer@writeslidentry@navbar| (see \autoref{sec:code-miniframes}) for +% every subframe. +% +% The section icon should point to the first and last page of the section the +% subframe belongs to in the main part. For this, the first page of the first +% and the last page of the last subframe of a section is needed also. The +% information is stored in two steps. +% \begin{enumerate} +% \item A macro |\bsfrestoresection| is written to the |.sfr| file for each +% section. Its arguments are the number of the previous section and the +% first page of the section just started. +% \item When loading the |.sfr| file, the first |\bsfrestoresection| entry +% initializes some makros (used as variables). All subsequent entries +% write a |\bsf@sectionpages| entry to the |.nav| file, which has the +% necessary pages as arguments. +% \end{enumerate} +% For parts and subsections corresponding entries are written to the files. And +% for the last part, section, and subsection |\bsf@...pages| entries are written +% after appending the subframes. +% +% The |\beamer@...pages| entries written by Beamer at the end of the document +% would mix up the links of the navigation bar. It is not possible to prevent +% writing these entries. Instead they are disabled after appending the subframes. +% Since they would stay disabled for all pages after the first, they are +% reenabled at the beginning of the |.nav| file. Also, these entries have to be +% written before appending the subframes, in order to make the navigation bar +% work correctly for the last section and subsection in the main part. +% +% Since this is also done for the |\beamer@documentpages| entry, the right +% arrows of the section and subsection icons are limited to the last page of the +% main part, i.e.\ the page before the first subframe. The same applies to the +% right part of the presentation or appendix symbol. +% +% Unfortunately, this would apply to the right arrows of the slide icon and the +% frame icon too. Therefore the package writes a |\bsf@documentpages| entry to +% the |.nav| file after appending the subframes. Additionally, two macros of +% Beamer are redefined to use this information, instead of the information of +% the |\beamer@documentpages| entry. +% +% \paragraph{The Macros}~\\ +% Lets start with the two redefined macros. The originals are defined in +% \textsf{beamerbasenavigation.sty}. +% +% \begin{macro}{\hyperlinkslidenext} +% The new definition of |\hyperlinkslidenext| uses |\bsf@nextpage| instead of +% |\beamer@nextpage|. +% \begin{macrocode} +\def\hyperlinkslidenext{% + \bsf@nextpage\c@page% + \hyperlink{Navigation\the\beamer@tempcount}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyperlinkframestartnext} +% The new definition of |\hyperlinkframestartnext| also uses |\bsf@nextpage| +% instead of |\beamer@nextpage|. +% \begin{macrocode} +\def\hyperlinkframestartnext{% + \bsf@nextpage\beamer@endpageofframe% + \hyperlink{Navigation\the\beamer@tempcount}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bsf@nextpage} +% The macro |\bsf@nextpage| works like |\beamer@nextpage| (from +% \textsf{beamerbasenavigation.sty}), but it uses |\bsf@endpageofdocument| as +% the last page for links, instead of |\beamer@endpageofdocument|. +% \begin{macrocode} +\def\bsf@nextpage#1{% + \beamer@tempcount=#1% + \advance\beamer@tempcount by1\relax% + \ifnum\beamer@tempcount>\bsf@endpageofdocument% + \beamer@tempcount=\bsf@endpageofdocument% + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bsf@documentpages} +% The |\bsf@endpageofdocument| is defined by the |\bsf@documentpages| entry of +% the |.nav| file. +% \begin{macrocode} +\def\bsf@documentpages#1{\def\bsf@endpageofdocument{#1}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bsf@endpageofdocument} +% And |\bsf@endpageofdocument| is initialized to reflect the original. +% \begin{macrocode} +\def\bsf@endpageofdocument{\beamer@endpageofdocument} +% \end{macrocode} +% \end{macro} +% +% To disable and reenable the |\beamer@...pages| entries, first +% \begin{macro}{\beamer@partpages@orig} +% the macro |\beamer@partpages|, +% \begin{macrocode} +\let\beamer@partpages@orig\beamer@partpages +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\beamer@subsectionpages@orig} +% the macro |\beamer@subsectionpages|, +% \begin{macrocode} +\let\beamer@subsectionpages@orig\beamer@subsectionpages +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\beamer@sectionpages@orig} +% the macro |\beamer@sectionpages|, +% \begin{macrocode} +\let\beamer@sectionpages@orig\beamer@sectionpages +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\beamer@documentpages@orig} +% and the macro |\beamer@documentpages| are saved. +% \begin{macrocode} +\let\beamer@documentpages@orig\beamer@documentpages +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bsf@enablenaventries} +% The command |\bsf@enablenaventries| restores the original meanings of the +% |\beamer@...pages| entries. It is written to the |.nav| file at the beginning +% of the document (see \autoref{sec:code-beginend}). +% \begin{macrocode} +\def\bsf@enablenaventries{% + \let\beamer@partpages\beamer@partpages@orig + \let\beamer@subsectionpages\beamer@subsectionpages@orig + \let\beamer@sectionpages\beamer@sectionpages@orig + \let\beamer@documentpages\beamer@documentpages@orig +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bsf@disablenaventries} +% And |\bsf@disablenaventries| disables the entries by letting them gobble their +% arguments. It is written to the |.nav| file after appending the subframes (see +% \autoref{sec:code-appendsub}). +% \begin{macrocode} +\def\bsf@disablenaventries{% + \let\beamer@partpages\@gobbletwo + \let\beamer@subsectionpages\@gobbletwo + \let\beamer@sectionpages\@gobbletwo + \let\beamer@documentpages\@gobble +} +% \end{macrocode} +% \end{macro} +% +% In order to write the |\bsfrestore...| entries to the |.sfr| file, the +% sectioning commands must be extended. First the originals for +% +% \begin{macro}{\part@orig} +% the macro |\part|, +% \begin{macrocode} +\let\part@orig\part +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\section@orig} +% the macro |\section|, +% \begin{macrocode} +\let\section@orig\section +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\subsection@orig} +% and the macro |\subsection| are saved. +% \begin{macrocode} +\let\subsection@orig\subsection +% \end{macrocode} +% \end{macro} +% The sectioning macros are only redefined in append mode. +% \begin{macrocode} +\if@bsf@append +% \end{macrocode} +% +% \begin{macro}{\part} +% The new version of |\part| writes the |\bsfrestorepart| entry to the |.sfr| +% file. The original version is called at the end, so its arguments are of no +% concern here. But because of that, |\c@part| still contains the number of the +% previous part. Here, |\c@page| already contains the number of the first page +% of the new part. +% \begin{macrocode} + \def\part{% + \immediate\write\bsf@sfrout{\string\bsfrestorepart{\the\c@part}% + {\the\c@page}}% + \part@orig + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\section} +% The new version of |\section| writes the |\bsfrestoresection| entry to the +% |.sfr| file. Besides that, it works like the new |\part| command. +% \begin{macrocode} + \def\section{% + \immediate\write\bsf@sfrout{\string\bsfrestoresection{\the\c@section}% + {\the\c@page}}% + \section@orig + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\subsection} +% And the new version of |\subsection| writes the |\bsfrestoresubsection| entry +% to the |.sfr| file. It also works like the new |\part| command. +% \begin{macrocode} + \def\subsection{% + \immediate\write\bsf@sfrout{\string\bsfrestoresubsection{\the\c@subsection}% + {\the\c@page}}% + \subsection@orig + } +\fi +% \end{macrocode} +% \end{macro} +% +% The |\bsfrestore...| entries are executed, when loading the |.sfr| file. +% Basically, they write the |\bsf@... pages| entries to the |.nav| file. But +% the first time, they just initialize some macros used as variables, because +% at this point only the first page of the first subframe of a part, section +% or subsection and the first page of the part, section or subsection itself +% are known. +% +% \begin{macro}{\bsfrestorepart} +% On the first call, |\bsfrestorepart| stores the the first page of the new part +% (|#2|), the number of the previous part (|#1|), and the number of the first +% page of the first subframe belonging to the new part (|c@page|). +% \begin{macrocode} +\def\bsfrestorepart#1#2{% + \if@bsf@firstpart + \@bsf@firstpartfalse + \def\bsf@partstartpage{#2}% + \def\bsf@prevpart{#1}% + \edef\bsf@partfirstsubframepage{\the\c@page}% + \else +% \end{macrocode} +% On all subsequent calls, if there is a new part, the last page of the last +% subframe belonging to the previous part (in |\@tempcnta|) and the last page +% of the previous part (in |\@tempcntb|) are calculated. +% \begin{macrocode} + \@tempcnta=\bsf@prevpart\relax + \ifnum#1>\@tempcnta + \@tempcnta\c@page\advance\@tempcnta -1\relax + \@tempcntb=#2\relax\advance\@tempcntb -1\relax +% \end{macrocode} +% Then the |\bsf@partpages| entry is written to the |.nav| file. Here +% |\addtocontents| can not be used, because it doesn't work, if |\bsfrestorepart| +% appears after the last subframe. +% \begin{macrocode} + \if@filesw + \immediate\write\@auxout{\string\@writefile{nav}% + {\noexpand\headcommand{% + \noexpand\bsf@partpages{\bsf@partfirstsubframepage}% + {\the\@tempcnta}{\bsf@partstartpage}{\the\@tempcntb}}}}% + \fi +% \end{macrocode} +% After that, the ``variables'' are reinitialized. +% \begin{macrocode} + \def\bsf@partstartpage{#2}% + \def\bsf@prevpart{#1}% + \edef\bsf@partfirstsubframepage{\the\c@page}% + \fi + \fi +} +% \end{macrocode} +% Two of the ``variables'' must be initialized, in order to make the package +% work for presentations without sectioning commands. +% \begin{macrocode} +\def\bsf@partstartpage{1}% +\def\bsf@prevpart{0}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bsfrestoresection} +% The macros |\bsfrestoresection| and |\bsfrestoresubsection| work the same way +% as |\bsfrestorepart|. But additionally, they must keep track of sections +% without subsections. For this, the flags |\if@bsf@nosubsection| and +% |\if@bsf@prevnosubsection| and the macro |\bsf@prevsectionstartpage| are used. +% \begin{macrocode} +\def\bsfrestoresection#1#2{% + \if@bsf@firstsection + \@bsf@firstsectionfalse + \def\bsf@prevsectionstartpage{#2}% + \@bsf@nosubsectiontrue + \@bsf@prevnosubsectionfalse + \def\bsf@sectionstartpage{#2}% + \def\bsf@prevsection{#1}% + \edef\bsf@sectionfirstsubframepage{\the\c@page}% + \else + \@tempcnta=\bsf@prevsection\relax + \ifnum#1>\@tempcnta +% \end{macrocode} +% When a new section starts, the start page and the |\if@bsf@nosubsection| flag +% of the previous section are stored. +% \begin{macrocode} + \edef\bsf@prevsectionstartpage{\bsf@sectionstartpage}% + \if@bsf@nosubsection + \@bsf@prevnosubsectiontrue + \else + \@bsf@prevnosubsectionfalse + \fi +% \end{macrocode} +% The flag |\if@bsf@nosubsection| is set to false, because the new section has +% no subsections yet. +% \begin{macrocode} + \@bsf@nosubsectiontrue +% \end{macrocode} +% And the number of the previous subsection is set to $-1$, because the +% subsection counter will be reset to 0 on the start of each section. +% \begin{macrocode} + \def\bsf@prevsubsection{-1}% + \@tempcnta\c@page\advance\@tempcnta -1\relax + \@tempcntb=#2\relax\advance\@tempcntb -1\relax + \if@filesw + \immediate\write\@auxout{\string\@writefile{nav}% + {\noexpand\headcommand{% + \noexpand\bsf@sectionpages{\bsf@sectionfirstsubframepage}% + {\the\@tempcnta}{\bsf@sectionstartpage}{\the\@tempcntb}}}}% + \fi + \def\bsf@sectionstartpage{#2}% + \def\bsf@prevsection{#1}% + \edef\bsf@sectionfirstsubframepage{\the\c@page}% + \fi + \fi +} +\def\bsf@sectionstartpage{1}% +\def\bsf@prevsection{0}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bsfrestoresubsection} +% The macro |\bsfrestoresubsection| uses the flags |\if@bsf@nosubsection| and +% |\if@bsf@prevnosubsection| and the macro |\bsf@prevsectionstartpage| to set +% the correct range of pages. +% \begin{macrocode} +\def\bsfrestoresubsection#1#2{% + \if@bsf@firstsubsection + \@bsf@firstsubsectionfalse + \@bsf@prevnosubsectionfalse + \def\bsf@subsectionstartpage{#2}% + \def\bsf@prevsubsection{#1}% + \edef\bsf@subsectionfirstsubframepage{\the\c@page}% + \else + \@tempcnta=\bsf@prevsubsection\relax + \ifnum#1>\@tempcnta + \@tempcnta\c@page\advance\@tempcnta -1\relax +% \end{macrocode} +% Since the |\bsf@...pages| entries are written (indirectly) at the point of the +% next part, section or subsection, the entry for let's say subsection 1.3 would +% be written at the point of subsection 3.1, if section 2 has no subsections. +% So if the previous section had no subsection, its start page is used to +% calculate the last page of the last subsection instead of the start page of +% this subsection. +% \begin{macrocode} + \if@bsf@prevnosubsection + \@tempcntb=\bsf@prevsectionstartpage\relax + \else + \@tempcntb=#2\relax + \fi + \advance\@tempcntb -1\relax +% \end{macrocode} +% Because |\if@bsf@prevnosubsection| can only be used at the point of the first +% subsection of a new section, it is set to false. +% \begin{macrocode} + \@bsf@prevnosubsectionfalse + \@bsf@nosubsectionfalse + \if@filesw + \immediate\write\@auxout{\string\@writefile{nav}% + {\noexpand\headcommand{% + \noexpand\bsf@subsectionpages{\bsf@subsectionfirstsubframepage}% + {\the\@tempcnta}{\bsf@subsectionstartpage}{\the\@tempcntb}}}}% + \fi + \def\bsf@subsectionstartpage{#2}% + \def\bsf@prevsubsection{#1}% + \edef\bsf@subsectionfirstsubframepage{\the\c@page}% + \fi + \fi +} +\def\bsf@subsectionstartpage{1}% +\def\bsf@prevsubsection{0}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bsf@partpages} +% The |\bsf@partpages| macro is similar to the |\beamer@partpages| macro (from +% \textsf{beamerbasenavigation.sty}). But to decide if the first and the last +% page of a part are stored in |\beamer@startpageofpart| and |\beamer@endpageofpart|, +% it uses the first page of the first subframe (|#1|) and the last page of the +% last subframe (|#2|) belonging to the part. +% +% There may be parts with no subframes. In this case, |#1| is greater then |#2| +% and the first (|#3|) and last page (|#4|) of the part are not stored. +% \begin{macrocode} +\def\bsf@partpages#1#2#3#4{% + \ifnum\c@page<#1% + \else% + \ifnum\c@page>#2% + \else% + \gdef\beamer@startpageofpart{#3}% + \gdef\beamer@endpageofpart{#4}% + \fi% + \fi% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bsf@sectionpages} +% The macro |\bsf@sectionpages| works the same way as |\bsf@partpages|. +% \begin{macrocode} +\def\bsf@sectionpages#1#2#3#4{% + \ifnum\c@page<#1% + \else% + \ifnum\c@page>#2% + \else% + \gdef\beamer@startpageofsection{#3}% + \gdef\beamer@endpageofsection{#4}% + \fi% + \fi% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bsf@subsectionpages} +% And |\bsf@sectionpages| works the same way as |\bsf@partpages| too. +% \begin{macrocode} +\def\bsf@subsectionpages#1#2#3#4{% + \ifnum\c@page<#1% + \else% + \ifnum\c@page>#2% + \else% + \gdef\beamer@startpageofsubsection{#3}% + \gdef\beamer@endpageofsubsection{#4}% + \fi% + \fi% +} +% \end{macrocode} +% \end{macro} +% +% ^^A------------------------- +% \subsubsection{Inserts} +% Beamers |\inserttotalframenumber| is changed by simply writing its definition +% a second time to the |.nav| file, thus overwriting Beamers original definition. +% This is done at the end of the document (see \autoref{sec:code-beginend}). +% The necessary frame number is stored in |\bsf@totalframenumber| before +% appending the subframes (see \autoref{sec:code-appendsub}). +% \begin{macro}{\inserttotalframenumberwithsub} +% The new |\inserttotalframenumberwithsub| is written at the end of the documnet +% (see \autoref{sec:code-beginend}), regardless of the mode of \BSF, so it's +% always defined. But to work on the first \TeX\ run, it must be initialized. +% \begin{macrocode} +\def\inserttotalframenumberwithsub{\inserttotalframenumber} +% \end{macrocode} +% \end{macro} +% +% ^^A------------------------- +% \subsubsection{The \texttt{subframe} environment} +% \label{sec:code-subframe} +% \begin{environment}{subframe} +% The |subframe| environment is defined differently for the two modes. In append +% mode it is basically a verbatim environment, which writes its contents to the +% |.sfr| file. Here, the verbatim package is used. +% +% Before writing the contents, it writes the |\bsfrestore| entry for the +% subframe. The latter contains the value of the |subsectionslide| counter as +% fourth argument, which has to be corrected, if miniframes for subframes should +% not appear. The counter needs to be incremented, if miniframes should appear +% for subframes. +% +% The |\bsfrestore| entry also has to restore the section and subsection heads. +% Since they might contain macros and not just the text itself, +% |\insertsectionhead| and |\insertsubsectionhead| can not be used directly. +% Their current meaning is stored in macros, which are later used to restore +% the heads. +% +% The first line of the |subframe| environment, which contains the arguments, is +% treated differently. It is preceded with |\begin{frame}|. +% +% At the end of the environment, |\end{frame}| is written to the |.sfr| file. +% And the |\subslideentry| is written with |\beamer@writeslidentry@miniframes|, +% but only if miniframes should appear for subframes. +% \begin{macrocode} +\if@bsf@append + \newenvironment{subframe}{% + \@tempcnta\c@subsectionslide + \if@bsf@miniframes\else \advance\@tempcnta by -1\fi + \expandafter\global\expandafter\let + \csname bsf@sectionhead\the\c@part.\the\c@section + \endcsname\insertsectionhead + \expandafter\global\expandafter\let + \csname bsf@subsectionhead\the\c@part.\the\c@section.\the\c@subsection + \endcsname\insertsubsectionhead + \immediate\write\bsf@sfrout{\string\bsfrestore{\the\c@part}{\the\c@section}% + {\the\c@subsection}{\the\@tempcnta}}% + \if@bsf@miniframes \addtocounter{subsectionslide}{1}\fi + \@bsf@firstlinetrue + \let\do\@makeother\dospecials\catcode`\^^M\active + \def\verbatim@processline{% + \if@bsf@firstline + \immediate\write\bsf@sfrout{\string\begin{frame}\the\verbatim@line}% + \@bsf@firstlinefalse + \else + \immediate\write\bsf@sfrout{\the\verbatim@line}% + \fi + }% + \verbatim@}{\immediate\write\bsf@sfrout{\string\end{frame}^^J}% + \if@bsf@miniframes \beamer@writeslidentry@miniframes \fi + } +\else +% \end{macrocode} +% In embed mode, the |subframe| environment is basically a |frame| environment. +% Before calling it, |\if@bsf@subframe| is set to true. And after the |frame| +% environment, |\if@bsf@subframe| is set to false again. This is needed for the +% |\ifsubframe| command. +% +% The main problem here is adding |environment=subframe| to the options. For +% this, |\bsf@frame| is called with the name of the environment, the optional +% overlay specification (|#2|), and the first optional argument (|#1|). +% \begin{macrocode} + \newenvironment<>{subframe}[1][]{% + \@bsf@subframetrue + \bsf@frame{subframe}{#2}{#1}}{\end{frame}\@bsf@subframefalse} +\fi +% \end{macrocode} +% \end{environment} +% +% \begin{macro}{\bsf@frame} +% The macro |\bsf@frame| initializes the token register |\bsf@frame@param|, sets +% a default for the second optional argument and then calls |\bsf@@frame|. +% \begin{macrocode} +\def\bsf@frame#1#2#3{\bsf@frame@param={}% + \@ifnextchar[{\bsf@@frame{#1}{#2}{#3}}{\bsf@@frame{#1}{#2}{#3}[]}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bsf@@frame} +% The macro |\bsf@@frame| is called with the name of the new frame environment +% (|#1|), the overlay specification (|#2|), and the first (|#3|) and the second +% (|#4|) optional argument. It stores the arguments in|\bsf@frame@param|, +% thereby adding |environment=|\meta{name of the new frame environment} at the +% appropriate place. +% \begin{macrocode} +\def\bsf@@frame#1#2#3[#4]{% + \def\@tempa{#3} +% \end{macrocode} +% If |#3| is empty, then there are no optional arguments, i.e.\ no default +% overlay specification and no options. In this case, |#4| is empty too. +% \begin{macrocode} + \ifx\@tempa\@empty + \bsf@frame@param={#2[environment=#1]}% + \else + \def\@tempb{#4} +% \end{macrocode} +% If only |#4| is empty, then there is one optional argument. This case is +% handled by |\bsf@@@frame|. +% \begin{macrocode} + \ifx\@tempb\@empty + \bsf@@@frame{#1}{#2}#3\@@end +% \end{macrocode} +% Otherwhise, both optional arguments are present. +% \begin{macrocode} + \else + \bsf@frame@param={#2[#3][environment=#1,#4]}% + \fi + \fi +% \end{macrocode} +% At the end, |\bsf@frame@| is called with the token register |\bsf@frame@param| +% already expanded. +% \begin{macrocode} + \expandafter\bsf@frame@\the\bsf@frame@param\@@end +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bsf@@@frame} +% The macro |\bsf@@@frame| checks, if the only optional argument is a default +% overlay specification or the list of options. Here |#1| is the name of the new +% frame environment, |#2| is the overlay specification, |#3| is the first +% character of the optional argument and |#4| contains all subsequent characters. +% +% If |#3| is `|<|', then the optional argument is a default overlay specification. +% Otherwhise, it is the list of options. +% \begin{macrocode} +\def\bsf@@@frame#1#2#3#4\@@end{% + \def\@tempa{#3}\def\@tempb{<}% + \ifx\@tempa\@tempb\relax + \bsf@frame@param={#2[#3#4][environment=#1]}% + \else + \bsf@frame@param={#2[environment=#1,#3#4]}% + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bsf@frame@} +% The macro |\bsf@frame@| calls |\begin{frame}| with its argument, which +% contains the overlay specification and the default overlay specification if +% present, and the options, containing at least |environment=...|. This includes +% angle brackets and brackets. +% \begin{macrocode} +\def\bsf@frame@#1\@@end{\begin{frame}#1} +% \end{macrocode} +% \end{macro} +% +% ^^A------------------------- +% \subsubsection{The \texttt{lastframe} environment} +% \label{sec:code-lastframe} +% \begin{environment}{lastframe} +% The |lastframe| environment also uses |\bsf@frame| to add |environment=lastframe| +% to the options before calling the |frame| environment. +% +% Before that, it uses |\bsfrestore| to reset all sectioning counters. After +% this, the counters are in the same state, as they would be for a title frame +% before all sectioning commands. By this, navigation in the sidebar or headline +% will appear the same way as on the title page. +% \begin{macrocode} +\newenvironment<>{lastframe}[1][]{% + \bsfrestore{0}{0}{0}{0}% + \bsf@frame{lastframe}{#2}{#1}}{\end{frame}} +% \end{macrocode} +% \end{environment} +% +% ^^A------------------------- +% \subsubsection{Appending Subframes} +% \label{sec:code-appendsub} +% \begin{macro}{\appendsubframes} +% The macro |\appendsubframes| does nothing in embed mode. In append mode it +% first writes |\endinput| to the |.sfr| file and initializes some macros for +% navigation. The page number of the last frame of the main part is stored in +% |\bsf@pagebeforesub|, to be used after loading the |.sfr| file. +% \begin{macrocode} +\newcommand{\appendsubframes}{% + \if@bsf@append + \immediate\write\bsf@sfrout{\string\endinput}% + \edef\bsf@partfirstsubframepage{\the\c@page}% + \edef\bsf@sectionfirstsubframepage{\the\c@page}% + \edef\bsf@subsectionfirstsubframepage{\the\c@page}% + \@tempcnta\c@page\advance\@tempcnta -1\relax + \edef\bsf@pagebeforesub{\the\@tempcnta}% +% \end{macrocode} +% For the navigation in the main part, the |\beamer@...pages| entries are +% written to the |.nav| file. +% \begin{macrocode} + \addtocontents{nav}{\protect\headcommand{% + \protect\beamer@partpages{\the\beamer@partstartpage}{\bsf@pagebeforesub}}}% + \addtocontents{nav}{\protect\headcommand{% + \protect\beamer@subsectionpages{\the\beamer@subsectionstartpage}{\bsf@pagebeforesub}}}% + \addtocontents{nav}{\protect\headcommand{% + \protect\beamer@sectionpages{\the\beamer@sectionstartpage}{\bsf@pagebeforesub}}}% + \addtocontents{nav}{\protect\headcommand{% + \protect\beamer@documentpages{\bsf@pagebeforesub}}}% +% \end{macrocode} +% The number of the last frame of the main part is stored in |\bsf@totalframenumber|. +% And |\beamer@writeslidentry| is replaced by |\beamer@writeslidentry@navbar|. +% \begin{macrocode} + \edef\bsf@totalframenumber{\the\c@framenumber}% + \let\beamer@writeslidentry\beamer@writeslidentry@navbar +% \end{macrocode} +% Before loading the |.sfr| file, it is closed and the flags for the navigation +% bar are initialized. The flag for |\ifsubframe| is set to true, because from +% now on there are only subframes. +% \begin{macrocode} + \immediate\closeout\bsf@sfrout + \@bsf@firstparttrue + \@bsf@firstsectiontrue + \@bsf@firstsubsectiontrue + \@bsf@subframetrue + \input{\jobname.sfr} +% \end{macrocode} +% After all subframes are typeset, the final |\bsf@...pages| entries are written +% to the |.nav| file. +% \begin{macrocode} + \@tempcnta\c@page\advance\@tempcnta -1\relax + \if@filesw + \immediate\write\@auxout{\string\@writefile{nav}% + {\noexpand\headcommand{\noexpand\bsf@partpages{\bsf@partfirstsubframepage}% + {\the\@tempcnta}{\bsf@partstartpage}{\bsf@pagebeforesub}}}}% + \immediate\write\@auxout{\string\@writefile{nav}% + {\noexpand\headcommand{\noexpand\bsf@sectionpages{\bsf@sectionfirstsubframepage}% + {\the\@tempcnta}{\bsf@sectionstartpage}{\bsf@pagebeforesub}}}}% + \immediate\write\@auxout{\string\@writefile{nav}% + {\noexpand\headcommand{\noexpand\bsf@subsectionpages{\bsf@subsectionfirstsubframepage}% + {\the\@tempcnta}{\bsf@subsectionstartpage}{\bsf@pagebeforesub}}}}% + \immediate\write\@auxout{\string\@writefile{nav}% + {\noexpand\headcommand{\noexpand\bsf@documentpages{\the\@tempcnta}}}}% +% \end{macrocode} +% Finally, the command to disable the remaining |\beamer@...pages| entries is +% written to the |.nav| file. +% \begin{macrocode} + \immediate\write\@auxout{\string\@writefile{nav}% + {\noexpand\headcommand{\noexpand\bsf@disablenaventries}}}% + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% +% ^^A------------------------- +% \subsubsection{At Begin and End of the Document} +% \label{sec:code-beginend} +% At the beginning of the document, first the |.sfp| file is loaded. The |.sfr| +% file is only opened in append mode. +% \begin{macrocode} +\AtBeginDocument{% + \InputIfFileExists{\jobname.sfp}{}{}% + \if@bsf@append + \immediate\openout\bsf@sfrout\jobname.sfr\relax +% \end{macrocode} +% To reenable the |\beamer@...pages| entries after the first page, the command +% |\bsf@enablenaventries| is written as the first entry to the |.nav| file. +% \begin{macrocode} + \if@filesw + \immediate\write\@auxout{\string\@writefile{nav}% + {\noexpand\headcommand{\noexpand\bsf@enablenaventries}}}% + \fi + \fi +} +% \end{macrocode} +% +% At the end of the document in append mode first the |.sfp| file is checked. +% After that |\bsf@totalframenumber| is initialized if necessary, i.e.\ if +% |\appendsubframes| was omitted in the source. +% \begin{macrocode} +\AtEndDocument{% + \if@bsf@append + \bsf@checksfp + \@ifundefined{bsf@totalframenumber}{% + \edef\bsf@totalframenumber{\the\c@framenumber}}{}% + \if@filesw +% \end{macrocode} +% The definition for |\inserttotalframenumber| is written to the |.nav| file a +% second time, thus overwriting the first definition written by Beamer. Here it +% contains the number of frames of the main part. +% \begin{macrocode} + \immediate\write\@auxout{\string\@writefile{nav}% + {\noexpand\headcommand{% + \noexpand\def\noexpand\inserttotalframenumber{\bsf@totalframenumber}}}} +% \end{macrocode} +% A stream for the for the |.sfp| file is defined and the file is opened, so +% \LaTeX\ can write it, when loading the |.aux| file at the end of the document. +% \begin{macrocode} + \newwrite\tf@sfp + \immediate\openout\tf@sfp\jobname.sfp\relax + \fi + \fi +% \end{macrocode} +% Regardless of the mode, the definition of |\inserttotalframenumberwithsub| is +% written to the |.nav| file, so it can be used in themes in both modes. +% \begin{macrocode} + \if@filesw + \immediate\write\@auxout{\string\@writefile{nav}% + {\noexpand\headcommand{% + \noexpand\def\noexpand\inserttotalframenumberwithsub{\the\c@framenumber}}}} + \fi +} +% \end{macrocode} +% +% ^^A------------------------- +% \subsubsection{Contitional Execution} +% \begin{macro}{\ifappend} +% The macro |\ifappend| simply expands to its first argument in append mode and +% to its second in embed mode. +% \begin{macrocode} +\newcommand{\ifappend}[2]{\if@bsf@append #1\else #2\fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\ifsubframe} +% The macro |\ifsubframes| simply expands to its first argument in subframes and +% to its second in normal frames. +% \begin{macrocode} +\newcommand{\ifsubframe}[2]{\if@bsf@subframe #1\else #2\fi} +% \end{macrocode} +% \end{macro} +% +% \newpage +% \Finale\endinput +%</package> +% ^^A-------------------------------------------------------------------------- +% ^^A Now the source of the example +%<*example> +\documentclass{beamer} +\usepackage{lmodern} +\usepackage[T1]{fontenc} + +\usepackage[append]{beamersubframe} + +\newcommand<>{\linkdetail}[4]{% + \ifappend{\uncover#5{\hyperlink{#3}{\beamergotobutton{#4}}}}% + {\uncover#5{\hyperlink{#1}{\beamerskipbutton{#2}}}} +} +\newcommand<>{\returndetail}[2]{% +\ifappend{\uncover#3{\hyperlink{#1}{\beamerreturnbutton{#2}}}}% + {\visible<0>{\beamerreturnbutton{#2}}} +} +\newcommand<>{\linkdifftext}[3]{% + \ifappend{\uncover#4{\hyperlink{#1}{\beamergotobutton{#3}}}}% + {\uncover#4{\hyperlink{#1}{\beamerskipbutton{#2}}}} +} + +\defbeamertemplate*{sidebar left}{bsf test}[1][50] +{ + \vfill% + \rlap{\hskip0.1cm\hbox{\color{fg!#1!bg}\tiny{\ifsubframe{detail}{main part}}}}% + \vskip2pt% +} + +\begin{document} +\begin{frame}{some frame} +\begin{itemize}[<+->] +\item there is foo +\item foo is good +\item and there is bar +\item bar is good too +\end{itemize} +\end{frame} + +\begin{frame}<1-2>[label=lfoo]{frame on foo} +\begin{itemize}[<+->] +\item item a +\item item b \linkdetail<2>{lfoo<3>}{Skip Details}{ldfoob}{Goto Details} +\item item c +\item item d +\end{itemize} +\end{frame} + +\begin{subframe}[label=ldfoob]{details on foo item b} +\begin{itemize}[<+->] +\item item b.1 +\item item b.2 +\item item b.3 +\item item b.4 +\end{itemize} +\end{subframe} + +\begin{subframe} +\frametitle{more details on foo item b} +\begin{itemize}[<+->] +\item item b.5 +\item item b.6 +\item item b.7 +\item item b.8 +\end{itemize} + +\vspace{2ex} +\returndetail<4>{lfoo<3>}{Return from Details} +\end{subframe} + +\againframe<3->{lfoo} + +\begin{frame}{frame on bar} +\begin{itemize}[<+->] +\item item w +\item item x +\item item y +\item item z \linkdetail<4>{lother}{Skip Details}{ldbarz}{Goto Details} +\end{itemize} +\end{frame} + +\begin{subframe}[label=ldbarz] +\frametitle{details on bar item z} +\begin{itemize}[<+->] +\item item z.1 +\item item z.2 +\item item z.3 +\item item z.4 +\end{itemize} + +\vspace{2ex} +\linkdifftext<4>{lother}{Skip further Details}{Return from Details} +\end{subframe} + +\begin{subframe}{more details on bar item z} +\begin{itemize}[<+->] +\item item z.5 +\item item z.6 +\item item z.7 +\item item z.8 +\end{itemize} + +\vspace{2ex} +\returndetail<4>{lother}{Return from Details} +\end{subframe} + +\begin{frame}[label=lother]{another frame} +\begin{itemize}[<+->] +\item conclusion 1 +\item conclusion 2 +\item conclusion 3 +\item conclusion 4 +\end{itemize} +\end{frame} + +\appendsubframes +\end{document} +%</example> |