1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336
|
% \iffalse
%%
%% File: dcounter.dtx Copyright (C) 1998-2005 by Alexander I. Rozhenko
%%
%<package>\NeedsTeXFormat{LaTeX2e}
%<package>\ProvidesPackage{dcounter}
%<package> [2005/04/25 v1.2 Dynamic Counters (NCC)]
%
% \changes{v1.0}{1998/12/19}{Initial version}
% \changes{v1.1}{2004/11/23}{Minor corrections of the documentation}
% \changes{v1.2}{2005/04/25}{Emulate dynamic style for non-dynamic counters}
%
%<*driver>
\documentclass{ltxdoc}
\usepackage{dcounter}
\GetFileInfo{dcounter.sty}
\begin{document}
\title{The \textsf{dcounter} package\thanks{This file
has version number \fileversion, last
revised \filedate.}}
\author{Alexander I. Rozhenko\\rozhenko@oapmg.sscc.ru}
\date{\filedate}
\maketitle
\DocInput{dcounter.dtx}
\end{document}
%</driver>
% \fi
% This package implements a concept of \emph{dynamic counters}. The
% counter declared as dynamic is really created at the first use
% and receives at that moment the \emph{count style} which was
% established by the |\countstyle| command. For example,
% if |\countstyle{section}| is established, all dynamically created
% counters will be subordinated to |section| counter (i.e., reset
% to zero when |section| counter is stepped) and their typesetting
% command |\the|\emph{foo} will be equal to
% |\thesection.\arabic{|\emph{foo}|}|. This package is compatible with
% |calc| package.
%
% \section{User Interface}
%
% \DescribeMacro\DeclareDynamicCounter
% To declare a dynamic counter \meta{foo} you have to write
% \begin{quote}
% |\DeclareDynamicCounter|\marg{foo}
% \end{quote}
% If the \meta{foo} 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
% \begin{tabbing}
% | \setcounter|\marg{foo}\marg{number}\qquad\qquad\=
% |\stepcounter|\marg{foo}\\
% | \addtocounter|\marg{foo}\marg{number}\>
% |\refstepcounter|\marg{foo}
% \end{tabbing}
% If the \meta{foo} counter exists, it will emulate the dynamic style.
% I use the following trick for such counters: let |\the|\meta{foo} 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.\footnote{This trick was added in version 1.2 of the package.}
% This allows work with existing counters by the same manner as with
% ``true dynamic'' counters.
%
% \DescribeMacro\countstyle
% To specify a count style you have to use the command
% \begin{quote}
% |\countstyle|\marg{counter}
% \end{quote}
% The parameter \meta{counter} have to be existing counter, or dynamic
% counter, or empty. Empty \meta{counter} means the \emph{plain} count
% style without subordination. If \meta{counter} not exists and is
% dynamic it is created here within the previously specified count style.
% The default count style is the plain style.
%
% The |\counstyle| command has an optional parameter useful for
% special purposes. If you want to create some counters in another style
% that is specified by |\countstyle| command, you can write
% \begin{quote}
% |\countstyle|\oarg{list of counters}\marg{another counter}
% \end{quote}
% Here \meta{list of counters} is the list of comma separated counters
% whose count style you want to subordinate to
% \meta{another counter}. This command creates all undefined 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
% \meta{another counter}. Note, that if this counter was subordinated
% before to any other counter, \emph{the previous subordination will be
% rejected}. For example, let you want to use the |book| document class
% and set |\Roman| enumeration of chapters, independent arabic
% enumeration of sections and to subordinate enumeration of figures,
% tables and equations to the \emph{section} counter. You can write
% \begin{quote}
% |\documentclass{book}|\\
% |\usepackage{dcounter}|\\
% |\renewcommand\thechapter{\Roman{chapter}}|\\
% |\countstyle[section]{}|\\
% |\countstyle[figure,table,equation]{section}|
% \end{quote}
% After that the \emph{chapter} counter will not affect on
% \emph{section} counter, and all figure, table, and equation numbers
% will typeset as |\thesection.\arabic{|\emph{foo}|}|.
%
% \DescribeMacro\DynamicCount
% The command
% \begin{quote}
% |\DynamicCount|\marg{counter}
% \end{quote}
% sets the count style for \meta{counter} 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.
%
% \textbf{Note}. All described commands are used in the preamble.
%
% \StopEventually{}
%
% \section{The Basic Implementation Part}
%
% \begin{macro}{\DCNT@list}
% \begin{macro}{\DCNT@elist}
% We begin from the initialization of the list of dynamic counters.
% |\DCNT@list| contains a list of undeclared counters and
% |\DCNT@elist| contains a list of existing counters that are declared
% as dynamic counters.
% \begin{macrocode}
%<*package>
\def\DCNT@list{}
\def\DCNT@elist{}
\@onlypreamble\DCNT@elist
% \end{macrocode}
% Their items will have the form |\@elt|\marg{counter}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\DCNT@in}
% The macro |\DCNT@in|\marg{list}\marg{yes}\marg{no}
% tests the list of counters \meta{list} to contain the counter
% |\DCNT@foo| and after testing executes \meta{yes}-sequence if
% |\DCNT@foo| found or \meta{no}-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 counters the
% command executes |\DCNT@noteq|\marg{counter} hook for every
% counter which name is distinct from the tested name.
% \begin{macrocode}
\def\DCNT@in#1#2#3{\@tempswafalse
\let\@elt\DCNT@elt #1%
\if@tempswa #2\else #3\fi
}
\def\DCNT@elt#1{\def\DCNT@name{#1}%
\ifx\DCNT@name\DCNT@foo \@tempswatrue \else \DCNT@noteq{#1}\fi
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\DCNT@define}
% The command |\DCNT@define|\marg{command}\marg{foo}
% tests the counter \meta{foo} to be undefined and, if it is true,
% tries to create it dynamically. After that it executes \meta{command}
% with the \meta{foo} parameter.
% \begin{macrocode}
\def\DCNT@define#1#2{%
\@ifundefined{c@#2}%
{{\edef\DCNT@foo{#2}\let\DCNT@noteq\@gobble
\DCNT@in\DCNT@list{\newcounter{#2}\DCNT@the{#2}}{}%
}}{}%
#1{#2}%
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\DCNT@the}
% The command |\DCNT@the|\marg{foo} redefines |\the|\meta{foo}
% command to typeset it in the count style subordinated to |\DCNT@main|
% counter. It also adds the name \meta{foo} to the resetting list of\/
% |\DCNT@main| counter.
% \begin{macrocode}
\def\DCNT@the#1{%
\ifx\DCNT@main\@empty
\expandafter\xdef\csname the#1\endcsname
{\noexpand\@arabic \expandafter\noexpand \csname c@#1\endcsname}%
\else
\expandafter\xdef\csname the#1\endcsname
{\expandafter\noexpand \csname the\DCNT@main\endcsname
.\noexpand\@arabic \expandafter\noexpand \csname c@#1\endcsname}%
\@addtoreset{#1}\DCNT@main
\fi
}
\let\DCNT@main\@empty
% \end{macrocode}
% \end{macro}
%
% \section{The Preamble Only Commands}
%
% \begin{macro}{\DeclareDynamicCounter}
% The following command tests the counter and adds it to the list of
% dynamic counters if it does not exist or to the list
% of emulated counters if it already exists. In the last case,
% |\the|\meta{counter} command is defined as empty command. It will be
% redefined later at the beginning of document.
% \begin{macrocode}
\newcommand*{\DeclareDynamicCounter}[1]{%
\begingroup
\edef\DCNT@foo{#1}%
\ifx\DCNT@foo\@empty
\PackageError{dcounter}%
{Cannot declare a dynamic counter with empty name}{}%
\fi
\let\DCNT@noteq\@gobble
\@ifundefined{c@#1}%
{\DCNT@in\DCNT@list{}{\@cons\DCNT@list{{#1}}}}%
{\DCNT@in\DCNT@elist{}{\@cons\DCNT@elist{{#1}}}%
\expandafter\global\expandafter\let
\csname the#1\endcsname\@empty}%
\endgroup
}
\@onlypreamble\DeclareDynamicCounter
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\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.
% \begin{macrocode}
\newcommand{\countstyle}{\@ifnextchar[{\DCNT@lcstyle}{\DCNT@cstyle}}
\@onlypreamble\countstyle
\def\DCNT@cstyle#1{\edef\DCNT@foo{#1}%
\ifx\DCNT@foo\@empty \else
\DCNT@define\@gobble{#1}%
\@ifundefined{c@#1}{\@nocounterr{#1}}{}%
\fi
\let\DCNT@main\DCNT@foo
}
\@onlypreamble\DCNT@cstyle
% \end{macrocode}
% The special variant of this command with optional parameter locally
% sets the special count style and redefines all counters in list via
% the |\DynamicCount| command.
% \begin{macrocode}
\def\DCNT@lcstyle[#1]#2{%
{\DCNT@cstyle{#2}\@for\@tempa:=#1\do{\DynamicCount\@tempa}}%
}
\@onlypreamble\DCNT@lcstyle
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\DynamicCount}
% The macro |\DynamicCount|\marg{foo} modifies the count style of
% the counter \meta{foo} and defines this counter if it is undefined.
% \begin{macrocode}
\newcommand*{\DynamicCount}[1]{%
\@ifundefined{c@#1}%
{\newcounter{#1}}%
% \end{macrocode}
% If the counter is already defined, we check all resetting lists and
% remove all references to this counter.
% \begin{macrocode}
{{\edef\DCNT@foo{#1}\let\DCNT@noteq\DCNT@add
\let\@elt\DCNT@remove \cl@@ckpt
}}%
\DCNT@the{#1}%
}
\@onlypreamble\DynamicCount
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\DCNT@remove}
% The |\DCNT@remove|\marg{foo} command removes all references
% to |\DCNT@foo| counter from the |\cl@|\meta{foo} list of counters.
% \begin{macrocode}
\def\DCNT@remove#1{\expandafter\DCNT@remlist\csname cl@#1\endcsname}
\def\DCNT@remlist#1{%
{\let\@tempa\@empty \DCNT@in#1{\global\let#1\@tempa}{}}%
}
\@onlypreamble\DCNT@remove
\@onlypreamble\DCNT@remlist
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\DCNT@add}
% The |\DCNT@add|\marg{counter} command locally adds
% |\@elt|\marg{counter} to |\@tempa|.
% \begin{macrocode}
\def\DCNT@add#1{%
\let\@elt\relax\edef\@tempa{\@tempa\@elt{#1}}\let\@elt\DCNT@elt
}
\@onlypreamble\DCNT@add
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\DCNT@eltemu}
% The |\DCNT@emu|\marg{counter} command test |\the|\meta{counter}
% 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.
% \begin{macrocode}
\def\DCNT@emu#1{%
\expandafter\ifx\csname the#1\endcsname\@empty
\DynamicCount{#1}\fi
}
\@onlypreamble\DCNT@emu
% \end{macrocode}
% \end{macro}
%
% \section{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.
% \begin{macrocode}
\AtBeginDocument{%
\ifx\DCNT@list\@empty
\@onlypreamble\DCNT@list
\@onlypreamble\DCNT@in
\@onlypreamble\DCNT@elt
\@onlypreamble\DCNT@define
\@onlypreamble\DCNT@the
\@onlypreamble\DCNT@main
\@onlypreamble\DCNT@name
\@onlypreamble\DCNT@foo
\@onlypreamble\DCNT@noteq
\else
\let\DCNT@setcounter\setcounter
\def\setcounter{\DCNT@define\DCNT@setcounter}
\let\DCNT@addtocounter\addtocounter
\def\addtocounter{\DCNT@define\DCNT@addtocounter}
\fi
{\let\@elt\DCNT@emu \DCNT@elist}%
}
%</package>
% \end{macrocode}
\endinput
|