0% found this document useful (0 votes)
3K views6 pages

Dcounter

Uploaded by

Habib Hosseini
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3K views6 pages

Dcounter

Uploaded by

Habib Hosseini
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 6

The dcounter package∗

Alexander I. Rozhenko
[email protected]

2005/04/25

This package implements a concept of dynamic counters. The counter de-


clared as dynamic is really created at the first use and receives at that moment
the count style which was established by the \countstyle command. For ex-
ample, if \countstyle{section} is established, all dynamically created coun-
ters will be subordinated to section counter (i.e., reset to zero when section
counter is stepped) and their typesetting command \thefoo will be equal to
\thesection.\arabic{foo}. This package is compatible with calc package.

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 The Basic Implementation Part


\DCNT@list We begin from the initialization of the list of dynamic counters. \DCNT@list
\DCNT@elist contains a list of undeclared counters and \DCNT@elist contains a list of existing
counters that are declared as dynamic counters.
1 h∗packagei
2 \def\DCNT@list{}
3 \def\DCNT@elist{}
4 \@onlypreamble\DCNT@elist

Their items will have the form \@elt{hcounter i}

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 }

\DCNT@define The command \DCNT@define{hcommand i}{hfooi} tests the counter hfooi to be


undefined and, if it is true, tries to create it dynamically. After that it executes
hcommand i with the hfooi parameter.
12 \def\DCNT@define#1#2{%
13 \@ifundefined{c@#2}%
14 {{\edef\DCNT@foo{#2}\let\DCNT@noteq\@gobble
15 \DCNT@in\DCNT@list{\newcounter{#2}\DCNT@the{#2}}{}%
16 }}{}%
17 #1{#2}%
18 }

\DCNT@the The command \DCNT@the{hfooi} redefines \thehfooi command to typeset it in


the count style subordinated to \DCNT@main counter. It also adds the name hfooi
to the resetting list of \DCNT@main counter.
19 \def\DCNT@the#1{%
20 \ifx\DCNT@main\@empty
21 \expandafter\xdef\csname the#1\endcsname
22 {\noexpand\@arabic \expandafter\noexpand \csname c@#1\endcsname}%
23 \else
24 \expandafter\xdef\csname the#1\endcsname
25 {\expandafter\noexpand \csname the\DCNT@main\endcsname
26 .\noexpand\@arabic \expandafter\noexpand \csname c@#1\endcsname}%
27 \@addtoreset{#1}\DCNT@main
28 \fi
29 }
30 \let\DCNT@main\@empty

3 The Preamble Only Commands


\DeclareDynamicCounter The following command tests the counter and adds it to the list of dynamic coun-
ters if it does not exist or to the list of emulated counters if it already exists. In
the last case, \thehcounter i command is defined as empty command. It will be
redefined later at the beginning of document.

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

\countstyle Now we implement \countstyle command which redefines \DCNT@main macro to


new main counter. It tests the counter to be defined and tries to define it if not.
47 \newcommand{\countstyle}{\@ifnextchar[{\DCNT@lcstyle}{\DCNT@cstyle}}
48 \@onlypreamble\countstyle
49 \def\DCNT@cstyle#1{\edef\DCNT@foo{#1}%
50 \ifx\DCNT@foo\@empty \else
51 \DCNT@define\@gobble{#1}%
52 \@ifundefined{c@#1}{\@nocounterr{#1}}{}%
53 \fi
54 \let\DCNT@main\DCNT@foo
55 }
56 \@onlypreamble\DCNT@cstyle
The special variant of this command with optional parameter locally sets the spe-
cial count style and redefines all counters in list via the \DynamicCount command.
57 \def\DCNT@lcstyle[#1]#2{%
58 {\DCNT@cstyle{#2}\@for\@tempa:=#1\do{\DynamicCount\@tempa}}%
59 }
60 \@onlypreamble\DCNT@lcstyle

\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

\DCNT@remove The \DCNT@remove{hfooi} command removes all references to \DCNT@foo counter


from the \cl@hfooi list of counters.
70 \def\DCNT@remove#1{\expandafter\DCNT@remlist\csname cl@#1\endcsname}
71 \def\DCNT@remlist#1{%
72 {\let\@tempa\@empty \DCNT@in#1{\global\let#1\@tempa}{}}%
73 }
74 \@onlypreamble\DCNT@remove
75 \@onlypreamble\DCNT@remlist

\DCNT@add The \DCNT@add{hcounter i} command locally adds \@elt{hcounter i} to \@tempa.


76 \def\DCNT@add#1{%
77 \let\@elt\relax\edef\@tempa{\@tempa\@elt{#1}}\let\@elt\DCNT@elt
78 }
79 \@onlypreamble\DCNT@add

\DCNT@eltemu The \DCNT@emu{hcounter i} command test \thehcounter i command to be empty


and redefines the counter in the dynamic style. This command is applied to all
existing counters that are emulated as dynamic counters.
80 \def\DCNT@emu#1{%
81 \expandafter\ifx\csname the#1\endcsname\@empty
82 \DynamicCount{#1}\fi
83 }
84 \@onlypreamble\DCNT@emu

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

You might also like