From 5d2b9323781e86126ca48a5d182002e28b387825 Mon Sep 17 00:00:00 2001
From: Karl Berry <karl@freefriends.org>
Date: Fri, 22 Aug 2014 00:17:27 +0000
Subject: assoccnt (21aug14)

git-svn-id: svn://tug.org/texlive/trunk@35003 c570f23f-e606-0410-a88d-b1316a301751
---
 Master/texmf-dist/tex/latex/assoccnt/assoccnt.sty | 200 ++++++++++++++++++----
 1 file changed, 165 insertions(+), 35 deletions(-)

(limited to 'Master/texmf-dist/tex/latex/assoccnt/assoccnt.sty')

diff --git a/Master/texmf-dist/tex/latex/assoccnt/assoccnt.sty b/Master/texmf-dist/tex/latex/assoccnt/assoccnt.sty
index b6406ff56a4..08697e37332 100644
--- a/Master/texmf-dist/tex/latex/assoccnt/assoccnt.sty
+++ b/Master/texmf-dist/tex/latex/assoccnt/assoccnt.sty
@@ -1,26 +1,30 @@
 \NeedsTeXFormat{LaTeX2e}%
-\ProvidesPackage{assoccnt}[2014/08/13 v0.2 -- Associate counters stepping]%
+\ProvidesPackage{assoccnt}[2014/08/21 v0.3 -- 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]%
+\RequirePackage{xkeyval}[2012/10/14 v2.6b]%
+
 
+\def\@@assoccnt@@keys{@@assoccnt@@keyfamily}%
 
 
-\let\@@assoccnt@standardstepcounter\stepcounter%
 
-\let\@@assoccnt@standardrefstepcounter\refstepcounter%
+\newcounter{@@assoccnt@@internalcounter}%
+
+\let\@@assoccnt@@standardstepcounter\stepcounter%
+\let\@@assoccnt@@standardrefstepcounter\refstepcounter%
 
 
 % Just for a quick suffix
-\newcommand{\@@associatedcounterslistsuffix}{%
+\newcommand{\@@assoccnt@@associatedcounterslistsuffix}{%
 AssociatedCountersList%
 }%
 
@@ -29,62 +33,137 @@ 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
+@@#1@@\@@assoccnt@@associatedcounterslistsuffix
 }%
 
+\newcommand{\@@assoccnt@@drivercounterlist}{%
+@@assoccnt@@DriverCountersList%
+}%
 
