4

I created a beamer theme which uses parts (for lecture slides) and where the slides are numbered using the part number and the frame number. The frame number is reset at the beginning of each part.

The problem is, when I create a reference with \ref, only the frame number is shown.

How can I show both the part number and the frame number?

Here is a minimal example:

\documentclass{beamer}
\AtBeginPart{\setcounter{framenumber}{0}}
\makeatletter
\newcommand{\slidenumber}
{slide \ifnum\c@part=0
\insertframenumber
\else
\insertpartnumber-\insertframenumber
\fi}
\makeatother
\begin{document}
\frame{\slidenumber, ref: \ref{one-two}}
\frame{\slidenumber}
\part{one}
\frame{\slidenumber}
\frame[label=one-two]{\slidenumber}
\part{two}
\frame{\slidenumber}
\frame{\slidenumber}
\end{document}

This example shows "ref: 2" on the first slide, but I would like it to show "ref: 1-2".

I guess I'll have to somehow redefine \label and/or \ref, but sadly, this is way beyond my TeX/LaTeX skills.

  • Your code just changes the slidenumber which is shown on every frame where you include command \slidenumber but not the real slide number which is stored in .aux file and later referenced by \ref. But I cannot help with this part. – Ignasi May 7 '14 at 12:25
3

Here's one possible solution:

\documentclass{beamer}
\usepackage{etoolbox}

\AtBeginPart{\setcounter{framenumber}{0}}
\makeatletter
\newcommand{\slidenumber}{%
slide \ifnum\c@part=0\relax
  \insertframenumber
\else
  \insertpartnumber-\insertframenumber
\fi}
\def\mynumberwithin#1#2{\@ifundefined{c@#1}{\@nocounterr{#1}}{%
  \@ifundefined{c@#2}{\@nocnterr{#2}}{%
  \@addtoreset{#1}{#2}%
  \toks@\expandafter\expandafter\expandafter{\csname the#1\endcsname}%
  \expandafter\xdef\csname the#1\endcsname
    {\expandafter\noexpand\csname the#2\endcsname
     -\the\toks@}}}}
\pretocmd{\part}{%
\ifnum\c@part=0\relax
  \mynumberwithin{framenumber}{part}
\fi%
}{}{}

\makeatother

\begin{document}

\frame{\slidenumber, ref~\ref{two}, ref~\ref{one-two} and ref~\ref{two-two}}
\frame[label=two]{\slidenumber}

\part{one}
\frame{\slidenumber}
\frame[label=one-two]{\slidenumber}

\part{two}
\frame{\slidenumber}
\frame[label=two-two]{\slidenumber}

\end{document}

An image showing the produced cross-references:

enter image description here

The idea is simply to set the framenumber counter to be prepended by the part counter. I used a similar mechanism as the used by amstex's \numberwithin, but with a variation to use a hyphen instead of a dot. Provision was made to make this change just after a \part command has been actually used so eventual references to frames before the first part will produce just the frame number.

Notice that with these settings, there's no need for your \slidenumber command, since now you can simply use \theframenumber:

\documentclass{beamer}
\usepackage{etoolbox}

\AtBeginPart{\setcounter{framenumber}{0}}
\makeatletter
\def\mynumberwithin#1#2{\@ifundefined{c@#1}{\@nocounterr{#1}}{%
  \@ifundefined{c@#2}{\@nocnterr{#2}}{%
  \@addtoreset{#1}{#2}%
  \toks@\expandafter\expandafter\expandafter{\csname the#1\endcsname}%
  \expandafter\xdef\csname the#1\endcsname
    {\expandafter\noexpand\csname the#2\endcsname
     -\the\toks@}}}}
\pretocmd{\part}{%
\ifnum\c@part=0\relax
  \mynumberwithin{framenumber}{part}
\fi%
}{}{}

\makeatother

\begin{document}

\frame{\theframenumber, ref~\ref{two}, ref~\ref{one-two} and ref~\ref{two-two}}
\frame[label=two]{\theframenumber}

\part{one}
\frame{\theframenumber}
\frame[label=one-two]{\theframenumber}

\part{two}
\frame{\theframenumber}
\frame[label=two-two]{\theframenumber}

\end{document}

enter image description here

  • Thanks for the quick answer, this works great! ... except ... when I'm using \appendix this is treated like yet another \part. Would it be possible to show something like "A-1", "A-2" etc. in the appendix? I'm already re-defining \appendix, so I could easily add something there. – Matthias May 7 '14 at 14:37
  • 1
    @Matthias You're welcome! For the case of the appendices, you can do something like \usepackage{etoolbox} \usepackage{chngcntr} \pretocmd{\appendix}{% \counterwithout{framenumber}{part} }{}{} \apptocmd{\appendix}{\setcounter{part}{0}\renewcommand\thepart{\Alph{part}}}{}{} (or something similar if you are already redefining \appendix). – Gonzalo Medina May 7 '14 at 16:33
  • Perfect, thanks a lot! I just added \renewcommand{\thepart}{A} to my re-definition of \appendix, because I don't want to use further parts within the appendix anyway. – Matthias May 7 '14 at 17:44
  • I'm sorry to ask yet again, but another issue came up: When using \includeonly, the slide numbers using \theframenumber don't work anymore. Strangely, it still works for part 0 and part 1, but starting with part 2, \theframenumber is just a single number continuing from the last frame number in part 1. The numbers inserted with \ref are still correct. Do you have an idea what could be the problem? If my situation is not quite clear, I can create a new question with a MWE. – Matthias May 12 '14 at 15:41
  • I found a solution to my \includeonly problem, but it's not very nice: I have to use the \slidenumber macro to get part number and frame number and I have to use \AtBeginPart{\setcounter{framenumber}{0}} to reset the frame number (which happens automatically if I don't use \includeonly). Is there a better way? – Matthias May 13 '14 at 9:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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