1

I'm writing a book in which each chapter ends with a list of numbered exercises. I would like to persuade LaTeX to count the total number of exercises in the book, to be referred to with \ref or something like it (e.g., \total from totcount). Each chapter is loaded separately using \include, and I want the counts to be correct even when using \includeonly.

It looks like the totcount package might help, provided I somehow jigger the exercise environments to step a suitable counter. But I'm not quite clear on how I can do that in a way that is compatible with the \suspend and \resume commands from package mdwlist.

Any suggestions how I would define an exercises environment that would work with totcount and be compatible with \suspend and \resume? Or suggest another approach entirely?

Here's an MWE in which each exercise is correctly numbered: exercises in chapter 1 are numbered 1 to 4, as are exercises in chapter 2. The problem I'm trying to solve is to accumulate the correct total (8) in the preface.

\documentclass{book}
\usepackage{totcount}
\usepackage{mdwlist}

\newtotcounter{exercises} \newenvironment{exercises} {\enumerate} % need something here to count each exercise {\endenumerate}

\begin{document}

\section*{Preface}

There are \total{exercises} exercises. (Should be~8.)

% this chapter meant to be in a separate file loaded with \include \chapter{Diet}

\section{Omnivorous}

\begin{exercises} \item Which do you prefer? \begin{enumerate} \item Fish \item Fowl \end{enumerate} \item What won't you touch? \begin{enumerate} \item Snakes \item Snails \end{enumerate} \suspend{exercises}

\section{Vegetarian}

\resume{exercises} \item Which do you prefer? \begin{enumerate} \item Corn \item Squash \end{enumerate} \item What won't you touch? \begin{enumerate} \item Broccoli \item Cilantro \end{enumerate} \end{exercises}

% this chapter meant to be in a separate file loaded with \include \chapter{Technology}

\section{Typesetting}

\begin{exercises} \item Which do you prefer? \begin{enumerate} \item Plain \TeX \item \LaTeX \end{enumerate} \item What won't you touch? \begin{enumerate} \item Word \item Scribe \end{enumerate} \suspend{exercises}

\section{Operating systems}

\resume{exercises} \item Which do you prefer? \begin{enumerate} \item Debian \item Arch \end{enumerate} \item What won't you touch? \begin{enumerate} \item BeOS \item NeXT \end{enumerate} \end{exercises}

\end{document}

  • You can also modify/rename an environment to increment a new counter each time. \refsteprcounter and \label to save the last value (plus one). – John Kormylo Aug 04 '20 at 02:51
  • Can you please post a minimal working example that shows what your exercises look like. Your document class, for example, might be relevant to the solution. It sounds like you are using the enumitem package. Is this right? –  Aug 04 '20 at 05:02
  • @Andrew for MWE do you recommend separate file for each chapter? – Norman Ramsey Aug 04 '20 at 15:08
  • I asked for a MWE as it is not clear to me what you are trying to do. A MWE should clarify this and show the packages that you need. Your example code is not so helpful as it's a snippet that is not well explained and does not compile. Can you clearly describe what want. In particular, how are the exercises numbered, how and where do you want to refer back to the number of exercises? Is it essential that you use \suspend and \resume or are these just commands that you think might help? Please add either a MWE or a mock-up of the output you want. –  Aug 05 '20 at 00:51
  • @Andrew ack! Hadn't realized the problem was unclear. Let's hope the MWE at least states precisely what problem I am trying to solve. – Norman Ramsey Aug 07 '20 at 14:12
  • Avoid mdwlist: last version dated 1996. – egreg Aug 27 '23 at 11:07

2 Answers2

0

You can define your own environment and counters.

enter image description here

\documentclass{article}
\usepackage{etoolbox}
\usepackage{expl3}
\usepackage{xparse}
\usepackage{enumitem}

\begin{document}

\ExplSyntaxOn

% define and initialize exercise counter \int_new:N \g_exercise_count_int \int_gset:Nn \g_exercise_count_int {0}

\NewDocumentEnvironment{exercise}{O{}}{ % increment counter when environment starts \int_gincr:N \g_exercise_count_int % forward optional arguments \begin{enumerate}[#1] }{ \end{enumerate} }

\newcommand{\exercisecount}{ \int_use:N \g_exercise_count_int }

\ExplSyntaxOff

\begin{exercise}[font=\bfseries] \item Question 1 \item Question 2 \end{exercise}

\begin{exercise}[label=\Roman*.] \item Question 1 \item Question 2 \end{exercise}

\begin{exercise} \item Question 1 \item Question 2 \end{exercise}

Number of exercises: \exercisecount

\end{document}

Alan Xiang
  • 5,227
0

A minimal working example was requested, but I decided the time required to prepare one might be better spend on trying to solve the problem. I defined an exercises environment intended to behave like enumerate and also to keep track of the total number of exercises in the book. I also used package totcounter. Here's what I learned:

  • You can't just ask \item to increment a counter for you, because that would increment inside nested lists.

  • It would work to ask to increment a counter at the end of an exercises environment, except the \suspend macro from package mdwlist ends an environment multiple times. I tried a few tricks, like defining a hook for various suspended environments, but in the end a simple \ifsuspended was easier to get working. This condition enables the \end{exercises} to tell the difference between truly ending and just being suspended.

Code below.

\newtotcounter{exercises}

\newif\ifexercising

\makeatletter

\newenvironment{exercises} {\ifexercising @latexerr{Nested exercises}{Don't nest exercise environments}% \else \exercisingtrue \ifnum @listdepth >1\relax @latexerr{Nested exercises}{Don't put exercises inside another list}% \fi \fi \enumerate } {\ifsuspended\else\addtocounter{exercises}{\value{enumi}}\fi \endenumerate }

\def@suspend@exercises{\addtocounter{exercises}{-\value{enumi}}}

\newif\ifsuspended \suspendedfalse

\def\suspend@i[#1]#2{% \edef@tempa{% \noexpand\suspendedtrue \noexpand\end{#2}% \def\expandafter\noexpand\csname resume.#1\endcsname{% \csname c@@listctr\endcsname\the\csname c@@listctr\endcsname% }% }% @tempa% }

\makeatother

  • I would have suggested writing out in the .aux file a subtotal of how many exercises are in each chapter, then adding those up in the subsequent run to get the "total total". – barbara beeton Sep 01 '22 at 03:18