Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I'm using the beamer package to create a presentation. Additionally I'd like to have a handout containing more information (as presentation slides should not contain much text). For this I use the article mode.

In order to allow my audience to take notes on their handouts, it would be helpful to have frame numbers on the handout. I accomplished this using the following code:

\mode<article>{
    \renewcommand{\frametitle}[1]{\subsubsection*{#1 [Slide \insertframenumber]}}
}

This works perfectly well unless you insert section start frames using

\AtBeginSection[] % nothing for \section*{}
{
    \begin{frame}
        \begin{center}
            \structure{\Huge \insertsection}
        \end{center}
    \end{frame}
}

The problem is that \AtBeginSection doesn't work in article mode. The additional frames are not inserted and thus the frame numbering gets wrong.

So I did the following to fix this:

\mode<article>{ % repair frame numbers in article mode as there are no section start frames
    \newcommand*\oldsectionmacro{}%
    \let\oldsectionmacro\section%
    \renewcommand*\section{%
    \addtocounter{framenumber}{1}\oldsectionmacro}%
}

This works unless there is a \section*. In this case the frame number is incremented but shouldn't as there is no section start frame. I could avoid using \section* but there are also some implicit ones (table of contents, bibliography, ...).

Currently I correct this manually (see below) and it works for now but I don't like it. Is there a better way of doing so? Can I rewrite \section* or have an \AtBeginSection for article mode or insert the frame numbers in a different way?

Here is a small example to play around with:

\documentclass[a4paper]{scrartcl} % problem doesn't change if I use article instead
\usepackage{beamerarticle}
%\documentclass{beamer}

\usepackage[utf8]{inputenc}

\setbeamertemplate{footline}[frame number]

\mode<article>{
    % frame number in frametitle
    \renewcommand{\frametitle}[1]{\subsubsection*{#1 [Slide \insertframenumber]}}
}

% section start frame
% this has no effect in article mode
\AtBeginSection[] % nothing for \section*{}
{
    \begin{frame}
        \begin{center}
            \structure{\Huge \insertsection}
        \end{center}
    \end{frame}
}
\mode<article>{ % repair frame numbers in article mode as there are no section start frames
    \newcommand*\oldsectionmacro{}%
    \let\oldsectionmacro\section%
    \renewcommand*\section{%
    \addtocounter{framenumber}{1}\oldsectionmacro}%
%
%   \newcommand*\oldtocmacro{}%
%   \let\oldtocmacro\tableofcontents%
%   \renewcommand*\tableofcontents{%
%   \addtocounter{framenumber}{-1}\oldtocmacro}
}

\begin{document}

    \begin{frame}
        \tableofcontents
    \end{frame}

    \section{Section 1}

        \begin{frame}
            \frametitle{Frame A}

            Frame A
        \end{frame}

    \section{Section 2}
    %\section*{Section Star}

        \begin{frame}
            \frametitle{Frame B}

            Frame B
        \end{frame}

\end{document}
share|improve this question
1  
Is not numbering the section start frames (both in the presentation and on the handout) an alternative? –  diabonas Apr 8 '12 at 11:17
    
@diabonas: Good point! Would be OK although I'd prefer leaving them numbered. –  R2C2 Apr 9 '12 at 19:01
add comment

1 Answer 1

up vote 7 down vote accepted

In my opinion, the cleanest approach here is to make \AtBeginSection work in a beamerarticle. The reason why it doesn't is that the \AtBeginSection macro works by defining hooks to be executed at the beginning of theses sections. In article mode, however, the \section macro as defined by the document class is used, so these hooks are never executed.

To overcome this, a redefinition of the \section macro is necessary. This is a bit complicated because it calls \@startsection internally, so simply adding the hook to the end of the macro won't work. Instead, a complete "wrapper" around the original command is necessary:

\mode<article>
\usepackage{xparse}
\makeatletter
\expandafter\let\expandafter\originalsection\expandafter=\csname @orig\string\section\endcsname
\RenewDocumentCommand{\section}{ D<>{} s o m }
{
  \alt<#1>
  {
    \IfBooleanTF {#2}
    {
      \originalsection*{#4}
      %\beamer@atbeginsections % breaks because section* is also used e.g. in the TOC
    }
    {
      \IfNoValueTF {#3} { \originalsection{#4} } { \originalsection[#3]{#4} }
      \beamer@atbeginsection
    }
  }
  {
    \beamer@secgobble
  }
}
\makeatother
\mode<all>

Insert this code into the preamble of your document, after having loaded beamerarticle. What it does is to save the original, beamer-free meaning of the \section macro stored in the macro with the "weird" name @orig\section to \originalsection. Afterwards, \section is redefined to execute the original sectioning command and the hook \beamer@atbeginsection afterwards. As \section has a starred and non-starred version, an optional argument and an (optional) overlay specification, I used xparse which allows you to define such macros in a very convenient way.

Now you can use \AtBeginSection as usual to insert the section start frames. As you probably don't want them to actually show up in article mode, you should use \begin{frame}<article:0> for these (the frame number is still incremented). Additionally, you need to \def\insertsection{} because this command is unknown to beamerarticle and would result in an error otherwise.

Note that using the optional argument of \AtBeginSection to define a hook for starred sections won't work (the line executing it is commented out in the above code). The reason is that \section* is also used for the table of contents etc., where such inserts would result in an error message.

Output of your MWE using the above code

In presentation mode (click on the image to see it full-size):

five frames in presentation mode

In article mode:

beamerarticle with the correct frame numbers

For completeness, the full source that produced the above results can be found on pastebin.com.

Edit: The xparse package I used to redefine \section relies on the experimental LaTeX3 kernel. If it is not available, you can use this plain LaTeX2e solution instead:

\mode<article>
\makeatletter
\expandafter\let\expandafter\originalsection\expandafter=\csname @orig\string\section\endcsname
\def\sectionwithhook{\@ifstar\@sectionwithhook\@@sectionwithhook}
\newcommand{\@sectionwithhook}[1]{\originalsection*{#1}}
\newcommand{\@@sectionwithhook}[2][]{\beamer@ifempty{#1}{\originalsection{#2}}{\originalsection[#1]{#2}}\beamer@atbeginsection}
\renewcommand<>{\section}{\alt#1{\sectionwithhook}{\beamer@secgobble}}
\makeatother
\mode<all>

This replaces the whole code given above, achieving the same as the \RenewDocumentCommand with some helper macros.

share|improve this answer
    
Thank you! Looks very nice. But unfortunately the xparse package seems to be a bit of a problem for me. I'm not an expert in this but it seems to be some kind of backport of LaTeX3 features to LaTeX 2e, right? I'm using Tex Live on Ubuntu and there doesn't seem to be an Ubuntu package for installing xparse/l3packages/l3kernel. I could install Tex Live manually but I'd rather avoid that. –  R2C2 Apr 9 '12 at 19:08
    
@RC2C You're right, xparse requires the experimental LaTeX3 kernel which may be not available in the Ubuntu version of TeX Live dating from 2009. It's not really necessary to use it here, just more convenient. I'll see if I can implement \sectionwithhook in plain LaTeX2e, stay tuned... :-) –  diabonas Apr 9 '12 at 19:15
    
@R2C2 There you go, I updated my answer with a solution not requiring xparse or other additional packages. –  diabonas Apr 9 '12 at 19:41
    
Unfortunately I have problems compiling this. I get "! LaTeX Error: Command \beamerx@\section already defined. Or name \end... illegal, see p.192 of the manual." and after hitting enter the compiler finally seems to get stuck in an infinite loop. –  R2C2 Apr 9 '12 at 21:54
1  
@R2C2 Never mind, I think I found the problem myself: It's most likely a bug in your outdated version of the beamer package that will always give you an error if you try to \renewcommand<> a macro twice! I suppose this could be patched, but I urge you to consider installing the latest version of TeX Live instead, which includes a version where this has already been fixed. After all, problems with the Debian/Ubuntu version of TeX Live are quite a common source of frustration here, so I think you save yourself a lot of time and energy if you use the recent version! –  diabonas Apr 9 '12 at 22:53
show 3 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.