4

I'm using a custom counter to cycle bullet point colours in beamer:

\documentclass{beamer}
\usepackage{graphicx,color}
\usepackage[T1]{fontenc}
\usepackage[latin9]{inputenc}
\usepackage{marvosym}

\newcommand{\myitem}[1]{\item[{\textcolor{#1}\Laserbeam}]}
\newcounter{myc}%[frame] <--if I uncomment [frame] it won't compile
\makeatletter
\def\newitem{
\stepcounter{myc}%
\ifnum\value{myc}=1
  \myitem{red}
\else\ifnum\value{myc}=2
  \myitem{green}
\else\ifnum\value{myc}=3
  \myitem{blue}
  \setcounter{myc}{0}
\fi\fi\fi
}

\begin{document}
\begin{frame}
    \begin{itemize}
        \newitem An item
        \newitem Another item
        \newitem Yet another item
        \newitem These items...
        \newitem ...are rather boring
    \end{itemize}
\end{frame}

\begin{frame}
    \begin{itemize}
        \newitem An item on a second slide
        \newitem Another item
        \newitem Yet another item
        \newitem These items...
        \newitem ...are rather boring
    \end{itemize}
\end{frame}
\end{document}

with the following result (2 slides combined in to 1 image) example, non resetting

However I would like the colours to reset at the start of a new frame, without having to insert \setcounter{myc}{0} after each \begin{frame} Based on this answer I thought I might be able to use \newcounter{myc}[frame], but I can't: ! LaTeX Error: No counter 'frame' defined.

So how do I reset a counter per frame?

4

You were near: the counter is called framenumber. There's an easier way to branch for numeric cases.

\documentclass{beamer}
\usepackage{graphicx,color}
\usepackage[T1]{fontenc}
\usepackage[latin9]{inputenc}
\usepackage{marvosym}

\newcommand{\myitem}[1]{\item[{\textcolor{#1}\Laserbeam}]}
\newcounter{myc}[framenumber]
\newcommand\newitem{%
  \stepcounter{myc}%
  \ifcase\value{myc}%
    % no value for 0
  \or
    \myitem{red}%
  \or
    \myitem{green}%
  \or
    \myitem{blue}%
    \setcounter{myc}{0}%
  \fi
}

\begin{document}
\begin{frame}
    \begin{itemize}
        \newitem An item
        \newitem Another item
        \newitem Yet another item
        \newitem These items...
        \newitem ...are rather boring
    \end{itemize}
\end{frame}

\begin{frame}
    \begin{itemize}
        \newitem An item on a second slide
        \newitem Another item
        \newitem Yet another item
        \newitem These items...
        \newitem ...are rather boring
    \end{itemize}
\end{frame}
\end{document}

An easier way for extending the number of colors is using xparse; you just call \assigncolors{red,green,blue} or with any other list. You can issue this command any times you want during the document, but it's better to do it outside frames, to avoid multiple evaluations.

\documentclass{beamer}
\usepackage{graphicx,color}
\usepackage[T1]{fontenc}
\usepackage[latin9]{inputenc}
\usepackage{marvosym}
\usepackage{xparse}

\newcounter{myc}[framenumber]

\ExplSyntaxOn
\NewDocumentCommand{\newitem}{}
 {
  \chris_newitem:
 }

\NewDocumentCommand{\assigncolors}{m}
 {
  \chris_assign_colors:n { #1 }
 }

\seq_new:N \g_chris_colors_seq
\int_new:N \l_chris_color_int
\cs_new_protected:Npn \chris_assign_colors:n #1
 {
  \seq_gset_from_clist:Nn \g_chris_colors_seq { #1 }
 }
\cs_new_protected:Npn \chris_newitem:
 {
  \stepcounter{myc}
  \int_set:Nn \l_chris_color_int
   {
    \int_mod:nn { \value{myc} } { \seq_count:N \g_chris_colors_seq }
   }
  \int_compare:nT {\l_chris_color_int = 0 }
   {
    \int_set:Nn \l_chris_color_int { \seq_count:N \g_chris_colors_seq }
   }
  \chris_do_item:n
   {
    \seq_item:Nn \g_chris_colors_seq { \l_chris_color_int }
   }
 }
\cs_new:Npn \chris_do_item:n #1
 {
  \item[ \textcolor { #1 }{ \Laserbeam } ]
 }
\ExplSyntaxOff

\assigncolors{red,green,blue}

\begin{document}
\begin{frame}
    \begin{itemize}
        \newitem An item
        \newitem Another item
        \newitem Yet another item
        \newitem These items...
        \newitem ...are rather boring
    \end{itemize}
\end{frame}

\begin{frame}
    \begin{itemize}
        \newitem An item on a second slide
        \newitem Another item
        \newitem Yet another item
        \newitem These items...
        \newitem ...are rather boring
    \end{itemize}
\end{frame}
\end{document}
  • You answered my next question as well, before I even asked - that's a much easier way of increasing the number of colours – Chris H Sep 19 '13 at 11:01
4

The simplest thing to do in cases like this is to use etoolbox which provides the useful \AtBeginEnvironment macro.

So, to reset the custom counter in each frame is quite straightforward:

\usepackage{etoolbox}

\AtBeginEnvironment{frame}{\setcounter{myc}{0}}

The complete example:

\documentclass{beamer}
\usepackage{graphicx,color}% not really needed
\usepackage[T1]{fontenc}
\usepackage[latin9]{inputenc}
\usepackage{marvosym}

\usepackage{etoolbox}

\AtBeginEnvironment{frame}{\setcounter{myc}{0}}

\newcommand{\myitem}[1]{\item[{\textcolor{#1}\Laserbeam}]}
\newcounter{myc}%[frame] <--if I uncomment [frame] it won't compile
\makeatletter
\def\newitem{
\stepcounter{myc}%
\ifnum\value{myc}=1
  \myitem{red}
\else\ifnum\value{myc}=2
  \myitem{green}
\else\ifnum\value{myc}=3
  \myitem{blue}
  \setcounter{myc}{0}
\fi\fi\fi
}

\begin{document}
\begin{frame}
    \begin{itemize}
        \newitem An item
        \newitem Another item
        \newitem Yet another item
        \newitem These items...
        \newitem ...are rather boring
    \end{itemize}
\end{frame}

\begin{frame}
    \begin{itemize}
        \newitem An item on a second slide
        \newitem Another item
        \newitem Yet another item
        \newitem These items...
        \newitem ...are rather boring
    \end{itemize}
\end{frame}
\end{document}

The result:

enter image description here

  • Two good answers, I've gone with egreg's, but +1 for teaching me about \AtBeginEnvironment – Chris H Sep 19 '13 at 11:05
  • @ChrisH: you're welcome :) – Claudio Fiandrino Sep 19 '13 at 11:06

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.