Dcounter
Dcounter
Alexander I. Rozhenko
[email protected]
2005/04/25
1 User Interface
\DeclareDynamicCounter To declare a dynamic counter hfooi you have to write
\DeclareDynamicCounter{hfooi}
If the hfooi counter does not exist, its name is added to the list of dynamic counters.
This allows create a counter at the first use with one of the following commands
\setcounter{hfooi}{hnumber i} \stepcounter{hfooi}
\addtocounter{hfooi}{hnumber i} \refstepcounter{hfooi}
If the hfooi counter exists, it will emulate the dynamic style. I use the following
trick for such counters: let \thehfooi command empty and test it at the beginning
of document; if it is empty, the count style of this counter is redefined on the base
of dynamic style.1 This allows work with existing counters by the same manner
as with “true dynamic” counters.
\countstyle To specify a count style you have to use the command
\countstyle{hcounter i}
The parameter hcounter i have to be existing counter, or dynamic counter, or
empty. Empty hcounter i means the plain count style without subordination. If
hcounter i not exists and is dynamic it is created here within the previously speci-
fied count style. The default count style is the plain style.
∗ This file has version number v1.2, last revised 2005/04/25.
1 This trick was added in version 1.2 of the package.
1
The \counstyle command has an optional parameter useful for special pur-
poses. If you want to create some counters in another style that is specified by
\countstyle command, you can write
\countstyle[hlist of countersi]{hanother counter i}
Here hlist of countersi is the list of comma separated counters whose count style
you want to subordinate to hanother counter i. This command creates all unde-
fined counters of the list. The list may contain not only undefined counters but
also existing counters. If counter in the list exists, its count style will be modified
to be subordinated to hanother counter i. Note, that if this counter was subordi-
nated before to any other counter, the previous subordination will be rejected. For
example, let you want to use the book document class and set \Roman enumera-
tion of chapters, independent arabic enumeration of sections and to subordinate
enumeration of figures, tables and equations to the section counter. You can write
\documentclass{book}
\usepackage{dcounter}
\renewcommand\thechapter{\Roman{chapter}}
\countstyle[section]{}
\countstyle[figure,table,equation]{section}
After that the chapter counter will not affect on section counter, and all figure,
table, and equation numbers will typeset as \thesection.\arabic{foo}.
\DynamicCount The command
\DynamicCount{hcounter i}
sets the count style for hcounter i exactly the same as for dynamically created
counters and creates this counter if it is undefined. This command is internally
used in emulation of dynamic counters and in the \countstyle command with
optional parameter. Since version 1.2, this command is obsolete, but it is saved
for backward compatibility.
Note. All described commands are used in the preamble.
2
\DCNT@in The macro \DCNT@in{hlisti}{hyesi}{hnoi} tests the list of counters hlisti to con-
tain the counter \DCNT@foo and after testing executes hyesi-sequence if \DCNT@foo
found or hnoi-sequence if not. To restrict the scope of internal modifications made
by this macro we always enclose it into a group. While processing the list of coun-
ters the command executes \DCNT@noteq{hcounter i} hook for every counter which
name is distinct from the tested name.
5 \def\DCNT@in#1#2#3{\@tempswafalse
6 \let\@elt\DCNT@elt #1%
7 \if@tempswa #2\else #3\fi
8}
9 \def\DCNT@elt#1{\def\DCNT@name{#1}%
10 \ifx\DCNT@name\DCNT@foo \@tempswatrue \else \DCNT@noteq{#1}\fi
11 }
3
31 \newcommand*{\DeclareDynamicCounter}[1]{%
32 \begingroup
33 \edef\DCNT@foo{#1}%
34 \ifx\DCNT@foo\@empty
35 \PackageError{dcounter}%
36 {Cannot declare a dynamic counter with empty name}{}%
37 \fi
38 \let\DCNT@noteq\@gobble
39 \@ifundefined{c@#1}%
40 {\DCNT@in\DCNT@list{}{\@cons\DCNT@list{{#1}}}}%
41 {\DCNT@in\DCNT@elist{}{\@cons\DCNT@elist{{#1}}}%
42 \expandafter\global\expandafter\let
43 \csname the#1\endcsname\@empty}%
44 \endgroup
45 }
46 \@onlypreamble\DeclareDynamicCounter
\DynamicCount The macro \DynamicCount{hfooi} modifies the count style of the counter hfooi
and defines this counter if it is undefined.
61 \newcommand*{\DynamicCount}[1]{%
62 \@ifundefined{c@#1}%
63 {\newcounter{#1}}%
If the counter is already defined, we check all resetting lists and remove all refer-
ences to this counter.
64 {{\edef\DCNT@foo{#1}\let\DCNT@noteq\DCNT@add
65 \let\@elt\DCNT@remove \cl@@ckpt
66 }}%
67 \DCNT@the{#1}%
68 }
4
69 \@onlypreamble\DynamicCount
4 Final Modifications
Finally, we modify \setcounter and \addtocounter commands. We do it at the
beginning of the document to avoid conflict with the calc package. If the list of
dynamic counters is empty, we delete all commands of the package. We also define
all dynamically emulated counters if their \the command is empty.
85 \AtBeginDocument{%
86 \ifx\DCNT@list\@empty
87 \@onlypreamble\DCNT@list
88 \@onlypreamble\DCNT@in
89 \@onlypreamble\DCNT@elt
90 \@onlypreamble\DCNT@define
91 \@onlypreamble\DCNT@the
92 \@onlypreamble\DCNT@main
93 \@onlypreamble\DCNT@name
94 \@onlypreamble\DCNT@foo
95 \@onlypreamble\DCNT@noteq
96 \else
97 \let\DCNT@setcounter\setcounter
98 \def\setcounter{\DCNT@define\DCNT@setcounter}
99 \let\DCNT@addtocounter\addtocounter
100 \def\addtocounter{\DCNT@define\DCNT@addtocounter}
5
101 \fi
102 {\let\@elt\DCNT@emu \DCNT@elist}%
103 }
104 h/packagei