%D \module %D [ file=strc-pag, %D version=2008.10.20, %D title=\CONTEXT\ Structure Macros, %D subtitle=Pagenumbering, %D author=Hans Hagen, %D date=\currentdate, %D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] %C %C This module is part of the \CONTEXT\ macro||package and is %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. \writestatus{loading}{ConTeXt Structure Macros / Pagenumbering} \registerctxluafile{strc-pag}{1.001} \unprotect % Allocation: \countdef\realpageno = 0 \realpageno = 1 \countdef\userpageno = 1 \userpageno = 1 \countdef\subpageno = 2 \subpageno = 0 % !! \countdef\arrangeno = 3 \arrangeno = 0 % !! \countdef\pagenoshift = 4 \pagenoshift = 0 % !! \let\pageno\userpageno \def\realfolio{\the\realpageno} \def\userfolio{\the\userpageno} \def\subfolio {\the\subpageno } \newtoks\everyinitializepagecounters \def\initializepagecounters{\the\everyinitializepagecounters} \appendtoks \initializepagecounters \to \everyjob % Page numbers are kind of independent of each other and therefore they % all get their own counter. After all, it's easier to combine them in % a pseudo counterset than to deal with a complex set itself. % \defineprefixset [mine][section-1,section-2] % \defineseparatorset[mine][:] % % \setupuserpagenumber % [way=bypart, % prefix=yes, % prefixset=mine, % prefixseparatorset=mine] % \defineconversionset[frontpart:pagenumber][][romannumerals] % \defineconversionset[bodypart:pagenumber] [][numbers] % % \setupuserpagenumber[way=byblock] % \setupuserpagenumber[way=bychapter] % \setupuserpagenumber[numberconversionset=pagenumber] % % \starttext % \startfrontmatter % \completecontent[criterium=all] % \chapter{tufte} \section{one} \input tufte \page \section{two} \input tufte \page % \chapter{tufte} \section{one} \input tufte \page \section{two} \input tufte \page % \stopfrontmatter % \startbodymatter % \chapter{knuth} \section{one} \input knuth \page \section{two} \input knuth \page \section{three} \input knuth \page % \chapter{knuth} \section{one} \input knuth \page \section{two} \input knuth \page \section{three} \input knuth \page % \stopbodymatter % \stoptext \definecounter[\s!realpage][\c!prefix=\v!no,\c!start=1,\c!prefixsegments=,\s!counter=realpageno,\c!method=\v!page] \definecounter[\s!userpage][\c!prefix=\v!no,\c!start=1,\c!prefixsegments=,\s!counter=userpageno,\c!method=\v!page] \definecounter[\s!subpage] [\c!prefix=\v!no,\c!start=1,\c!prefixsegments=,\s!counter=subpageno, \c!method=\v!page] \newtoks\everysetuprealpagenumber % todo: set state: none, start, stop, reset \newtoks\everysetupuserpagenumber % todo: set state: none, start, stop, reset \newtoks\everysetupsubpagenumber % todo: set state: none, start, stop, reset \unexpanded\def\setuprealpagenumber{\dosingleargument\dosetuprealpagenumber} \unexpanded\def\setupuserpagenumber{\dosingleargument\dosetupuserpagenumber} \unexpanded\def\setupsubpagenumber {\dosingleargument\dosetupsubpagenumber} \def\dosavepagenumberstate#1{\edef\oldpagenumberstate{\counterparameter#1\c!state}} \def\dosetuprealpagenumber[#1]{\dosavepagenumberstate\s!realpage\strc_counters_setup[\s!realpage][#1]\the\everysetuprealpagenumber} \def\dosetupuserpagenumber[#1]{\dosavepagenumberstate\s!userpage\strc_counters_setup[\s!userpage][#1]\the\everysetupuserpagenumber} \def\dosetupsubpagenumber [#1]{\dosavepagenumberstate\s!subpage \strc_counters_setup[\s!subpage ][#1]\the\everysetupsubpagenumber } \def\resetrealpagenumber {} % not permitted \def\resetuserpagenumber {\strc_counters_reset\s!userpage} \def\resetsubpagenumber {\strc_counters_reset\s!subpage} \appendtoks \strc_counters_set\s!realpage\realpageno \strc_counters_set\s!userpage\userpageno \strc_counters_set\s!subpage \subpageno \to \everyinitializepagecounters \let\setuppagenumber\setupuserpagenumber \let\resetpagenumber\resetuserpagenumber \def\savecurrentpagestate % \normalexpanded? {\ctxlua{structures.pages.save({ prefix = "\counterparameter\s!userpage\c!prefix", separatorset = "\counterparameter\s!userpage\c!prefixseparatorset", conversion = "\counterparameter\s!userpage\c!prefixconversion", conversionset = "\counterparameter\s!userpage\c!prefixconversionset", set = "\counterparameter\s!userpage\c!prefixset", segments = "\counterparameter\s!userpage\c!prefixsegments", connector = \!!bs\counterparameter\s!userpage\c!prefixconnector\!!es, },{ conversion = "\counterparameter\s!userpage\c!numberconversion", conversionset = "\counterparameter\s!userpage\c!numberconversionset", starter = \!!bs\counterparameter\s!userpage\c!numberstarter\!!es, stopper = \!!bs\counterparameter\s!userpage\c!numberstopper\!!es, } )}} \prependtoks \savecurrentpagestate \to \everyshipout \def\pushpagestate{\setxvalue{\??nm:\s!userpage:\c!state}{\counterparameter\s!userpage\c!state}} \def\poppagestate {\normalexpanded{\setuppagenumber[\c!state=\getvalue{\??nm:\s!userpage:\c!state}]}} \setuppagenumber [\c!way=\v!by\v!text, \c!prefix=\v!no, \c!prefixset=\v!part, \c!prefixconnector=\endash, \c!state=\v!start] \setupsubpagenumber [\c!way=\v!by\v!part, \c!state=\v!stop] % Counters \def\firstrealpagenumber{\convertedcounter[\s!realpage][\c!type=\v!first]} \def\firstuserpagenumber{\convertedcounter[\s!userpage][\c!type=\v!first]} \def\firstsubpagenumber {\convertedcounter[\s!subpage ][\c!type=\v!first]} \def\lastrealpagenumber {\convertedcounter[\s!realpage][\c!type=\v!last]} \def\lastuserpagenumber {\convertedcounter[\s!userpage][\c!type=\v!last]} \def\lastsubpagenumber {\convertedcounter[\s!subpage ][\c!type=\v!last]} \def\prevrealpagenumber {\convertedcounter[\s!realpage][\c!type=\v!previous]} \def\prevuserpagenumber {\convertedcounter[\s!userpage][\c!type=\v!previous]} \def\prevsubpagenumber {\convertedcounter[\s!subpage ][\c!type=\v!previous]} \def\nextrealpagenumber {\convertedcounter[\s!realpage][\c!type=\v!next]} \def\nextuserpagenumber {\convertedcounter[\s!userpage][\c!type=\v!next]} \def\nextsubpagenumber {\convertedcounter[\s!subpage ][\c!type=\v!next]} \def\firstrealpage{\strc_counters_first\s!realpage} \def\firstuserpage{\strc_counters_first\s!userpage} \def\firstsubpage {\strc_counters_first\s!subpage } \def\prevrealpage {\strc_counters_prev \s!realpage} \def\prevuserpage {\strc_counters_prev \s!userpage} \def\prevsubpage {\strc_counters_prev \s!subpage } \def\nextrealpage {\strc_counters_next \s!realpage} \def\nextuserpage {\strc_counters_next \s!userpage} \def\nextsubpage {\strc_counters_next \s!subpage } \def\lastrealpage {\strc_counters_last \s!realpage} \def\lastuserpage {\strc_counters_last \s!userpage} \def\lastsubpage {\strc_counters_last \s!subpage } \let\firstpage\firstrealpage \let\prevpage \prevrealpage \let\nextpage \nextrealpage \let\lastpage \lastrealpage % Compatibility counters: \def\nofrealpages {\lastrealpage} \def\totalnumberofpages{\lastrealpage} \def\nofuserpages {\lastuserpage} \def\lastpagenumber {\lastuserpage} \def\nofsubpages {\lastsubpage } % Renderers: \def\pagenumber {\strc_counters_raw\s!userpage} \def\prefixedpagenumber {\directconvertedcounter\s!userpage\empty} % \userpagenumber \def\realpagenumber {\directconvertedcounter\s!realpage\empty} \def\userpagenumber {\directconvertedcounter\s!userpage\empty} \def\subpagenumber {\directconvertedcounter\s!subpage \empty} \def\firstrealpagenumber{\directconvertedcounter\s!realpage\v!first} \def\firstuserpagenumber{\directconvertedcounter\s!userpage\v!first} \def\firstsubpagenumber {\directconvertedcounter\s!subpage \v!first} \def\lastrealpagenumber {\directconvertedcounter\s!realpage\v!last} \def\lastuserpagenumber {\directconvertedcounter\s!userpage\v!last} \def\lastsubpagenumber {\directconvertedcounter\s!subpage \v!last} \def\prevrealpagenumber {\directconvertedcounter\s!realpage\v!previous} \def\prevuserpagenumber {\directconvertedcounter\s!userpage\v!previous} \def\prevsubpagenumber {\directconvertedcounter\s!subpage \v!previous} \def\nextrealpagenumber {\directconvertedcounter\s!realpage\v!next} \def\nextuserpagenumber {\directconvertedcounter\s!userpage\v!next} \def\nextsubpagenumber {\directconvertedcounter\s!subpage \v!next} \def\dodeincrementpageboundcounters % only at the end {\strc_counters_decrement\s!realpage \strc_counters_decrement\s!userpage \strc_counters_decrement\s!subpage} \def\doincrementpageboundcounters {\incrementpagenumber \incrementsubpagenumber} \appendtoks \dodeincrementpageboundcounters \to \everygoodbye % Equivalents (compatibility): % % todo: maybe leave lastpage etc lua calls \def\realpage{\the\realpageno} \def\userpage{\the\userpageno} \def\subpage {\the\subpageno} % Hooks: \def\currentpage{\the\realpageno}% rather useless \appendtoks \ifnum\realpageno>\lastpage \globallet\lastpage\lastrealpage \fi \to \everyinitializepagecounters % States: \newif\ifrightpage \rightpagetrue \newif\ifdoublesided \newconditional\layoutisdoublesided \newif\ifsinglesided \newconditional\layoutissinglesided % Realpage and subpage numbers: \def\setnextrealpageno{\global\realpageno\strc_counters_incremented\s!realpage\relax} \def\setnextsubpageno {\global\subpageno \strc_counters_incremented\s!subpage \relax} % Page numbers: (can move to lua) ... inconsistent names \def\dodecrementpagenumber {\global\userpageno\strc_counters_decremented\s!userpage\relax} \def\doincrementpagenumber {\global\userpageno\strc_counters_incremented\s!userpage\relax} \def\decrementsubpagenumber{\global\subpageno \strc_counters_decremented\s!subpage \relax} \def\incrementsubpagenumber{\global\subpageno \strc_counters_incremented\s!subpage \relax} \def\dosynchronizepagenumber{\global\let\@@pnstate\v!start} \def\decrementpagenumber{\csname\??pn-\counterparameter\s!userpage\c!state\endcsname} \def\incrementpagenumber{\csname\??pn+\counterparameter\s!userpage\c!state\endcsname} \letvalue{\??pn-\v!start}\dodecrementpagenumber \letvalue{\??pn-\v!none }\dodecrementpagenumber \letvalue{\??pn-\v!empty}\dodecrementpagenumber \letvalue{\??pn+\v!start}\doincrementpagenumber \letvalue{\??pn+\v!none }\doincrementpagenumber \setvalue{\??pn+\v!empty}{\doincrementpagenumber\dosynchronizepagenumber} \letvalue{\??pn+\v!keep }\dosynchronizepagenumber % Control: \def\getpagestatus % hierboven gebruiken {\ifdoublesided \global\rightpagetrue % todo: \global\rightpagetrue or \global\rightpagefalse \else \global\rightpagetrue \fi} % Setup general page numbering \newtoks\everysetuppagenumbering \unexpanded\def\setuppagenumbering {\dosingleempty\dosetuppagenumbering} \def\dosetuppagenumbering[#1]% {\getparameters[\??nm][#1]\the\everysetuppagenumbering} \appendtoks \singlesidedfalse \setfalse\layoutisdoublesided \doublesidedfalse \setfalse\layoutissinglesided \normalexpanded{\noexpand\processallactionsinset[\@@nmalternative]} [ \v!singlesided=>\singlesidedtrue\settrue\layoutissinglesided, \v!doublesided=>\doublesidedtrue\settrue\layoutisdoublesided]% \ifdefined\trackingmarginnotestrue \ifdoublesided \trackingmarginnotestrue \else \trackingmarginnotesfalse \fi \fi \page_backgrounds_recalculate \dosetpagenumberlocation \to \everysetuppagenumbering \ifdefined \page_backgrounds_recalculate \else \let\page_backgrounds_recalculate\relax \fi \ifdefined \dosetpagenumberlocation \else \let\dosetpagenumberlocation\relax \fi \def\flushfinallayoutpage {\doifsomething\@@nmpage{\doifnot\@@nmpage\v!no{\page[\@@nmpage]}}} % The numbered location handler is there because we need to be downward % compatible. So, in fact there can be multiple handlers active at the % same time, but only the current one does something. % Rendering: \unexpanded\def\placelocationpagenumber {\ifnum\userpagenumberstate=\plustwo \ifnum\overallpagenumberstate=\plusone \doif\@@nmstrut\v!yes\strut \begingroup \dousestyleparameter\@@nmstyle \dousecolorparameter\@@nmcolor \@@nmcommand{\@@nmleft\labeltexts\v!pagenumber{\prefixedpagenumber}\@@nmright}% \endgroup \fi \fi} \unexpanded\def\completepagenumber {\ifnum\userpagenumberstate=\plustwo \ifnum\overallpagenumberstate=\plusone \@@nmleft\labeltexts\v!pagenumber\prefixedpagenumber\@@nmright \fi \fi} \unexpanded\def\placepagenumber {\ifnum\userpagenumberstate=\plustwo \ifnum\overallpagenumberstate=\plusone \labeltexts\v!pagenumber\pagenumber \fi \fi} \unexpanded\def\referencepagenumber[#1]% {\doifelsenothing{#1}{?}{}} % The numbered location handler is there because we need to be downward % compatible. So, in fact there can be multiple handlers active at the % same time, but only the current one does something. \setnewconstant\realpagenumberstate \plustwo % counter state : 0=stop, 1=start, 2=start and visible \setnewconstant\userpagenumberstate \plustwo % counter state : 0=stop, 1=start, 2=start and visible \setnewconstant\subpagenumberstate \plustwo % counter state : 0=stop, 1=start, 2=start and visible \setnewconstant\overallpagenumberstate\plusone % general number: 0=invisible, 1=visible \def\checkpagenumberstatechange#1#2% {\edef\newpagenumberstate{\counterparameter#1\c!state}% \ifx\newpagenumberstate\oldpagenumberstate \else \doifelse\newpagenumberstate\v!start {#2\plustwo}% {#2\zerocount}% \fi} \appendtoks % todo: set state: none, start, stop, reset \checkpagenumberstatechange\s!realpage\realpagenumberstate \to \everysetuprealpagenumber \appendtoks % todo: set state: none, start, stop, reset \checkpagenumberstatechange\s!userpage\userpagenumberstate \to \everysetupuserpagenumber \appendtoks % todo: set state: none, start, stop, reset \checkpagenumberstatechange\s!subpage\subpagenumberstate \to \everysetupsubpagenumber \appendtoks % todo: set state: none, start, stop, reset \doifelse\@@nmstate\v!start {\overallpagenumberstate\plusone }% {\overallpagenumberstate\zerocount}% \to \everysetuppagenumbering % Done % \c!way=\v!by\v!part % \c!text= % \v!chapter\v!number=\v!no % \v!part\v!number=\v!yes % \c!numberseparator=-- % \c!conversion=\v!numbers \setuppagenumbering [\c!alternative=\v!singlesided, \c!location={\v!header,\v!middle}, \c!width=, % in geval van \v!marginedge \c!left=, \c!right=, \c!page=\v!last, \c!textseparator=\tfskip, \c!state=\v!start, \c!command=, \c!strut=\v!yes, \c!style=, % empty, otherwise conflict \c!color=] % just for downward compatbility \appendtoks \edef\askeduserpagenumber{\counterparameter\s!userpage\c!number}% \ifx\askeduserpagenumber\empty \else \normalexpanded{\setuppagenumber[\c!start=\counterparameter\s!userpage\c!number,\c!number=]}% \userpageno\strc_counters_raw\s!userpage \fi \to \everysetupuserpagenumber % todo: set state: none, start, stop, reset \appendtoks \edef\askedsubpagenumber{\counterparameter\s!subpage\c!number}% \ifx\askedsubpagenumber\empty \else \normalexpanded{\setupsubpagenumber[\c!start=\counterparameter\s!subpage\c!number,\c!number=]}% \subpageno\strc_counters_raw\s!subpage\relax \fi \to \everysetupsubpagenumber % todo: set state: none, start, stop, reset % \setuplayout[width=300pt,backspace=4cm] % \setuppagenumbering [alternative=doublesided] % \setupuserpagenumber[start=2] % \starttext \dorecurse{20}{\input knuth \par} \stoptext \def\checkpagenumbershift {\userpageno\strc_counters_raw\s!userpage\relax \ifnum\realpageno=\plusone \ifodd\userpageno \else \global\pagenoshift\plusone \fi \fi} \appendtoks % todo: set state: none, start, stop, reset % this makes starting at an even page possible \checkpagenumbershift \to \everysetupuserpagenumber \appendtoks % todo: set state: none, start, stop, reset % this makes starting at an even page possible \checkpagenumbershift \to \everysetuppagenumbering \initializepagecounters \protect \endinput