summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/ncctools/source/dcounter.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/ncctools/source/dcounter.dtx')
-rw-r--r--macros/latex/contrib/ncctools/source/dcounter.dtx337
1 files changed, 337 insertions, 0 deletions
diff --git a/macros/latex/contrib/ncctools/source/dcounter.dtx b/macros/latex/contrib/ncctools/source/dcounter.dtx
new file mode 100644
index 0000000000..785ce5d911
--- /dev/null
+++ b/macros/latex/contrib/ncctools/source/dcounter.dtx
@@ -0,0 +1,337 @@
+% \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>
+\let\makeindex\relax
+\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