summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/cntperchap/cntperchap.sty
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/cntperchap/cntperchap.sty
Initial commit
Diffstat (limited to 'macros/latex/contrib/cntperchap/cntperchap.sty')
-rw-r--r--macros/latex/contrib/cntperchap/cntperchap.sty505
1 files changed, 505 insertions, 0 deletions
diff --git a/macros/latex/contrib/cntperchap/cntperchap.sty b/macros/latex/contrib/cntperchap/cntperchap.sty
new file mode 100644
index 0000000000..93704b9a5d
--- /dev/null
+++ b/macros/latex/contrib/cntperchap/cntperchap.sty
@@ -0,0 +1,505 @@
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{cntperchap}[2015/06/01 v0.3 -- store counter values per chapter]%
+%%
+%% License: LaTeX Project Public License version 1.3
+%% Copyright (2015) Dr. Christian Hupfer
+%% Author: Christian Hupfer christian.hupfer@yahoo.de
+%%
+%% This work may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3 or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%% This work has the LPPL maintenance status `maintained'.
+%%
+%% This work consists of all files listed in README
+%%
+%%%%
+
+
+\RequirePackage{ifthen}
+\RequirePackage{assoccnt}
+\RequirePackage{morewrites}
+\RequirePackage{xpatch}
+\RequirePackage{xparse}
+
+%%%% Data macros
+
+
+\def\cps@@data@@tracklevel{chapter}
+\edef\cps@@data@@packagename{\@currname} % Store the actual packagename
+
+\newcommand{\cpspackagename}{%
+ \cps@@data@@packagename%
+}
+
+\newcommand{\@cps@@writefilehandleprefix}{tf@cps}
+
+%%%%%
+
+%%%% Preconfiguration depending on the class in the background
+
+
+\edef\cps@@config@@tracklevel{\cps@@data@@tracklevel}%
+
+\@ifclassloaded{article}{%
+ \edef\cps@@config@@tracklevel{section}
+}{%
+ \@ifclassloaded{scrartcl}{%
+ \edef\cps@@config@@tracklevel{section}%
+ }{%
+ }%
+}
+
+
+\newif\ifcpsstorage
+
+\newcommand{\EnableCPSStorage}{%
+ \cpsstoragetrue%
+}
+
+\newcommand{\DisableCPSStorage}{%
+ \cpsstoragefalse%
+}
+
+\EnableCPSStorage
+
+
+%%%% Command options
+
+\define@boolkey{cpskeys}{autodefine}[false]{}
+
+\define@key{cpskeys}{tracklevel}[\cps@@config@@tracklevel]{%
+ \gdef\@cps@@keymacro@@tracklevel{#1}%
+}
+
+\presetkeys{cpskeys}{autodefine=false,tracklevel=\cps@@config@@tracklevel}{}%
+
+\NewDocumentCommand{\DeclareCPSCounter}{s+O{cps}m}{%
+ \ifltxcounter{#3}{%
+ }{%
+ \newcounter{#2@@cps@@#3}%
+ }
+ % Not really useful so far
+ % \expandafter\newcommand\csname #3countername\endcsname{#2@@cps@@#3}%
+}
+
+\@onlypreamble{\DeclareCPSCounter}
+
+
+%%%% Package options
+
+\newif\ifcpsnoendclose
+\cpsnoendclosefalse
+
+\newif\ifcpsverbose
+\cpsverbosefalse
+
+\newif\ifcpsautodefine
+\cpsautodefinefalse
+
+\newif\ifcpsdraftmode
+\cpsdraftmodetrue
+
+
+\DeclareOptionX{autodefine}{\cpsautodefinetrue\presetkeys{cpskeys}{autodefine=true}{}}
+\DeclareOptionX{draft}{\cpsdraftmodetrue}
+\DeclareOptionX{final}{\cpsdraftmodefalse}
+\DeclareOptionX{noendclose}{\cpsnoendclosetrue}
+\DeclareOptionX{tracklevel}{\presetkeys{cpskeys}{tracklevel=#1}{}}
+\DeclareOptionX{verbose}{\cpsverbosetrue}
+
+
+\ProcessOptionsX*
+
+
+\newcommand{\@cps@@counterlistname}{cps@@counterstostore}
+\listcsadd{\@cps@@counterlistname}{}
+
+
+
+
+
+%%%% Internal commands
+
+% Instead of using totcount package
+\newcounter{cps@@totaltracklevelcount}
+
+% Intermediate package counters
+\newcounter{cps@@currentlevelcount}
+\newcounter{cps@@togglecounter}
+\newcounter{cps@@tempcounter}
+\newcounter{cps@@tempcounterstorage}
+\newcounter{cps@@cpscounters}
+
+
+\newcommand{\@cps@@cpscountersname}{%
+ cps@@cpscounters%
+}
+
+
+\newcommand{\@cps@@typeout}[1]{%
+ \ifcpsverbose%
+ \typeout{\cps@@data@@packagename: #1}%
+ \fi%
+}
+
+
+\NewDocumentCommand{\@cps@@tracklevelstarthook}{}{%
+ \stepcounter{cps@@currentlevelcount}%
+ \ifnumgreater{\value{cps@@currentlevelcount}}{0}{%
+ \StoreCounters%
+ }{}%
+ \ResetStoredCounters%
+}
+
+
+% This disables the usage of the automatic counter storage for ToC - like macros, since those use `\chapter*` and confuse the tracking counter
+\NewDocumentCommand{\PrepareTocCommand}{m}{%
+ \xpretocmd{#1}{\DisableCPSStorage}{}{}% Lazy so far
+ \xapptocmd{#1}{\EnableCPSStorage}{}{}% Lazy so far
+}
+
+
+
+\AtBeginDocument{%
+ % Do a check first whether the given tracklevel does exist at all
+ \expandafter\ifx\csname \@cps@@keymacro@@tracklevel\endcsname\relax
+ \GenericError{Error}{Error in \jobname.tex: At line \the\inputlineno: The section level \@cps@@keymacro@@tracklevel\ is unknown}{%
+ Please check your document class and the tracklevel option}{%
+ }%
+ \else
+ % Generate a read file handle
+ \@cps@@generatereadfilehandle%
+ % Prepending the \csname \@cps@keymacro@tracklevel\endcsname command with some starter hook
+ \expandafter\xpretocmd\expandafter{\csname \@cps@@keymacro@@tracklevel\endcsname}{\@cps@@tracklevelstarthook}{\typeout{\@cps@@keymacro@@tracklevel{} command redefined}}{}%
+ \PrepareTocCommand{\tableofcontents}%
+ \PrepareTocCommand{\listoffigures}%
+ \PrepareTocCommand{\listoftables}%
+ \PrepareTocCommand{\printindex}%
+ \fi%
+}
+
+\AtEndDocument{%
+ % Store the total value of the considered sectioning level to the `.aux` file
+ \immediate\write\@auxout{%
+ \string\setcounter{cps@@totaltracklevelcount}{\number\value{cps@@currentlevelcount}}^^J
+ }% End of \immediate\write
+}
+
+\newcommand{\@cps@@readfilehandlename}{%
+ tfr@cpsreadfile%
+}
+
+\newcommand{\@cps@@readfilehandle}{%
+ \csname\@cps@@readfilehandlename\endcsname%
+}
+
+
+\newcommand{\@cps@@generatereadfilehandle}{%
+ \@cps@@typeout{Generating read filehandle}%
+ \expandafter\newread\csname \@cps@@readfilehandlename\endcsname%
+}
+
+\newcommand{\@cps@@generatewritefilehandle}[1]{%
+ \@cps@@typeout{Generating write filehandle #1}%
+ \expandafter\newwrite\csname\@cps@@writefilehandlename{#1}\endcsname% Generate the file handles
+}
+
+\newcommand{\@cps@@writefilehandle}[1]{%
+ \csname\@cps@@writefilehandlename{#1}\endcsname% Generate the file handles
+}
+
+
+\newcommand{\@cps@@writefilehandlename}[1]{%
+ \@cps@@writefilehandleprefix#1%
+}
+
+\newcommand{\@cps@@closeinfile}[1]{%
+ \immediate\closein#1%
+}
+
+\newcommand{\@cps@@openincpsfile}[2][\@cps@@readfilehandle]{%
+ \expandafter\immediate\openin#1=\jobname.cps#2\relax%
+}
+
+\newcommand{\@cps@@openoutcpsfile}[1]{%
+ \expandafter\immediate\openout\@cps@@writefilehandle{#1}=\jobname.cps#1\relax%
+}
+
+\newcommand{\@cps@@closeoutfile}[1]{%
+ \immediate\closeout#1%
+}
+
+\newcommand{\@cps@@closeoutcpsfile}[1]{%
+ \@cps@@typeout{Closing cps#1 file}%
+ \@cps@@closeoutfile{\csname\@cps@@writefilehandlename{#1}\endcsname}%
+}
+
+
+
+\newcommand{\@startcountertoc}[1]{%
+ \begingroup%
+ % The file handles are generated either by `\@registercounterspertracklevel` or in \AtBeginDocument
+ \makeatletter
+ % Read first before deleting it
+ \IfFileExists{\jobname.cps#1}{%
+ \@cps@@openincpsfile{#1}%
+ \@cps@@readcounternumbers{\@cps@@readfilehandle}{#1}%
+ \@cps@@closeinfile{\@cps@@readfilehandle}%
+ }{%
+ \typeout{No #1{} counter values so far}%
+ }
+ \if@filesw
+ % Write only if not `\nofiles` is specified
+ \@cps@@openoutcpsfile{#1}%
+ \fi%
+ \@nobreakfalse%
+ \endgroup%
+}
+
+
+
+\newcommand{\@cps@@readcounternumbers}[2]{%
+ \setcounter{cps@@togglecounter}{0}%
+ \whiledo {\value{cps@@togglecounter} < 1}{%
+ \read#1 to \@cps@@numberfromfile%
+ \ifeof #1%
+ \stepcounter{cps@@togglecounter}%
+ \else%
+ \listcsxadd{#2countlist}{\@cps@@numberfromfile}%
+ \fi%
+ }%
+}
+
+\newcommand{\@cps@@storecounter}[1]{%
+ \addtocontents{cps#1}{%
+ \number\value{cps@@cps@@total#1}%
+ }%
+}
+
+
+\newcommand{\@cps@@csloop}[1]{%
+ \ifnumgreater{\value{\@cps@@cpscountersname}}{0}{%
+ \expandafter\forlistcsloop{\csname #1\endcsname}{\@cps@@counterlistname}
+ }{%
+ }%
+}
+
+\newcommand{\@cps@@loopstorecounters}{%
+ \ifnumgreater{\value{\@cps@@cpscountersname}}{0}{%
+ \forlistcsloop{\@cps@@storecounter}{\@cps@@counterlistname}%
+ }{%
+ }%
+}
+
+
+\newcommand{\@cps@@registercounter}[1]{%
+ \listcsxadd{\@cps@@counterlistname}{#1}%
+ \stepcounter{cps@@cpscounters}%
+ \listcsxadd{#1countlist}{}%
+ \DeclareCPSCounter{total#1}%
+ \DeclareCPSCounter{grandtotaltemp#1}%
+ \DeclareCPSCounter{grandtotal#1}%
+ \@cps@@generatewritefilehandle{#1}%
+ % This needs some work to do
+ \DeclareAssociatedCounters{#1}{cps@@cps@@total#1,cps@@cps@@grandtotaltemp#1}%
+}
+
+%% Searches the list of counter values for the tracklevel (#2)
+\newcommand{\@cps@@searchcountervalue}[3]{%
+ \setcounter{cps@@tempcounterstorage}{-1}%
+ \ifnumequal{#1}{\value{#2}}{%
+ % Value found, store it temporarily
+ \setcounter{cps@@tempcounterstorage}{#3}%
+ \listbreak%
+ }{%
+ \stepcounter{#2}%
+ }%
+}
+
+
+\newcommand{\@cps@@auxsetcounter}[2]{%
+ \immediate\write\@auxout{%
+ \string\setcounter{#1}{\number\value{#2}}
+ }
+}%
+
+\newcommand{\@cps@@storegrandtotal}[1]{%
+ \@cps@@auxsetcounter{cps@@cps@@grandtotal#1}{cps@@cps@@grandtotaltemp#1}%
+}
+
+
+
+
+%%%%%%%%%%%%%% User commands %%%%%%%%%%%%%%%%%%%%
+
+
+\newcommand{\RegisterCounter}[2][]{%
+ \begingroup
+ \setkeys{cpskeys}{#1}%
+ \ifltxcounter{#2}{%
+ \@cps@@registercounter{#2}%
+ }{%
+ \ifKV@cpskeys@autodefine
+ \newcounter{#2}%
+ \@cps@@registercounter{#2}%
+ \else%
+ % Ignore non existing counters
+ \GenericWarning{Counter #1 is not defined}{}%
+ \fi
+ }%
+ \endgroup
+}
+
+\newcommand{\RegisterCounters}[1]{%
+ \forcsvlist{\RegisterCounter}{#1}%
+}
+
+% Prevent usage later in document body
+
+\@onlypreamble{\@registercounters}
+\@onlypreamble{\RegisterCounter}
+\@onlypreamble{\RegisterCounters}
+\@onlypreamble{\PrepareToCCommands}
+
+
+\newcommand{\ResetStoredCounter}[1]{%
+ \setcounter{cps@@cps@@total#1}{0}%
+}
+
+
+% Reset all total counters
+\newcommand{\ResetStoredCounters}{%
+ \ifnumgreater{\value{\@cps@@cpscountersname}}{0}{%
+ \forlistcsloop{\ResetStoredCounter}{\@cps@@counterlistname}%
+ }{}%
+}
+
+%% Only for statistical purposes. Do not use it in a production run
+\newcommand{\IndividualCounterStatistics}[2][\number\value{cps@@currentlevelcount}]{%
+ \ifcpsdraftmode
+ \GetStoredCounterValue[#1]{#2}%
+ \ifnumgreater{\value{cps@@tempcounterstorage}}{-1}{%
+ \noindent \@cps@@keymacro@@tracklevel\ #1~has \number\value{cps@@tempcounterstorage} #2(s)\par
+ }{}
+ \fi
+}%
+
+%% Only for statistical purposes. Do not use it in a production run
+\newcommand{\ShowStatistics}[1][\number\value{cps@@currentlevelcount}]{%
+ \ifcpsdraftmode%
+ \ifnumgreater{\value{\@cps@@cpscountersname}}{0}{%
+ \forlistcsloop{\IndividualCounterStatistics[\number#1]}{\@cps@@counterlistname}%
+ }{%
+ \typeout{No counters registered}%
+ }%
+ \fi%
+}
+
+\newcommand{\fullstatistics}[1]{%
+\hspace{1cm} \number\value{cps@@cps@@grandtotal#1}{} #1(s)%
+
+}
+
+
+\newcommand{\Fullstatistics}{%
+ This document has
+
+ \ifnumgreater{\value{\@cps@@cpscountersname}}{0}{%
+ \forlistcsloop{\fullstatistics}{\@cps@@counterlistname}%
+ }{%
+ \typeout{No counters registered}%
+ }%
+}
+
+
+\newcommand{\GetStoredCounterValue}[2][\number\value{cps@@currentlevelcount}]{%
+ \setcounter{cps@@tempcounter}{0}%
+ \ifnumgreater{#1}{\value{cps@@totaltracklevelcount}}{%
+ \def\cps@@trackleveltoshow{\value{cps@@totaltracklevelcount}}%
+ }{%
+ \def\cps@@trackleveltoshow{#1}%
+ }%
+ \ifcsdef{#2countlist}{%
+ \forlistcsloop{\@cps@@searchcountervalue{\cps@@trackleveltoshow}{cps@@tempcounter}}{#2countlist}%
+ }{%
+ \typeout{Warning: List for counter #2 not defined}%
+ }% Failure branch should be improved
+}
+
+\newcommand{\FetchStoredCounterValue}[2][\number\value{cps@@currentlevelcount}]{%
+ \GetStoredCounterValue[#1]{#2}%
+ \number\value{cps@@tempcounterstorage}%
+}
+
+
+\newcommand{\StartCounterToc}{%
+ \ifnumgreater{\value{\@cps@@cpscountersname}}{0}{%
+ \forlistcsloop{\@startcountertoc}{\@cps@@counterlistname}%
+ }{%
+ }%
+}
+
+
+
+\newcommand{\CloseCPSFiles}{%
+ \ifnumgreater{\value{\@cps@@cpscountersname}}{0}{%
+ \forlistcsloop{\@cps@@closeoutcpsfile}{\@cps@@counterlistname}%
+ }{%
+ }%
+}
+
+\newcommand{\StoreCounters}{%
+ \ifcpsstorage% Only store counters if \cpsstoragetrue
+ \@cps@@loopstorecounters%
+ \fi%
+}
+
+\newcommand{\StoreGrandTotalCounters}{%
+ \forlistcsloop{\@cps@@storegrandtotal}{\@cps@@counterlistname}%
+}
+
+
+\newcommand{\StopCounting}{%
+ \StoreCounters%
+}
+
+
+
+%% Informational macros -- very hackish so far
+
+\newcommand{\CPSGetCounterList}{%
+ \csname\@cps@@counterlistname\endcsname%
+}
+
+\newcommand{\numberofstoredcounters}{%
+ \number\value{\@cps@@cpscountersname}%
+}
+
+\AtBeginDocument{%
+ \StartCounterToc%
+}
+
+
+\AtEndDocument{%
+ % Write the last counter values to the file
+ \StopCounting%
+ % Full counter values
+ \StoreGrandTotalCounters%
+}
+
+%% etoolbox - addition
+\AfterEndDocument{%
+ \ifcpsnoendclose
+ % Prevent the explicit closing
+ \else
+ \CloseCPSFiles%
+ \fi
+}
+
+
+\endinput