# Run macro on each frame in beamer

How to patch the beamer \frame command (frame environment) so that \note{} is executed on every frame. This question is closely related to this one, however, I want the additional macro (\note{} in my case) to be executed not before but on every frame, that is:

\begin{frame}
% empty dummy note, ensures that beamer renders a note page for this frame
% if compiled with \setbeameroption{show notes}
\note{}

% frame content (may contain "real" \note commands, which accumulate)

\end{frame}


I am trying to achieve that in the resulting PDF every slide (even from frames that do not specify notes) is followed by a notes pages, so that I can use pdfnup --nup 1x2 (or similar tools) to pair them on the same page. That is, the following minimal example should result in a 4 page PDF file:

\documentclass{beamer}
\setbeameroption{show notes}

\begin{document}

\begin{frame}{Slide with notes}
Slide content
\note{Cool note!}
\end{frame}

\begin{frame}{Slide without a single note (a notes page should follow nevertheless!)}
More slide content:
\end{frame}

\end{document}


Side note: I do not want any solution that builds on pgfpages (such as "notes on second screen"), as this package interferes at the shipout level with the textpos package, which I absolutely need for absolute positioning. The results look "funny" at best!

Any ideas are welcome!

-
I don't know a solution to this – but I would like to point out to would-be responders that this is not as easy as it looks because of the highly non-standard syntax of beamer's frame environment. –  Harald Hanche-Olsen Feb 22 '11 at 11:03
I know you said you're wedded to textpos, but tikz nodes can also be used to place text boxes at arbitrary positions on the page. Then it would play better with pgfpages and not require this hack. –  Matthew Leingang Feb 22 '11 at 12:56
at one point you say that you want a notes page for every slide which is different from every frame. I think you should change that to avoid confusion: if you use overlays, one frame may contain several slides... –  Seamus Feb 22 '11 at 13:35
@Matthew: I have tried quite hard to use tikz for this purpose. However, for some reasons I still do not understand, absolute positioning with tikz on beamer slides does not really work as expected: The (current page) node seems to "move around" as you put some more content onto the slide. So I finally gave up on this route, but would appreciate any link to examples that prove me wrong. –  Daniel Feb 22 '11 at 21:54
@Seamus: You are right, of course: I want it for every slide. However, as beamer implicitly repeats the notes pages for every slide of a frame this is not so much of an issue. –  Daniel Feb 22 '11 at 21:58

This seemed to work for your small example:

\makeatletter
\def\beamer@framenotesbegin{% at beginning of slide
\gdef\beamer@noteitems{}%
\gdef\beamer@notes{{}}% used to be totally empty.
}
\makeatother


Mind you, I've not put too much thought into it, so complain if it doesn't work. :)

-
You are the man! Works like a charm (even in not so small examples). Moreover, it improves over the manual solution by shipping out notes pages even for slides generated by [allowframebreaks]. Thanks a lot! –  Daniel Feb 22 '11 at 22:10

One sneaky way to do this is to put the code somewhere else that gets evaluated each frame rather than to try to hook in to the frame environment itself. For example, the templates can contain arbitrary code so you could redefine one of the always-used templates to include the relevant command.

In a similar circumstance, I've hooked in to the \frametitle command as that's a bit more robust. I don't know if \begin{frame}{Some Title} calls \frametitle internally so I don't know if this would work for you.

-
The solution provided by Ulrich works pretty well, so I have not tried your approach for this particular issue. However, it is a neat idea that certainly is worth remembering. –  Daniel Feb 22 '11 at 22:20

Perhaps the easiest approach would be to create a wrapper environment. Basic example:

\documentclass{beamer}
\newenvironment{nframe}[1]{%
\begin{frame}[environment=nframe]\frametitle{#1}\note{}%
}{%
\end{frame}%
}
\begin{document}
\begin{nframe}{Title}
Foo
\end{nframe}
\end{document}


I think this currently breaks if you don't supply a frametitle, which is awkward... Leave the second argument empty to not have a frametitle.

Here's a solution that apparently doesn't work, I keep it up here for the sake of posterity.

Adapting the answer in the linked question, could you not use etoolbox's \appto like so: \appto{\frame}{\note{}} to include a note at the beginning of each frame?

-
No, \frame is very fragile. It is not only used for the \frame command and for the frame environment differently but uses \@ifnextchar to look ahead for < and [ etc. –  Martin Scharrer Feb 22 '11 at 13:58
@Martin OK. Thanks. I didn't have time to test the solution. I've added a different way to tackle the problem. This one I did do rudimentary testing on, but it's still suboptimal... –  Seamus Feb 22 '11 at 14:25
This doesn't support 'fragile' frames. You need the environment=nframe option like in this answer. –  Martin Scharrer Feb 22 '11 at 14:31
@Martin thanks for the comments! I don't fully understand what a "fragile" frame is, but I think the above solution works now... –  Seamus Feb 22 '11 at 14:41
@Seamus: AFAIK a fragile frame is for verbatim or similar content. The frame content is written into \jobname.vrb first and then processed. However a simple verbatim environment still breaks for some reason. You forgot a [1] in your \newcommand. –  Martin Scharrer Feb 22 '11 at 14:47