11

How can one count the total number of sections within each chapter?

I am trying to use the totcount package, but it returns the total number of sections of the last chapter, not total number of sections of the current chapter.

In the following MWE, the desired behaviour would be to report 3 sections for the first Chapter, and 1 section for the second and last chapter.

totcount reports only 1 section (the counter value for the last chapter).

\documentclass[12pt]{book}

\usepackage{totcount}
\regtotcounter{section}

\begin{document}
\chapter*{First Chapter}

The total number of sections in this chapter should be 3.

The totcount package reports: \total{section}

\section{First Section}
First text

\section{Second Section}
Second text

\section{Third Section}
Third text

\chapter*{Last Chapter}

The total number of sections in this chapter should be 1.

The totcount package reports: \total{section}

\section{First and only section}
Section text

\end{document}

How can one count the total number of sections within each chapter?

Note: totcount reports 0 sections if using \section*, see Sigur's comment.

  • 2
    \section*{} does not increase the counter section so it is not counted. – Sigur May 1 '15 at 12:54
  • I see, thank you. I guess, if needed,, one could create and manage his own counter. That answer the second issue, thank you. – gsl May 1 '15 at 12:59
  • 1
    @gsl: assoccnt might help – user31729 May 1 '15 at 13:02
  • @christian-hupfer: Thank you, I believe that would be a solution. Would you care to submit a brief answer (perhaps with example) , so that I can accept it? – gsl May 1 '15 at 13:04
  • 1
    @gsl: I just uploaded a pre-version of a new package named cntpersec to CTAN. It provides the means of storing counter values on a per chapter base and displaying the values in advance after two compilation runs have been made. If you send me an email to my address (see my profile page), I'll send you the package files with some preliminary documentation as long it's not fully available on CTAN – user31729 May 3 '15 at 0:40
10

Edit The look-ahead - version of knowing section numbers per chapter in advance is at the very end of this post. It requires two runs of compilation.

This question lead to a new package cntperchap which is available in its version 0.2 on CTAN since 2015/9/5

This uses the assoccnt package (whose author I accidentally know quite well ;-))

It associates a counter totalsections to the section counter -- each time the section counter is increased, the totalsections counter is stepped as well.

However, there is no automatic resetting for \chapter* usage. In this case, it can be done automatically by prepending some code to \chapter using \xpretocmd from xpatch package

Note The author of assoccnt should really incorporate this into his package ;-)

\documentclass[12pt]{book}
\usepackage{assoccnt}

\usepackage{xpatch}
\newcounter{totalsections}[chapter] % Does not work with `chapter*`

% Automatically provide for resetting of the section counter each time 
%`\chapter` or `\chapter*` is used -- in this setup this is requested.
\xpretocmd{\chapter}{\setcounter{totalsections}{0}}{}{}


\DeclareAssociatedCounters{section}{totalsections}

\begin{document}
\chapter*{First Chapter}

The total number of sections in this chapter should be 3.



\section{First Section}
First text

\section{Second Section}
Second text

\section{Third Section}
Third text

There \number\value{totalsections} sections in this chapter

\chapter*{Last Chapter}


\section{First and only section}
Section text

There \number\value{totalsections} sections in this chapter


\end{document}

Edit Some new version, which uses a per chapter count of sections (requires two runs to be successful).

Explanation: Each time a new chapter is used, the accumulated number of sections is written to external file, \jobname.seccnt, say foo.seccnt for short. This file is read again at the next latex compile run and the values are stored to a etoolbox list. The macro \GetTotalSectionCounter will advance through this list until it's at the right position and will then print out the number of sections in this chapter, even ahead. (The macro should be expandable, I think this is the case)

At the moment, it's necessary to manually remove the foo.seccnt file if there have been changes to number of chapters/sections.

I'll try to get around this drawback.

\documentclass{book}

\usepackage{ifthen}
\usepackage{assoccnt}

\usepackage{xpatch}

\usepackage{pgffor} % Only for quick usage of a lot of sections, demo only

\newwrite\seccountfile%

\newread\seccountinfile%

\listgadd{\seccountlist}{}% Initialize an empty list


\newcounter{currentchapter}
\newcounter{totalsections}
\newcounter{togglecounter}

\DeclareAssociatedCounters{section}{totalsections}


\newcommand{\getsectioncountnumbers}{%
  \setcounter{togglecounter}{0}%  
  \whiledo {\value{togglecounter} < 1}{%
    \read\seccountinfile to \gandalf%
    \ifeof\seccountinfile%
    \stepcounter{togglecounter}%
    \else%
    \listxadd{\seccountlist}{\gandalf}%
    \fi%
  }%
}


\xpretocmd{\chapter}{%
  \stepcounter{currentchapter}%
  \immediate\write\seccountfile{%
    \number\value{totalsections}%
  }%
  \setcounter{totalsections}{0}
}{}{}

