5

I am trying to use the totcount package, and I noticed some strange behaviour I cannot explain.

With the following MWE :

\documentclass{book}
\usepackage{lipsum}
\usepackage{totcount}

\newtotcounter{mycount}

\let\oldsec=\section
\def\section{\stepcounter{mycount}\oldsec}

\newcounter{testcount}
\setcounter{testcount}{\totvalue{mycount}}
\begin{document}
\total{mycount} \\
\arabic{testcount}


\section{First section header}
\lipsum[1]
\section{Second section header}
\lipsum[2]


\end{document}

even after several compilations, \total{mycount} prints 2 as expected, while \arabic{testcount} prints -1.

However, if I add \AtBeginDocument around \setcounter{}{} then the two commands are printing 2, which is the expected behaviour.

Maybe I missed some point in the totcount package documentation, but is there any reason why one cannot use totvalue in the preamble ?

  • 2
    totcount uses the .aux file which is only read at \begin{document}. – egreg Jul 16 '15 at 20:27
  • @egreg : Ok, that makes sense now! Thank you. A naïve question : what if in the preamble I define other commands using totvalue. It does not matter because these commands will be expanded only at the moment they are called? – mvienney Jul 16 '15 at 20:35
  • 1
    Note that redefining \section that way means that also \section* increments mycount. – egreg Jul 16 '15 at 20:45
2

There is a good reason: the only way LaTeX has for saving values during a run for using them during the next one is via some auxiliary file.

The totcount package uses the standard .aux file, which is a very reasonable choice, as this file is always written (unless \nofiles has been declared) and read in at the start (and at the end, for making a comparison and issuing warning, if necessary).

However there's a catch: the first reading happens as part of \begin{document} and there's a good reason also for this: its contents can be interpreted only when all packages have been loaded, because some of them define things that can find their place in the file (hyperref is a prime example).

The \totvalue command is defined in such a way that it returns –1 if the value has not yet been established (which always happens when the counter has just been declared). So the behavior you describe is expected.

Use \AtBeginDocument, which is executed after the reading of the .aux file for setting a counter using \totvalue.

Defining a command in terms of \totvalue is safe, provided the command is only used in the document, because \newcommand doesn't interpret the replacement text, it just stores it unchanged. The \totvalue macro will be expanded when the command is used.

Actually, there is a way for reading the total value in the preamble, but it involves using a different auxiliary file. On the other hand, I still believe that doing the setting at begin document is cleaner.

\documentclass{book}
\usepackage{totcount}
\usepackage{etoolbox}

\usepackage{lipsum}

\newtotcounter[auxfile=\jobname.tot]{mycount}

\newcounter{testcount}
\setcounter{testcount}{\totvalue{mycount}}

\preto\section{\stepcounter{mycount}}

\begin{document}

\total{mycount} \\
\arabic{testcount}

\section{First section header}
\lipsum[1]
\section{Second section header}
\lipsum[2]

\end{document}
1

See the new version with xassoccnt at the end

This uses the assoccnt package which associates counters to a driver counter, here the section counter as the master and mycount as the driven counter, which is stepped each time section is stepped as well, regardless whether section is reset in between. This does not require to redefine \section then.

At the end of the document, the total number of sections is stored to totalsections.

It should be possible to use \AtBeginDocument{ in order to set the counter however, even with totcount counters, since this should be executed after .aux file has been read.

\documentclass{book}
\usepackage{lipsum}

\usepackage{assoccnt}
\newcounter{mycount}

\newcounter{totalsections}

\DeclareAssociatedCounters{section}{mycount}

\makeatletter
\AtEndDocument{%
  \immediate\write\@auxout{\string\setcounter{totalsections}{\number\value{mycount}}}
}%
\newcounter{anothercounter}
\AtBeginDocument{%
  \setcounter{anothercounter}{\value{totalsections}} % Not really needed here, but works ;-)
}

\begin{document}
There are \arabic{totalsections} in this document


\section{First section header}
\lipsum[1]
\section{Second section header}
\lipsum[2]


\end{document}

Version with xassoccnt, much shorter

\documentclass{book}
\usepackage{lipsum}

\usepackage{xassoccnt}


\NewTotalDocumentCounter{totalsections}

\DeclareAssociatedCounters{section}{totalsections}

\begin{document}
There are \TotalValue{totalsections} sections in this document


\section{First section header}
\lipsum[1]
\section{Second section header}
\lipsum[2]


\end{document}

Update No 2

With xassoccnt v1.2 it is possible to simplify the counter definition a little bit:

\documentclass{book}
\usepackage{lipsum}

\usepackage{xassoccnt}


% Defines totalsections as a counter and associates it to section
\DeclareTotalAssociatedCounters{section}{totalsections}

\begin{document}
There are \TotalValue{totalsections} sections in this document


\section{First section header}
\lipsum[1]
\section{Second section header}
\lipsum[2]


\end{document}

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.