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.
\section*{}
does not increase the countersection
so it is not counted.assoccnt
might helpcntpersec
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