\makeatletter
\newcounter{tempcount@a}
\newcommand{\@getsectiontotalcounter}[1]{%
  \setcounter{tempcount@a}{0}%
  \renewcommand*{\do}[1]{%
    \ifnumequal{\value{#1}}{\value{tempcount@a}}{%
      ##1\listbreak%
    }{%
      \stepcounter{tempcount@a}%
    }%  
  }%    
  \dolistloop{\seccountlist}%
}   


\newcommand{\GetSectionTotalCounter}[1][currentchapter]{%
  \ifdef{\seccountlist}{%
    \@getsectiontotalcounter{#1}%
    }{}%
}

\makeatother


\AtBeginDocument{%
  \IfFileExists{\jobname.seccnt}{%
    % Open for reading
    \immediate\openin\seccountinfile=\jobname.seccnt%
    \getsectioncountnumbers%
  }{%
    % Open for writing
    \immediate\openout\seccountfile=\jobname.seccnt%
  }%
}



\AtEndDocument{% 
  \immediate\write\seccountfile{%
    \number\value{totalsections}%
  }%
  \immediate\closeout\seccountfile%
}




\begin{document}

\chapter*{First}
This chapter will have \GetSectionTotalCounter sections
\section{First}
\section{Second}

\chapter*{Second}
This chapter will have \GetSectionTotalCounter sections
\section{First}
\section{Second}
\section{Third}
\section{Fourth}


% Now a really large chapter
\chapter*{Third}
This chapter will have \GetSectionTotalCounter sections

\foreach \x in {1,...,100} {%
\section{\x}
}

\end{document}

Edit This is the version without explicit deleting the foo.seccnt file

I used the addtocontents approach to let LaTeX write the section numbers to a separate file just as it is done with the toc related stuff. The foo.seccnt is then treated as a faked toc, read in before (and the values temporarily stored) rewritten in the run.

\documentclass{book}

\usepackage{ifthen}
\usepackage{assoccnt}
\usepackage{xpatch}
\usepackage{pgffor}

\listgadd{\seccountlist}{}% Initialize an empty list

\newcounter{currentchapter}
\newcounter{totalsections}
\newcounter{togglecounter}

\DeclareAssociatedCounters{section}{totalsections}


\makeatletter
\newcommand{\getsectioncountnumbers}{%
  \setcounter{togglecounter}{0}%  
  \whiledo {\value{togglecounter} < 1}{%
    \read\tf@seccnt to \seccountnumberfromfile%
    \ifeof\tf@seccnt
    \stepcounter{togglecounter}%
    \else%
    \listxadd{\seccountlist}{\seccountnumberfromfile}%
    \fi%
  }%
}


\xpretocmd{\chapter}{%
  \stepcounter{currentchapter}%
  \addtocontents{seccnt}{%
    \number\value{totalsections}%
  }%
  \setcounter{totalsections}{0}
}{}{}

\newcounter{tempcount@a}
\newcommand{\@getsectiontotalcounter}[1]{%
  \setcounter{tempcount@a}{0}%
  \renewcommand*{\do}[1]{%
    \ifnumequal{\value{#1}}{\value{tempcount@a}}{%
      ##1\listbreak%
    }{%
      \stepcounter{tempcount@a}%
    }%  
  }%    
  \dolistloop{\seccountlist}%
}   

\newcommand{\GetSectionTotalCounter}[1][currentchapter]{%
  \ifdef{\seccountlist}{%
    \@getsectiontotalcounter{#1}%
  }{}%
}

% This is a modified version from \@starttoc, being defined latex.ltx
\def\@startfaketoc#1{%
  \begingroup
  % Generate the file handle first
  \expandafter\newwrite\csname tf@#1\endcsname%
  \makeatletter
  % Read first before deleting it
  \ifcsdef{tf@#1}{%
    \IfFileExists{\jobname.#1}{%
    \immediate\openin\csname tf@#1\endcsname \jobname.#1\relax
    \getsectioncountnumbers%
    }{}
  }{%
    \typeout{No section count numbers so far}
  }%
  \if@filesw
  % Write only if not `\nofiles` is specified
  \immediate\openout \csname tf@#1\endcsname \jobname.#1\relax
  \fi
  \@nobreakfalse
  \endgroup%
}


\AtBeginDocument{%
  \@startfaketoc{seccnt}
}



\AtEndDocument{%
  % Write the last section count to the file
  \addtocontents{seccnt}{%
    \number\value{totalsections}%
  }%
}
\makeatother




\begin{document}
\tableofcontents

\chapter*{First}
This chapter will have \GetSectionTotalCounter sections
\section{First}
\section{Second}

\chapter*{Second}
This chapter will have \GetSectionTotalCounter sections
\section{First}
\section{Second}
\section{Third}
\section{Fourth}



% Now a really large chapter
\chapter*{Third}
This chapter will have \GetSectionTotalCounter sections

\foreach \x in {1,...,100} {%
\section{\x}
}

\chapter{Fourth}
This chapter will have \GetSectionTotalCounter sections

\section{A single section}


\end{document}

Edit The OP gsl noted some error in this code. I could track it down to the fact that \@startfaketoc tries to read in the external foo.seccnt file in the first run already. This fails of course, since there is no such file if it was deleted or the documentat is compiled for the very first time.

  • 2
    @gsl: Yes, it has some advantages, but it has to be used with care! It's no swiss-knife ;-) Happy texing – user31729 May 1 '15 at 13:22
  • If one needs to know the value of totalsections at any place withing a chapter, like for example at the beginning, like in the MWE, it seems that system is not working. Just move the line There are \number\value{totalsections} sections in this chapter right after \chapter to see what I mean, or see this MWE: paste.lisp.org/display/147711 – gsl May 1 '15 at 14:13
  • 1
    @gls: Yes, I see the point. I will think about it. It will probably need more than one run to achieve since assoccnt can't ahead how many sections there will be per chapter in advance. – user31729 May 1 '15 at 14:32
  • @gls: How many chapters do you intend to use in your document? I try to use a new setup – user31729 May 1 '15 at 15:09
  • 1
    @gsl: I am still working on it, but the first version will be a hack, nothing nice – user31729 May 1 '15 at 17:42

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.