\NeedsTeXFormat{LaTeX2e}% \ProvidesPackage{assoccnt}[2014/08/13 v0.2 -- Associate counters stepping]% %%% %% License: LaTeX Project Public License %% Copyright (2014) Dr. Christian Hupfer %% Author: Christian Hupfer christian.hupfer@siebenfelsen.de %% %% %%%% %%% Some options later on %%%% \RequirePackage{etoolbox}[2011/01/03 2.2]% \let\@@assoccnt@standardstepcounter\stepcounter% \let\@@assoccnt@standardrefstepcounter\refstepcounter% % Just for a quick suffix \newcommand{\@@associatedcounterslistsuffix}{% AssociatedCountersList% }% %%% Internal macro to generate the name of the list of associated counters \newcommand{\@@assoccnt@@generatelistname}[1]{% % #1 Name of the driver counter @#1\@@associatedcounterslistsuffix }% \newcommand{\@@assoccnt@@addassociatedcounter}[2]{% \ifcsdef{#1}{% \ifinlistcs{#2}{#1}{% % Do nothing, since counter is already in the list }{% \listcsadd{#1}{#2}% }% }{% % Nothing in here }% }% % This command defines a list of counters, that should be stepped also if the driver counter % is `\stepcounter`ed. % A self - association is not possible, as this would lead to inconsistent counting \newcommand{\DeclareAssociatedCounters}[2]{% % #1 --> driver counter % #2 --> CSV list of other counters, that should be stepped, if the driver counter is stepped \ifcsdef{\@@assoccnt@@generatelistname{#1}}{% % % Nothing to be done --> List already exists \GenericWarning{}{Warning: List of associated counters for counter #1 already exists}% }{% \csgdef{\@@assoccnt@@generatelistname{#1}}{}% Define some global list }% % Now add the counter names from #2 to the list % Note: Currently, it is not checked whether a counter is already added! \forcsvlist{\@@assoccnt@@addassociatedcounter{\@@assoccnt@@generatelistname{#1}}}{#2}% % Now remove an accidental self-association \RemoveAssociatedCounter{#1}{#1}% }% %%% A generic macro, that removes a list entry from the list by %%% defining a temporary list and omitting the \newcommand{\@@assoccnt@removefromlist}[2]{% % #1 list name % #2 element to be removed \ifcsdef{#1}{% \gdef\@@mytemplist{}% \renewcommand*{\do}[1]{% \ifstrequal{##1}{#2}{ % Later one some success routine etc. ??? }{% \listgadd{\@@mytemplist}{##1}% }% }% \dolistcsloop{#1}% \csxdef{#1}{\@@mytemplist}% }{% % The list is not defined at all, can't remove something from something not existing... }% }% %% Remove a particular counter from the list \newcommand{\RemoveAssociatedCounter}[2]{% % #1 arg: driver counter % #2 arg: counter name to be removed \@@assoccnt@removefromlist{\@@assoccnt@@generatelistname{#1}}{#2}% }% %% Remove a CSV list of counters from the list of associated counters \newcommand{\RemoveAssociatedCounters}[2]{% % #1 arg: driver counter % #2 arg: CSV list of counters to be removed \forcsvlist{\RemoveAssociatedCounter{#1}}{#2}% }% %% Remove all associated counters from the list \newcommand{\ClearAssociatedCountersList}[1]{% % #1 arg: driver counter \csundef{\@@assoccnt@@generatelistname{#1}}% }% %% Test if a counter is an associated counter of driver counter \newcommand{\IfIsAssociatedCounter}[4]{% % #1 arg: driver counter % #2 arg: (possibly) associated counter % #3 arg: Code for execution on true branch % #4 arg: Code for execution on false branch \ifcsdef{\@@assoccnt@@generatelistname{#1}}{% \ifinlistcs{#2}{\@@assoccnt@@generatelistname{#1}}{% #3% }{% #4% }% }{% List does not exist, so it's not associated #4% }% }% %%% The stepcounter wrapper for the standard stepcounter command %%% This is just for convenience, if the command as to be improved/extended later on in future \newcommand{\@@assoccnt@stepcounter}[1]{% \@@assoccnt@standardstepcounter{#1}% }% %%% Not needed so far \newcommand{\@@assoccnt@refstepcounter}[1]{% \@@assoccnt@standardrefstepcounter{#1}% }% %%%% Redefinition of the \stepcounter command \renewcommand{\stepcounter}[1]{% \@@assoccnt@standardstepcounter{#1}% Traditional behaviour, since this is expected! \ifcsdef{\@@assoccnt@@generatelistname{#1}}{% Check first, whether the list exists at all, \forlistcsloop{\@@assoccnt@stepcounter}{\@@assoccnt@@generatelistname{#1}}% March through the list }{% %No list -> do nothing at all }% }% %%%% Redefinition of the \stepcounter command \renewcommand{\refstepcounter}[1]{% \@@assoccnt@standardstepcounter{#1}% Traditional behaviour, since this is expected! \protected@edef\@currentlabel% {\csname p@#1\endcsname\csname the#1\endcsname}% \ifcsdef{\@@assoccnt@@generatelistname{#1}}{% Check first, whether the list exists at all, \forlistcsloop{\@@assoccnt@stepcounter}{\@@assoccnt@@generatelistname{#1}}% March through the list }{% %No list -> do nothing at all }% }% \endinput%