[Tex/LaTex] How to remove some pages from the navigation bullets in Beamer

beamermini-framesnavigation

I'm making a beamer presentation using the miniframes outer theme, with navigation bullets, and the subsection=false option, meaning the bullets are all on a single row. The problem I have is that, if one section has too many pages, the bullets overflow to the next section:

Section 1 Section 2
oooooooooooooooooooo

I tend to have many frames, some of them just asking a question, leading to the next detailed frame. I don't really need those frames to be represented by navigation bullets, and removing them would fix the problem. Any idea how to do that?

I could cheat by using overlays to have the question and the answer on the same frame, but that would be a mess…

Code example to answer percusse's question: this should give you one circle per frame, not one per subsection. If you add many frames in one subsection, the circles will overflow over the next section.

\documentclass[compress]{beamer}
\useoutertheme[subsection=false]{miniframes}
\begin{document}
\section{S1}
\subsection{SS1}
\frame{1}
\frame{2}
\frame{3}
\subsection{SS2}
\frame{1}
\frame{2}
\frame{3}
...
\end{document}

Best Answer

The mini frames are generated using the \beamer@framepages entries in the auxiliary .nav file. If you remove these for certain frames, they don't appear in the navigation1. To do so, you have to patch the \beamer@writeslidentry macro responsible for writing the commands to the .nav file:

\makeatletter
\let\beamer@writeslidentry@miniframeson=\beamer@writeslidentry
\def\beamer@writeslidentry@miniframesoff{%
  \expandafter\beamer@ifempty\expandafter{\beamer@framestartpage}{}% does not happen normally
  {%else
    % removed \addtocontents commands
    \clearpage\beamer@notesactions%
  }
}
\newcommand*{\miniframeson}{\let\beamer@writeslidentry=\beamer@writeslidentry@miniframeson}
\newcommand*{\miniframesoff}{\let\beamer@writeslidentry=\beamer@writeslidentry@miniframesoff}
\makeatother

Include this code in your document, then you can switch between the original implementation and the modified one not generating any mini frames by using \miniframeson and \miniframesoff.

1This may, however, have some unwanted consequences I'm not aware of!

Full example code:

\documentclass[compress]{beamer}
\useoutertheme[subsection=false]{miniframes}
\makeatletter
\let\beamer@writeslidentry@miniframeson=\beamer@writeslidentry
\def\beamer@writeslidentry@miniframesoff{%
  \expandafter\beamer@ifempty\expandafter{\beamer@framestartpage}{}% does not happen normally
  {%else
    % removed \addtocontents commands
    \clearpage\beamer@notesactions%
  }
}
\newcommand*{\miniframeson}{\let\beamer@writeslidentry=\beamer@writeslidentry@miniframeson}
\newcommand*{\miniframesoff}{\let\beamer@writeslidentry=\beamer@writeslidentry@miniframesoff}
\makeatother
\begin{document}
\section{S1}
\subsection{SS1}
\frame{1}
\miniframesoff
\frame{2}
\miniframeson
\frame{3}
\subsection{SS2}
\miniframesoff
\frame{1}
\miniframeson
\frame{2}
\frame{3}
\end{document}

Resulting headline (only four of six mini frames are displayed):

headline produced by the example code, showing only four (of originally six) mini frames