TeX counts and LaTeX counters
When answering questions about storing and manipulating numbers, there is often a choice between using a TeX count and a LaTeX counter. For new users, the difference between the two is not necessarily clear, so I thought it would be worth summarising how things work.
At the LaTeX level, a counter is created using
\newcounter{mycounter}
This creates a counter initialised at zero which can then be set using
\setcounter{mycounter}{4} % Or whatever
or manipulated using \stepcounter and \addtocounter
\setcounter{mycounter}{0} % Value is 0
\stepcounter{mycounter} % Value is 1
\stepcounter{mycounter} % Value is 2
\addtocounter{mycounter}{3} % Value is 5
There are then some methods to get the counter value back out. LaTeX creates a \the… function for each counter, which will print the current value. In places where TeX expects a number, there is also the \value function:
\themycounter % Prints the current value
\ifnum\value{mycounter} > \value{myothercounter}%
% Do stuff!
\fi
This covers a lot of what you might want to do, so the need to use the lower-level TeX system is not obvious. Perhaps the most important thing to notice is that LaTeX’s counters are set globally. That makes them good for tracking something that covers the entire document, but not as good for localised calculations.
How about at the TeX level? A count is created using
\newcount\mycount
where the name is a name including a backslash. Setting a count is done very simply: there is no set function
\mycount 4\relax
Notice the \relax here. Without it, TeX will continue to look for the number in the next thing it finds. This can have some odd effects, and is best avoided. Altering the value can then be carried out using \advance
\mycount 0\relax % Value is 0 \advance\mycount 1\relax % Value is 1 \advance\mycount 1\relax % value is 2 \advance\mycount 3\relax % Value is 5
The value of a count register can be recovered using \the or \number, and the name itself can be used where TeX expects a number.
\the\mycount % Prints the current value \number\mycount % The same result \ifnum\mycount > \myothercount % Do stuff! \fi
The big difference is that TeX sets count registers locally. So to do a global assignment you have to do it deliberately
\global\mycount 3\relax
As LaTeX is built on TeX, you might guess that LaTeX’s counters are an interface to TeX’s count registers, but it’s not immediately obvious how this is done. The way it works is that LaTeX prefixes all of the counter names with c@, so that if I did
\newcount\c@mycounter
\newcounter{mycounter}
LaTeX would issue an error message: the counter is already defined. The other LaTeX functions then build on this, so that they manipulate the internal counters. This is all done globally and with some error checking. For example, the definition of \addtocounter is
\def\addtocounter#1#2{%
\@ifundefined{c@#1}%
{\@nocounterr{#1}}%
{\global\advance\csname c@#1\endcsname #2\relax}}
This checks the counter exists, and if it does globally advances it.
Why choice one or other method? Well, LaTeX does error checking and also adds some refinements (such as resetting one counter based on another). It also ensures you always include the appropriate \relax statements to avoid TeX picking up “extra” material for numbers. On the other hand, if you want to do local assignments then you have to use TeX’s count registers: LaTeX always does global assignments. I tend to find that for document-level things counters are best (anything I actually want to print), whereas count registers are more flexible for programming.
[...] Joseph Wright bloggt über "TeX counts and LaTeX counters": http://www.texdev.net/2009/11/17/tex-counts-and-latex-counters/ [...]
Jürgen Fenn (juergenfenn) 's status on Tuesday, 17-Nov-09 11:26:51 UTC - Identi.ca
17 Nov 09 at 11:26 am
Good article.
Personally, I use a space instead of \relax, but I guess this is a matter of taste.
And one more thing: there is also \refstepcounter, which is used for counters which number something that should be accessible by the label-ref mechanism. The details of label printing are a bit tricky, though.
Marcin
17 Nov 09 at 4:24 pm
The thing with a space is that it will fail if the number is stored in a macro:
\mycount\somemacro \morecsnames
which is usually where problems appear. As I said, LaTeX uses \relax internally.
I’ve mainly focussed on looking at things as numbers, rather than the entire label system in LaTeX. Things get complex, as you say.
Joseph
Joseph Wright
17 Nov 09 at 5:36 pm
Nice summary. Two more differences between the behaviour of counters and counts:
1. With the calc package, all \setcounter (etc.) calls accept integer expressions such as (1+6)/2. Of course, similar (and more efficient) results can be achieved in eTeX with \mycount=\intexpr(1+6)/2\relax
2. \setcounter and friends are occasionally redefined inside certain contexts. In tabularx, for example, material is typeset multiple times and \stepcounter is redefined to only increment the first time the code in the table is executed:
\documentclass{article}
\usepackage{tabularx}
\begin{document}
\newcount\mycount
\newcounter{mycount}
\begin{tabularx}{5cm}{X}
\global\advance\mycount 1\relax \the\mycount \\
\stepcounter{mycount}\themycount \\
\end{tabularx}
\end{document}
This counter redefinition is usually a good thing, but I once had an unfortunate interaction that caused a bug (although I forget exactly how…)
Will Robertson
18 Nov 09 at 5:44 am
[...] dem Perl-Skript ctanify von Scott Pakin, über das ich schon einmal berichtet hatte. Ein weiterer Beitrag beschäftigt sich mit dem Unterschied zwischen „TeX counts and LaTeX counters“. In der TUG [...]
TeX Live 2009, MacTeX 2009, Binaries für FreeBSD, LuaTeX 0.46.0, LaTeX News 19, TeX Catalogue, pdfTeX 1.40.10-RC, JabRef 2.6 beta 2, Writer2LaTeX 1.0 final, WinShell 3.31, LEd 0.53, TeXMakerX 1.9.2, TeXTable 0.2, LyX 1.6.4.2, LaTeXiT 2.0.1, PS-
30 Nov 09 at 12:58 pm
[...] dem Perl-Skript ctanify von Scott Pakin, über das ich schon einmal berichtet hatte. Ein weiterer Beitrag beschäftigt sich mit dem Unterschied zwischen „TeX counts and LaTeX counters“. In der TUG [...]
TeX Live 2009, MacTeX 2009, Binaries für FreeBSD, LuaTeX 0.46.0, LaTeX News 19, TeX Catalogue, pdfTeX 1.40.10-RC, JabRef 2.6 beta 2, Writer2LaTeX 1.0 final, WinShell 3.31, LEd 0.53, TeXMakerX 1.9.2, TeXTable 0.2, LyX 1.6.4.2, LaTeXiT 2.0.1, PS-
30 Nov 09 at 1:05 pm
[...] dem Perl-Skript ctanify von Scott Pakin, über das ich schon einmal berichtet hatte. Ein weiterer Beitrag beschäftigt sich mit dem Unterschied zwischen „TeX counts and LaTeX counters“. In der TUG [...]
TeX Live 2009, MacTeX 2009, Binaries für FreeBSD, LuaTeX 0.46.0, LaTeX News 19, TeX Catalogue, pdfTeX 1.40.10-RC, JabRef 2.6 beta 2, Writer2LaTeX 1.0 final, WinShell 3.31, LEd 0.53, TeXMakerX 1.9.2, TeXTable 0.2, LyX 1.6.4.2, LaTeXiT 2.0.1, PS-
30 Nov 09 at 1:06 pm