%D \module %D [ file=page-ini, %D version=2000.10.20, %D title=\CONTEXT\ Page Macros, %D subtitle=Initializations, %D author=Hans Hagen, %D date=\currentdate, %D copyright={PRAGMA / Hans Hagen \& Ton Otten}] %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 Page Macros / Initializations} % still a dutch/english mess %D This class of modules implements the output routines and %D floating body support. Although the modules are relatively %D new, the code herein is rather old. This reordering was %D needed when column sets were implemented and sharing code %D started to make sense. %D The history shows from the code, since both column %D mechanism use a different way of looping over columns. \unprotect \def\m!otr{otr} % \setnewconstant\normalpagebox 255 % already set \newbox\pagebox \ifx\recalculatelayout\undefined \let \recalculatelayout \relax \fi \ifx\recalculatebackgrounds\undefined \let \recalculatebackgrounds \relax \let \addmainbackground \gobbleoneargument % \let \addtextbackground \gobbleoneargument % \let \addpagebackground \gobbleoneargument % \let \addprintbackground \gobbleoneargument % \let \addstatusinfo \gobbleoneargument % \fi \ifx\realpageno\undefined \countdef\realpageno = 0 \realpageno = 1 \countdef\userpageno = 1 \userpageno = 1 \countdef\subpageno = 2 \subpageno = 0 % !! \countdef\arrangeno = 3 \arrangeno = 0 % !! \let\pageno\userpageno \fi \ifx\realfolio\undefined \def\realfolio{\the\realpageno} \fi \newcount\nofshipouts \appendtoks \global\advance\nofshipouts\plusone \to \everyaftershipout % principle: % % multiple otr's % % (1) single column, simple routine (old one) % (2) multi column, collect and split routine (old one) % (3) multi column, page by page (new one, needed for taco) % (4) single column, spread handling (for fun) % (5) multi column, page by page, spread handling (as challenge) % % common components % % (1) float placement % (2) float flushing % (3) page body building % (4) ... % % ort % % + balancing % - mixed / one / multi / balancetofit % + backgrounds % + pre / post % + distances / heights % + ragged / baseline / normal % - pos sync % - last page % % - itemize / subtexts -> old mechanism % % floats % % - top / bottom / side / page / column / spead % - flush / packed flush / current page / next page / area % % footnotes % % + carry over pre column / local to column % + last column / pre last column / each column % - multiple classes % - area / page / end % % areas % % - top / bottom / mid in spread % % IMPORTANT % % switchtobodyfont in between ivm top % floats: % % tricky in balancing mode, a la huidige multi columns \ifx\dosetuplayout\undefined % overloaded in page-lay ! \unexpanded\def\setuplayout{\dodoubleempty\getparameters[\??ly]} \fi \ifx\mkprocesscolumncontents\undefined\let\mkprocesscolumncontents\gobbleoneargument\fi \ifx\mkprocesspagecontents \undefined\let\mkprocesspagecontents \gobbleoneargument\fi \ifx\mkprocessboxcontents \undefined\let\mkprocessboxcontents \gobbleoneargument\fi \def\normalejectpenalty{-\plustenthousand } \let\ejectpenalty\normalejectpenalty \def\normalsuperpenalty{-\plustwentythousand} \let\superpenalty\normalsuperpenalty %D In case we're not running \ETEX, we need to bypass a %D couple of primitives. % ONE = single column % MUL = multi column % SET = columns sets \def\@@OTR{OTR} \let\OTRdefault\empty % obsolete \def\installotr#1% andere naam, beter \connectotr of zo {\def\OTRidentifier{#1}} % \def\OTRcommand#1% % {\csname\@@OTR % \ifcsname\@@OTR\OTRidentifier\strippedcsname#1\endcsname % \OTRidentifier % \else\ifcsname\@@OTR\OTRdefault\strippedcsname#1\endcsname % fallback % \OTRdefault % \fi\fi % \strippedcsname#1\endcsname} % % maybe faster but at least less tracing: \def\OTRcommand#1% {\csname\@@OTR \ifcsname\@@OTR\OTRidentifier\expandafter\gobbleoneargument\string#1\endcsname \OTRidentifier \else\ifcsname\@@OTR\OTRdefault\expandafter\gobbleoneargument\string#1\endcsname % fallback \OTRdefault \fi\fi \expandafter\gobbleoneargument\string#1\endcsname} \def\activateotr#1#2% {\def\OTRidentifier{#1}% \def\OTRdefault {#2}} % variant that does a preset: \newtoks\registeredotrcommands \def\registerotrcommand#1% {\appendtoks\dowithotrcommand#1\to\registeredotrcommands} \def\dopresetotrcommand#1% {\expandafter\let\expandafter#1\csname\@@OTR \ifcsname\@@OTR\OTRidentifier\expandafter\gobbleoneargument\string#1\endcsname \OTRidentifier \else\ifcsname\@@OTR\OTRdefault\expandafter\gobbleoneargument\string#1\endcsname % fallback \OTRdefault \fi\fi \expandafter\gobbleoneargument\string#1\endcsname} \def\activateotr#1#2% {\def\OTRidentifier{#1}% \def\OTRdefault {#2}% \let\dowithotrcommand\dopresetotrcommand \the\registeredotrcommands} \appendtoks \activateotr{ONE}{}% \to\everydump %D The initialization of the \type {\hsize} and \type {\vsize} %D depends on the OTR used. % todo: \registerotrcommand\output, is a toks \registerotrcommand\setvsize % \def\setvsize {\OTRcommand\setvsize} \registerotrcommand\sethsize % \def\sethsize {\OTRcommand\sethsize} \registerotrcommand\finalsidefloatoutput % \def\finalsidefloatoutput {\OTRcommand\finalsidefloatoutput} \registerotrcommand\dopagecontents % \def\dopagecontents {\OTRcommand\dopagecontents} \registerotrcommand\dosettopinserts % \def\dosettopinserts {\OTRcommand\dosettopinserts} \registerotrcommand\dosetbotinserts % \def\dosetbotinserts {\OTRcommand\dosetbotinserts} \registerotrcommand\dotopinsertions % \def\dotopinsertions {\OTRcommand\dotopinsertions} \registerotrcommand\dobotinsertions % \def\dobotinsertions {\OTRcommand\dobotinsertions} \registerotrcommand\dosetbothinserts % \def\dosetbothinserts {\OTRcommand\dosetbothinserts} \registerotrcommand\doflushfloats % \def\doflushfloats {\OTRcommand\doflushfloats} \registerotrcommand\flushfloatbox % \def\flushfloatbox {\OTRcommand\flushfloatbox} \registerotrcommand\docheckiffloatfits % \def\docheckiffloatfits {\OTRcommand\docheckiffloatfits} \registerotrcommand\flushsavedfloats % \def\flushsavedfloats {\OTRcommand\flushsavedfloats} \registerotrcommand\synchronizehsize % \def\synchronizehsize {\OTRcommand\synchronizehsize} \registerotrcommand\gotonextpage % \def\gotonextpage {\OTRcommand\gotonextpage } \registerotrcommand\gotonextpageX % \def\gotonextpageX {\OTRcommand\gotonextpageX} % will become obsolete % wrong, will be redone % % \registerotrcommand\someherefloat % \def\someherefloat {\OTRcommand\someherefloat} % \registerotrcommand\somefixdfloat % \def\somefixdfloat {\OTRcommand\somefixdfloat} % \registerotrcommand\somepagefloat % \def\somepagefloat {\OTRcommand\somepagefloat} % \registerotrcommand\sometopsfloat % \def\sometopsfloat {\OTRcommand\sometopsfloat} % \registerotrcommand\somebotsfloat % \def\somebotsfloat {\OTRcommand\somebotsfloat} % \registerotrcommand\somesidefloat % \def\somesidefloat {\OTRcommand\somesidefloat} % beter een \installotr#1 met #1 = macro en auto test \newif \iftraceotr \newif \ifinotr \newtoks \mainoutput \newcount\otrlevel % When issuing two \par\penalty-\plustenthousand's, only the first % triggers the otr; obscure feature or optimization? \newcount\outputcounter \outputcounter=-100010 % -10010 \def\doinvokeoutput {\iftraceotr \expandafter\dodotracedoutput \else \expandafter\dodoinvokeoutput \fi} \def\doshowoutputmessage#1#2#3% {\writestatus\m!otr{#1 #2 \number#3}} \def\dodoinvokeoutput#1% {\bgroup\par\penalty#1\egroup} \def\dodotracedoutput#1% {\doshowoutputmessage+{traced}{#1/\the\outputpenalty}% \writestatus\m!otr{c:\number\mofcolumns,v:\the\vsize,g:\the\pagegoal,t:\the\pagetotal}% \dodoinvokeoutput{#1}% \writestatus\m!otr{c:\number\mofcolumns,v:\the\vsize,g:\the\pagegoal,t:\the\pagetotal}% \doshowoutputmessage-{traced}{#1/\the\outputpenalty}} \def\installoutput#1#2% \invoke \action {\global\advance\outputcounter\minusone \edef#1{\noexpand\doinvokeoutput{\number\outputcounter}}% \setvalue{\@@OTR\number\outputcounter}{#2}} \def\invoketracedoutputroutine {\doshowoutputmessage+{trying}\outputpenalty \ifcsname\@@OTR\the\outputpenalty\endcsname \doshowoutputmessage+{special}\outputpenalty \csname\@@OTR\the\outputpenalty\endcsname \doshowoutputmessage-{special}\outputpenalty \else \doshowoutputmessage+{normal}\outputpenalty \the\OTRcommand\output \doshowoutputmessage-{normal}\outputpenalty \fi \doshowoutputmessage-{trying}\outputpenalty} \def\invokenormaloutputroutine {\ifcsname\@@OTR\the\outputpenalty\endcsname \csname\@@OTR\the\outputpenalty\endcsname \else \the\OTRcommand\output \fi} \def\invokeoutputroutine {\iftraceotr \expandafter\invoketracedoutputroutine \else \expandafter\invokenormaloutputroutine \fi} \mainoutput{\invokeoutputroutine} %D Some hooks: \def\setoutputroutine#1% {\global\output{\inotrtrue\the\everybeforeoutput#1\the\everyafteroutput}} \setoutputroutine{\the\mainoutput} \ifx\pagediscards\undefined \let\pagediscards\relax \fi \installoutput\synchronizeoutput % maybe add pagediscards {\ifvoid\normalpagebox\else \unvbox\normalpagebox \pagediscards % maybe not needed ? \fi} \installoutput\discardpage {\setbox\scratchbox\box\normalpagebox} %D In order to force consistent use of variables, we %D predefine a lot of them here. %D The next two registers can be used to store pre column %D material as well as footnotes or so. \newbox\precolumnbox \newdimen\precolumnboxheight \newbox\postcolumnbox \newdimen\postcolumnboxheight %D We reserve a counter for the number of columns as well as %D the current column. Both are not to be changed by users! \newcount\nofcolumns \nofcolumns = 1 \newcount\mofcolumns \mofcolumns = 1 \setnewconstant\maxnofcolumns 50 \setnewconstant\allocatednofcolumns 0 %D The next dimensions reports the final column height \newdimen\finalcolumnheights \newcount\finalcolumnlines %D During initialization the temporary boxes are allocated. %D This enables us to use as much columns as we want, without %D exhausting the pool of boxes too fast. We could have packed %D them in one box, but we've got enough boxes. %D %D Two sets of boxes are declared, the txtboxes are used for %D the text, the topboxes are for moved column floats. \def\@col@{@col@} \def\initializecolumns#1% {\ifnum#1>\maxnofcolumns \showmessage\m!columns1\maxnofcolumns \nofcolumns\maxnofcolumns \else \nofcolumns#1\relax \fi \ifnum\nofcolumns>\allocatednofcolumns \dorecurse\nofcolumns {\ifnum\recurselevel>\allocatednofcolumns\relax % \newbox\next \letgvalue{\@col@-\recurselevel-t}=\next \@EA\newbox\csname\@col@-\recurselevel-t\endcsname % text \@EA\newbox\csname\@col@-\recurselevel-f\endcsname % foot \@EA\newbox\csname\@col@-\recurselevel-h\endcsname % top insert \@EA\newbox\csname\@col@-\recurselevel-l\endcsname % top insert \fi}% \global\allocatednofcolumns\nofcolumns \fi} \def\firstcolumnbox {\columntextbox\plusone} \def\currentcolumnbox {\columntextbox\mofcolumns} \def\lastcolumnbox {\columntextbox\nofcolumns} \def\firsttopcolumnbox {\columntopbox \plusone} \def\currenttopcolumnbox{\columntopbox \mofcolumns} \def\lasttopcolumnbox {\columntopbox \nofcolumns} \def\columntextbox#1{\csname\@col@-\number#1-t\endcsname} \def\columnfootbox#1{\csname\@col@-\number#1-f\endcsname} \def\columntopbox #1{\csname\@col@-\number#1-h\endcsname} \def\columnbotbox #1{\csname\@col@-\number#1-l\endcsname} \def\columnsettextbox{\global\setbox\columntextbox} \def\columnsetfootbox{\global\setbox\columnfootbox} \def\columnsettopbox {\global\setbox\columntopbox} \def\columnsetbotbox {\global\setbox\columnbotbox} \def\columngettextbox{\copy\columntextbox} \def\columngetfootbox{\copy\columnfootbox} \def\columngettopbox {\copy\columntopbox} \def\columngetbotbox {\copy\columnbotbox} \def\columnerasetextboxes{\dorecurse\allocatednofcolumns{\columnsettextbox\recurselevel\emptybox}} \def\columnerasefootboxes{\dorecurse\allocatednofcolumns{\columnsetfootbox\recurselevel\emptybox}} \def\columnerasetopboxes {\dorecurse\allocatednofcolumns{\columnsettopbox \recurselevel\emptybox}} \def\columnerasebotboxes {\dorecurse\allocatednofcolumns{\columnsetbotbox \recurselevel\emptybox}} %D Without going in details we present two macro's which handle %D the columns. The action which is transfered by the the first %D and only parameter can do something with \type %D {\currentcolumnbox}. In case of the mid columns, \type %D {\firstcolumnbox} and \type {\lastcolumnbox} are handled %D outside these macro's. \def\dohandlecolumn#1% {\mofcolumns\recurselevel \let\currentcolumn\recurselevel #1\relax} \def\dohandleallcolumns#1% {\dorecurse\nofcolumns{\dohandlecolumn{#1}}} \def\dohandlerevcolumns#1% {\dostepwiserecurse\nofcolumns\plusone\minusone{\dohandlecolumn{#1}}} \def\dohandlemidcolumns#1% {\dohandleallcolumns {\ifnum\recurselevel>\plusone \ifnum\recurselevel<\nofcolumns \dohandlecolumn{#1}% \fi \fi}} %D This register can be used as a temporary storage for page %D content. \newbox\restofpage %D Features. \newif\ifintermediatefootnotes \newif\ifcarryoverfootnotes %\carryoverfootnotestrue \newif\iflastcolumnfootnotes %\lastcolumnfootnotestrue \newif\ifbalancecolumns %\balancecolumnstrue \newif\ifbalancetoheight %\balancetoheighttrue \newif\ifforcecolumngrid \forcecolumngridtrue \newif\ifstretchcolumns \stretchcolumnsfalse \newif\ifinheritcolumns \inheritcolumnsfalse \newif\ifheightencolumns \heightencolumnsfalse \newif\ifbalancingcolumns \newif\ifcollectingcontent \newif\ifcolumnoverflow \newdimen\intercolumnwidth \newdimen\localcolumnwidth \newdimen\savedpagetotal \newconstant\columndirection % 0:lr 1:rl \def\minbalancetoplines {1} \def\minfreecolumnlines {2} \newif\ifrecentercolumnbox \recentercolumnboxtrue \newif\ifrerecentercolumnbox \rerecentercolumnboxtrue \newif\ifpackcolumnfloats \packcolumnfloatstrue \newbox\collectedpagefloats \newbox\collectedleftpagefloats \newbox\collectedrightpagefloats %D The \type {\ifdim} test is needed, because otherwise the %D last line of a text end up on top of the baseline instead of %D on the baseline, as is the case with preceding pages. %D Also, a \type {\vfil} better than a \type {\vfill}. % to be replaced by \page[now] \page[final] / merged % \def\eject {\par\penalty-\plustenthousand } % == {\par\break} % plain % \def\supereject {\par\penalty-\plustwentythousand} % also plain \def\eject {\par\ifvmode\penalty\ejectpenalty\fi\resetpagebreak} % == {\par\break} % plain \def\supereject {\par\ifvmode\penalty\superpenalty\fi\resetpagebreak} % also plain \def\doejectpage {\par\ifvmode\ifdim\pagetotal>\pagegoal\else\normalvfil\fi\fi} % pg set to \textheight \def\ejectpage {\doejectpage\eject} \def\superejectpage{\doejectpage\supereject} \ifx\bye\undefined \def\bye{\par\vfill\supereject\end} \fi % plain tex command % floats \def\ejectinsert {%\flushnotes already done \bgroup \noftopfloats\plusthousand \nofbotfloats\zerocount % this is needed in case a float that has been stored % ends up at the current page; this border case occurs when % the calculated room is 'eps' smaller that the room available % when just flushing; so now we have (maybe optional): \pagebaselinecorrection % alas, this is tricky but needed (first surfaced in prikkels) \doflushfloats \egroup} \def\ejectdummypage {\endgraf \ifvmode \ejectinsert \fixedspace \vfill \gotonextpage \fi} \def\beforefinaloutput {} \def\afterfinaloutput {%\forgetall \vskip\zeropoint\relax \ifvoid\normalpagebox \else \unvbox\normalpagebox \penalty\outputpenalty \fi % not really needed, replaced by \flushsavedfloats \ifnum\outputpenalty>\superpenalty \else % better use a proper otr signal \dosupereject \fi % but does not hurt either (we're still in the otr!) \inpagebodytrue % needed for enabling \blank ! \flushsavedfloats % was \dosetbothinserts; only otr one ! \setvsize} % this is needed for interacting components, like floats and multicolumns \def\dofinaloutput#1#2% \vbox: prevents spurious spaces in every..pagebody {\forgetall \beforefinaloutput \the\everybeforeshipout % brrr not in shipout \the\pageboundsettings \myshipout{\hbox{\vbox{\dopagebody#1#2}}}% is this hbox needed \the\everyaftershipout \afterfinaloutput} \def\donofinaloutput#1#2% {\forgetall \beforefinaloutput \the\everybeforeshipout \message{[-\the\realpageno]}% \setbox\scratchbox\hbox{\dopagebody#1#2}% \deadcycles\zerocount \setnextrealpageno \the\everyaftershipout \afterfinaloutput} % beware: \ifprocessingpages is in use \ifdefined\doflushspread\else \let\doflushspread\relax \fi % todo \def\finaloutput#1#2% {\ifprocessingpages \ifpageselected \@EAEAEA\dofinaloutput \else \@EAEAEA\donofinaloutput \fi \else \ifpageselected \@EAEAEA\donofinaloutput \else \@EAEAEA\dofinaloutput \fi \fi#1#2% \resetselectiepagina \doincrementpageboundcounters % should hook into an every \checkpagedimensions \ifnum\outputpenalty>\superpenalty \else \dosupereject \fi \doflushspread \doflushpostponedcontent} \def\dooutput {\finaloutput\unvbox\normalpagebox} \maxdeadcycles=1000 % this needs a real cleanup \def\doplaceversiontext#1#2% {\doifsomething{#2} {\defconvertedcommand\ascii{#2}% \space#1:\space\ascii\space \!!doneatrue}} \unexpanded\def\placeversioninfo % nog engels maken {\ifcase\conceptmode % 0 : nothing \or % 1 : simple \vskip\!!sixpoint \hbox to \makeupwidth {\infofont \v!concept:\space\currentdate \hss\reportpagedimensions}% \else % 2/3 : extensive \vskip\!!sixpoint \hbox to \makeupwidth {\infofont \getmessage\m!system{27}:\space\currentdate\space \doplaceversiontext\v!project \currentproject \doplaceversiontext\v!product \currentproduct \doplaceversiontext\v!component\currentcomponent \if!!donea\else\space\v!file:\space\jobname\fi \hss\reportpagedimensions}% \fi} % tot hier \def\doversion[#1]% {\conceptmode\zerocount \overfullrule\zeropoint \processaction % \v!final=> [#1] [ \v!concept=>\conceptmode\plusone, % simple banner \v!file=>\conceptmode\plustwo, % full banner \v!temporary=>\conceptmode\plusthree % full banner plus \overfullrule5\points]} % info in the margin \def\version {\dosingleargument\doversion} \def\addstatusinfo {\ifcase\conceptmode \@EA\gobbleoneargument \else \@EA\doaddstatusinfo \fi} \def\doaddstatusinfo#1% {\setbox#1\vbox to \paperheight {\vsmashbox#1\box#1% \offinterlineskip \vskip\topspace \hsize\paperwidth %\hfill\hbox{\placetestinfo\hskip.5cm}\vss % obsolete \settexthoffset\hskip\texthoffset % brrrr \vbox to 1cm{\vss\placeversioninfo\vss}}} \def\dotestinfo#1#2#3% {\ifinpagebody\else\ifnum\conceptmode=\plusthree \begingroup \defconvertedcommand\ascii{#3}% \xdef\extratestinfo {#2\space\ascii}% \gdef\totaltestinfo {\global\setbox#1\vbox {\unvbox#1\relax \infofont \setupinterlinespace \hbox {\strut \expanded{\doboundtext{\extratestinfo}{12em}{..}}% \quad}}}% \endgroup \ifinner \aftergroup\totaltestinfo \else \totaltestinfo \fi \fi\fi} \version[\v!final] % bewaren tvb documentatie % % \hbox to \hsize % {\en % \switchnaarkorps[5pt]% % \emergencystretch2em % \dimen0=\baselineskip % \baselineskip=\dimen0 plus 1pt % \hsize=.2\hsize % \vsize=2\hsize % \ruledvbox to \vsize{\input tufte \par}\hss % \ruledvbox to \vsize{\input tufte \par\kern-\prevdepth}\hss % \ruledvbox to \vsize{\input tufte \par\kern0pt}\hss % \ruledvbox to \vsize{\input tufte \par\vfill}\hss % \ruledvbox to \vsize{\input tufte \par\kern-\prevdepth\vfill}} % % \hbox to \hsize % {\en % \switchnaarkorps[5pt]% % \emergencystretch2em % \dimen0=\baselineskip % \baselineskip=\dimen0 plus 1pt % \hsize=.18\hsize % \vsize=2.5\hsize % \setbox0=\vbox{\input tufte\relax}% % \ruledvbox to \vsize{\unvcopy0}\hss % \ruledvbox to \vsize{\unvcopy0\kern-\dp0}\hss % \ruledvbox to \vsize{\unvcopy0\kern0pt}\hss % \ruledvbox to \vsize{\unvcopy0\vfill}\hss % \ruledvbox to \vsize{\unvcopy0\kern-\dp0\vfill}} \newtoks\afterpage \newtoks\aftereverypage \newtoks\beforepage \newtoks\beforeeverypage \newconstant\showgridstate \unexpanded\def\showgrid {\dosingleempty\doshowgrid} \def\doshowgrid[#1]% {\showgridstate \plusone % downward compatible default \gridboxlinemode \plusone \gridboxlinenomode\plusone \processallactionsinset [#1]% [ \v!reset=>\showgridstate \zerocount, \v!bottom=>\showgridstate \plusone, \v!top=>\showgridstate \plustwo, \v!none=>\gridboxlinemode \zerocount, \v!all=>\gridboxlinemode \plusone, \v!lines=>\gridboxlinemode \plustwo, \v!frame=>\gridboxlinemode \plusthree, \v!nonumber=>\gridboxlinenomode\zerocount, \v!right=>\gridboxlinenomode\plusone, \v!left=>\gridboxlinenomode\plustwo, \v!outer=>\gridboxlinenomode\plusthree]% \ifcase\showgridstate \let\addtextgridlayer\gobbleoneargument \else % 1=bottom 2=top \let\addtextgridlayer\doaddtextgridlayer \fi} \definepalet [layout] [grid=red, page=green] % if really needed for speed we can cache the grid \let\addtextgridlayer\gobbleoneargument \def\doaddtextgridlayer#1% to be checked for color and layer {\startcolor[layout:grid]% \setgridbox\scratchbox\makeupwidth\textheight % todo: check color \global\setbox#1\hbox {\ifcase\showgridstate\or\or\box#1\hskip-\makeupwidth\fi \bgroup % color \ifcase\layoutcolumns\else \gray \setlayoutcomponentattribute\v!grid\v!columns \hbox \layoutcomponentboxattribute to \makeupwidth {\dorecurse\layoutcolumns {\hskip\layoutcolumnwidth \ifnum\recurselevel<\layoutcolumns \vrule \!!height\ht\scratchbox \!!depth\dp\scratchbox \!!width\layoutcolumndistance \fi}}% \hskip-\makeupwidth \fi \setlayoutcomponentattribute\v!grid\v!lines \hbox \layoutcomponentboxattribute{\box\scratchbox}% \egroup \ifcase\showgridstate\or\hskip-\makeupwidth\box#1\fi}% \stopcolor} \def\buildpagebox#1% {\setbox#1\vbox to \paperheight {\hsize\paperwidth \vskip\topspace \doifbothsides {\hskip\backspace} {\hskip\backspace} {\hskip\paperwidth \hskip-\backspace \hskip-\makeupwidth}% \box#1}% \dp#1\zeropoint} % \newif\ifpagebodyornaments \pagebodyornamentstrue % % \appendtoks % \global\pagebodyornamentstrue % \to \everyaftershipout \newif\ifarrangingpages \arrangingpagesfalse \newconstant\pageornamentstate % 0=on 1=one-off 2=always-off \def\pagebodyornamentstrue {\pageornamentstate\zerocount} % for a while \def\pagebodyornamentsfalse{\pageornamentstate\plusone} % for a while \appendtoks \ifcase\pageornamentstate\or \pageornamentstate\zerocount \fi \to \everyaftershipout \let\poparrangedpages\relax \let\pusharrangedpage\relax \ifdefined\shiftprintpagebox \else \let\shiftprintpagebox\gobbleoneargument \let\shiftpaperpagebox\gobbleoneargument \fi \ifdefined\registerpageposition \else \let\registerpageposition\gobbleoneargument \fi \newif\ifsavepagebody \newbox\savedpagebody % beware, \??ly is used before defined, i.e. bad module design \setuplayout[\c!method=\v!normal] \def\docolumnpagebodymarks#1#2#3#4% first last column box {\ifnum#3=#1\relax \dosynchronizemarking[\number#3,\v!column:\number#3,\v!first,\v!column:\v!first][#4]% \else\ifnum#3=#2\relax \dosynchronizemarking[\number#3,\v!column:\number#3,\v!last, \v!column:\v!last ][#4]% \else \dosynchronizemarking[\number#3,\v!column:\number#3 ][#4]% \fi\fi} \def\buildpagebody#1#2% {\ifsavepagebody\global\setbox\savedpagebody\fi \vbox {%\pushcatcodetable %\forgetall % igv problemen, check: \boxmaxdepth\maxdimen \boxmaxdepth\maxdimen % new \dontcomplain % marks get done here \dosynchronizemarking[\v!page][#2]% % the following plugin uses and sets pagebox; beware: this % will change and is for my (hh) personal experiments \executeifdefined{\??ly\c!method\@@lymethod}{\getvalue{\??ly\c!method\v!normal}}#1#2% % the finishing touch \ifcase\pageornamentstate \addpagebackground \pagebox \fi \registerpageposition\pagebox \ifarrangingpages \shiftpaperpagebox \pagebox % \v!paper \else \clippagebox \pagebox \doifelse\@@lymarking\v!page {\replicatepagebox \pagebox \addpagecutmarks \pagebox} {\addpagecutmarks \pagebox \replicatepagebox \pagebox}% \scalepagebox \pagebox \mirrorpaperbox \pagebox \orientpaperbox \pagebox \addpagecolormarks \pagebox \centerpagebox \pagebox \addprintbackground\pagebox \mirrorprintbox \pagebox \orientprintbox \pagebox \shiftprintpagebox \pagebox % \v!page \offsetprintbox \pagebox \negateprintbox \pagebox \fi \box\pagebox }% \popcatcodetable \ifsavepagebody\copy\savedpagebody\fi} \setvalue{\??ly\c!method\v!normal}#1#2% {\setbox\pagebox\vbox {\offinterlineskip \ifcase\pageornamentstate \bgroup % else footnotes get inconsistent font/baseline \dostartattributes\??ly\c!style\c!color\empty \offinterlineskip \gettextboxes \dostopattributes \egroup \fi \getmainbox#1#2}% including footnotes \ifcase\pageornamentstate \addmainbackground \pagebox \fi \buildpagebox \pagebox \addstatusinfo \pagebox} \def\finishpagebox#1% {\ifarrangingpages \addpagecutmarks #1% \addpagecolormarks#1% \centerpagebox #1% \mirrorprintbox #1% \orientprintbox #1% \offsetprintbox #1% \negateprintbox #1% \fi} \appendtoks \restoreouterspacing \to \everybeforepagebody \appendtoks \restoreglobalbodyfont \to \everybeforepagebody %appendtoks \restoreouterspacing \to \everybeforepagebody \ifx\nestednewbox\undefined \newbox\nestednextbox \fi \prependtoks \let\nextbox\nestednextbox \to \everybeforepagebody \def\dopagebody#1#2% {\the\everybeforepagebody \starttextproperties % \setnextsubpageno % nog eens: als in pagina (tbv standaard opmaak) \dontshowboxes % dan hier blokkeren en verderop resetten % \shipoutfacingpage \checkmarginblocks \the\beforeeverypage \normalexpanded{\global\beforepage\emptytoks\the\beforepage}% \scratchtoks\beforepage\global\beforepage\emptytoks\the\scratchtoks % was \flushtoks\beforepage \inpagebodytrue\buildpagebody#1#2% \normalexpanded{\global\afterpage \emptytoks\the\afterpage }% \scratchtoks\afterpage \global\afterpage \emptytoks\the\scratchtoks % was \flushtoks\afterpage \the\aftereverypage \resetpagebreak %updatelistreferences % now in aftereverypage \resetlayouttextlines % will go to \aftereverypage \stoptextproperties \the\everyafterpagebody} \newtoks\pageboundsettings % \prependtoks \initializepaper \to \pageboundsettings % not here \newif\ifpagebreakdisabled \pagebreakdisabledfalse \newconstant\testpagemethod % todo: \testnewpage[method=,lines=,voffset=] \newconstant\testpagetrigger \def\testpage {\dotripleempty\dotestpage[\plusone ]} % \def\testpageonly{\dotripleempty\dotestpage[\plustwo ]} % no penalties added to the mvl \def\testpagesync{\dotripleempty\dotestpage[\plusthree]} % force sync \def\dotestpage[#1][#2][#3]% don't change, only add more methods {\relax % needed before \if \ifpagebreakdisabled \endgraf \else % new from here \ifcase\testpagetrigger \endgraf \or \ifvmode \dosomebreak\allowbreak \else % indeed? \vadjust{\allowbreak}% \endgraf \fi \fi % till here \ifdim\pagegoal<\maxdimen \relax \ifdim\pagetotal<\pagegoal \relax \scratchdimen\lineheight \multiply\scratchdimen#2\relax \advance\scratchdimen \pagetotal \ifdim\lastskip<\parskip \advance\scratchdimen \parskip \fi \ifthirdargument \advance\scratchdimen#3\relax \fi \ifcase\testpagemethod \ifdim\scratchdimen>.99\pagegoal \penalty-\!!tenthousand\relax \fi \or \advance\scratchdimen-\pagegoal \ifdim\scratchdimen>-\lineheight \penalty-\!!tenthousand\relax \fi \or \getnoflines\pagegoal \advance\scratchdimen-\noflines\lineheight \relax \ifdim\scratchdimen>-\lineheight \penalty-\!!tenthousand\relax \fi \or % same as 0 but more accurate \advance\scratchdimen-10\s!sp\relax \ifdim\scratchdimen>\pagegoal \penalty-\!!tenthousand\relax \fi \fi \else \ifnum#1=\plusthree \flushpagesofar \fi \fi \else \ifnum#1=\plusone\goodbreak\fi \fi \fi} \def\flushpagesofar {\endgraf \ifdim\pagetotal>\pagegoal \ifdim\dimexpr\pagetotal-\pageshrink\relax>\pagegoal \goodbreak % \penalty0 \else \page \fi \else \fi} \def\testcolumn {\dodoubleempty\dotestcolumn} \def\dotestcolumn[#1][#2]% {%\relax % needed before \if ! \endgraf \ifdim\pagegoal<\maxdimen \ifdim\pagetotal<\pagegoal % \relax \scratchdimen\pagegoal \advance\scratchdimen-\pagetotal \ifdim\lastskip<\parskip \advance\scratchdimen \parskip \fi \ifsecondargument \advance\scratchdimen#2% \fi \getrawnoflines\scratchdimen % raw ! % \message{[\number#1>\number\noflines ?}\wait \ifnum#1>\noflines \column \fi \else \penalty-\!!tenthousand % untested ! ! \column \fi \fi} \ifdefined\resetcurrentstructuremarkswithpage \else \let\resetcurrentstructuremarkswithpage\relax \fi \def\page{\pagebreak} % the short form of \pagebreak (mult-com one) \def\resetpagebreak {\global\pagebreakdisabledfalse} \def\simplifypagebreak {\def\dopagebreak[##1]{\goodbreak}} \def\disablepagebreaks {\def\dopagebreak[##1]{}} \def\executepagebreakhandler#1% {\edef\@@pagespecification{#1}% \ifcsname\??pe:\@@pagespecification\endcsname \csname\??pe:\@@pagespecification\endcsname \else\ifcsname\??pe::\@@pagespecification\endcsname \executepagebreakhandlers{\csname\??pe::\@@pagespecification\endcsname}% \else \csname\??pe:\s!unknown\endcsname \fi\fi} \long\def\installpagebreakhandler#1#2% {\long\setvalue{\??pe:#1}{#2}} \unexpanded\def\pagebreak {\dosingleempty\dopagebreak} \def\dopagebreak[#1]% so, page ornaments are reset after a pagebreak command, unless set {\bgroup \flushnotes \edef\prevrealpageno{\the\realpageno}% \ifcase\pageornamentstate \or % disable reset after shipout \global\pageornamentstate\plustwo \fi \iffirstargument % or if empty i.e. [] \executepagebreakhandlers{#1}% \else % so, no pagebreak when \pagebreak[] ! ! ! \executepagebreakhandler\v!yes \fi \ifnum\prevrealpageno<\realpageno % there must have been a reason why i added the ifcase % but it fails on tests/mkiv/pages/ornaments-001.tex % as WS found out so we have to wait till the next side % effect shows up % \ifcase\pageornamentstate\or \global\pageornamentstate\zerocount % \fi \fi \egroup} \def\executepagebreakhandlers#1% {\processcommacommand[#1]\executepagebreakhandler} \installpagebreakhandler \s!dummy {\ejectinsert \gotonextpage \ejectdummypage} \installpagebreakhandler \v!frame {\page\bgroup\showframe\page[\v!empty]\egroup} \installpagebreakhandler \s!unknown {\doifinstringelse{+}\@@pagespecification {\ejectinsert \gotonextpage \dorecurse\@@pagespecification\ejectdummypage} {\doifnumberelse\@@pagespecification {\ejectinsert \gotonextpage \doloop {\ifnum\userpageno<\@@pagespecification\relax \ejectdummypage \else \exitloop \fi}} {}}} \installpagebreakhandler \s!default {} % do nothing if empty \installpagebreakhandler \v!reset {% better not: \global\pageornamentstate\zerocount \resetpagebreak} \installpagebreakhandler \v!disable {\global\pagebreakdisabledtrue} \installpagebreakhandler \v!yes {\ifpagebreakdisabled\else \ejectinsert \gotonextpage \ifinsidecolumns % this will move to MUL \ejectpage % anders soms geen overgang \fi \fi} \installpagebreakhandler \v!makeup % ?? {\ifpagebreakdisabled\else \eject \fi} \installpagebreakhandler \v!blank {\ifcase\pageornamentstate \global\pageornamentstate\plusone \fi} \installpagebreakhandler \v!no {\ifpagebreakdisabled\else \dosomebreak\nobreak \fi} \installpagebreakhandler \v!preference {\ifpagebreakdisabled\else \ifinsidecolumns % this will move to MUL \dosomebreak\goodbreak \else \testpage[3][\zeropoint]% \fi \fi} \installpagebreakhandler \v!bigpreference {\ifpagebreakdisabled\else \ifinsidecolumns % this will move to MUL \dosomebreak\goodbreak \else \testpage[5][\zeropoint]% \fi \fi} \installpagebreakhandler \v!empty {\ejectinsert \gotonextpage \doifnotvalue{\??tk\v!header\c!state}\v!stop{\setupheader[\c!state=\v!empty]}% \doifnotvalue{\??tk\v!footer\c!state}\v!stop{\setupfooter[\c!state=\v!empty]}% \ejectdummypage} \installpagebreakhandler \v!left {\ejectinsert \gotonextpageX % will become \gotonextpage \doifbothsidesoverruled{}{\resetcurrentstructuremarkswithpage\ejectdummypage}{}} \installpagebreakhandler \v!right {\ejectinsert \gotonextpageX % will become \gotonextpage \doifbothsidesoverruled{}{}{\resetcurrentstructuremarkswithpage\ejectdummypage}} \installpagebreakhandler \v!even {\page \doifoddpageelse{\resetcurrentstructuremarkswithpage\ejectdummypage}\donothing} \installpagebreakhandler \v!odd {\page \doifoddpageelse\donothing{\resetcurrentstructuremarkswithpage\ejectdummypage}} \installpagebreakhandler \v!quadruple % not yet ok inside columnsets {\ifdoublesided \!!counta\realpageno \!!countb\realpageno \divide\!!counta 4 \divide\!!countb 2 \ifnum\!!counta=\!!countb \else \executepagebreakhandler\v!yes \executepagebreakhandler\v!empty \executepagebreakhandler\v!empty \fi \fi} \installpagebreakhandler \v!last {\ejectinsert \gotonextpageX % will become \gotonextpage \relax \doifbothsidesoverruled {\shipoutfacingpage} {} {\noheaderandfooterlines \ejectdummypage}% \filluparrangedpages} \installpagebreakhandler \v!lastpage % handy for backpage preceded by empty pages {\executepagebreakhandler\v!yes \ifdoublesided \executepagebreakhandler\v!left \executepagebreakhandler\v!empty \executepagebreakhandler\v!empty \fi} \installpagebreakhandler \v!start {\globallet\shipout\normalshipout} \installpagebreakhandler \v!stop {\globallet\shipout\noshipout} % nb: \executepagebreakhandler\v!hoofd in other ones \installpagebreakhandler \v!header {\doifnotvalue{\??tk\v!header\c!state}\v!stop{\setupheader[\c!state=\v!empty]}} \installpagebreakhandler \v!footer {\doifnotvalue{\??tk\v!footer\c!state}\v!stop{\setupfooter[\c!state=\v!empty]}} % \definepagebreak % [chapter] % [yes,header,right] % % \setuphead % [chapter] % [page=chapter, % header=empty, % footer=chapter] % % \definepagebreak % untested % [lastpage] % [left,{empty,right},{empty,left}] % public page handler, beware: definepage already in use (core-ref) % % \definepagebreak[instance][forsure] % \definepagebreak[forsure][yes,+4] \unexpanded\def\definepagebreak {\dodoubleargument\dodefinepagebreak} \def\dodefinepagebreak[#1][#2]% non recursive, meant for simple mappings {\setvalue{\??pe::#1}{#2}} % don't change this / test case: % % \setupbackgrounds[state=repeat] % \setupbackgrounds[text][text][background=whatever] % \couplepage[chapter][before={\defineoverlay[whatever][ON]}] % \setuphead[chapter][before={\pagetype[chapter]}] % \chapter{First} \page test \chapter{second} \page test \long\def\installcolumnbreakhandler#1#2#3% #1=otr-id #2=tag {\long\setvalue{\??cn:#1:#2}{#3}} \unexpanded\def\definecolumnbreak {\dodoubleargument\dodefinecolumnbreak} \def\dodefinecolumnbreak[#1][#2]% non recursive, meant for simple mappings {\setvalue{\??cn::#1}{#2}} %\def\columnbreak % {\dosingleempty\docolumnbreak} % %\def\docolumnbreak[#1]% % {\expanded{\nextcolumn[\executeifdefined{\??cn::#1}{#1}]}} \definecomplexorsimple\columnbreak \def\simplecolumnbreak {\executecolumnbreakhandler\v!yes} \def\complexcolumnbreak[#1]% if empty, do nothing and avoid processing {\doifsomething{#1}{\executecolumnbreakhandlers{#1}}} \def\executecolumnbreakhandlers#1% {\processcommacommand[#1]\executecolumnbreakhandler} \def\executecolumnbreakhandler#1% here no commalist {\edef\@@columnspecification{#1}% \doifdefinedelse{\??cn:\OTRidentifier:\@@columnspecification} {\getvalue{\??cn:\OTRidentifier:\@@columnspecification}} {\doifdefinedelse{\??cn::\@@columnspecification} {\executecolumnbreakhandlers{\getvalue{\??cn::\@@columnspecification}}} {\getvalue{\??cn:\OTRidentifier:\s!unknown}}}} %let\nextcolumn\columnbreak \let\column \columnbreak % We don't want spurious last pages (due to left over marks): \def\noshipout {\writestatus\m!system{ignoring further shipouts}% \global\advance\realpageno\minusone % else no flush of resources \dowithnextbox{\deadcycles\zerocount}} % \def\doignorerestoftext % {\ifarrangingpages \else \ifnum\textlevel>\zerocount \else % \globallet\shipout\noshipout % \fi \fi} % % better: \def\doignorerestoftext {\ifarrangingpages \else \ifnum\textlevel=\plusone \globallet\shipout\noshipout \fi \fi} \let\ignorerestoftext\donothing \prependtoks % only ignore in a symmetrical doc \globallet\ignorerestoftext\doignorerestoftext \to \everystarttext % \appendtoks % \ignorerestoftext % \to \everylastshipout \newif\ifpageselected \pageselectedtrue \newif\ifselectingpages \selectingpagesfalse \newif\ifprocessingpages\processingpagestrue \let\pageselection \empty \let\currentpageselection\empty \let\aftershipout \relax \let\beforeshipout \relax \def\dodobeforeshipout#1% {\global\let\beforeshipout\relax \csname\??pg#1\c!before\endcsname} \def\dobeforeshipout {\doifsomething\currentpageselection {\processcommacommand[\currentpageselection]\dodobeforeshipout}} \def\dododoaftershipout#1% {\global\let\aftershipout\relax \global\let\currentpageselection\empty \csname\??pg#1\c!after\endcsname} \def\dodoaftershipout#1% {\doifelsevalue{\??pg#1\c!option}\v!doublesided {\doifbothsidesoverruled {\dododoaftershipout{#1}} {\dododoaftershipout{#1}} {}} {\dododoaftershipout{#1}}} \def\doaftershipout {\doifsomething\currentpageselection {\processcommacommand[\currentpageselection]\dodoaftershipout}} % Dit wordt eigenlijk nooit en moet worden vervangen door % het meer algemene mechanisme. \def\dopagetype[#1]% {\edef\desoortpagina{#1}% \ifx\desoortpagina\empty \else \@EA\doglobal\@EA\addtocommalist\@EA{\desoortpagina}\currentpageselection \ifselectingpages \fullexpandtwoargsafter\doifcommon\desoortpagina\pageselection {\global\pageselectedtrue}% \fi \gdef\beforeshipout{\dobeforeshipout}% \gdef\aftershipout {\doaftershipout}% \fi} \def\pagetype {\dosingleargument\dopagetype} \def\docouplepage[#1][#2]% {\getparameters [\??pg] [\c!before=, \c!after=, \c!option=, #2]% \def\docommand##1% {\getparameters [\??pg##1] [\c!before=\@@pgbefore, \c!after=\@@pgafter, \c!option=\@@pgoption]}% \processcommalist[#1]\docommand}% \def\couplepage {\dodoubleargument\docouplepage} \def\doprocesspage[#1][#2]% {\processaction [#2] [\v!yes=>\global\processingpagestrue, \v!no=>\global\processingpagesfalse]% \gdef\pageselection{#1}% \global\selectingpagestrue \global\pageselectedfalse} \def\processpage {\dodoubleargument\doprocesspage} \def\resetselectiepagina {\ifselectingpages \doifbothsidesoverruled{\global\pageselectedfalse}{}{\global\pageselectedfalse}% \fi} \newif\ifregistertextareas \newif\iftracetextareas \newbox\registertextbox % \def\registeredtextarea#1#2#3% #1=lower-dp #2=correct-ht #3=box % {\hbox{\box#3}} \def\enabletextarearegistration{\global\registertextareastrue} \def\registeredtextarea#1#2#3% #1=lower-dp #2=correct-ht #3=box {\hbox\bgroup \ifregistertextareas \ifx\registerMPtextarea\undefined \else \setbox\registertextbox\emptyhbox \wd\registertextbox\wd#3% \ht\registertextbox\ht#3% \dp\registertextbox\dp#3% \ifcase#1\or % 1 \setbox\registertextbox\hbox{\lower\strutdp\box\registertextbox}% \fi \ifcase#2\or % 1 \setbox\registertextbox\hbox{\raise\topskip\hbox{\lower\strutht\box\registertextbox}}% \dp\registertextbox\strutdp \fi \dp\registertextbox\strutdp % needed %\setbox\registertextbox\hbox % {\iftracetextareas\gray\boxrulewidth2pt\ruledhbox\fi % {\registerMPtextarea{\box\registertextbox}}}% \setbox\registertextbox\hbox {\registerMPtextarea{\box\registertextbox}}% \smashbox\registertextbox \box\registertextbox \fi \fi \box#3% \egroup} %D \macros %D {setupoppositeplacing,startopposite} %D %D \starttyping %D \starttext %D test \startopposite \blackrule[width=3cm,height=4cm] \stopopposite test %D test \startopposite \blackrule[width=3cm,height=4cm] \stopopposite test %D \stoptext %D \stoptyping % Moved from page-mar.tex, made english, cleaned up, but still to be % redesigned \newbox\facingpage \unexpanded\def\setupoppositeplacing {\dodoubleargument\getparameters[\??np]} \unexpanded\def\startopposite {\dowithnextboxcontent {\hsize\makeupwidth}% {\global\setbox\facingpage\vbox {\ifvoid\facingpage \@@npbefore \else \@@npinbetween \unvbox\facingpage \fi \box\nextbox}}% \vbox\bgroup} \unexpanded\def\stopopposite {\egroup} \def\finishfacingpage {\ifvoid\facingpage\else \global\setbox\facingpage\vbox to \makeupheight {\unvbox\facingpage \@@npafter \vss}% \fi} \def\shipoutfacingpage {\doif\@@npstate\v!start {\ifvoid\facingpage\else \ifnum\realpageno>\plusone \bgroup \pageornamentstate\plusone \finishfacingpage \myshipout{\buildpagebody\box\facingpage}% \egroup \else \global\setbox\facingpage\emptybox \fi \fi}} \setupoppositeplacing [\c!state=\v!start, \c!before=, \c!inbetween=\blank, \c!after=] \protect \endinput