%D \module %D [ file=page-set, %D version=2000.10.20, %D title=\CONTEXT\ Page Macros, %D subtitle=Column Sets, %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. % getnoflines vs getrawnoflines % some day: cleanup and go etex \writestatus{loading}{ConTeXt Page Macros / Column Sets} % todo : last longer than previous % todo : block span over last column if footnotes % todo : diagnosis balancing run % todo : separate footnote placement % todo : go on on same page with colset % todo : test page areas per page % todo : leftmargin/rightmargin (better than afstand(1)) % use the OTRSET layer for more purposes, like the footnotes ! \unprotect \newcount\tofcolumns % total \newcount\lofcolumns % left \newcount\rofcolumns % right \newcount\columnfirstcell \columnfirstcell=1 \newcount\columnlastcell \newcount\columnfreecells \newcount\currenthcell \newcount\currentvcell \newcount\columnhcells \newcount\columnvcells \newif\ifenoughcolumncells \newif\ifsomefreecolumncells \newif\ifcolumnspread \newif\iftracecolumnset % \tracecolumnsettrue \def\columnmaxcells {75} % runtime \def\columnmaxfreecells {0} % runtime \def\columngaplimit {0} % {5} \def\@otr@{otr} \def\OTRSETmakeupwidth{\innermakeupwidth} \let\OTRSETflushsidefloats \forgetsidefloats % \relax \let\OTRSETsynchronizesidefloats\forgetsidefloats % \relax \def\OTRSETgridcell #1#2{\csname \@otr@:\number#1:\number#2\endcsname} \def\OTRSETgetgridcell#1#2{\box\csname \@otr@:\number#1:\number#2\endcsname} \def\OTRSETsetgridcell#1#2{\global\setbox\csname\@otr@:\number#1:\number#2\endcsname} \long\def\OTRSETdoifcellelse#1#2% {\relax\ifvoid\csname\@otr@:\number#1:\number#2\endcsname \@EA\secondoftwoarguments\else\@EA\firstoftwoarguments \fi} % The following two macros are used to compensate for a switch in body fonts % as in: % % \definecolumnset [two] [n=2,balancing=yes] % \definecolumnset [three] [n=3,balancing=yes] % % \setupcolumnsetlines[two][1][1][7] % \setupcolumnsetlines[two][1][2][10] % % \setupcolumnsetlines[three][1][1][40] % \setupcolumnsetlines[three][1][2][40] % \setupcolumnsetlines[three][1][3][40] % % \setupcolumnsetstart[three][1][1][15] % \setupcolumnsetstart[three][1][2][20] % \setupcolumnsetstart[three][1][3][20] % % \starttext % \startcolumnset [two] \dorecurse {1}{\input tufte \par} \stopcolumnset % \switchtobodyfont[small] % \startcolumnset [three] \dorecurse {1}{\input tufte \par} \stopcolumnset % \stoptext %D Marks in columnsets: %D %D \starttyping %D \definemarking[M] %D \setupheadertexts[\setups{show-M-marks}] %D \definecolumnset[test][n=3] %D %D \startsetups show-M-marks %D \getmarking[M][1][previous]/\getmarking[M][1][first]/\getmarking[M][1][last]\quad %D \getmarking[M][2][previous]/\getmarking[M][2][first]/\getmarking[M][2][last]\quad %D \getmarking[M][3][previous]/\getmarking[M][3][first]/\getmarking[M][3][last]\quad %D \getmarking[M][1][previous]/\getmarking[M][1][first]/\getmarking[M][last]\quad %D \getsavedmarking[M][previous]/\getsavedmarking[M][first]/\getsavedmarking[M][last] %D \stopsetups %D %D \startbuffer %D \section{Knuth} [K1]\marking[M]{k1} [K2]\marking[M]{k2} \input knuth %D \section{Zapf} [Z]\marking[M]{z} \input zapf %D \stopbuffer %D %D \startbuffer %D \section{Ward} [W]\marking[M]{w} \input ward %D \placefigure[here]{none}{\externalfigure[a][height=2cm]} %D \section{Davis} [D]\marking[M]{d} \input davis %D \section{Zapf} [Z]\marking[M]{z} \input zapf %D \stopbuffer %D %D \startbuffer %D \section{Ward} [W]\marking[M]{w} \input ward %D \placefigure[here]{none}{\externalfigure[a][height=2cm]} %D \section{Davis} [D]\marking[M]{d} \input davis %D \section{Zapf} [Z]\marking[M]{z} \input zapf %D \section{Douglas} [O]\marking[M]{o} \input douglas %D \stopbuffer %D %D \starttext %D \startcolumnset[test] %D \dorecurse{5}{\getbuffer} %D \placefigure[here]{none}{\externalfigure[a][height=2cm]} %D % \column % sometimes needed %D \stopcolumnset %D \stoptext %D \stoptyping % not ok yet, for column sets we need a special case: within a column we % need to bubble-up the marks; the indirectness permits overloading here \let\saveOTRSETmark \refreshsavedmark \let\bubbleOTRSETmark\bubblesavedmark \let\resetOTRSETmark \resetsavedmark \let\presetOTRSETmark\presetsavedmark \def\doregisterOTRSETmarks#1{\saveOTRSETmark [#1][\number\mofcolumns]} \def\dobubbleOTRSETmarks #1{\bubbleOTRSETmark[#1][\number\mofcolumns]} \def\doresetOTRSETmarks #1{\resetOTRSETmark [#1][\recurselevel]} \def\dopresetOTRSETmarks #1{\presetOTRSETmark[#1][\recurselevel]} \def\registerOTRSETmarks {\processcommacommand[\alldefinedmarks]\doregisterOTRSETmarks} \def\bubbleOTRSETmarks {\processcommacommand[\alldefinedmarks]\dobubbleOTRSETmarks} \def\resetOTRSETmarks {\dorecurse\nofcolumns{\processcommacommand[\alldefinedmarks]\doresetOTRSETmarks}} \def\presetOTRSETmarks {\dorecurse\nofcolumns{\processcommacommand[\alldefinedmarks]\dopresetOTRSETmarks}} %D test case of Vit Zika (context list): %D %D \starttyping %D \setuplayout[height=middle,width=middle,grid=yes] %D %D \starttext %D \startcolumnset %D \dorecurse{10} %D {\input thuan \endgraf %D \bgroup %D \ss\restoreinterlinespace %D \dorecurse{3}{\input hawking \endgraf} %D \egroup %D \input bryson \endgraf} %D \stopcolumnset %D \stoptext %D \stoptyping \def\OTRSETsetcorrectnofcells#1% {\bgroup \!!counta#1\relax \ifdim\globalbodyfontsize=\localbodyfontsize \restoreinterlinespace \else \!!dimena-\!!counta\lineheight \restoreglobalbodyfont % slow, we need a fast one \advance\!!dimena\!!counta\lineheight \getnoflines\!!dimena \advance\!!counta\noflines \ifnum\!!counta<#1\else \!!counta#1\relax \fi \fi \relax % needed ! ! ! ! else lookahead over \fi and \@EA \@EA\egroup\@EA\scratchcounter\the\!!counta\relax} \def\OTRSETsetcorrectcellht {\bgroup \!!dimena-\strutht\relax \ifdim\globalbodyfontsize=\localbodyfontsize \restoreinterlinespace \else \restoreglobalbodyfont \fi \advance\!!dimena\strutht \relax % needed ! ! ! ! else lookahead over \fi and \@EA \@EA\egroup\@EA\scratchdimen\the\!!dimena\relax} \def\columnerasegridboxes % maybe dedicated loops {\bgroup \increment\columnmaxcells\relax \ifodd\realpageno \else % we are on the other page \columnspreadfalse \fi \ifcolumnspread \dorecurse\nofcolumns {\let\!!stringa\recurselevel \scratchcounter\recurselevel \advance\scratchcounter\lofcolumns \edef\!!stringb{\the\scratchcounter}% \dostepwiserecurse \zerocount \columnmaxcells \plusone {\ifcsname\@otr@:\!!stringa:\recurselevel\endcsname \global\setbox\csname\@otr@:\!!stringa:\recurselevel\endcsname \ifcsname\@otr@:\!!stringb:\recurselevel\endcsname \box\csname\@otr@:\!!stringb:\recurselevel\endcsname %\global\setbox\csname\@otr@:\!!stringa:\recurselevel\endcsname\box\csname\@otr@:\!!stringb:\recurselevel\endcsname \else \emptybox %\global\setbox\csname\@otr@:\!!stringa:\recurselevel\endcsname\emptybox \expandafter\newbox\csname\@otr@:\!!stringb:\recurselevel\endcsname \fi \else \expandafter\newbox\csname\@otr@:\!!stringa:\recurselevel\endcsname \ifcsname\@otr@:\!!stringb:\recurselevel\endcsname \global\setbox\csname\@otr@:\!!stringa:\recurselevel\endcsname\box\csname\@otr@:\!!stringb:\recurselevel\endcsname \else \expandafter\newbox\csname\@otr@:\!!stringb:\recurselevel\endcsname \fi \fi}}% \else \dorecurse \tofcolumns {\let\!!stringa\recurselevel \dostepwiserecurse \zerocount \columnmaxcells \plusone {\ifcsname\@otr@:\!!stringa:\recurselevel\endcsname \global\setbox\csname\@otr@:\!!stringa:\recurselevel\endcsname\emptybox \else \expandafter\newbox\csname\@otr@:\!!stringa:\recurselevel\endcsname \fi}}% \fi \dorecurse\tofcolumns {\global\setbox\csname\@otr@:\recurselevel:\columnmaxcells\endcsname\copy\placeholderboxa}% \global\columnfirstcell\zerocount \global\columnlastcell\columnfirstcell \global\columnfreecells\columnfirstcell \egroup} \def\doOTRSETsetgridcells#1#2#3#4#5#6% placeholder col row wid hei {data} {\!!countd#2\advance\!!countd#4\advance\!!countd\minusone \!!counte#3\advance\!!counte#5\advance\!!counte\minusone \dostepwiserecurse{#2}\!!countd\plusone {\!!countf\recurselevel \dostepwiserecurse{#3}\!!counte\plusone {\OTRSETsetgridcell\!!countf\recurselevel#1}}% \dostepwiserecurse{#3}\!!counte\plusone {\wd\OTRSETgridcell{#2}\recurselevel\hsize}% \OTRSETsetgridcell{#2}\!!counte#6} \def\OTRSETsetgridcells {\doOTRSETsetgridcells{\copy\placeholderboxb}} \def\OTRSETerasegridcells#1#2#3#4% {\doOTRSETsetgridcells{\emptybox}{#1}{#2}{#3}{#4}{\emptybox}} \def\setupcolumnsetlines{\doquintupleempty\dosetupcolumnsettrick[l]} \def\setupcolumnsetstart{\doquintupleempty\dosetupcolumnsettrick[s]} \def\dosetupcolumnsettrick[#1][#2][#3][#4][#5]% tag id page col value {% not needed, is already relative % \doifinstringelse{+}{#3}{\scratchcounter\realpageno}{\scratchcounter\zerocount}% % \advance\scratchcounter#3\relax % \relax needed % \setevalue{\??mc:#1:#2:\the\scratchcounter:\number#4}{\number#5}} \iffifthargument \setevalue{\??mc:#1:#2:\number#3:\number#4}{\number#5}% \else \setevalue{\??mc:#1:#2:\number#3:0}{\number#4}% \fi} \def\currentcolumnmaxcellstag #1{\??mc:l:\OTRSETidentifier:\columnsetpage:\number#1} \def\currentcolumnstartcelltag#1{\??mc:s:\OTRSETidentifier:\columnsetpage:\number#1} \def\doresetcolumnsetlines#1% {\ifcsname\currentcolumnmaxcellstag{#1}\endcsname \letgvalue{\currentcolumnmaxcellstag{#1}}\zerocount \fi \ifcsname\currentcolumnmaxcellstag{#1}\endcsname \letgvalue{\currentcolumnmaxcellstag{#1}}\zerocount \fi} \def\currentcolumnsomecells#1#2% {\ifcsname#1\mofcolumns\endcsname \ifnum\csname#1\mofcolumns\endcsname=\zerocount #2% \else \number\numexpr\ifnum\csname#1\mofcolumns\endcsname<\zerocount \columnmaxcells+\fi\csname#1\mofcolumns\endcsname\relax \fi \else\ifcsname#10\endcsname \ifnum\csname#10\endcsname=\zerocount #2% \else \number\numexpr\ifnum\csname#10\endcsname<\zerocount \columnmaxcells+\fi\csname#10\endcsname\relax \fi \else #2% \fi\fi} \def\currentcolumnmaxcells {\currentcolumnsomecells\currentcolumnmaxcellstag \columnmaxcells} \def\currentcolumnstartcell{\currentcolumnsomecells\currentcolumnstartcelltag\plusone} \def\OTRSETsetfreecells#1#2% col start {\bgroup \global\columnfirstcell\ifnum#2=0 1\else#2\fi\relax \OTRSETsetcorrectnofcells\currentcolumnmaxcells % sets \scratchcounter \edef\columnmaxcells{\the\scratchcounter}% \ifnum\columnfirstcell>\columnmaxcells \global\columnfreecells\zerocount \global\columnfirstcell\plusone \global\columnlastcell \zerocount \global\somefreecolumncellsfalse %\message{no cells a}% \else \doloop {\ifnum\columnfirstcell>\columnmaxcells\relax \exitloop \else \OTRSETdoifcellelse{#1}\columnfirstcell {\global\advance\columnfirstcell\plusone}\exitloop \fi}% \global\columnlastcell\columnfirstcell \doloop {\ifnum\columnlastcell>\columnmaxcells\relax \exitloop \else \OTRSETdoifcellelse{#1}\columnlastcell {\global\advance\columnlastcell \minusone \exitloop} {\global\advance\columnlastcell \plusone }% \fi}% \ifnum\columnfirstcell>\columnmaxcells \global\columnfreecells\zerocount \global\columnfirstcell\plusone \global\columnlastcell \zerocount \global\somefreecolumncellsfalse %\message{no cells b}% \else \ifnum\columnlastcell>\columnmaxcells \global\columnlastcell\columnmaxcells \fi \global\columnfreecells\columnlastcell \global\advance\columnfreecells -\columnfirstcell \global\advance\columnfreecells \plusone \global\somefreecolumncellstrue %\message{\number\columnfirstcell-\number\columnlastcell=\number\columnfreecells}% \fi \fi \egroup} \def\OTRSETgetmaxfreecells#1#2% col start {\let\columnmaxfreecells\!!zerocount \let\columnfrmfreecells\!!zerocount \pushmacro \columnmaxcells \OTRSETsetcorrectnofcells\currentcolumnmaxcells % sets \scratchcounter \edef\columnmaxcells{\the\scratchcounter}% \scratchcounter\zerocount \dostepwiserecurse{#2}\columnmaxcells\plusone {\OTRSETdoifcellelse{#1}\recurselevel {\ifnum\columnmaxfreecells<\scratchcounter \edef\columnmaxfreecells{\the\scratchcounter}% \let\columnfrmfreecells\recurselevel \fi \scratchcounter\zerocount} {\advance\scratchcounter\plusone}}% \popmacro\columnmaxcells} \long\def\OTRSETrecurseRL#1% {\dostepwiserecurse\nofcolumns\plusone\minusone {#1\hskip\OTRSETgetparameter\c!distance\recurselevel}} \def\OTRSETmakegridbox {\ifcase\columndirection \OTRSETdomakegridbox\plusone\nofcolumns\plusone \else \OTRSETdomakegridbox\nofcolumns\plusone\minusone \fi} \def\OTRSETmakeupwidth{\makeupwidth} % temporary indirectness \def\OTRSETdomakegridbox#1#2#3% {\hbox\bgroup \dontcomplain \forgetall % can go once in \flush \!!heighta \textheight % test first ! \hbox to \OTRSETmakeupwidth {\dostepwiserecurse{#1}{#2}{#3} {\mofcolumns\recurselevel \localcolumnwidth\OTRSETlocalwidth\mofcolumns \setbox\scratchbox\hbox\localframed [\??mc\OTRSETidentifier\number\mofcolumns]% [\c!width=\localcolumnwidth,\c!height=\!!heighta,\c!lines=]% {}% \wd\scratchbox\localcolumnwidth \ht\scratchbox\!!heighta \ifcase\columndirection \hskip\OTRSETgetparameter\c!distance\recurselevel \box\scratchbox \else \box\scratchbox \hskip\OTRSETgetparameter\c!distance\recurselevel \fi}}% \hskip-\OTRSETmakeupwidth % main text \hbox to \OTRSETmakeupwidth {\dostepwiserecurse{#1}{#2}{#3} {\mofcolumns\recurselevel \localcolumnwidth\OTRSETlocalwidth\mofcolumns \offinterlineskip \setbox\scratchbox\vbox to \!!heighta {\topskipcorrection % not needed \ifcase\OTRSETbalancemethod % no \or % yes \doifelselayerdata{OTRTEXT}\vfill\relax % temp hack \or % top \or % bottom \vfill \fi \dorecurse\columnmaxcells {\setbox\scratchbox\hbox{\OTRSETgetgridcell\mofcolumns\recurselevel}% % {\setbox\scratchbox\hbox % {\localstarttextcolor % \OTRSETgetgridcell\mofcolumns\recurselevel % \localstoptextcolor}% \ht\scratchbox\strutht \dp\scratchbox\strutdp \ifcase\columndirection \box\scratchbox \else \hbox to \localcolumnwidth {\hskip\localcolumnwidth\llap{\box\scratchbox}}% \fi \par}% \ifcase\OTRSETbalancemethod % no \else % yes, top, bottom \ifdim\globalbodyfontsize=\localbodyfontsize \removedepth \restoreglobalbodyfont \vskip\strutdepth \fi \kern\zeropoint \vss \fi}% \wd\scratchbox\localcolumnwidth % \textwidth \ifcase\columndirection \hskip\OTRSETgetparameter\c!distance\recurselevel\box\scratchbox \else \box\scratchbox\hskip\OTRSETgetparameter\c!distance\recurselevel \fi}}% \egroup} \let\OTRSETbalht\zeropoint \def\OTRSETreducegridbox % for the moment no difference between methods {\globallet\OTRSETbalht\zeropoint \ifcase\OTRSETbalancemethod % no balancing \else \bgroup \!!counta\columnmaxcells \donetrue \doloop {\dorecurse\nofcolumns{\OTRSETdoifcellelse\recurselevel\!!counta\donefalse\donothing}% \ifdone \ifnum\!!counta>\plusone\advance\!!counta\minusone\else\exitloop\fi \else \exitloop \fi}% \ifnum\!!counta>\plusone \!!heighta\lineheight \multiply\!!heighta \!!counta \advance\!!heighta \topskip \advance\!!heighta -\lineheight \else \!!heighta\zeropoint \fi \xdef\OTRSETbalht{\the\!!heighta}% \egroup \fi} \def\OTRSETflushfinalfootnotes {\ifcase\lastcolumnlastcell \else \setbox\scratchbox\hbox {\placebottomnotes}% \ifdim\ht\scratchbox>\zeropoint \setbox\scratchbox\hbox {\hbox to \zeropoint{\OTRSETgetgridcell\nofcolumns\lastcolumnlastcell}% \box\scratchbox}% \ht\scratchbox\strutht \dp\scratchbox\strutdp \OTRSETsetgridcell\nofcolumns\lastcolumnlastcell\box\scratchbox \fi \global\lastcolumnlastcell\zerocount \fi} \def\OTRSETdoflush {\ifcollectingcontent \registerOTRSETmarks \global\mofcolumns\plusone \else \OTRSETdofinalflush \OTRSETdofinaloutput \ifnum\columnsetpage>0 \dorecurse\nofcolumns{\doresetcolumnsetlines\recurselevel}% \fi \doglobal\increment\columnsetpage \OTRSETinitializecolumns %\OTRSETdoflushfloats \OTRSETstartnextpage \presetOTRSETmarks \initializecolumntextareas \fi} \newbox\OTRfinalpagebox \def\OTRSETdofinalflush % see \OTRSETdoflush {\OTRSETflushfinalfootnotes \placecolumntextareas \OTRSETcentergridcells \bgroup % we want to keep the reduction local \OTRSETreducegridbox \global\setbox\OTRfinalpagebox\OTRSETmakegridbox \egroup % otherwise we get the wrong number of free cells %\gdef\localcolumnmaxcells{0}% here ? \global\mofcolumns\nofcolumns} % otherwise problems in finaloutput \def\OTRSETdofinaloutput {\ifdim\ht\OTRfinalpagebox=\textheight \bgroup % \let\OTRSETsetvsize\relax % prevents useless search for gap \ifcase\OTRSETbalancemethod \finaloutput\box\OTRfinalpagebox \else\ifdim\OTRSETbalht>\zeropoint % catch a bordercase \scratchdimen\OTRSETbalht \advance\scratchdimen\lineheight\relax \ifdim\scratchdimen>\textheight % full page \finaloutput\box\OTRfinalpagebox \else % same page \global\setbox\OTRfinalpagebox \iftracecolumnset\ruledvbox\else\vbox\fi to \OTRSETbalht {\box\OTRfinalpagebox\vss}% \setlayer[OTRTEXT]{\box\OTRfinalpagebox}% \snaptogrid\vbox{\vskip\OTRSETbalht}% hack \fi \else \finaloutput\box\OTRfinalpagebox \fi \fi \globallet\OTRSETbalht\zeropoint \egroup \fi} \definesystemvariable {mc} \definesystemvariable {mt} \definesystemconstant {colset} \definetwopasslist\s!colset \newdimen \OTRSETtextswidth \newdimen \OTRSETtextsheight \let \OTRSETidentifier=\empty \newtoks \OTRSEToutput \def\OTRSETgetparameter#1#2{\csname\??mc\OTRSETidentifier\number#2#1\endcsname} \def\OTRSETsetparameter#1#2{\setvalue{\??mc\OTRSETidentifier\number#2#1}} \def\OTRSETskipstart {\scratchcounter\executeifdefined{\??mc\OTRSETidentifier\c!start}\zerocount \relax % needed ! \ifcase\scratchcounter\else \advance\scratchcounter\plusone \doOTRSETsetgridcells {\copy\placeholderboxe} \plusone\plusone\nofcolumns\scratchcounter \null \fi} \def\OTRSETsetvsize % snap per sectie (gap here?) {\ifcollectingcontent \else % can be assigndimen \OTRSETskipstart % not that well tested \OTRSETcheckinsert % added \OTRSETsetfreecells\mofcolumns\columnfirstcell \ifsomefreecolumncells \global\vsize\columnfreecells\lineheight \ifinotr % else problems with floats, see extreme \global\pagegoal\vsize % niet nodig, tenzij binnen otr \fi \synchronizeoutput % fails on example % \allowbreak % hm \fi \synchronizenotes \fi} \def\OTRSETsethsize % of course this does not migrate outside the otr {\localcolumnwidth\OTRSETlocalwidth\mofcolumns \textwidth\localcolumnwidth \hsize\localcolumnwidth} \def\OTRSETsynchronizehsize {\ifcase0\getvalue{\??mc\??mc\c!width}\else % some width set \bgroup \scratchdimen\OTRSETlocalwidth\mofcolumns \ifdim\scratchdimen=\textwidth \egroup \else % only if change in width and \column/\break \egroup \OTRSETsethsize \fi \fi} \def\OTRSETcheckfreelines {\OTRSETsetvsize} \def\doOTRSETcolumnseparator {\hbox to \zeropoint{\hss\red\vl\hss}} \let\OTRSETcolumnseparator\relax \def\showbreaks {\let\OTRSETcolumnseparator\doOTRSETcolumnseparator} % \installcolumnbreakhandler {SET} \v!ja % {% hmmm: % \ifhmode % \bgroup % \removeunwantedspaces % \parfillskip\zeropoint % \OTRSETcolumnseparator % \par % \egroup % \fi % % brrr: % \ejectinsert % \ejectpage % \OTRSETsynchronizehsize} % no \OTRSETsethsize, can be mid smaller (like tabulate) % % \installcolumnbreakhandler {SET} \v!forceer % {\OTRSETgotocolumn[\v!forceer]} % \installcolumnbreakhandler {SET} \v!eerste % {\OTRSETgotocolumn[\v!eerste]} % \installcolumnbreakhandler {SET} \v!laatste % {\OTRSETgotocolumn[\v!laatste]} % % \installcolumnbreakhandler {SET} \v!pagina % {\simplepagebreak % \flushnotes \executepagebreakhandler\v!ja % \ifnum\mofcolumns>\plusone % \OTRSETgotocolumn[\v!laatste,\v!forceer]% % \fi} \def\OTRSETcolumnhbreak {\ifhmode \bgroup \removeunwantedspaces \parfillskip\zeropoint \OTRSETcolumnseparator \par \egroup \fi} \installcolumnbreakhandler {SET} \v!local {\OTRSETcolumnhbreak \ejectinsert \ejectpage % brrr % no \OTRSETsethsize, can be mid smaller (like tabulate) % also, this one should be executed at the outer level % (setting hsize inside otr does not work) \OTRSETsynchronizehsize} % We need to make sure that we really leave the column; mid % column we may end up in an empty gap, and we don't want to % stay there (basically such a gap is a small empty page % then). \installcolumnbreakhandler {SET} \v!yes {\OTRSETcolumnhbreak \edef\savedmofcolumns{\the\mofcolumns}% \edef\savedrealpageno{\the\realpageno}% \ejectinsert \ejectpage % brrr \doloop {\ifnum\savedmofcolumns=\mofcolumns \ifnum\savedrealpageno=\realpageno \OTRSETdummycolumn \else \exitloop \fi \else \exitloop \fi}% \OTRSETsynchronizehsize} \installcolumnbreakhandler {SET} \s!unknown {\expanded{\OTRSETgotocolumn[\@@columnspecification]}} \installcolumnbreakhandler {SET} \v!page {\vfill\eject % \doejectpage\eject \OTRSETgotonextpage} \newtoks\OTRSETeverystartofcolumn \newbox\OTRSETsavedfootnotes % \installoutput\OTRSETflushtextsofar % spacing goes wrong %\def\OTRSETflushtextsofar % {\ifvoid\normalpagebox \else % \setbox\scratchbox\vbox{\unvbox\normalpagebox}% % \OTRSETsavenotes % \OTRSEThandleflushedtext0 % \fi} % The complication is in the fact that when the HERE float % is placed, the otr is not invoked when there is not yet % enough content; this can lead to a change in order (turning % on the tracer with option 0 is very instructive, watch the % small numbers in the margin) % % 0 = no flushing, so no interference but user should handle % border cases of placement % 1 = the normal otr, rather untested % 2 = a solution that works ok, is experimental and above % all messy \chardef\OTRSETflushtextmode=0 \def\OTRSETflushtextsofar {\ifcase\OTRSETflushtextmode % don't mess around \or % the normal one \ifvoid\normalpagebox\else \OTRSETnaturalflush \OTRSETcheckfreelines \fi \or % way to complicated, but kind of ok \doOTRSETflushtextsofar \fi} \newskip\lastskipinotr \installoutput\doOTRSETflushtextsofar % experimental {\ifvoid\normalpagebox\else \scratchdimen\dp\normalpagebox \setbox\scratchbox\vbox {\forgetall \unvbox\normalpagebox \global\lastskipinotr\lastskip\relax \ifdim\lastskipinotr>\zeropoint\relax \removelastskip \else \kern-\scratchdimen % handle depth \fi}% \ifdim\lastskipinotr>\zeropoint \scratchskip\ht\scratchbox \setbox\scratchbox\hbox {\lower\strutdepth\box\scratchbox}% \dp\scratchbox\scratchdimen \ht\scratchbox\scratchskip \fi \OTRSETsavenotes \OTRSEThandleflushedtext\zerocount \ifdim\lastskipinotr>\zeropoint %\vskip \lastskipinotr % hm, gets lost anyway \else % we should not discard skips after here; tricky \fi \OTRSETsetvsize \fi} \def\OTRSETplacebottomnotes {\iflastcolumnfootnotes \ifnum\nofcolumns=\mofcolumns \ifintermediatefootnotes \placebottomnotes \fi \fi \else \placebottomnotes \fi} \def\OTRSETflushsavednotes {\iflastcolumnfootnotes \ifnum\nofcolumns=\mofcolumns \flushsavednotes \fi \else \flushsavednotes \fi} \def\OTRSETsavenotes {\iflastcolumnfootnotes \ifnum\nofcolumns=\mofcolumns \else \savenotes \fi \fi} \appendtoks \OTRSETflushsavednotes \to \OTRSETeverystartofcolumn \def\OTRSETnaturalflush {\bgroup \forgetall % new, needed ! \setbox0\vbox to \columnfreecells\lineheight {\vskip-\topskip \vskip\lineheight \prevdepth\strutdp \unvbox\normalpagebox \vfill}% \setbox2\hbox {\OTRSETplacebottomnotes}% \setbox\scratchbox\hbox {\wd0\zeropoint\box0\box2}% \dp\scratchbox\strutdp \OTRSEThandleflushedtext\plusone \egroup} \newcount\lastcolumnlastcell \def\OTRSEThandleflushedtext#1% {\getnoflines{\ht\scratchbox}% %\wd\scratchbox\textwidth % geen \hsize kan < zijn in bv split tabulate \wd\scratchbox\OTRSETlocalwidth\mofcolumns \doOTRSETsetgridcells {\copy\placeholderboxf} \mofcolumns\columnfirstcell\plusone\noflines {\registeredtextarea1\columnfirstcell\scratchbox}% == \hbox / tricky htcorr == \columnfirstcell \global\columnlastcell\columnfirstcell \global\advance\columnlastcell \noflines \global\lastcolumnlastcell\columnlastcell \global\advance\lastcolumnlastcell \minusone % find next (acceptable) gap, todo: deadcycle \ifcase#1\else \OTRSETfillgapsbetweencells\mofcolumns\columnlastcell \fi \OTRSETfindnextgap % \message{\the\mofcolumns,\the\columnfirstcell,\the\columnfreecells}% % \wait % we cannot adapt the hsize since it may have changed (like % inside a tabulate) so we only change it when there is a % reason to do so \OTRSETsynchronizehsize \OTRSETsetvsize} \def\OTRSETfindnextgap {\OTRSETsetfreecells\mofcolumns\columnlastcell \ifsomefreecolumncells % okay \bubbleOTRSETmarks % not robust because we reenter \else \registerOTRSETmarks % not robust because we reenter \global\advance\mofcolumns \plusone \ifnum\mofcolumns>\nofcolumns \OTRSETdoflush \global\columnlastcell\plusone \global\columnfirstcell\zerocount \OTRSETdoflushfloats \else \the\OTRSETeverystartofcolumn \global\columnlastcell\plusone \global\columnfirstcell\zerocount \fi \fi} \let\OTRSETcheckfreelines\donothing \def\OTRSETfillgapsbetweencells#1#2% col {\ifnum\columngaplimit>\zerocount \donefalse \dostepwiserecurse{#2}\columnmaxcells\plusone {\OTRSETdoifcellelse{#1}\recurselevel {\ifdone \!!countb\recurselevel \advance\!!countb -\!!counta\relax \ifnum\!!countb>\plusone \advance\!!countb \minusone \ifnum\!!countb<\columngaplimit\relax \!!countb\recurselevel \advance\!!countb \minusone \dostepwiserecurse\!!counta\!!countb\plusone {\OTRSETsetgridcell{#1}\recurselevel\copy\placeholderboxc}% %\message{[gap]}% \fi \fi \fi \donefalse} {\ifdone \else \donetrue \!!counta\recurselevel \fi}}% \fi} \appendtoks \OTRSETfillgapsbetweencells\mofcolumns\plusone \to \OTRSETeverystartofcolumn %\def\OTRSETfreezeminimumgap#1% % {\OTRSETgetmaxfreecells{#1}{1}% % \ifnum\columnmaxfreecells>0 % \!!countb=\columnfrmfreecells % \!!counta=\!!counta \advance\!!counta -\columnmaxfreecells % \dorecurse{\columnmaxcells} % {\ifnum\recurselevel<\!!counta\relax % \donetrue % \else\ifnum\recurselevel>\!!countb % \donetrue % \else % \donefalse % \fi\fi % \ifdone % \OTRSETdoifcellelse{#1}{\recurselevel} % {}{\OTRSETsetgridcell{#1}\recurselevel\copy\placeholderboxc}% % \fi}% % \fi} % %\def\OTRSETfillgaps#1#2#3% col from to % {\dostepwiserecurse{#2}{#3}{1} % {\OTRSETdoifcellelse{#1}{\recurselevel} % {}{\OTRSETsetgridcell{#1}\recurselevel\copy\placeholderboxc}}} % %\def\OTRSETfillbotgaps#1#2% col first % {\OTRSETfillgaps{#1}{#2}{\columnmaxcells}} % %\def\OTRSETfilltopgaps#1#2% col last % {\OTRSETfillgaps{#1}{1}{#2}} \newif\ifspancolumnslots \spancolumnslotstrue \newif\ifcheckcolumnspan \checkcolumnspantrue \def\OTRSETcheckwidthgap#1#2% box size {\ifcheckcolumnspan \bgroup \scratchdimen#2% \advance\scratchdimen-\wd#1\relax \ifdim-10\scaledpoint>\scratchdimen \egroup \else\ifdim10\scaledpoint<\scratchdimen \egroup \else \egroup \wd#1=#2% \fi\fi \fi} \def\OTRSETcheckcolumnslot#1% {\enoughcolumncellstrue \ifspancolumnslots\else \OTRSETcheckwidthgap#1\hsize \ifdim\wd#1>\hsize \enoughcolumncellsfalse \fi \fi \ifenoughcolumncells \getnoflines\pagetotal \scratchcounter\noflines \getnoflines{\ht#1}% \columnvcells\noflines \columnhcells\plusone \advance\scratchcounter \columnvcells \relax \ifnum\scratchcounter>\columnfreecells \enoughcolumncellsfalse \fi \fi} \def\OTRSETstoreincolumnslotPAGE#1% {\ifenoughcolumncells % to do \OTRSETsavebox{#1}% \else \OTRSETsavebox{#1}% \fi} \def\OTRSETstoreincolumnslotTOPS#1% {\OTRSETprepareforcolumnslot1{#1}% \OTRSETcheckcolumnslot{#1}% \ifenoughcolumncells \OTRSETcheckcolumnspace\mofcolumns\columnfirstcell{#1}% \fi \ifenoughcolumncells \OTRSETsetgridcells\mofcolumns\columnfirstcell\columnhcells\columnvcells {\hbox{\copy#1}}% \OTRSETsetvsize \else \OTRSETsavebox{#1}% \fi} \def\OTRSETstoreincolumnslotBOTS#1% {\OTRSETprepareforcolumnslot3{#1}% \edef\savedcolumnlastcell{\the\columnlastcell}% \OTRSETcheckcolumnslot{#1}% \ifenoughcolumncells \advance\columnlastcell -\columnvcells \advance\columnlastcell \plusone % \OTRSETcheckcolumnspace\mofcolumns\columnfirstcell{#1}% \OTRSETcheckcolumnspace\mofcolumns\columnlastcell{#1}% \fi \ifenoughcolumncells \OTRSETsetgridcells\mofcolumns\columnlastcell\columnhcells\columnvcells{\copy#1}% \OTRSETfillgapsbetweencells\mofcolumns\savedcolumnlastcell % -) \OTRSETsetvsize \else \columnlastcell\savedcolumnlastcell \OTRSETsavebox{#1}% \fi} \newdimen\totalcolumnspace \def\columnspacetopoffset{0} \def\columnspacebotoffset{0} \def\OTRSETcheckcolumnspace#1#2#3% col row box {\columnhcells\plusone \totalcolumnspace\zeropoint \scratchcounter#1% \enoughcolumncellstrue \doloop {\advance\totalcolumnspace \OTRSETlocalwidth\scratchcounter\relax % needed \OTRSETcheckwidthgap#3\totalcolumnspace \ifnum\wd#3>\totalcolumnspace\relax \ifnum\scratchcounter=\nofcolumns \enoughcolumncellsfalse \exitloop \else \advance\columnhcells \plusone \advance\scratchcounter \plusone \advance\totalcolumnspace \OTRSETgetparameter\c!distance\scratchcounter \fi \else \exitloop \fi}% \ifenoughcolumncells \getnoflines{\ht#3}% \columnvcells\noflines \OTRSETcheckcolumncells{#1}{#2}\columnhcells\columnvcells \fi} \def\OTRSETcheckcolumncells#1#2#3#4% col row wid hei {\!!countd#1\advance\!!countd#3\advance\!!countd\minusone \!!counte#2\advance\!!counte#4\advance\!!counte\minusone \ifnum\!!counte>\columnmaxcells\relax \enoughcolumncellsfalse \else \enoughcolumncellstrue %\let\columnspacetopoffset\zerocount %\scratchcounter#2\advance\scratchcounter\minusone %\ifnum\scratchcounter>0 % \dostepwiserecurse{#1}\!!countd\plusone % {\ifdim\wd\OTRSETgridcell\recurselevel\scratchcounter>\zeropoint % \let\columnspacetopoffset\plusone % \else\ifdim\dp\OTRSETgridcell\recurselevel\scratchcounter>\zeropoint % \let\columnspacetopoffset\plusone % \fi\fi}% % \advance\!!counte \columnspacetopoffset \relax % \advance\columnvcells \columnspacetopoffset \relax %\fi %\let\columnspacebotoffset\zerocount %\scratchcounter\!!counte %\advance\scratchcounter \columnvcells \relax %\ifnum\scratchcounter>\columnmaxcells\else % \dostepwiserecurse{#1}\!!countd\plusone % {\ifdim\wd\OTRSETgridcell\recurselevel\scratchcounter>\zeropoint % \let\columnspacebotoffset\plusone % \else\ifdim\dp\OTRSETgridcell\recurselevel\scratchcounter>\zeropoint % \let\columnspacebotoffset\plusone % \fi\fi}% % \advance\!!counte \columnspacebotoffset \relax % \advance\columnvcells \columnspacebotoffset \relax %\fi \dostepwiserecurse{#1}\!!countd\plusone % cols {\ifenoughcolumncells \!!countf\recurselevel\relax \dostepwiserecurse{#2}\!!counte\plusone % rows {\ifenoughcolumncells \OTRSETdoifcellelse\!!countf\recurselevel {\enoughcolumncellsfalse}{}% \fi}% \fi}% \fi} \def\OTRSETsetpreferedcolumnslot#1#2% {\doifsomething{#1}{\edef\preferedcolumn{#1}}% \doifsomething{#2}{\edef\preferedrow {#2}}} \OTRSETsetpreferedcolumnslot{\nofcolumns}{1} % default ? \let\pofcolumns\mofcolumns \let\qofcolumns\mofcolumns \newif\ifquitincurrentcolumn \def\OTRSETstoreincolumnslotLRTB#1% {\OTRSETprepareforcolumnslot1{#1}% \OTRSETflushtextsofar \OTRSETstoreincolumnslotindeed \mofcolumns\nofcolumns+\currenthcell \plusone\columnmaxcells+\currentvcell{#1}} \def\OTRSETstoreincolumnslotLRBT#1% {\OTRSETprepareforcolumnslot3{#1}% \OTRSETflushtextsofar \OTRSETstoreincolumnslotindeed \mofcolumns\nofcolumns+\currenthcell \columnmaxcells\plusone-\currentvcell{#1}} \def\OTRSETstoreincolumnslotRLTB#1% {\OTRSETprepareforcolumnslot1{#1}% \OTRSETflushtextsofar \OTRSETcheckprefered \OTRSETstoreincolumnslotindeed \nofcolumns\qofcolumns-\currenthcell \plusone\columnmaxcells+\currentvcell{#1}} \def\OTRSETstoreincolumnslotRLBT#1% {\OTRSETprepareforcolumnslot3{#1}% \OTRSETflushtextsofar \OTRSETcheckprefered \OTRSETstoreincolumnslotindeed \nofcolumns\qofcolumns-\currenthcell \columnmaxcells\plusone-\currentvcell{#1}} \def\OTRSETstoreincolumnslotTBLR#1% {\OTRSETprepareforcolumnslot1{#1}% \OTRSETflushtextsofar \OTRSETstoreincolumnslotindeed \plusone\columnmaxcells+\currentvcell \mofcolumns\nofcolumns+\currenthcell{#1}} \def\OTRSETstoreincolumnslotTBRL#1% {\OTRSETprepareforcolumnslot1{#1}% \OTRSETflushtextsofar \OTRSETcheckprefered \OTRSETstoreincolumnslotindeed \plusone\columnmaxcells+\currentvcell \nofcolumns\qofcolumns-\currenthcell{#1}} \def\OTRSETstoreincolumnslotBTLR#1% {\OTRSETprepareforcolumnslot3{#1}% \OTRSETflushtextsofar \OTRSETstoreincolumnslotindeed \columnmaxcells\plusone-\currentvcell \mofcolumns\nofcolumns+\currenthcell{#1}} \def\OTRSETstoreincolumnslotBTRL#1% {\OTRSETprepareforcolumnslot3{#1}% \OTRSETflushtextsofar \OTRSETcheckprefered \OTRSETstoreincolumnslotindeed \columnmaxcells\plusone-\currentvcell \nofcolumns\qofcolumns-\currenthcell{#1}} \def\OTRSETstoreincolumnslotFXTB#1% fixed column {\OTRSETcheckprefered \OTRSETdoifcellelse\pofcolumns\plusone {\OTRSETprepareforcolumnslot2}{\OTRSETprepareforcolumnslot1}{#1}% % 1/2 dependent of place, todo \OTRSETflushtextsofar \OTRSETstoreincolumnslotindeed \pofcolumns \pofcolumns +\currenthcell \preferedrow\columnmaxcells+\currentvcell{#1}} \def\OTRSETstoreincolumnslotFXBT#1% fixed column {\OTRSETcheckprefered \OTRSETdoifcellelse\pofcolumns\columnmaxcells {\OTRSETprepareforcolumnslot2}{\OTRSETprepareforcolumnslot3}{#1}% % 3/2 dependent of place, todo \OTRSETflushtextsofar \OTRSETstoreincolumnslotindeed \pofcolumns \pofcolumns +\currenthcell \columnmaxcells\preferedrow-\currentvcell{#1}} % \def\OTRSETstoreincolumnslotHERE#1% fixed column % {\OTRSETprepareforcolumnslot2{#1}% % \OTRSETflushtextsofar % \getnoflines\pagetotal \advance\noflines\columnfirstcell % \OTRSETstoreincolumnslotindeed % \mofcolumns\mofcolumns+\currenthcell % \noflines\columnmaxcells+\currentvcell{#1}% % \OTRSETsetvsize} \chardef\OTRSETforcefixedfloats=0 \def\OTRSETstoreincolumnslotHERE#1% fixed column {\ifcase\OTRSETforcefixedfloats \OTRSETstoreincolumnslotSOMEWHERE2{#1}% \else \OTRSETstoreincolumnslotFIXD{#1}% \fi} % this one looses too wide graphics % % \def\OTRSETstoreincolumnslotFIXD#1% fixed column % {\OTRSETprepareforcolumnslot2{#1}% % % no flush text sofar here, beware: no width test % \snaptogrid\vbox{\box#1}} % % still imperfect \def\OTRSETstoreincolumnslotFIXD#1% fixed column {\OTRSETflushtextsofar \ifdim\wd#1>\textwidth \OTRSETstoreincolumnslotSOMEWHERE2{#1}% \else % crappy test / needed for o-pbu-f / will be replaced \getnoflines{\ht#1}% \scratchdimen\noflines\lineheight \advance\scratchdimen\lineheight \advance\scratchdimen\pagetotal\relax \ifdim\scratchdimen<\pagegoal %OTRSETprepareforcolumnslot3{#1}% %ruledvskip\columnslotspacing\lineheight \blank[\columnslotspacing*\v!line]% \snaptogrid\hbox to \hsize{\hss\box#1\hss}% strange, why the centering \blank[\columnslotspacing*\v!line]% \else \OTRSETstoreincolumnslotSOMEWHERE2{#1}% \fi \fi} \def\OTRSETstoreincolumnslotSOMEWHERE#1#2% {\OTRSETprepareforcolumnslot{#1}{#2}% \OTRSETflushtextsofar \getnoflines\pagetotal \advance\noflines\columnfirstcell \OTRSETstoreincolumnslotindeed \mofcolumns\mofcolumns+\currenthcell \noflines\columnmaxcells+\currentvcell{#2}% \OTRSETsetvsize} \def\OTRSETcheckprefered {\ifnum\preferedcolumn<\mofcolumns \let\pofcolumns\mofcolumns \else \let\pofcolumns\preferedcolumn \fi \ifquitincurrentcolumn \ifnum\mofcolumns=\nofcolumns \def\qofcolumns{\mofcolumns}% \else \scratchcounter\mofcolumns \advance\scratchcounter \plusone \edef\qofcolumns{\the\scratchcounter}% \fi \else \let\qofcolumns\mofcolumns \fi} \def\OTRSETstoreincolumnslotindeed#1#2#3#4#5#6#7#8#9% {\OTRSETcheckprefered \enoughcolumncellsfalse \donefalse \dostepwiserecurse{#1}{#2}{#31} {\ifdone \exitloop \else #4=\recurselevel \dostepwiserecurse{#5}{#6}{#71} {\ifdone \exitloop \else #8=\recurselevel \OTRSETcheckcolumnspace\currenthcell\currentvcell{#9}% \ifenoughcolumncells \donetrue \fi \fi}% \fi}% \ifdone \enoughcolumncellstrue \else \enoughcolumncellsfalse \fi \ifenoughcolumncells % \ifnum\columnspacetopoffset>0\message{[+++]}\fi % \ifnum\columnspacebotoffset>0\message{[---]}\fi % \OTRSETsetgridcells\currenthcell\currentvcell\columnhcells\columnvcells % {\vbox % {\ifcase\columnspacetopoffset\else\ruledvskip\columnspacetopoffset\lineheight\fi % \copy#9 % \ifcase\columnspacebotoffset\else\ruledvskip\columnspacebotoffset\lineheight\fi}}% \OTRSETsetgridcells\currenthcell\currentvcell\columnhcells\columnvcells {\copy#9}% \ifnum\currenthcell=\mofcolumns\relax \ifdim\ht\OTRSETsavedfootnotes>\zeropoint \OTRSETsetfreecells\mofcolumns\columnfirstcell \ifsomefreecolumncells \getnoflines{\ht\OTRSETsavedfootnotes}\relax \ifnum\columnfreecells<\noflines \global\somefreecolumncellsfalse \else %\message{[flt]}% float \fi \fi \ifsomefreecolumncells % ok, enough room for notes %\message{[flt]}% float \else % ? \OTRSETsavebox{#9}% \OTRSETerasegridcells\currenthcell\currentvcell\columnhcells\columnvcells %\message{[clr]}% save box \fi \else %\message{[flt]}% float \fi \else %\message{[flt]}% float \fi \OTRSETsetvsize %\message{[fnt]}% float \else %\message{[rej]}% save box \OTRSETsavebox{#9}% \fi} \chardef\columnslotspacing \plusone \def\OTRSETstoreincolumnslot#1% #2 % {method} {box} % alleen last {% no messing around here % \dp#2=\zeropoint % \ifcase\columnslotspacing\else % \setbox#2=\vbox spread \columnslotspacing\lineheight % {\vss\box#2\vss}% % \fi % and don't change this any more % \doifdefinedelse{\strippedcsname\OTRSETstoreincolumnslot#1} % {\getvalue{\strippedcsname\OTRSETstoreincolumnslot#1}{#2}} % {\OTRSETstoreincolumnslotUNKNOWN{#2}}} \executeifdefined{\strippedcsname\OTRSETstoreincolumnslot#1} \OTRSETstoreincolumnslotUNKNOWN} % {#2}} \def\OTRSETstoreincolumnslotUNKNOWN#1% {\OTRSETprepareforcolumnslot2{#1}\copy#1} % {} ? % \def\OTRSETprepareforcolumnslot#1#2% 1=hoog 2=midden 3=laag % {\dp#2\zeropoint % \ifcase\columnslotspacing\else % \scratchdimen\columnslotspacing\lineheight % \ifnum#1=2 \scratchdimen2\scratchdimen \fi % \setbox#2\vbox spread \scratchdimen % {\ifnum#1>1\vss\fi\box#2\relax\ifnum#1<3\vss\fi}% % \fi} \def\OTRSETprepareforcolumnslot#1#2% 1=hoog 2=midden 3=laag {\dp#2\zeropoint \ifcase\columnslotspacing\else \scratchdimen\columnslotspacing\lineheight \ifnum#1=2 \scratchdimen2\scratchdimen \fi \begingroup \advance\scratchdimen\ht#2\relax \ifdim\scratchdimen<\columnmaxcells\lineheight \endgroup \setbox#2\vbox spread \scratchdimen \bgroup \else \endgroup \setbox#2\vbox to \columnmaxcells\lineheight \bgroup \vskip\strutdepth \fi \ifnum#1>1\vss\fi \box#2\relax \ifnum#1<3\vss\fi \egroup \fi} \def\OTRSETdocheckiffloatfits % eigenlijk moet else float anders {\global\ifnofloatpermitted\roomforfloatfalse\else\roomforfloattrue\fi} \def\OTRSETunpreparebox#1% {\ifhbox#1% spans and so \global\setbox\floatbox\vbox{\box#1}% \else \setbox\scratchbox\vbox {\unvbox#1\unskip\unskip\unskip \global\setbox\floatbox\lastbox}% \fi} \def\OTRSETsavebox#1% clean up the skips {\OTRSETunpreparebox{#1}% \dosavefloat} \def\OTRSETresavebox#1% clean up the skips {\OTRSETunpreparebox{#1}% \doresavefloat} \def\OTRSETflushfloatbox % nog verder doorvoeren en meer info in marge {\iftestfloatbox\ruledhbox\fi{\box\floatbox}} \def\OTRSETdoflushfloats {\bgroup \def\OTRSETsavebox##1{\!!doneafalse}% \doloop {\ifsomefloatwaiting \OTRSETskipstart \dogetfloat \ifdim\wd\floatbox>\zeropoint \!!doneatrue \dp\floatbox\zeropoint \OTRSETstoreincolumnslot{TBLR}\floatbox \if!!donea %\message{[flu]}% \else \OTRSETresavebox\floatbox \exitloop \fi \else %\message{[err]}% happens but why? \fi \else \exitloop \fi} \egroup} \newif\ifcentergridcells \centergridcellstrue \newif\ifcentergridcellonly \centergridcellonlyfalse \newif\ifautocentergridcellonly \autocentergridcellonlytrue \def\OTRSETcentergridcells {\ifcentergridcells \dorecurse\nofcolumns {\currenthcell\recurselevel \ifautocentergridcellonly % we prevent centering when the next column is empty % to be checked ! ! ! ! \advance\currenthcell \plusone \centergridcellonlytrue \ifnum\currenthcell>\nofcolumns % ok already \else % only span if there is a next column with content \dorecurse\columnmaxcells {\ifdim\ht\OTRSETgridcell\currenthcell\currentvcell>\zeropoint \centergridcellonlyfalse \else\ifdim\dp\OTRSETgridcell\currenthcell\currentvcell>\zeropoint \centergridcellonlyfalse \fi\fi}% \fi \fi \currenthcell\recurselevel \dorecurse\columnmaxcells {\currentvcell\recurselevel\relax \ifdim\ht\OTRSETgridcell\currenthcell\currentvcell>\zeropoint \ifdim\dp\OTRSETgridcell\currenthcell\currentvcell=\zeropoint \bgroup \setbox\scratchbox\OTRSETgetgridcell\currenthcell\currentvcell \getnoflines{\ht\scratchbox}% \!!counta\currentvcell \advance\!!counta -\noflines \advance\!!counta \plusone % first col always ok \!!countb\currenthcell \!!countc\currenthcell \advance\!!countc \plusone \!!donebtrue \ifcentergridcellonly \!!countc\maxdimen \fi \dostepwiserecurse\!!countc\nofcolumns\plusone {\if!!doneb \let\xrecurselevel\recurselevel \dostepwiserecurse\!!counta\currentvcell\plusone {\ifdim\ht\OTRSETgridcell\xrecurselevel\recurselevel>\zeropoint \!!donebfalse \else\ifdim\wd\OTRSETgridcell\xrecurselevel\recurselevel>\zeropoint \!!donebfalse \fi\fi}% \if!!doneb \!!countb\xrecurselevel \fi \fi}% \totalcolumnspace\OTRSETlocalwidth\currenthcell \dostepwiserecurse\!!countc\!!countb\plusone {\advance\totalcolumnspace \OTRSETlocalwidth\recurselevel \advance\totalcolumnspace \OTRSETgetparameter\c!distance\recurselevel}% \ifdim\totalcolumnspace>\wd\scratchbox \setbox\scratchbox\hbox to \totalcolumnspace{\hss\box\scratchbox\hss}% \fi \OTRSETsetgridcell\currenthcell\currentvcell\box\scratchbox \egroup \fi \fi}}% \fi} \def\OTRSETinitializecolumns% once per page {\columnspreadtrue % todo \ifcolumnspread \global\rofcolumns\getvalue{\??mc\OTRSETidentifier\c!nright}% \global\lofcolumns\getvalue{\??mc\OTRSETidentifier\c!nleft}% \global\tofcolumns\rofcolumns \relax \ifodd\realpageno\relax \global\nofcolumns\rofcolumns \else \global\advance\tofcolumns\lofcolumns \global\nofcolumns\lofcolumns \fi \else \global\nofcolumns\getvalue{\??mc\OTRSETidentifier\c!n}% \global\rofcolumns\nofcolumns \global\lofcolumns\nofcolumns \global\tofcolumns\nofcolumns \fi \OTRSETassignwidths \global\mofcolumns\plusone \columnerasegridboxes} % vanaf hier: \def\definecolumnset {\dodoubleargument\dodefinecolumnset} \def\dodefinecolumnset[#1][#2]% {\getparameters[\??mc#1] [\c!direction=\v!right, \c!balance=\v!no, \c!distance=1.5\bodyfontsize, % controleren \c!n=2, \c!nleft=\getvalue{\??mc#1\c!n}, \c!nright=\getvalue{\??mc#1\c!n}, \c!width=\v!fit, \c!lines=0, \c!start=0, #2]% \dorecurse{\getvalue{\??mc#1\c!nleft}} % todo {\dododefinecolumnset[#1][\recurselevel]}% \dorecurse{\getvalue{\??mc#1\c!nright}} % todo {\dododefinecolumnset[#1][\recurselevel]}% % redo framed settings \setupcolumnset[#1][1][\c!distance=\!!zeropoint]} \def\dododefinecolumnset[#1][#2]% {\presetlocalframed [\??mc#1#2]% \setupcolumnset [#1][#2] [\c!offset=\v!overlay, \c!frame=\v!off, \c!align=, \c!lines=0,% really needed since c!regels is now part of framed \c!width=\getvalue{\??mc#1\c!width}, \c!distance=\getvalue{\??mc#1\c!distance}]} \def\setupcolumnset {\dotripleargument\dosetupcolumnset} \def\dosetupcolumnset[#1][#2][#3]% {\ifthirdargument \def\docommand##1% {\doifelse{##1}\v!each {\dorecurse{\getvalue{\??mc#1\c!n}}{\docommand\recurselevel}} {\getparameters[\??mc#1##1][#3]}}% \processcommalist[#2]\docommand \else \getparameters[\??mc#1][#2]% \fi} \definecolumnset[\s!default][\c!n=2] % fallback \def\OTRSETgotonextpage {\vfill\eject \relax\ifnum\mofcolumns>\plusone \OTRSETgotocolumn[\v!last]% \ifnum\mofcolumns>\plusone \OTRSETgotocolumn[\v!force]% \fi \fi} \let\OTRSETgotonextpageX\OTRSETgotonextpage % will become obsolete \def\OTRSETgotocolumn {\dosingleempty\doOTRSETgotocolumn} \def\doOTRSETgotoCOLROW#1% |* {\bgroup % really needed \splitstring#1\at*\to\column\and\row \bgroup \ifx\column\empty\else\expanded{\doOTRSETgotoCOLUMN{\column}}\fi \egroup \bgroup \ifx\row \empty\else\expanded{\doOTRSETgotoROW {\row }}\fi \egroup \egroup} \def\doOTRSETgotoCOLUMN#1% {\ifnum\mofcolumns=#1\else \vfill\eject % \doejectpage\eject \doloop {\ifnum\mofcolumns=#1\relax \exitloop \else \OTRSETdummycolumn \fi}% \fi} \def\doOTRSETgotoROW#1% {\ifnum#1>1 \scratchcounter\zerocount \currenthcell\mofcolumns \currentvcell#1\advance\currentvcell \minusone \dorecurse\currentvcell {\OTRSETdoifcellelse\mofcolumns\recurselevel\donothing {\advance\scratchcounter\plusone}} \getnoflines\pagetotal \advance\scratchcounter-\noflines \ifnum\scratchcounter>\zerocount \dorecurse\scratchcounter{\line{\strut}}% \fi \fi \OTRSETsetvsize} \def\doOTRSETgotocolumn[#1]% yes|force|first|last||* {\processallactionsinset [#1] [ \v!yes=>\OTRSETdummycolumn, \v!no=>,% not supported \v!force=>\OTRSETdummycolumn, \v!first=>\expanded{\doOTRSETgotoCOLUMN{1}}, \v!last=>\expanded{\doOTRSETgotoCOLUMN{\the\nofcolumns}}, \s!default=>\OTRSETdummycolumn, \s!unknown=>\expanded{\doOTRSETgotoCOLROW{\commalistelement}}]} % to be documented and tested, not yet that robust % \def\OTRSETgotocell#1#2% % {\endgraf % \gdef\gotocellcounter{0}% % \doloop % {\ifnum\mofcolumns<#1\relax % \doglobal\increment\gotocellcounter\relax % \ifnum\gotocellcounter>#1\relax % \line{\strut}\crlf % \line{\strut}\crlf % \column % \writestatus{columnset}{quitting goto cell}% % \exitloop % \else % \column % \fi % \else % \exitloop % \fi}% % \ifnum\mofcolumns=#1\relax % \ifnum#2>1 % \scratchcounter\zerocount % \currenthcell\mofcolumns % \currentvcell#2\advance\currentvcell \minusone % \dorecurse\currentvcell % {\OTRSETdoifcellelse\mofcolumns\recurselevel\donothing % {\advance\scratchcounter\plusone}} % \getnoflines\pagetotal % \advance\scratchcounter-\noflines % \ifnum\scratchcounter>\zerocount % \dorecurse\scratchcounter{\line{\strut}}% % \fi % \fi % \fi % \OTRSETsetvsize} \def\OTRSETgotocell#1#2% obsolete: now \column[#1*#2] {\endgraf \doOTRSETgotoCOLUMN{#1}% \doOTRSETgotoROW {#2}} \def\OTRSETdummycolumn {\verticalstrut \vskip-\struttotal \vfill \eject} \newcounter\columnsetlevel \let\currentcolumnset\empty \chardef\OTRSETfinish\zerocount \def\startcolumnset {\dodoubleempty\dostartcolumnset} \def\dostartcolumnset[#1][#2]% {\increment\columnsetlevel\relax \globallet\localcolumnmaxcells\!!zerocount \global\chardef\OTRSETfinish\zerocount \resetOTRSETmarks \ifnum\columnsetlevel=\plusone \bgroup \saveinterlinespace \globallet\columnsetpage\!!plusone \def\currentcolumnset{#2}% \insidecolumnstrue % will be different flag in addition \activateotr{SET}{ONE}% andere naam, activate or so \doifelsenothing{#1} {\globallet\OTRSETlist\s!default} {\xdef\OTRSETlist{#1}}% \OTRSETstartnextpage \OTRSETassignwidths \OTRSETsethsize \else \bgroup \fi} % \setuplayout[grid=yes] \definecolumnset[example] \showgrid % \starttext % \startcolumnset[example] % \input knuth \endgraf \input knuth % \placetable{table}{\framed[width=\makeupwidth,height=4cm]{Hello}} % \input knuth \endgraf \input knuth % \stopcolumnset % \input knuth \endgraf \input knuth % \stoptext \def\OTRSETflushleftovers % new per 13/4/2006 {\OTRSETdoifcellelse{1}{1} {\bgroup \OTRSETcentergridcells \chardef\OTRSETbalancemethod\plusone \OTRSETreducegridbox \global\setbox\OTRfinalpagebox\OTRSETmakegridbox \ht\OTRfinalpagebox\textheight % signals output that there is content \OTRSETdofinaloutput \globallet\OTRSETbalht\zeropoint \egroup} {}} \def\stopcolumnset {\relax \ifnum\columnsetlevel=\plusone \endgraf % needed, else wrong vsize in one par case \global\chardef\OTRSETfinish\plusone % no, extra page \pagebreak % (test on pascal toc) \dostopcolumnset \egroup \global\notelimittrue % brrr, untested and fuzzy \setvsize \sethsize \ifvoid\OTRfinalpagebox\else % probably balanced \ifdim\ht\OTRfinalpagebox<\textheight \snaptogrid[\v!page]\hbox{\box\OTRfinalpagebox}% \else \box\OTRfinalpagebox \fi \fi \global\chardef\OTRSETfinish\zerocount \ifsomefloatwaiting \setvsize \pagebreak \setvsize \fi \OTRSETflushleftovers \else \egroup \fi \decrement\columnsetlevel\relax} \chardef\OTRSETbalancemethod\zerocount \def\dostopcolumnset {%\OTRSETdofinalflushfloats % yes/no \ifcase\OTRSETbalancemethod \OTRSETnobalance \else \OTRSETdobalance \fi} \def\OTRSETdobalance {\OTRSETnobalance} \def\localcolumnmaxcells{0} % don't loose empty 1page/1column with area (example **) % % \definecolumntextarea[title][x=1,y=4,nx=2,ny=7,state=start] % \setupcolumntextareatext[title][\vtop to 5cm{a\\b\\b\\d}] % % \starttext % \startcolumnset \dorecurse{1}{\input tufte \par} \stopcolumnset % \stoptext % better: \def\definecolumnsetarea {\definecolumntextarea} \def\setupcolumnsetarea {\setupcolumntextarea} \def\setupcolumnsetareatext{\setupcolumntextareatext} \def\OTRSETnobalance {\iflastcolumnfootnotes % testen ! optie % inhibit flush of floats ! % todo: nothing if no footnotes, else empty page \dostepwiserecurse\mofcolumns\nofcolumns\plusone {\vskip-\struttotal\verticalstrut\vfill\eject}% \else \ifnum\mofcolumns>\plusone \donetrue \else\ifdim\pagetotal>\zeropoint % too dangerous, we loose data \donetrue \else \donefalse \fi\fi \ifdone \ifnum\mofcolumns=\nofcolumns \OTRSETflushfinalfootnotes \else % probably todo \fi \vfill \eject \registerOTRSETmarks % brr, may result in empty page after nicely fit text % or if left, then lost of first column only text \ifnum\mofcolumns>\plusone \OTRSETdofinalflush \OTRSETdofinaloutput \fi \fi \fi} \def\OTRSETstartnextpage {\doifsomething\OTRSETlist {\getfromcommacommand[\OTRSETlist][1]% \global\let\OTRSETidentifier\commalistelement \doifundefined{\??mc\OTRSETidentifier\c!n} {\globallet\OTRSETidentifier\s!default}% \let\newcommalistelement\empty \doglobal\replaceincommalist\OTRSETlist1% \OTRSETrestart}} \def\OTRSETrestart % weed {\OTRSETinitializefeatures \OTRSETflushpreposttext \OTRSETinitializecolumns \OTRSETcheckinsert \OTRSETcheckgrid \OTRSETsetvsize \OTRSETsethsize % or local ? \OTRSETsetplaceholders \OTRSEThandlepreposttext \initializecolumntextareas % name ! \OTRSETcheckstartcells \OTRSETsetvsize} % \def\OTRSETcheckstartcells % {\dorecurse\nofcolumns % {\bgroup % \mofcolumns\recurselevel % \scratchcounter\currentcolumnstartcell % uses \mofcolumns, returns 1 or more % \advance\scratchcounter \minusone % \dorecurse\scratchcounter % {\OTRSETdoifcellelse\mofcolumns\recurselevel % \donothing{\OTRSETsetgridcell\mofcolumns\recurselevel\copy\placeholderboxe}}% % \egroup}} \def\OTRSETcheckstartcells {\dorecurse\nofcolumns {\bgroup \mofcolumns\recurselevel \OTRSETsetcorrectnofcells\currentcolumnstartcell \advance\scratchcounter \minusone \dorecurse\scratchcounter {\OTRSETdoifcellelse\mofcolumns\recurselevel \donothing{\OTRSETsetgridcell\mofcolumns\recurselevel\copy\placeholderboxe}}% \egroup}} % \OTRSEToutput % {\dontcomplain % new, get rid of overfull message (to be sorted out) % \OTRSETnaturalflush % %\OTRSETstartnextpage % \OTRSETdoflushfloats % actually belongs in \flushsavedfloats (but goes wrong) % \OTRSETcheckfreelines % \OTRSETchecksidefloat} \OTRSEToutput {\dontcomplain % new, get rid of overfull message (to be sorted out) \doloop {\OTRSETnaturalflush %\OTRSETstartnextpage % no \OTRSETdoflushfloats % actually belongs in \flushsavedfloats (but goes wrong) \OTRSETcheckfreelines \ifsomefreecolumncells \exitloop \else % flush page and get rid of more floats if present \fi}% \OTRSETchecksidefloat} \def\OTRSETinitializefeatures {% number of lines % new: raw \getrawnoflines\textheight\xdef\columnmaxcells{\the\noflines}% % direction \doifelsevalue{\??mc\OTRSETidentifier\c!direction}\v!right {\chardef\columndirection\zerocount} {\chardef\columndirection\plusone}% % balancing \chardef\OTRSETbalancemethod\zerocount \processaction [\getvalue{\??mc\OTRSETidentifier\c!balance}] [ \v!yes=>\chardef\OTRSETbalancemethod\plusone, \v!top=>\chardef\OTRSETbalancemethod\plustwo, \v!bottom=>\chardef\OTRSETbalancemethod\plusthree]} % keep 'm for a while % % \installoutput\OTRSETflushpreposttext % {\global\setbox\precolumnbox\vbox{\unvbox\normalpagebox}% % \ifcarryoverfootnotes \else % \global\setbox\postcolumnbox\vbox{\placebottomnotes}% % \fi} % % to be tested on 'boekinhoud' in 'pascal/demo-bbi' % % junk ! ! ! ! ! % %\installoutput\OTRSETflushpreposttext % {\global\setbox\precolumnbox\vbox % {\unvbox\normalpagebox % \strut\vskip-2\lineheight\strut}% we want a proper depth % \ifcarryoverfootnotes \else % \global\setbox\postcolumnbox\vbox{\placebottomnotes}% % \fi} % % \starttext % \definecolumnset[two][n=2] % \startcolumnset[two] \dorecurse{4}{\input tufte } \stopcolumnset % \input tufte % \startcolumnset[two] \input tufte \stopcolumnset % \stoptext % % \installoutput\OTRSETflushpreposttext % {\global\setbox\precolumnbox\vbox{\unvbox\normalpagebox}% % \dp\precolumnbox\strutdepth % \ifcarryoverfootnotes \else % \global\setbox\postcolumnbox\vbox{\placebottomnotes}% % \fi} % test: % % \setupcolumnset [test-1] [balance=yes] % \setupcolumnset [test-2] [balance=yes] % \setupcolumnsetlines[test-1][1][1] [8] % \setupcolumnsetlines[test-1][1][2][10] % \startcolumnset [test-1] \dorecurse {1}{\input tufte \par} \stopcolumnset % \startcolumnset [test-2] \dorecurse {2}{\input ward \par} \stopcolumnset \ifx\lastskipinotr\undefined \newskip\lastskipinotr \fi \installoutput\OTRSETflushpreposttext {\global\setbox\precolumnbox\vbox {\unvbox\normalpagebox \global\lastskipinotr\lastskip}% \ifdim\lastskipinotr>\zeropoint \global\setbox\precolumnbox\hbox {\lower\strutdepth\box\precolumnbox}% \fi \dp\precolumnbox\strutdepth \ifcarryoverfootnotes \else \global\setbox\postcolumnbox\vbox{\placebottomnotes}% \fi} \let\precolumnlines \!!zerocount \let\postcolumnlines\!!zerocount \def\OTRSEThandlepreposttext {\ifdim\ht\precolumnbox>\zeropoint % new \getnoflines{\ht\precolumnbox}% \edef\precolumnlines{\the\noflines}% \doOTRSETsetgridcells {\copy\placeholderboxe} \plusone\plusone\nofcolumns\noflines % normal version (single column set) % {\box\precolumnbox}% % compensated for bodyfont change {\hbox {\OTRSETsetcorrectcellht \raise\scratchdimen\box\precolumnbox}}% \else \let\precolumnlines\!!zerocount \fi \ifdim\ht\postcolumnbox>\zeropoint % new, otherwise empty bottom line \getnoflines{\ht\postcolumnbox}% \edef\postcolumnlines{\the\noflines}% \advance\columnfreecells -\noflines \advance\columnfreecells \plusone \doOTRSETsetgridcells {\copy\placeholderboxe} \plusone\columnfreecells\nofcolumns\noflines {\box\postcolumnbox}% \else \let\postcolumnlines\!!zerocount \fi} \def\OTRSETchecksidefloat {} % {\sidefloatoutput} \def\OTRSETfinalsidefloatoutput {} \def\OTRSETcheckgrid {\topskip1\topskip \ifforcecolumngrid \widowpenalty\zerocount \clubpenalty\zerocount \brokenpenalty\zerocount \fi} \def\OTRSETcheckinsert {\iflastcolumnfootnotes \ifnum\nofcolumns=\mofcolumns \OTRSETforceinserts \else \OTRSETinhibitinserts \fi \else \OTRSETforceinserts \fi} \def\OTRSETforceinserts {\enablenotes} \def\OTRSETinhibitinserts {\disablenotes} % undocumented goodie \def\definecolumnsethsize#1#2#3#4% will be improved/speed up {\bgroup \def\OTRSETidentifier{#1}% \ifcase\columnsetlevel\relax \mofcolumns\plusone \OTRSETinitializecolumns \OTRSETassignwidths \OTRSETsethsize \fi \!!counta#2\!!countb#3\docalculatecolumnsetspan \expandafter\egroup\expandafter\edef\expandafter #4\expandafter{\the\!!widtha}} % interface to footnotes \def\OTRSETassignwidths {%\scratchdimen\makeupwidth \freezetextwidth \scratchdimen\textwidth % \scratchcounter\zerocount \dorecurse\nofcolumns {\doifelsevalue{\??mc\OTRSETidentifier\recurselevel\c!width}\v!fit {\advance\scratchcounter \plusone } {\advance\scratchdimen -\getvalue{\??mc\OTRSETidentifier\recurselevel\c!width}}% \advance\scratchdimen -\getvalue{\??mc\OTRSETidentifier\recurselevel\c!distance}}% \ifcase\scratchcounter\else \divide\scratchdimen \scratchcounter \fi \setgvalue{\??mc\??mc\c!width}{0}% \dorecurse\nofcolumns {\doifelsevalue{\??mc\OTRSETidentifier\recurselevel\c!width}\v!fit {\dimen0=\scratchdimen} {\setgvalue{\??mc\??mc\c!width}{1}% \dimen0=\getvalue{\??mc\OTRSETidentifier\recurselevel\c!width}}% \setxvalue{\??mc\recurselevel\??mc\c!width}{\the\dimen0}}} \def\OTRSETlocalwidth#1% {\getvalue{\??mc\number#1\??mc\c!width}} \newbox\placeholderboxa \newbox\placeholderboxb \newbox\placeholderboxc \newbox\placeholderboxd \newbox\placeholderboxe \newbox\placeholderboxf \def\columnplaceholder#1#2% {\hbox {\localcolortrue \setbox\scratchbox\hbox to \hsize {\iftracecolumnset \incolortrue \localcolortrue \hskip-.5ex% \startcolor[columnset:#2]\vrule\!!width1ex\!!height.5ex\!!depth.5ex\stopcolor \fi \hss}% \ifcase#1\relax \ht\scratchbox\zeropoint \dp\scratchbox\zeropoint \wd\scratchbox\zeropoint \else \wd\scratchbox\hsize \ht\scratchbox\strutht \dp\scratchbox\strutdp \fi \box\scratchbox}} \definepalet [columnset] [a=cyan,b=green,c=blue,d=red,e=magenta,f=darkgray] \def\OTRSETsetplaceholders {\global\setbox\placeholderboxa\columnplaceholder0a% \global\setbox\placeholderboxb\columnplaceholder0b% \global\setbox\placeholderboxc\columnplaceholder0c% \global\setbox\placeholderboxd\columnplaceholder0d% \global\setbox\placeholderboxe\columnplaceholder0e% \global\setbox\placeholderboxf\columnplaceholder1f} \def\doOTRSETshowstatus {\llap{\incolortrue \localcolortrue \tt\tfxx \startcolor[blue](\the\vsize->\number\columnfirstcell\#\number\columnfreecells)\stopcolor \hskip\leftskip}} \def\OTRSETshowstatus {\iftracecolumnset \doOTRSETshowstatus \fi} % \appendtoks \OTRSETshowstatus \to \everypar % page contents \def\OTRSETdopagecontents#1#2% takes two args: \box \unvbox {\vbox to \textheight{\forgetall#1#2\pushproperties}} \def\OTRSETsomepagefloat {\def\floatmethod{PAGE}\OTRSETsomeslotfloat} % check \def\OTRSETsomeherefloat {\def\floatmethod{HERE}\OTRSETsomeslotfloat} % check \def\OTRSETsomeelsefloat {\def\floatmethod{HERE}\OTRSETsomeslotfloat} % check \def\OTRSETsomefixdfloat {\def\floatmethod{FIXD}\OTRSETsomeslotfloat} % check \def\OTRSETsometopfloat {\def\floatmethod{TOPS}\OTRSETsomeslotfloat} % check \def\OTRSETsomebottomfloat{\def\floatmethod{BOTS}\OTRSETsomeslotfloat} % check \def\OTRSETflushfloatbox % nog verder doorvoeren en meer info in marge {\iftestfloatbox\ruledhbox\fi{\box\floatbox}} \def\OTRSETsomeslotfloat[#1]% {\setbox\floatbox\vbox{\flushfloatbox}% \dp\floatbox\strutdp \@EA\uppercasestring\floatmethod\to\floatmethod \OTRSETstoreincolumnslot\floatmethod\floatbox \doinsertfloatinfo} % kind of new, looks much like OTRONE, but not entirely \def\OTRSETdosettopinserts {\bgroup \ifsomefloatwaiting \noffloatinserts\zerocount \let\totaltopinserted\!!zeropoint \OTRSETdodosettopinserts \ifnum\@@bknbottom=\zerocount \ifnum\@@bknlines>\zerocount \ifdim\totaltopinserted>\zeropoint\relax \dimen0\lineheight \dimen0=\@@bknlines\dimen0 \advance\dimen0 \totaltopinserted\relax \ifdim\dimen0>\textheight % \vsize %%%%%%%%% \textheight \showmessage\m!floatblocks8{\@@bknlines}% \vfilll\eject \fi \fi \fi \fi \fi \egroup} \def\OTRSETdodosettopinserts {\ifnum\noffloatinserts<\noftopfloats \dogetfloat \ifdim\topinserted=\zeropoint\relax \topofinserttrue \else \topofinsertfalse \fi \setbox\scratchbox\vbox % kan beter ! {\forgetall \iftopofinsert \ifdim\OTRSETtopoffset=\zeropoint \moveongrid[\v!top] \fi \else \betweenfloatblanko % inserts can't look back \fi \flushfloatbox \blank[\@@bkspaceafter]}% \global\advance\topinserted \ht\scratchbox\relax \ifdim\topinserted>\vsize % was \textheight\relax \OTRSETresavebox\floatbox \noffloatinserts\noftopfloats\relax \global\advance\topinserted -\ht\scratchbox \let\OTRSETdodosettopinserts\relax % to be tested \else \xdef\totaltopinserted{\the\topinserted}% \insert\topins{\forgetall\box\scratchbox}% interlineskip ? \ifsomefloatwaiting \advance\noffloatinserts \plusone \else \noffloatinserts\noftopfloats\relax \fi \dofloatflushedinfo \fi \else \ifsomefloatwaiting \showmessage\m!floatblocks6{\the\noftopfloats}% \fi \let\OTRSETdodosettopinserts\relax \fi \OTRSETdodosettopinserts} \def\OTRSETdosetbotinserts {\bgroup \ifsomefloatwaiting \noffloatinserts\zerocount \OTRSETdodosetbotinserts \fi \egroup} \def\OTRSETdodosetbotinserts {\ifnum\noffloatinserts<\nofbotfloats\relax \dogetfloat \global\advance\botinserted \ht\floatbox\relax \global\advance\botinserted \dp\floatbox\relax \global\advance\botinserted \floattopskip\relax \ifdim\botinserted<\pagegoal\relax \insert\botins {\forgetall \blank[\@@bkspacebefore]% \flushfloatbox}% \ifsomefloatwaiting \advance\noffloatinserts \plusone \else \noffloatinserts\nofbotfloats \fi \dofloatflushedinfo \else \OTRSETresavebox\floatbox \noffloatinserts\nofbotfloats\relax \fi \global\nofloatpermittedtrue % vgl topfloats s! \else \ifsomefloatwaiting \showmessage\m!floatblocks7{\the\nofbotfloats}% \fi \let\OTRSETdodosetbotinserts\relax \fi \OTRSETdodosetbotinserts} \let\OTRSETdosetbothinserts\relax \def\OTRSETdotopinsertions {\ifvoid\topins\else \ifvoid\columntopbox\mofcolumns \columnsettopbox\mofcolumns\box\topins \else \columnsettopbox\mofcolumns\vbox % temp, must be better {\forgetall \offinterlineskip \box\columntopbox\mofcolumns \box\topins} \fi \fi \global\topinserted\zeropoint\relax} % goes away \def\OTRSETdobotinsertions {\ifvoid\botins \else \columnsetbotbox\mofcolumns\box\botins % \else % \columnsetbotbox\mofcolumns\vbox % temp, must be better % {\forgetall % \offinterlineskip % \box\botins % \box\columnbotbox\mofcolumns} \fi \global\botinserted\zeropoint\relax} % goes away % set ipv text % left right 1 2 3 +1 +2 +3 \let\columnleftareas \empty \let\columnrightareas\empty % links rechts => odd, even, n, named \def\definecolumntextarea {\dotripleempty\dodefinecolumntextarea} \def\dodefinecolumntextarea[#1][#2][#3]% y=0 is mogelijke en handig ! {\ifthirdargument \doifinsetelse{#2}{\v!both,\v!fixed} {\definecolumntextarea[#1][\v!left ][\c!type=#2,#3]% \definecolumntextarea[#1][\v!right][\c!type=#2,#3]} {\doifelse{#2}\v!next {\doifoddpageelse {\definecolumntextarea[#1][\v!right][\c!type=#2,#3]} {\definecolumntextarea[#1][\v!left ][\c!type=#2,#3]}} {\presetlocalframed [\??mt#1#2]% \processaction[#2] % \doglobal voorkomt stack build up [ \v!left=>\doglobal\addtocommalist{#1}\columnleftareas, \v!right=>\doglobal\addtocommalist{#1}\columnrightareas]% \getparameters[\??mt#1#2] [\c!x=1,\c!y=1,\c!nx=1,\c!ny=1,\c!clipoffset=2\lineheight, \c!leftoffset=\zeropoint,\c!rightoffset=\zeropoint, \c!offset=\v!overlay,\c!strut=\v!no,\c!frame=\v!off, \c!type=#2,\c!page=1,\c!state=\v!stop,#3]}}% \else \definecolumntextarea[#1][\v!next][#2]% \fi} \def\setupcolumntextarea {\dotripleempty\dosetupcolumntextarea} \def\dosetupcolumntextarea[#1][#2][#3]% {\ifthirdargument \doifelse{#2}\v!both {\setupcolumntextarea[#1][\v!left ][#3]% \setupcolumntextarea[#1][\v!right][#3]} {\doifelse{#2}\v!next {\doifoddpageelse {\setupcolumntextarea[#1][\v!right][#3]} {\setupcolumntextarea[#1][\v!left][#3]}} {\getparameters[\??mt#1#2][#3]}}% \else \setupcolumntextarea[#1][\v!next][#2]% \fi} \def\docheckcolumnsetareapage#1#2% {\ifnum\getvalue{\??mt#1\c!page}>\plusone \doifelsevalue{\??mt#1\c!type}\v!fixed {\ifnum\columnsetpage=\getvalue{\??mt#1\c!page}\relax \donetrue\else\donefalse \fi} {\ifnum\columnsetpage<\getvalue{\??mt#1\c!page}\relax \donefalse\else\donetrue \fi}% \else \donetrue \fi} \def\initializecolumntextareas {\ifodd\realpageno \doinitializecolumntextareas\columnrightareas\v!right \else \doinitializecolumntextareas\columnleftareas\v!left \fi} \def\doinitializecolumntextareas#1#2% {\def\docommand##1% {\docheckcolumnsetareapage{##1#2}\plusone \ifdone \donefalse \processaction [\getvalue{\??mt##1#2\c!state}] [ \v!start=>\donetrue, \v!repeat=>\donetrue, \s!unknown=>\doperformtest\commalistelement\donetrue\donefalse]% \ifdone\dodoinitializecolumntextareas{##1}{#2}\fi \fi}% \processcommacommand[#1]\docommand} \def\dodoinitializecolumntextareas#1#2% {\doOTRSETsetgridcells {\copy\placeholderboxd} {\getvalue{\??mt#1#2\c!x }}{\getvalue{\??mt#1#2\c!y }} {\getvalue{\??mt#1#2\c!nx}}{\getvalue{\??mt#1#2\c!ny}} {\copy\placeholderboxd}} \def\placecolumntextareas {\ifodd\realpageno \doplacecolumntextareas\columnrightareas\v!right \else \doplacecolumntextareas\columnleftareas\v!left \fi} \def\doplacecolumntextareas#1#2% global ? {\bgroup \forgetall \def\docommand##1% {\docheckcolumnsetareapage{##1#2}\zerocount \ifdone \donefalse \processaction [\getvalue{\??mt##1#2\c!state}] [ \v!start=>\donetrue\doglobal\removefromcommalist{##1}#1, \v!repeat=>\donetrue, \s!unknown=>\doperformtest\commalistelement\donetrue\donefalse]% \ifdone \dodoplacecolumntextareas{##1}{#2}% \else \doglobal\removefromcommalist{##1}#1% \fi \fi}% \processcommacommand[#1]\docommand \egroup} % \page[left] % \definecolumntextarea[intro][left][x=1,y=1,nx=4,ny=20,state=start,background=introlayer] % \setupcolumntextareatext[intro][left][\setups{intro}] % \flushcolumntextareas \def\flushcolumntextareas {\initializecolumntextareas \setvsize} \def\columntextlastbackspace{\backspace} % beware, we have clipping offsets of 2\lineheight by default \def\columntextareaparameter#1% {\csname\??mt\currentcolumntestarea#1\endcsname} \def\dodoplacecolumntextareas#1#2% {\def\currentcolumntestarea{#1#2}% \!!counta\columntextareaparameter\c!x \!!countb\columntextareaparameter\c!nx \docalculatecolumnsetspan \!!heighta\columntextareaparameter\c!ny\lineheight % wrong % \ifnum\columntextareaparameter\c!y=\zerocount % \advance\!!heighta -\lineheight % \advance\!!heighta \topskip % \fi % \advance\!!heighta -\lineheight % option \ifnum\columntextareaparameter\c!y=\plusone \advance\!!heighta -\lineheight \advance\!!heighta \topskip \fi % \setbox\scratchbox\vbox {\donetrue\localframed [\??mt\currentcolumntestarea] [\c!location=,% new (*) \c!width=\!!widtha,\c!height=\!!heighta,\c!lines=] {\columntextareaparameter\empty}}% \!!counta\columntextareaparameter\c!x \!!countb\columntextareaparameter\c!y \advance\!!countb \columntextareaparameter\c!ny \advance\!!countb \minusone % new (*) \doif{\columntextareaparameter\c!location}\v!depth {\setbox\scratchbox\hbox{\lower\strutdepth\box\scratchbox}% \dp\scratchbox\zeropoint \ht\scratchbox\!!heighta}% % \setbox0\hbox {\ifcase\!!countc \copy\scratchbox % \box \else \clip [ %\c!topoffset=\columntextareaparameter\c!clipoffset,% %\c!bottomoffset=\columntextareaparameter\c!clipoffset,% %\c!leftoffset=\columntextareaparameter\c!clipoffset,% \c!offset=\columntextareaparameter\c!clipoffset,% \c!offset=\columntextareaparameter\c!clipoffset,% \c!rightoffset=\columntextareaparameter\c!rightoffset,% \c!width=\!!widthb,% \c!height=\!!heighta]% {\copy\scratchbox}% \fi}% \OTRSETsetgridcell\!!counta\!!countb\box0 \ifcase\!!countc\else \advance\!!counta \columntextareaparameter\c!nx \advance\!!counta -\!!countc \advance\!!widtha -\!!widthb \setbox0\hbox {\hskip-\namedlayoutparameter\v!odd\c!backspace \clip [ %\c!topoffset=\columntextareaparameter\c!clipoffset,% %\c!bottomoffset=\columntextareaparameter\c!clipoffset,% %\c!rightoffset=\columntextareaparameter\c!clipoffset,% \c!offset=\columntextareaparameter\c!clipoffset,% \c!offset=\columntextareaparameter\c!clipoffset,% \c!leftoffset=\columntextareaparameter\c!leftoffset,% \c!width=\!!widtha,% \c!height=\!!heighta,% \c!hoffset=\!!widthb]% {\copy\scratchbox}}% \OTRSETsetgridcell\!!counta\!!countb\box0% \fi} \def\setupcolumntextareatext {\dotripleempty\dosetupcolumntextareatext} \long\def\dosetupcolumntextareatext[#1][#2][#3]% {\ifthirdargument \doifelse{#2}\v!both {\setvalue{\??mt#1\v!left }{#3}% \setvalue{\??mt#1\v!right}{#3}} {\doifelse{#2}\v!next {\doifoddpageelse {\setvalue{\??mt#1\v!right}{#3}}% {\setvalue{\??mt#1\v!left }{#3}}}% {\setvalue{\??mt#1#2}{#3}}}% \else \setupcolumntextareatext[#1][\v!next][{#2}]% \fi} \def\docalculatecolumnsetspan {% \!!counta <= x % \!!countb <= nx % \!!widtha => total width % \!!widthb => left width % \!!countc => left cols \!!widtha\!!countb\textwidth % we assume equal widths \advance\!!countb \!!counta \advance\!!countb \minusone \ifnum\!!countb>\nofcolumns \!!countc\!!countb \advance\!!countc -\nofcolumns \!!countb\nofcolumns \else \!!countc\zerocount \fi \advance\!!counta \plusone \dostepwiserecurse\!!counta\!!countb\plusone {\advance\!!widtha\OTRSETgetparameter\c!distance\recurselevel}% \!!widthb\!!widtha \advance\!!widthb -\!!countc\textwidth \ifodd\realpageno \else % tricky, assumes that we keep there \ifcase\!!countc\else % nog niet ok voor enkel/doublesided \advance\!!widtha \namedlayoutparameter\v!even\c!backspace \advance\!!widtha \namedlayoutparameter\v!odd \c!backspace \advance\!!widthb \namedlayoutparameter\v!even\c!backspace \dorecurse\!!countc {\advance\!!widtha\OTRSETgetparameter\c!distance\recurselevel}% \fi \fi} \def\columnsetspanhsize{\textwidth} \def\setcolumnsetspanhsize#1#2% x nx / uses counta/b {\!!counta#1\!!countb#2\docalculatecolumnsetspan \edef\columnsetspanhsize{\the\!!widtha}} \def\definecolumnsetspan {\dodoubleempty\dodefinecolumnsetspan} \def\dodefinecolumnsetspan[#1][#2]% {%\ifsecondargument \defineframedtext [cs:#1] [\c!frame=\v!off, \c!before=, \c!after=, \c!offset=\v!overlay, \c!location=\v!left, \c!linecorrection=\v!off, \c!depthcorrection=\v!off, \c!n=2, \c!nlines=0, \c!indenting=, \c!indentnext=\v!yes, \c!default=HERE, \c!alternative=\v!a, #2]% %\else % \definecolumnspan[][#1]% }%\fi} \definecolumnsetspan[\s!default] \def\setupcolumnsetspan {\dodoubleempty\dosetupcolumnsetspan} \def\dosetupcolumnsetspan[#1][#2]% {\ifsecondargument \setupframedtexts[cs:#1][#2]% \else \setupcolumnsetspan[\s!default][#1]% \fi} \def\startcolumnsetspan {\dotripleempty\dostartcolumnsetspan} %%%%%%%%%%%%%%%% TODO \def\dostartcolumnsetspan[#1][#2][#3]% [#3] gobbles space {\endgraf % else rubish output if forgotten \vskip \zeropoint % make sure otr is done, otherwise last line problems \bgroup \forgetall \ifnum\columnsetlevel>\zerocount\else % of course we needed a one-column fall back for tm \columnsetspanhsize\hsize \nofcolumns\plusone \mofcolumns\plusone \fi \setupframedtexts[cs:#1] [\c!width=\columnsetspanhsize, \c!linecorrection=\v!off, \c!depthcorrection=\v!off, #2]% % determine widths \!!countc\framedtextparameter{cs:#1}\c!n % \!!countd\numexpr(\nofcolumns-\mofcolumns+\plusone)% \!!countd\nofcolumns % n <= n of columns \ifnum\!!countc>\!!countd \!!countc\!!countd \fi \advance\!!countd -\mofcolumns \advance\!!countd \plusone % n <= n of available columns (alternative a) \doif{\framedtextparameter{cs:#1}\c!alternative}\v!a {\ifnum\!!countc>\!!countd \!!countc\!!countd \fi}% % here it all starts \setcolumnsetspanhsize\mofcolumns\!!countc % a/b used \hsize\columnsetspanhsize \setbox\scratchbox\vbox\bgroup \dostartframedtext[cs:#1][\v!none]% geen nils placement % spoils spacing : \vskip-\struttotal\par\verticalstrut\par \ifnum\columnsetlevel>\zerocount \framedtextparameter{cs:#1}\c!before \fi \def\stopcolumnsetspan{\dostopcolumnsetspan{#1}}} \def\dostopcolumnsetspan#1% {\par \verticalstrut \kern-2\struttotal \verticalstrut \ifnum\columnsetlevel>\zerocount \doifsomething{\framedtextparameter{cs:#1}\c!after} {\framedtextparameter{cs:#1}\c!after \kern\zeropoint}% otherwise blanks disappear, better be a switch \else \endgraf \fi \dostopframedtext \egroup \setbox\scratchbox\frozenhbox to \hsize {\dontcomplain \alignedline{\framedtextparameter{cs:#1}\c!location}\v!middle {\lower\strutdepth\box\scratchbox}}% \dp\scratchbox\zeropoint % else wrong snap insidefloat % % to be tested first (strange in grid mode) % % \setbox\scratchbox\frozenhbox to \hsize % {\dontcomplain % \chardef\alignstrutmode\zerocount % \alignedline{\framedtextparameter{cs:#1}\c!plaats}\v!midden % {\box\scratchbox}}% % \ifinsidefloat \box\scratchbox \else\ifnum\columnsetlevel>\zerocount % we only set \columnsetspacing when asked for, else bottom problems % don't change this any more (test naw) \chardef\columnslotspacing\framedtextparameter{cs:#1}\c!nlines\relax % todo: nboven/onder & \chardef\columnslotlocation2 %\OTRSETstoreincolumnslotHERE\scratchbox \edef\floatmethod{\framedtextparameter{cs:#1}\c!default}% \@EA\uppercasestring\floatmethod\to\floatmethod % todo : \v!here -> here enzovoorts \OTRSETstoreincolumnslot\floatmethod\scratchbox % watch out: no \dochecknextindentation{tag} \checknextindentation[\framedtextparameter{cs:#1}\c!indentnext]% \else % of course we needed a one-column fall back for tm; brrr, the box has now too % much height (try \ruledvbox); don't change this without testing techniek \scratchdimen\ht\scratchbox \advance\scratchdimen-\strutdp \ht\scratchbox\scratchdimen \framedtextparameter{cs:#1}\c!before \snaptogrid\vbox{\box\scratchbox}% \framedtextparameter{cs:#1}\c!after \fi\fi \egroup \endgraf} % \startcolumnset[two] % \input tufte % \startcolumnsetspan[two][width=20cm,location=middle] \input tufte \stopcolumnsetspan % \startcolumnsetspan[two][default=btlr] \input tufte \stopcolumnsetspan % \input tufte \par % \input tufte \par % \startcolumnsetspan[two] \emptylines[5] \stopcolumnsetspan % \startcolumnsetspan[two] \input tufte \stopcolumnsetspan % \stopcolumnset \protect \endinput % extreme examples (1) % % \setupfloats[numbering=nocheck] % % \definecolumnset [first] [n=2,start=0] % \definecolumnset [next] [n=2,start=3] % % \setuptexttexts[\vbox to \textheight{\topskipcorrection \hsize\makeupwidth left \hfill right\vfill}] % % \setuphead[chapter][text=empty] % % \starttext % % \startcolumnset[first,next] % \placefigure[btrl]{}{} % \placefigure[tblr]{}{} % \chapter{thuan} \dorecurse{25}{\recurselevel: \input thuan \endgraf} % \stopcolumnset % % \startcolumnset[first,next] % \chapter{thuan} \dorecurse{25}{\input thuan \endgraf\placefigure{}{}} % \stopcolumnset \unprotect % only in columnsets % \def\cornerfigure % {\dotripleempty\docornerfigure} % % \def\docornerfigure[#1][#2][#3]% [layer] [location] [settings] % {\bgroup % \dowithnextbox % {\!!doneafalse % \!!donebfalse % \processallactionsinset % [\v!left,\v!bottom,#2] % [ \v!left=>\!!doneatrue , % \v!right=>\!!doneafalse, % \v!top=>\!!donebtrue , % \v!bottom=>\!!donebfalse]% % \!!widtha\nextboxwd % \if!!donea % % unchecked % \advance\!!widtha-\backspace % \else % % unchecked % \advance\!!widtha-\backspace % \fi % \!!widtha\textwidth % could be an option % \!!heighta\nextboxht % % zou een macro moeten zijn \getnoflayoutlines % \ifnum\layoutparameter\c!lines=\zerocount % \getnoflines\textheight % \else % \noflines\layoutparameter\c!lines % \fi % % % \advance\noflines \plusone % wordt default, instelbaar % \!!heightb\noflines\lineheight\relax % \if!!doneb % boven % % unchecked % \advance\!!heighta-\topspace % \advance\!!heighta-\headerheight % \advance\!!heighta-\headerdistance % \else % onder % % checked % \advance\!!heighta-\paperheight % \advance\!!heighta+\!!heightb % \advance\!!heighta+\topspace % \advance\!!heighta+\headerheight % \advance\!!heighta+\headerdistance % \advance\!!heighta-\footerdistance % \advance\!!heighta-\footerheight % \fi % \getnoflines\!!heighta % \!!heighta\noflines\lineheight\relax % \def\docornerfigure[####1]% % {\expanded{\plaatsfiguur[####1,\v!none]{} % {\noexpand\phantombox[\c!width=\the\!!widtha,\c!height=\the\!!heighta]}}}% % \if!!donea % \if!!doneb % links boven / rb % \setlayer[#1] % [\c!corner={\v!left,\v!top},\c!location=rb,#3] % {\flushnextbox}% % \docornerfigure[tblr]% % \else % links onder / rt % \setlayer[#1] % [\c!corner={\v!left,\v!bottom},\c!location=rt,#3] % {\flushnextbox}% % \docornerfigure[btlr]% % \fi % \else % \if!!doneb % rechts boven / lt % \setlayer[#1] % [\c!corner={\v!right,\v!top},\c!location=lb,#3] % {\flushnextbox}% % \docornerfigure[tbrl]% % \else % rechts onder / lb % \setlayer[#1] % [\c!corner={\v!right,\v!bottom},\c!location=lt,#3] % {\flushnextbox}% % \docornerfigure[btrl]% % \fi % \fi % \egroup} % \vbox}