-\newcommand{\@@assoccnt@@addassociatedcounter}[2]{%
-  \ifcsdef{#1}{%
-    \ifinlistcs{#2}{#1}{%
-      % Do nothing, since counter is already in the list
-    }{%
-      \listcsadd{#1}{#2}%
+%%
+%% Adds a driver counter to an internal administration list
+\newcommand{\AddDriverCounter}[2][]{%
+% #1 -> options
+% #2 -> driver counter name
+  \setkeys{\@@assoccnt@@keys}{#1}%
+  \ifcsdef{\@@assoccnt@@drivercounterlist}{%
+  }{%
+    \csgdef{\@@assoccnt@@drivercounterlist}{}%
+  }%
+  \listcsgadd{\@@assoccnt@@drivercounterlist}{#2}%
+}%
+
+
+%%
+%% Removes the complete list of driver counters
+\newcommand{\ClearDriverCountersList}{%
+  \ifcsdef{\@@assoccnt@@drivercounterlist}%
+  {%
+    % Clear the possible driver counter entry in the list, the trailing associated counters list 
+    % is cleared as well
+    \forlistcsloop{\ClearAssociatedCountersList}{\@@assoccnt@@drivercounterlist}%
+  }{%
+    % Nothing to be done
+  }%
+}%
+
+\newcommand{\IsDriverCounter}[3]{%
+  \ifcsdef{\@@assoccnt@@drivercounterlist}{%
+    \ifinlistcs{#1}{\@@assoccnt@@drivercounterlist}{% True branch, it's in the list
+      #2%
+    }{% False branch, not in the list
+      #3% 
     }%
+  }{%  List does not exist at all --> expand false branch
+    #3%
+  }%
+}% 
+
+\newcommand{\@@assoccnt@@generateboundtocounterslist}[1]{%
+#1@@boundtocounterslist%
+}%
+
+
+\newcommand{\@@assoccnt@@addassociatedcounter}[3][]{%
+  \ifcsdef{\@@assoccnt@@generateboundtocounterslist{#3}}{%
+    % The counter is already to some other counter, it should not be multiply associated!
   }{%
-    % Nothing in here
+    \csgdef{\@@assoccnt@@generateboundtocounterslist{#3}}{}%
+    \listcsgadd{\@@assoccnt@@generateboundtocounterslist{#3}}{#1}
+    \ifcsdef{#2}{%
+      \ifinlistcs{#3}{#2}{%
+        % Do nothing, since counter is already in the list, prevent multiple list insertion
+      }{%
+        \listcsgadd{#2}{#3}%
+      }%
+    }{%
+      % Nothing in here
+    }%
   }%
 }%
 
 
 
+\newcommand{\AddAssociatedCounters}[3][]{%
+% #1 --> options
+% #2 --> driver counter 
+% #3 --> CSV list of counters, that should be stepped, if the driver counter is stepped
+\setkeys{\@@assoccnt@@keys}{#1}%
+  \ifcsdef{\@@assoccnt@@generatelistname{#2}}{%
+    %  % Nothing to be done --> List already exists
+    \forcsvlist{\@@assoccnt@@addassociatedcounter[#2]{\@@assoccnt@@generatelistname{#2}}}{#3}%
+    % Prevent accidental self - association
+    \RemoveAssociatedCounter{#2}{#2}% 
+  }{%
+    \GenericError{}{Error: List for driver counter #2 does not exist -- Usage on line \the\inputlineno}{}{}
+  }%
+}%
 
 % 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}}{%
+\newcommand{\DeclareAssociatedCounters}[3][]{%
+% #1 --> options
+% #2 --> driver counter 
+% #3 --> CSV list of other counters, that should be stepped, if the driver counter is stepped
+\setkeys{\@@assoccnt@@keys}{#1}%
+  \ifcsdef{\@@assoccnt@@generatelistname{#2}}{%
     %  % Nothing to be done --> List already exists
-    \GenericWarning{}{Warning: List of associated counters for counter #1 already exists}%
+    \GenericWarning{}{Warning: List of associated counters for driver counter #2 already exists}%
   }{%
-    \csgdef{\@@assoccnt@@generatelistname{#1}}{}%   Define some global list 
+    \AddDriverCounter{#2}%
+    \csgdef{\@@assoccnt@@generatelistname{#2}}{}%   Define some global list 
   }%
-  % Now add the counter names from #2 to the list 
+  % Now add the counter names from #3 to the list 
   % Note: Currently, it is not checked whether a counter is already added!
-  \forcsvlist{\@@assoccnt@@addassociatedcounter{\@@assoccnt@@generatelistname{#1}}}{#2}%
+  \forcsvlist{\@@assoccnt@@addassociatedcounter[#2]{\@@assoccnt@@generatelistname{#2}}}{#3}%
   % Now remove an accidental self-association
-  \RemoveAssociatedCounter{#1}{#1}% 
+  \RemoveAssociatedCounter{#2}{#2}% 
 }%
 
+%\@onlypreamble{\DeclareAssociatedCounters}%
+
+
+%%
+
 
 
 %%% A generic macro, that removes a list entry from the list by
 %%% defining a temporary list and omitting the 
-\newcommand{\@@assoccnt@removefromlist}[2]{%
+\newcommand{\@@assoccnt@@removefromlist}[2]{%
 % #1 list name
 % #2 element to be removed
   \ifcsdef{#1}{%
-    \gdef\@@mytemplist{}%
+    \gdef\@@assoccnt@@mytemplist{}%
     \renewcommand*{\do}[1]{%
       \ifstrequal{##1}{#2}{
         % Later one some success routine etc. ???
       }{%
-        \listgadd{\@@mytemplist}{##1}%
+        \listgadd{\@@assoccnt@@mytemplist}{##1}%
       }%
     }%
     \dolistcsloop{#1}%
-    \csxdef{#1}{\@@mytemplist}%
+    \csxdef{#1}{\@@assoccnt@@mytemplist}%
   }{%
     % The list is not defined at all, can't remove something from something not existing...
   }%
@@ -96,7 +175,7 @@ AssociatedCountersList%
 \newcommand{\RemoveAssociatedCounter}[2]{%
 % #1 arg: driver counter
 % #2 arg: counter name to be removed
-  \@@assoccnt@removefromlist{\@@assoccnt@@generatelistname{#1}}{#2}%
+  \@@assoccnt@@removefromlist{\@@assoccnt@@generatelistname{#1}}{#2}%
 }%
 
 %% Remove a CSV list of counters from the list of associated counters 
@@ -111,11 +190,12 @@ AssociatedCountersList%
 \newcommand{\ClearAssociatedCountersList}[1]{%
 % #1 arg: driver counter
   \csundef{\@@assoccnt@@generatelistname{#1}}%
+  \@@assoccnt@@removefromlist{\@@assoccnt@@drivercounterlist}{#1}%
 }%
 
 
 %% Test if a counter is an associated counter of driver counter 
-\newcommand{\IfIsAssociatedCounter}[4]{%
+\newcommand{\IsAssociatedToCounter}[4]{%
 % #1 arg: driver counter
 % #2 arg: (possibly) associated counter
 % #3 arg: Code for execution on true branch
@@ -132,22 +212,70 @@ AssociatedCountersList%
 }%
 
 
+\newcommand{\IsAssociatedCounter}[3]{%
+  \ifcsdef{\@@assoccnt@@generateboundtocounterslist{#1}}{% true branch
+    \setcounter{@@assoccnt@@internalcounter}{0}%
+    \renewcommand*{\do}[1]{%
+      \@@assoccnt@@standardstepcounter{@@assoccnt@@internalcounter}%
+    }%
+    \dolistcsloop{\@@assoccnt@@generateboundtocounterslist{#1}}%
+    \ifnumgreater{\number\value{@@assoccnt@@internalcounter}}{0}{%
+      #2%
+    }{%
+      #3%
+    }%
+  }{%
+    #3% 
+  }% End of \ifcsdef false branch
+}%
+
+
+\newcommand{\GetDriverCounter}[1]{%
+  \setcounter{@@assoccnt@@internalcounter}{0}%
+  \renewcommand*{\do}[1]{%
+    ##1%
+    \ifnumequal{\number\value{@@assoccnt@@internalcounter}}{1}{%
+      \listbreak}{%
+      \@@assoccnt@@standardstepcounter{@@assoccnt@@internalcounter}%
+    }%
+  }%
+  \dolistcsloop{\@@assoccnt@@generateboundtocounterslist{#1}}%
+}%
+
+\newcommand{\@@assoccnt@@showassociatedcounterlist}[1]{%
+  \textcolor{red}{\textbf{#1{ }}}%
+}%
+
+\newcommand{\@@assoccnt@@showdrivercounterlist}[1]{%
+  \textcolor{blue}{\textbf{#1}}
+  \ifcsdef{\@@assoccnt@@generatelistname{#1}}{%
+    \forlistcsloop{\@@assoccnt@@showassociatedcounterlist}{\@@assoccnt@@generatelistname{#1}}%
+  }{}%
+  \par%
+}%
+
+\newcommand{\AssociationStatistics}[1][]{%
+  \forlistcsloop{\@@assoccnt@@showdrivercounterlist}{\@@assoccnt@@drivercounterlist}%
+}%
+
+
+
 %%% 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}%
+\newcommand{\@@assoccnt@@stepcounter}[1]{%  
+  \@@assoccnt@@standardstepcounter{#1}%
 }%
 
 %%% Not needed so far
 \newcommand{\@@assoccnt@refstepcounter}[1]{%  
-  \@@assoccnt@standardrefstepcounter{#1}%
+  \@@assoccnt@@standardrefstepcounter{#1}%
 }%
 
 %%%% Redefinition of the \stepcounter command 
 \renewcommand{\stepcounter}[1]{%
-  \@@assoccnt@standardstepcounter{#1}%   Traditional behaviour, since this is expected!
+  \@@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
+    \forlistcsloop{\@@assoccnt@@stepcounter}{\@@assoccnt@@generatelistname{#1}}%  March through the list
   }{% 
     %No list -> do nothing at all
   }%
@@ -155,13 +283,15 @@ AssociatedCountersList%
 
 
 
+
+
 %%%% Redefinition of the \stepcounter command 
 \renewcommand{\refstepcounter}[1]{%
-  \@@assoccnt@standardstepcounter{#1}%   Traditional behaviour, since this is expected!
+  \@@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
+    \forlistcsloop{\@@assoccnt@@stepcounter}{\@@assoccnt@@generatelistname{#1}}%  March through the list
   }{% 
     %No list -> do nothing at all
   }%
-- 
cgit v1.2.3

