From 40dd5938ded99176abd37cee3b6271722fe30f24 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Mon, 11 May 2015 21:07:46 +0000 Subject: cntperchap (10may15) git-svn-id: svn://tug.org/texlive/trunk@37338 c570f23f-e606-0410-a88d-b1316a301751 --- .../texmf-dist/tex/latex/cntperchap/cntperchap.sty | 400 +++++++++++++++++---- 1 file changed, 327 insertions(+), 73 deletions(-) (limited to 'Master/texmf-dist/tex/latex') diff --git a/Master/texmf-dist/tex/latex/cntperchap/cntperchap.sty b/Master/texmf-dist/tex/latex/cntperchap/cntperchap.sty index 62c1e57f6e5..94b202903fd 100644 --- a/Master/texmf-dist/tex/latex/cntperchap/cntperchap.sty +++ b/Master/texmf-dist/tex/latex/cntperchap/cntperchap.sty @@ -1,5 +1,5 @@ \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{cntperchap}[2015/05/03 v0.1 -- store counter values per chapter]% +\ProvidesPackage{cntperchap}[2015/05/09 v0.2 -- store counter values per chapter]% %% %% License: LaTeX Project Public License version 1.3 %% Copyright (2015) Dr. Christian Hupfer @@ -26,220 +26,474 @@ \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]{} -\presetkeys{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{autodefine}{\cpsautodefinetrue\presetkeys{cpskeys}{autodefine=true}{}} +\DeclareOptionX{noendclose}{\cpsnoendclosetrue} +\DeclareOptionX{tracklevel}{\presetkeys{cpskeys}{tracklevel=#1}{}} +\DeclareOptionX{verbose}{\cpsverbosetrue} + \ProcessOptionsX* -\newcommand{\cpscounterlistname}{@counterstowatch} -\listcsadd{\cpscounterlistname}{} +\newcommand{\@cps@@counterlistname}{cps@@counterstostore} +\listcsadd{\@cps@@counterlistname}{} + + %%%% Internal commands -\newcounter{cps@@currentchapter} +% 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} -\NewDocumentCommand{\cpschapterstarthook}{}{% - \stepcounter{cps@@currentchapter}% - \ifnumgreater{\value{cps@@currentchapter}}{0}{% - \StoreCountersPerChapter% + +\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% }{}% - \ResetTotalCounters% + \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% } -% Prepending the \chapter command with some starter hook +\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}% +} -\xpretocmd{\chapter}{\cpschapterstarthook}{}{} -% This is a modified version from \@starttoc, being defined in latex.ltx \newcommand{\@startcountertoc}[1]{% \begingroup% - % Generate the file handle first - \expandafter\newwrite\csname tf@cps#1\endcsname% + % The file handles are generated either by `\@registercounterspertracklevel` or in \AtBeginDocument \makeatletter % Read first before deleting it - \ifcsdef{tf@cps#1}{% - \IfFileExists{\jobname.cps#1}{% - \immediate\openin\csname tf@cps#1\endcsname \jobname.cps#1\relax% - \@readcounternumbersfromfile{#1}% - }{% - % Oops, the file is not there :-( - }% + \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 - \immediate\openout \csname tf@cps#1\endcsname \jobname.cps#1\relax% + \@cps@@openoutcpsfile{#1}% \fi% \@nobreakfalse% \endgroup% } -\newcommand{\@readcounternumbersfromfile}[1]{% + +\newcommand{\@cps@@readcounternumbers}[2]{% \setcounter{cps@@togglecounter}{0}% \whiledo {\value{cps@@togglecounter} < 1}{% - \expandafter\read\csname tf@cps#1\endcsname to \cps@@numberfromfile% - \ifeof\csname tf@cps#1\endcsname% + \read#1 to \@cps@@numberfromfile% + \ifeof #1% \stepcounter{cps@@togglecounter}% \else% - \listcsxadd{#1countlist}{\cps@@numberfromfile}% + \listcsxadd{#2countlist}{\@cps@@numberfromfile}% \fi% }% } -\newcommand{\@cpsstorecounter}[1]{% +\newcommand{\@cps@@storecounter}[1]{% \addtocontents{cps#1}{% - \number\value{cps@total#1}% + \number\value{cps@@cps@@total#1}% }% } -\newcommand{\@cpscsloop}[1]{% - \ifnumgreater{\value{cps@@cpscounters}}{0}{% - \expandafter\forlistcsloop{\csname #1\endcsname}{\cpscounterlistname} +\newcommand{\@cps@@csloop}[1]{% + \ifnumgreater{\value{\@cps@@cpscountersname}}{0}{% + \expandafter\forlistcsloop{\csname #1\endcsname}{\@cps@@counterlistname} }{% }% } -\newcommand{\@cpsloopstorecounters}{% - \ifnumgreater{\value{cps@@cpscounters}}{0}{% - \forlistcsloop{\@cpsstorecounter}{\cpscounterlistname}% +\newcommand{\@cps@@loopstorecounters}{% + \ifnumgreater{\value{\@cps@@cpscountersname}}{0}{% + \forlistcsloop{\@cps@@storecounter}{\@cps@@counterlistname}% }{% }% } -\newcommand{\@registercounterperchapter}[1]{% - \listcsxadd{\cpscounterlistname}{#1}% + +\newcommand{\@cps@@registercounter}[1]{% + \listcsxadd{\@cps@@counterlistname}{#1}% \stepcounter{cps@@cpscounters}% \listcsxadd{#1countlist}{}% - \newcounter{cps@total#1}% - \DeclareAssociatedCounters{#1}{cps@total#1}% + \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 correct chapter -\newcommand{\@cpssearchcountervalue}[3]{% +%% Searches the list of counter values for the tracklevel (#2) +\newcommand{\@cps@@searchcountervalue}[3]{% + \setcounter{cps@@tempcounterstorage}{-1}% \ifnumequal{#1}{\value{#2}}{% - #3\listbreak% + % 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{\RegisterCounterPerChapter}[2][]{% +\newcommand{\RegisterCounter}[2][]{% \begingroup \setkeys{cpskeys}{#1}% \ifltxcounter{#2}{% - \@registercounterperchapter{#2}% + \@cps@@registercounter{#2}% }{% \ifKV@cpskeys@autodefine \newcounter{#2}% - \@registercounterperchapter{#2}% + \@cps@@registercounter{#2}% \else% % Ignore non existing counters + \GenericWarning{Counter #1 is not defined}{}% \fi }% \endgroup } -\newcommand{\RegisterCountersPerChapter}[1]{% - \forcsvlist{\RegisterCounterPerChapter}{#1}% +\newcommand{\RegisterCounters}[1]{% + \forcsvlist{\RegisterCounter}{#1}% } % Prevent usage later in document body -\@onlypreamble{\RegisterCounterPerChapter} -\@onlypreamble{\RegisterCountersPerChapter} -\newcommand{\ResetTotalCounter}[1]{% - \setcounter{cps@total#1}{0}% +\@onlypreamble{\@registercounters} +\@onlypreamble{\RegisterCounter} +\@onlypreamble{\RegisterCounters} +\@onlypreamble{\PrepareToCCommands} + + +\newcommand{\ResetStoredCounter}[1]{% + \setcounter{cps@@cps@@total#1}{0}% } % Reset all total counters -\newcommand{\ResetTotalCounters}{% - \ifnumgreater{\value{cps@@cpscounters}}{0}{% - \forlistcsloop{\ResetTotalCounter}{\cpscounterlistname}% +\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@@currentchapter}]{% +\newcommand{\IndividualCounterStatistics}[2][\number\value{cps@@currentlevelcount}]{% \ifcpsdraftmode - \noindent Chapter #1~ has \GetTotalCounter[#1]{#2} #2(s)\par + \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@@currentchapter}]{% +\newcommand{\ShowStatistics}[1][\number\value{cps@@currentlevelcount}]{% \ifcpsdraftmode% - \ifnumgreater{\value{cps@@cpscounters}}{0}{% - \forlistcsloop{\IndividualCounterStatistics[\number#1]}{\cpscounterlistname}% + \ifnumgreater{\value{\@cps@@cpscountersname}}{0}{% + \forlistcsloop{\IndividualCounterStatistics[\number#1]}{\@cps@@counterlistname}% }{% \typeout{No counters registered}% }% \fi% } -\newcommand{\GetTotalCounter}[2][\number\value{cps@@currentchapter}]{% +\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{\@cpssearchcountervalue{#1}{cps@@tempcounter}}{#2countlist}% + \forlistcsloop{\@cps@@searchcountervalue{\cps@@trackleveltoshow}{cps@@tempcounter}}{#2countlist}% }{% \typeout{Warning: List for counter #2 not defined}% }% Failure branch should be improved } + \newcommand{\StartCounterToc}{% - \ifnumgreater{\value{cps@@cpscounters}}{0}{% - \forlistcsloop{\@startcountertoc}{\cpscounterlistname}% + \ifnumgreater{\value{\@cps@@cpscountersname}}{0}{% + \forlistcsloop{\@startcountertoc}{\@cps@@counterlistname}% }{% }% } -\newcommand{\StoreCountersPerChapter}{% - \@cpsloopstorecounters% + + +\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{% - % Grab the counter 'tocs' \StartCounterToc% } \AtEndDocument{% - % Write the counter values to the file - \StoreCountersPerChapter% + % Write the last counter values to the file + \StopCounting% + % Full counter values + \StoreGrandTotalCounters% +} + +%% etoolbox - addition +\AfterEndDocument{% + \ifcpsnoendclose + % Prevent the explicit closing + \else + \CloseCPSFiles% + \fi } -- cgit v1.2.3