diff options
author | Hans Hagen <pragma@wxs.nl> | 2006-04-22 10:41:00 +0200 |
---|---|---|
committer | Hans Hagen <pragma@wxs.nl> | 2006-04-22 10:41:00 +0200 |
commit | 344364dee440fb66701665e8389445755c7d00f2 (patch) | |
tree | 58681cf1fe6b2c2472f84c38aee6090338703cb1 /tex/context/base/core-pgr.tex | |
parent | 7fe03c832e11f626335835ccbe3b48149f1ccac6 (diff) | |
download | context-344364dee440fb66701665e8389445755c7d00f2.tar.gz |
stable 2006.04.22 10:41
Diffstat (limited to 'tex/context/base/core-pgr.tex')
-rw-r--r-- | tex/context/base/core-pgr.tex | 1651 |
1 files changed, 1651 insertions, 0 deletions
diff --git a/tex/context/base/core-pgr.tex b/tex/context/base/core-pgr.tex new file mode 100644 index 000000000..832135434 --- /dev/null +++ b/tex/context/base/core-pgr.tex @@ -0,0 +1,1651 @@ +%D \module +%D [ file=core-pgr, % split off core-pos +%D version=1999.08.01, +%D title=\CONTEXT\ Core Macros, +%D subtitle=Positioning Support, +%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 Positioning Grapics} + +%D Before we come to graphics support, we have to make sure of +%D the reference point on the page. The next macro does so and +%D is hooked into the page building routine. + +\unprotect + +% in the future, the depth of tail will reflect page depth + +\def\textanchor{text:\realfolio} + +\ifx\textheight\undefined \def\textheight{\vsize} \fi + +\def\placepositionanchors % todo : depth pagebox + {\ifpositioning + \setbox\scratchbox\vbox to \textheight + {\simpletopskipcorrection + \hbox{\strut\dopositionaction\headanchor}% + \vfill + \hbox{\strut\dopositionaction\tailanchor}}% + \dp\scratchbox\zeropoint + \wd\scratchbox\makeupwidth % not \zeropoint, else wrong text backgrounds + \hpos\textanchor{\box\scratchbox}% + \else + \vskip\textheight + \fi} + +%D The first version of this module implemented head and tail +%D anchors. Currently we stick to just one anchor and derive +%D the head and tail anchors from this one. + +\def\headanchor{head:\realfolio} % virtual position +\def\tailanchor{tail:\realfolio} % virtual position + +\def\presetpositionanchors% compatibility hack (still needed?) + {\ifpositioning + \dopresetpositionanchors + \fi} + +\def\dopresetpositionanchors + {\bgroup + \!!dimena\ifdim\topskip>\strutht\topskip\else\strutht\fi + \!!dimenb\MPy\textanchor + \!!dimenc\!!dimenb + \advance\!!dimenb \MPh\textanchor % space is essential + \advance\!!dimenb -\!!dimena + \advance\!!dimenc \strutdp + \!!dimend\MPx\textanchor + \!!dimene\MPw\textanchor + \setxvalue{\POSprefix\headanchor}% + {\realfolio,\withoutpt\the\!!dimend,\withoutpt\the\!!dimenb,% + \withoutpt\the\!!dimene,\withoutpt\the\!!dimena,\withoutpt\the\strutdp}% + \setxvalue{\POSprefix\tailanchor}% + {\realfolio,\withoutpt\the\!!dimend,\withoutpt\the\!!dimenc,% + \withoutpt\the\!!dimene,\withoutpt\the\strutht,\withoutpt\the\strutdp}% + %\showanchor\textanchor\showanchor\headanchor\showanchor\tailanchor\wait + \egroup} + +\def\showanchor#1% + {\expanded{\writestatus{#1} + {\MPp{#1}\string|\MPx{#1}\string|\MPy{#1}\string|% + \MPw{#1}\string|\MPh{#1}\string|\MPd{#1}}}} + +%D We set these anchors before and after each page. + +\appendtoks \presetpositionanchors \to \beforeeverypage +\appendtoks \presetpositionanchors \to \aftereverypage + +%D \macros +%D {positionoverlay,startpositionoverlay} +%D +%D As long as we're dealing with graphics it makes much sense +%D to use the available overlay mechanism. For this purpose, we +%D define some dedicated overlay extensions. +%D +%D \startbuffer[sample] +%D \defineoverlay [sample] [\positionoverlay{sample}] +%D +%D \startpositionoverlay{sample} +%D \setMPpositiongraphic{A-1}{connectcenter}{from=A-1,to=A-2} +%D \stoppositionoverlay +%D \stopbuffer +%D +%D \typebuffer[sample] +%D +%D \startbuffer[graphic] +%D \startMPpositiongraphic{connectcenter} +%D path pa, pb ; pair ca, cb ; +%D initialize_box(\MPpos{\MPvar{from}}) ; pa := pxy ; ca := cxy ; +%D initialize_box(\MPpos{\MPvar{to}}) ; pb := pxy ; cb := cxy ; +%D draw pa withcolor red ; +%D draw pb withcolor red ; +%D draw ca -- cb withcolor blue ; +%D anchor_box(\MPanchor{\MPvar{from}}) ; +%D \stopMPpositiongraphic +%D \stopbuffer +%D +%D We can best demonstrate this in an example, say: +%D +%D \startbuffer[text] +%D \framed +%D [backgroundachtergrond=sample,align=middle,width=7cm] +%D {We want to connect \hpos {A-1} {this} word with its +%D grammatical cousin \hpos {A-2} {that}.} +%D \stopbuffer +%D +%D \typebuffer[text] +%D +%D \startlinecorrection +%D %\getbuffer[graphic,sample,text] +%D \stoplinecorrection +%D +%D The graphic is defined in the following way, using some +%D macros defined in an auxiliary \METAPOST\ module that is +%D preloaded. +%D +%D \typebuffer[graphic] + +\def\MPanchoridentifier{mpa} % {mp-anchor} +\def\MPoverlayposprefix{MO::} + +% obsolete and wrong anyway +% +% \long\def\defineMPpositiongraphic#1% +% {\long\setvalue{\MPoverlayposprefix#1}} + +%D The rest of the definitions concerning such overlays may +%D look complicated, + +\let\currentpositionoverlay\empty + +%D Position actions are automatically executed when a position +%D is set. + +\let\MPanchornumber\realfolio + +\def\positionoverlay#1% the test prevents too many redundant positions + {\ifpositioning % in (not used) text* position layers + \vbox to \overlayheight + {\doifpositionactionelse{#1::\MPanchoridentifier}% + {\edef\MPanchorid{#1::\MPanchoridentifier:\MPanchornumber}% + \edef\MPanchor##1{\MPpos{\MPanchorid}}% + \the\everyinsertpositionaction + \copyposition{#1::\MPanchoridentifier}{#1::\MPanchoridentifier:\MPanchornumber}% + \hpos + {#1::\MPanchoridentifier:\MPanchornumber}% + % this is ok + %{\hbox to \overlaywidth{\dopositionaction{#1::\MPanchoridentifier}\hss}}}% + % but this one prevents cyclic runs due to + % rounding errors + {\setbox\scratchbox\hbox to \overlaywidth + {\dopositionaction{#1::\MPanchoridentifier}\hss}% + \ht\scratchbox\overlayheight + \dp\scratchbox\zeropoint + \box\scratchbox}}% + {\hbox to \overlaywidth{\hss}}% + \vfill}% + \fi} + +\def\startpositionoverlay#1% + {\iftrialtypesetting % we don't want redundant entries in the list + \@EA\gobbleuntil\@EA\stoppositionoverlay + \else + \def\currentpositionoverlay{#1}% + \fi} + +\def\stoppositionoverlay + {\let\currentpositionoverlay\empty} + +\def\resetpositionoverlay#1% + {\dosetpositionaction{#1::\MPanchoridentifier::}{}} + +%D Here the complication has to do with collecting actions +%D for later execution. This collection is especially handy +%D when we want to move actions to a specific layer. +%D Such series of actions are stored in a macro (the one +%D with the funny \type {++}) which is cleaned up after each +%D invocation. + +\newtoks\everycleanpositionaction +\newtoks\everyinsertpositionaction + +\def\cleanuppositionaction#1% not in trialtypesetting + {\ifundefined{\POSactionprefix#1++}\else + \the\everycleanpositionaction + \iflocalpositioning + \letgvalue{\POSactionprefix#1++}\empty + \else + \setxvalue{\POSactionprefix#1++}{\getvalue{\POSactionprefix#1++}}% + \fi + \fi} + +\def\handlepositionaction#1\with#2\on#3% + {\bgroup + \ifx\currentpositionoverlay\empty + \edef\!!stringa{#3}% no layer, just pos itself as anchor + \else + \edef\!!stringa{\currentpositionoverlay::\MPanchoridentifier}% + \fi + \edef\!!stringc{\POSactionprefix\!!stringa++}% + \expanded{\dosetpositionaction{\!!stringa}{\noexpand\getvalue{\!!stringc}}}% + \global\let#1\relax + \edef\!!stringb{\executeifdefined\!!stringc\empty}% + \setxvalue\!!stringc{\!!stringb#1#2}% + \egroup} + +%D The indirectness enables us redefine macros for special +%D purposes, like a cleanup. + +\def\handlepositionboxes#1#2#3% + {\handlepositionaction\dohandlepositionboxes\with{#1}{#2}{#3}\on{#2}} + +\def\doinsertpositionboxes#1#2#3% pos tag setups + {\ifnum\MPp{#1}=\realpageno\relax + % \doifdefined{\MPoverlayposprefix#1} + % {\getvalue{\MPoverlayposprefix#1}{#1}{#2}{#3}}% + \executeifdefined{\MPoverlayposprefix#1}% + \gobblethreearguments{#1}{#2}{#3}% + \fi} + +\appendtoks + \let\dohandlepositionboxes\doinsertpositionboxes % was handle ? +\to \everyinsertpositionaction + +\def\docleanpositionboxes#1#2#3% pos tag setups + {\ifnum\MPp{#1}<\realpageno \else + \noexpand \dohandlepositionboxes{#1}{#2}{#3}% reinsert + \fi} + +\appendtoks + \let\dohandlepositionboxes\docleanpositionboxes +\to \everycleanpositionaction + +%D A position graphic is a normal (non||reused) \METAPOST\ +%D graphic, used immediately, with zero dimensions, so that a +%D sequence of them does not harm. + +\newbox\positiongraphicbox + +\def\startMPpositiongraphic % id setups + {\dodoublegroupempty\dostartMPpositiongraphic} + +\long\def\dostartMPpositiongraphic#1#2#3\stopMPpositiongraphic + {\long\setgvalue{MPG:#1}% tag list mpcode + {\useMPpositiongraphic{#1}{#2}{#3}}} + +\def\prepareMPpositionvariables + {\ifundefined{\@@meta self}\setvalue{\@@meta self}{\currentposition}\fi + \ifundefined{\@@meta from}\setvalue{\@@meta from}{\currentposition}\fi} + +\newif\ifcollectMPpositiongraphics \collectMPpositiongraphicstrue + +\long\def\useMPpositiongraphic#1#2#3% + {\bgroup + \prepareMPvariables{#2}% + \prepareMPpositionvariables + \enableincludeMPgraphics + \ifcollectMPpositiongraphics + \expanded{\startMPdrawing#3\noexpand\stopMPdrawing}% + \global\MPdrawingdonetrue + \else + \startMPgraphic#3\stopMPgraphic + \loadMPgraphic{\MPgraphicfile.\the\currentMPgraphic}{}% + \deallocateMPslot\currentMPgraphic + \placeMPgraphic + \fi + \egroup} + +% Now we need a adapted action handler: + +\def\dopositionaction#1% test saves hash entry in etex + {\ifundefined{\POSactionprefix#1::}\else + \ifnum\MPp{#1}>\zerocount % new + \bgroup + \setbox\scratchbox\hbox + \bgroup + \traceposstring\clap\red{<#1>}% + \the\everyinsertpositionaction + \the\everypositionaction + \ifcollectMPpositiongraphics + % can save a lot of run time + \pushMPdrawing + \MPshiftdrawingtrue + \resetMPdrawing + \getvalue{\POSactionprefix#1::}% + \ifMPdrawingdone + \getMPdrawing + \fi + \resetMPdrawing + \popMPdrawing + \else + \getvalue{\POSactionprefix#1::}% + \fi + \cleanuppositionaction{#1}% + \egroup % smashed is really needed else + \smashedbox\scratchbox % we get problems with too big + \egroup % overlays (s-pre-0x.tex) + \else + % shouldn't happen too often + \traceposstring\clap\cyan{<#1>}% + \fi + \fi} + +\def\MPpositiongraphic + {\dodoublegroupempty\doMPpositiongraphic} + +\def\doMPpositiongraphic#1#2% tag setups + {\bgroup + \def\@@meta{#1:}% + \setupMPvariables[#2]% + \prepareMPpositionvariables + \MPshiftdrawingtrue + \def\doMPpositiongraphic##1##2% + {{% new, see (techniek) + \def\@@meta{##1:}% + \setupMPvariables[#2,##2]% + \prepareMPpositionvariables + % and needed + \getvalue{MPG:##1}}}% temp hack + \setbox\positiongraphicbox\hbox + {\ignorespaces + \executeifdefined{MPM:#1}{\executeifdefined{MPG:#1}\donothing}% + \removelastspace}% + \smashbox\positiongraphicbox + \box\positiongraphicbox + \egroup} + +\long\def\startMPpositionmethod#1#2\stopMPpositionmethod + {\long\setgvalue{MPM:#1}{#2}} % todo: var list here + +%D Simple one position graphics. + +\def\setMPpositiongraphic + {\dotriplegroupempty\dosetMPpositiongraphic} + +\def\dosetMPpositiongraphic#1#2#3% pos tag vars + {\ifx\currentpositionoverlay\empty + \dosetpositionaction{#1}{\MPpositiongraphic{#2}{#3}}% + \else % silly can be one + \handlepositiongraphics{#1}{#2}{#3}% + \fi} + +\def\handlepositiongraphics#1#2#3% combine with boxes + {\handlepositionaction\dohandleMPpositiongraphic\with{#1}{#2}{#3}\on{#2}} + +\def\doinsertMPpositiongraphic#1#2#3% pos tag setups + {\ifnum\MPp{#1}=\realpageno\relax % extra saveguard + \def\currentposition{#1}\MPpositiongraphic{#2}{#3}% + \fi} + +\appendtoks + \let\dohandleMPpositiongraphic\doinsertMPpositiongraphic +\to \everyinsertpositionaction + +\def\docleanMPpositiongraphic#1#2#3% pos tag setups + {\ifnum\MPp{#1}<\realpageno \else + \noexpand \dohandleMPpositiongraphic{#1}{#2}{#3}% + \fi} + +\appendtoks + \let\dohandleMPpositiongraphic\docleanMPpositiongraphic +\to \everycleanpositionaction + +%D Graphics that span two positions. + +\def\setMPpositiongraphicrange + {\doquadruplegroupempty\dosetMPpositiongraphicrange} + +\def\dosetMPpositiongraphicrange#1#2#3#4% bpos epos tag vars + {\ifx\currentpositionoverlay\empty + \dosetpositionaction{#1}{\MPpositiongraphic{#3}{#4}}% + \else + \handlepositiongraphicsrange{#1}{#2}{#3}{#4}% + \fi} + +\def\handlepositiongraphicsrange#1#2#3#4% + {\handlepositionaction\dohandleMPpositiongraphicrange\with{#1}{#2}{#3}{#4}\on{#2}} + +\def\doinsertMPpositiongraphicrange#1#2#3#4% pos pos tag setups + {\ifnum\MPp{#1}\MPp{#2}>\zerocount + \iflocalpositioning + \donetrue + \else + \donefalse + \ifnum\MPp{#1}=\realpageno + \donetrue + \else\ifnum\MPp{#2}=\realpageno + \donetrue + \else\ifnum\MPp{#1}<\realpageno\relax\ifnum\MPp{#2}>\realpageno + \donetrue + \fi\fi\fi\fi + \fi + \ifdone + \def\currentposition{#1}\MPpositiongraphic{#3}{#4}% + \fi + \fi} + +\appendtoks + \let\dohandleMPpositiongraphicrange\doinsertMPpositiongraphicrange +\to \everyinsertpositionaction + +\def\docleanMPpositiongraphicrange#1#2#3#4% pos tag setups + {\ifnum\MPp{#2}<\realpageno \else + \noexpand \dohandleMPpositiongraphicrange{#1}{#2}{#3}{#4}% + \fi} + +\appendtoks + \let\dohandleMPpositiongraphicrange\docleanMPpositiongraphicrange +\to \everycleanpositionaction + +% will be overloaded, and/or code below moved to core-box + +\defineoverlay[\v!text-2][\positionoverlay{\v!text-2}] +\defineoverlay[\v!text-1][\positionoverlay{\v!text-1}] +\defineoverlay[\v!text+1][\positionoverlay{\v!text+1}] +\defineoverlay[\v!text+2][\positionoverlay{\v!text+2}] + +%D The auxiliary \METAPOST\ macros are defined by default, +%D by saying: + +\appendtoks + if unknown context_core : input mp-core.mp ; fi ; +\to \MPextensions + +%D Some of these macros are pretty clever but too complicated +%D to be nice. When things are kind of stable I'll clean up +%D this mess. + +%D THIS NEEDS A CLEANUP + +\setupMPvariables + [mpos:box] + [linecolor=blue, + linewidth=\linewidth, + fillcolor=lightgray, + filloffset=\!!zeropoint] + +\startMPpositiongraphic{mpos:box}{fillcolor,linecolor,linewidth} + initialize_box(\MPpos{\MPvar{self}}) ; + boxfillcolor := \MPvar{fillcolor} ; + boxlinecolor := \MPvar{linecolor} ; + boxlinewidth := \MPvar{linewidth} ; + boxfilloffset := \MPvar{filloffset} ; + draw_box ; + anchor_box(\MPanchor{\MPvar{self}}) ; +\stopMPpositiongraphic + +\setupMPvariables + [mpos:area] + [linecolor=blue, + linewidth=\linewidth, + fillcolor=lightgray, + filloffset=\!!zeropoint] + +\startMPpositiongraphic{mpos:area}{fillcolor,linecolor,linewidth} + initialize_area(\MPpos{b:\MPvar{self}},\MPpos{e:\MPvar{self}}) ; + boxfillcolor := \MPvar{fillcolor} ; + boxlinecolor := \MPvar{linecolor} ; + boxlinewidth := \MPvar{linewidth} ; + boxfilloffset := \MPvar{filloffset} ; + draw_area ; + anchor_area(\MPanchor{b:\MPvar{self}}) ; +\stopMPpositiongraphic + +%D This is already cleaned up. + +% gridtype = 1 => baseline +% gridtype = 2 => betweenline + +\setupMPvariables + [mpos:par] + [mp=mpos:par:shape, + gridtype=0, + linetype=1, + filltype=1, + %snaptops=true, % not that nice: true/false + gridcolor=red, + linecolor=blue, + fillcolor=lightgray, + filloffset=\!!zeropoint, + linewidth=\linewidth, + gridwidth=\linewidth, + lineradius=.5\bodyfontsize] + +\startuseMPgraphic{mpos:par:shape} + \iftracepositions show_par \else draw_par \fi ; +\stopuseMPgraphic + +\startuseMPgraphic{mpos:par:setup} + boxgridtype := \MPvar{gridtype} ; + boxlinetype := \MPvar{linetype} ; + boxfilltype := \MPvar{filltype} ; + boxgridcolor := \MPvar{gridcolor} ; + boxlinecolor := \MPvar{linecolor} ; + boxfillcolor := \MPvar{fillcolor} ; + boxfilloffset := \MPvar{filloffset} ; + boxlinewidth := \MPvar{linewidth} ; + boxgridwidth := \MPvar{gridwidth} ; + boxlineradius := \MPvar{lineradius} ; + %snap_multi_par_tops := \MPvar{snaptops} ; +\stopuseMPgraphic + +\startuseMPgraphic{mpos:par:extra} + % user stuff, like: + % snap_multi_par_tops := false ; +\stopuseMPgraphic + +% \startMPpositionmethod{mpos:par} +% \doifpositionelse{w:\MPvar{self}} +% {\startMPpositiongraphic{mpos:par}% +% {fillcolor,filloffset,linecolor,gridcolor,linewidth,gridwidth,lineradius} +% initialize_area_par(\MPpos{b:\MPvar{self}}, +% \MPpos{e:\MPvar{self}}, +% \MPpos{w:\MPvar{self}}) ; +% \includeMPgraphic{mpos:par:setup} ; +% \includeMPgraphic{mpos:par:extra} ; +% \includeMPgraphic{\MPvar{mp}} ; % \includeMPgraphic{mpos:par:shape} ; +% anchor_par(\MPanchor{b:\MPvar{self}}) ; +% \stopMPpositiongraphic} +% {\startMPpositiongraphic{mpos:par}% +% {fillcolor,filloffset,linecolor,gridcolor,linewidth,gridwidth,lineradius} +% initialize_par(\MPpos{b:\MPvar{self}}, +% \MPpos{e:\MPvar{self}}, +% \MPpos{text:\realfolio}, +% \MPpos{p:\MPparcounter}, +% \MPvv {p:\MPparcounter}{0,0,0,0,0,0}) ; +% \includeMPgraphic{mpos:par:setup} ; +% \includeMPgraphic{mpos:par:extra} ; +% \includeMPgraphic{\MPvar{mp}} ; % \includeMPgraphic{mpos:par:shape} ; +% anchor_par(\MPanchor{b:\MPvar{self}}) ; +% \stopMPpositiongraphic}% +% \MPpositiongraphic{mpos:par}{}% +% \stopMPpositionmethod + +%D Less readable but shorter. + +\ifx\MPparcounter\undefined \newcounter\MPparcounter \fi + +\def\MPself {\MPvar{self}} +\def\MPbself {b:\MPself} +\def\MPeself {e:\MPself} +\def\MPwself {w:\MPself} +\def\MPparanchor{p:\MPparcounter} + +\def\MPl#1{\MPplus{#1}20} +\def\MPr#1{\MPplus{#1}30} + +\startMPpositionmethod{mpos:par} %%%%%%%%%%% will become obsolete + \edef\MPparcounter{\MPv\MPbself{1}{0}}% + \doifpositionelse\MPwself + {\startMPpositiongraphic{mpos:par}% + {fillcolor,filloffset,linecolor,gridcolor,linewidth,gridwidth,lineradius} + initialize_area_par(\MPpos\MPbself, + \MPpos\MPeself, + \MPpos\MPwself) ; + \includeMPgraphic{mpos:par:setup} ; + \includeMPgraphic{mpos:par:extra} ; + \includeMPgraphic{\MPvar{mp}} ; + anchor_par(\MPanchor\MPbself) ; + \stopMPpositiongraphic} + {\startMPpositiongraphic{mpos:par}% + {fillcolor,filloffset,linecolor,gridcolor,linewidth,gridwidth,lineradius} + initialize_par(\MPpos\MPbself, + \MPpos\MPeself, + \MPpos\textanchor, + \MPpos\MPparanchor, + \MPvv \MPparanchor{0,0,0,0,0,0}) ; + \includeMPgraphic{mpos:par:setup} ; + \includeMPgraphic{mpos:par:extra} ; + \includeMPgraphic{\MPvar{mp}} ; + anchor_par(\MPanchor\MPbself) ; + \stopMPpositiongraphic}% + \MPpositiongraphic{mpos:par}{}% +\stopMPpositionmethod + +%D The next alternative works in columnsets : + +% \iftracepositions show\else draw\fi_multi_pars ; + +\startuseMPgraphic{mpos:par:columnset} + \iftracepositions show_multi_pars \else draw_multi_pars \fi ; +\stopuseMPgraphic + +\startMPpositionmethod{mpos:par:columnset} + \edef\MPparcounter{\MPv\MPbself{1}{0}}% + \startMPpositiongraphic{mpos:par}% + {fillcolor,filloffset,linecolor,gridcolor,% + linewidth,gridwidth,lineradius} + \includeMPgraphic{mpos:par:setup} ; + \includeMPgraphic{mpos:par:extra} ; + prepare_multi_pars(\MPpos\MPbself,\MPpos\MPeself,\MPpos\MPwself, + \MPpos\MPparanchor,\MPvv\MPparanchor{0,0,0,0,0,0}) ; + relocate_multipars(-\MPxy\MPanchorid) ; % inside layerpos + \includeMPgraphic{\MPvar{mp}} ; + \stopMPpositiongraphic + \MPpositiongraphic{mpos:par}{}% +\stopMPpositionmethod + +%D \starttyping +%D \setupbackground +%D [test] +%D [mp=mpos:par:columnset, +%D methodmethode=mpos:par:columnset] +%D \stoptyping + +%D We need to treat floats in a special way. + +\appendtoks + local_multi_par_area:=\iflocalpositioning true\else false\fi; +\to \MPinitializations + +\def\textbackgroundoverlay#1% + {\iflocalpositioning\v!local\else\v!text\fi#1} + +\newcounter\localpositionnumber + +\def\MPanchornumber + {\iflocalpositioning\localpositionnumber\else\realfolio\fi} + +%D So far for the trickery. + +\newcounter\textbackgrounddepth + +\appendtoks + \savecurrentvalue\totalnofparbackgrounds\nofparbackgrounds +\to \everybye + +\appendtoks + \initializeparbackgrounds +\to \everystarttext + +\ifx\totalnofparbackgrounds\undefined \newcounter\totalnofparbackgrounds \fi +\ifx\nofparbackgrounds \undefined \newcounter\nofparbackgrounds \fi + +\def\initializeparbackgrounds + {\ifcase\totalnofparbackgrounds\else + \global\positioningtrue + \global\positioningpartrue + \fi} + +\unexpanded\def\starttextbackground + {\bgroup + \increment\textbackgrounddepth + \dodoubleempty\dostarttextbackground} + +\let\dodostarttextbackground\relax +\let\dodostoptextbackground \relax + +\def\currentparbackground{pbg:0} +\def\nextparbackground {pbg:1} + +\def\btbanchor{b:\currentparbackground} +\def\etbanchor{e:\currentparbackground} + +\def\nextbtbanchor{b:\nextparbackground} +\def\nextetbanchor{e:\nextparbackground} + +\def\backgroundvariable#1% + {\csname\??td\currenttextbackground#1\endcsname} + +% \definetextbackground[more][state=start,backgroundcolor=red] % location=paragraph +% \definetextbackground[test][state=start,backgroundcolor=green] +% +% \page \placefigure[left]{}{} +% +% \starttextbackground[test] +% \readfile{ward}{}{} +% \starttextbackground[more] +% \readfile{ward}{}{} +% \stoptextbackground +% \readfile{ward}{}{} +% \stoptextbackground +% +% \page \placefigure[right]{}{} +% +% \starttextbackground[test] +% \readfile{ward}{}{} +% \starttextbackground[more] +% \readfile{ward}{}{} +% \stoptextbackground +% \readfile{ward}{}{} +% \stoptextbackground + +\def\dostarttextbackground[#1][#2]% + {\checktextbackgrounds + \def\currenttextbackground{#1}% + \doglobal\increment\nofparbackgrounds + %\edef\currentparbackground{background:\nofparbackgrounds}% + \edef\currentparbackground{pbg:\nofparbackgrounds}% + \bgroup + \increment\nofparbackgrounds + %\xdef\nextparbackground{background:\nofparbackgrounds}% + \xdef\nextparbackground{pbg:\nofparbackgrounds}% + \egroup + % todo : \synchonizepositionpage{b:\currentparbackground}{s:\currentparbackground}% + \setuptextbackground[#1][#2]% + \let\dodostarttextbackground\relax + \let\dodostoptextbackground \relax + \doifvalue{\??td#1\c!state}\v!start + {\dopresettextbackground{#1}}% + \dodostarttextbackground} + +% todo \backgroundvariable\c!variant + +\def\dopresettextbackground#1% todo: \backgroundparameter + {\ExpandFirstAfter\processaction % \EFA niet echt nodig + [\getvalue{\??td#1\c!location}] + [ \v!text=>\let\dodostarttextbackground\dostarttextbackgroundtxt + \let\dodostoptextbackground \dostoptextbackgroundtxt, + \v!paragraph=>\let\dodostarttextbackground\dostarttextbackgroundpar + \let\dodostoptextbackground \dostoptextbackgroundpar, + \v!none=>\let\dodostarttextbackground\relax + \let\dodostoptextbackground \relax]% + \ifx\dodostarttextbackground\dostarttextbackgroundpar % untested + \ifnum\textbackgrounddepth>\plusone % new + \let\dodostarttextbackground\dostarttextbackgroundtxt + \let\dodostoptextbackground \dostoptextbackgroundtxt + \fi + \fi + \doifelsevalue{\??td#1\c!frame}\v!on + {\doifelsevalue{\??td#1\c!corner}\v!round + {\setvalue{\??td#1\c!frame}{2}} + {\setvalue{\??td#1\c!frame}{1}}} + {\setvalue{\??td#1\c!frame}{0}}% + \doifelsevalue{\??td#1\c!background}\v!color + {\setvalue{\??td#1\c!background}{1}} + {\setvalue{\??td#1\c!background}{0}}% + %\startpositionoverlay{\v!text\getvalue{\??td#1\c!level}}% + \startpositionoverlay{\textbackgroundoverlay{\getvalue{\??td#1\c!level}}}% + \expanded + {\setMPpositiongraphicrange % moet veel efficienter + {\btbanchor}% {b:\currentparbackground}% + {\etbanchor}% {e:\currentparbackground}% + {\getvalue{\??td#1\c!method}}% + {self=\currentparbackground, + mp=\getvalue{\??td#1\c!mp}, + gridtype=\getvalue{\??td#1\c!alternative}, + filltype=\getvalue{\??td#1\c!background}, + linetype=\getvalue{\??td#1\c!frame}, + gridcolor=\getvalue{\??td#1\c!framecolor}, + linecolor=\getvalue{\??td#1\c!framecolor}, + fillcolor=\getvalue{\??td#1\c!backgroundcolor}, + filloffset=\getvalue{\??td#1\c!backgroundoffset}, + gridwidth=\getvalue{\??td#1\c!rulethickness}, + linewidth=\getvalue{\??td#1\c!rulethickness}, + lineradius=\getvalue{\??td#1\c!radius}}}% + \stoppositionoverlay} + +\def\stoptextbackground + {\dodostoptextbackground + \carryoverpar\egroup} + +\def\starttextbackgroundmanual + {\dostartattributes{\??td\currenttextbackground}\c!style\c!color\empty + \fpos\currentparbackground\ignorespaces} + +\def\stoptextbackgroundmanual + {\tpos\currentparbackground + \dostopattributes} + +\def\dostarttextbackgroundtxt + {\ifvmode \leavevmode \fi + \dostartattributes{\??td\currenttextbackground}\c!style\c!color\empty + \fpos\currentparbackground\ignorespaces} + +\def\dostoptextbackgroundtxt + {\tpos\currentparbackground + \dostopattributes} + +% keep this simple one, it's used in prikkels and alike +% +% \def\dostarttextbackgroundpar +% {\endgraf % new +% \getvalue{\??td\currenttextbackground\c!before}% +% \noindent\fpos\currentparbackground\ignorespaces +% \bgroup +% \nobreak \vskip-\lineheight \nobreak +% \doassignsomeskip\getvalue{\??td\currenttextbackground\c!topoffset}\to\scratchskip +% \kern\scratchskip\nobreak +% \dosetleftskipadaption{\getvalue{\??td\currenttextbackground\c!leftoffset}}% +% \advance\leftskip\leftskipadaption +% \dosetleftskipadaption{\getvalue{\??td\currenttextbackground\c!rightoffset}}% +% \advance\rightskip\leftskipadaption +% \dostartattributes{\??td\currenttextbackground}\c!style\c!color{}% +% \nowhitespace +% \seteffectivehsize +% \par} +% +% \def\dostoptextbackgroundpar +% {\par +% \dostopattributes +% \doassignsomeskip\getvalue{\??td\currenttextbackground\c!bottomoffset}\to\scratchskip +% \kern\scratchskip\nobreak +% \nobreak \vskip-\lineheight \nobreak +% \nowhitespace +% \egroup +% \nobreak \noindent \strut \hfill \kern\zeropoint \tpos\currentparbackground +% \endgraf % new +% \getvalue{\??td\currenttextbackground\c!after}} + +\def\dostarttextbackgroundpar + {\endgraf % new + \getvalue{\??td\currenttextbackground\c!before}% + \doassignsomeskip\getvalue{\??td\currenttextbackground\c!topoffset}\to\scratchskip + \xdef\textbackgroundskip{\the\scratchskip}% + \noindent + \ifgridsnapping + \ifdim\textbackgroundskip>\zeropoint + \struttedbox{\hbox{\raise\textbackgroundskip\hbox{\fpos\currentparbackground}}}% + \else + \fpos\currentparbackground + \fi + \else + \fpos\currentparbackground + \fi + \bgroup + \endgraf % we need a vertical nobreak - 29/06/2004 + \nobreak \vskip-\lineheight \nobreak + \doassignsomeskip\getvalue{\??td\currenttextbackground\c!topoffset}\to\scratchskip + \ifgridsnapping \else \ifdim\textbackgroundskip>\zeropoint + \kern\textbackgroundskip\nobreak + \fi \fi + \dosetleftskipadaption{\getvalue{\??td\currenttextbackground\c!leftoffset}}% + \advance\leftskip\leftskipadaption + \dosetleftskipadaption{\getvalue{\??td\currenttextbackground\c!rightoffset}}% + \advance\rightskip\leftskipadaption + % new + \dosetraggedcommand{\getvalue{\??td\currenttextbackground\c!align}}% + \raggedcommand + % + \dostartattributes{\??td\currenttextbackground}\c!style\c!color\empty + \nowhitespace + \seteffectivehsize + \doinhibitblank % \blank[\v!disable]% new + \par} + +\def\dostoptextbackgroundpar + {\par + \removelastskip % new + \dostopattributes + \doassignsomeskip\getvalue{\??td\currenttextbackground\c!bottomoffset}\to\scratchskip + \ifdim\lastskip>\zeropoint + \advance\scratchskip-\lastskip + \fi + \xdef\textbackgroundskip{\the\scratchskip}% + \ifgridsnapping \else \ifdim\textbackgroundskip>\zeropoint + \kern\scratchskip\nobreak + \fi \fi + \nobreak \vskip-\lineheight \nobreak + \nowhitespace + \egroup +\bgroup \forgeteverypar % NOT REALLY NEEDED, SAVES HASH/MEM + \nobreak \noindent \strut \hfill \kern\zeropoint + \ifgridsnapping % experimental, pascal (todo: topoffset in same way) + \ifdim\textbackgroundskip>\zeropoint + \struttedbox{\hbox{\lower\textbackgroundskip\hbox{\tpos\currentparbackground}}}% + \else + \tpos\currentparbackground + \fi + \else + \tpos\currentparbackground + \fi +\egroup + \endgraf % new + \getvalue{\??td\currenttextbackground\c!after}} + +\let\textparpages \!!zeropoint +\let\textparheight\!!zeropoint +\let\textparwidth \!!zeropoint + +\def\calculatetextpardimensions + {\docalculatetextpardimensions\btbanchor \etbanchor \MPparanchor} + +\def\calculatenexttextpardimensions + {\docalculatetextpardimensions\nextbtbanchor\nextetbanchor\relax} + +\def\docalculatetextpardimensions#1#2#3% + {\scratchcounter\MPp#2%\etbanchor + \advance\scratchcounter-\MPp#1%\btanchor + \edef\textparpages{\the\scratchcounter}% + \ifcase\scratchcounter + % one page + \scratchdimen \MPy#1%\btanchor + \advance\scratchdimen-\MPy#2%\etbanchor + \else + % two or more pages + \scratchdimen \MPy#1%\btanchor + \advance\scratchdimen-\MPy#2%\etbanchor + \advance\scratchdimen-\MPy\textanchor + \advance\scratchdimen \MPy\textanchor + \advance\scratchdimen \MPh\textanchor\relax + \ifcase\scratchcounter>2 \ifnum\scratchcounter<5 + % more pages + \scratchdimen\textheight + \advance\scratchcounter \minusone + \multiply\scratchdimen \scratchcounter + \else + % keep'm small + \scratchdimen5\textheight + \fi \fi + \fi + \edef\textparheight{\the\scratchdimen}% + \ifcase\scratchcounter + % one page + \scratchdimen \MPx#2%\etbanchor + \advance\scratchdimen-\MPx#1%\btanchor + \else + % two or more pages / maybe also hang + \ifx#3\relax + \scratchdimen\makeupwidth % \textwidth + \else + \scratchdimen\MPw\MPparanchor + \advance\scratchdimen-\MPl\MPparanchor + \advance\scratchdimen-\MPr\MPparanchor + \fi + \fi + \edef\textparwidth{\the\scratchdimen}} + +\def\mintextparheight{4\lineheight} + +\def\dontsplitnexttextbackground % dangerous but useful + {\ifdim\pagetotal>\textheight \else + \ifdim\pagegoal=\maxdimen \else + \calculatenexttextpardimensions + % too tricky + % \scratchdimen=\textparheight + % \advance\scratchdimen\pagetotal\relax + % \ifdim\scratchdimen>\pagegoal + % \page + % \fi + \ifdim\textparheight>\zeropoint + \ifdim\textparheight>\mintextparheight\else + \page % option + \fi + \fi + \fi + \fi} + +\def\definetextbackground + {\dodoubleempty\dodefinetextbackground} + +\def\dodefinetextbackground[#1][#2]% + {\ifsecondargument % why ? + \copyparameters[\??td#1][\??td] + [\c!state,\c!location,\c!alternative,\c!mp,\c!method, + \c!background,\c!backgroundcolor,\c!corner,\c!level, + \c!backgroundoffset,\c!before,\c!after,\c!align, + \c!radius,\c!frame,\c!framecolor,\c!rulethickness, + \c!leftoffset,\c!rightoffset,\c!topoffset,\c!bottomoffset]% + \getparameters[\??td#1][#2]% + \doifvalue{\??td#1\c!state}\v!start\checktextbackgrounds + \unexpanded\setvalue{#1}% + {\groupedcommand{\starttextbackground[#1]}{\stoptextbackground}}% + \setvalue{\e!start#1}{\starttextbackground[#1]}% + \setvalue{\e!stop #1}{\stoptextbackground}% + \fi} + +\def\setuptextbackground + {\dodoubleargument\dosetuptextbackground} + +\def\dosetuptextbackground[#1][#2]% + {\ifsecondargument + \doifelsenothing{#1} + {\dodosetuptextbackground{#2}\empty} + {\processcommalist[#1]{\dodosetuptextbackground{#2}}}% + \else + \dodosetuptextbackground{#1}\empty + \fi} + +\def\dodosetuptextbackground#1#2% + {\getparameters[\??td#2][#1]% + \def\currenttextbackground{#2}% + \doifvalue{\??td#2\c!state}\v!start\checktextbackgrounds} + +\let\currenttextbackground\empty + +\def\checktextbackgrounds + {\ifproductionrun + \enabletextarearegistration + \enablehiddenbackground + \fi} + +\setuptextbackground + [\c!mp=mpos:par:columnset, % buggy: mpos:par:shape + \c!method=mpos:par:columnset, % + \c!state=\v!start, + \c!location=\v!text, + \c!leftoffset=\!!zeropoint, % 1em, + \c!rightoffset=\getvalue{\??td\currenttextbackground\c!leftoffset}, + \c!topoffset=\!!zeropoint, % \v!medium, + \c!bottomoffset=\getvalue{\??td\currenttextbackground\c!topoffset}, + \c!level=-1, + \c!alternative=0, + \c!align=, + \c!background=\v!color, + \c!backgroundcolor=lightgray, + \c!backgroundoffset=\!!zeropoint, + \c!corner=\v!rectangular, + \c!radius=.5\bodyfontsize, + \c!frame=\v!on, + \c!framecolor=blue, + \c!rulethickness=\linewidth] + +%D As an example we define a grid background: + +\definetextbackground + [\v!grid] + [\c!state=\v!stop, + \c!location=\v!paragraph, + \c!frame=\v!off, + \c!framecolor=red, + \c!background=, + \c!alternative=1] + +\ifx\basegrid\undefined \else \letvalue\v!grid=\basegrid \fi + +% lelijk, aanpassen, opties + +\setupMPvariables + [mpos:connect] + [linecolor=red, + linewidth=1pt] + +\setupMPvariables + [mpos:encircle] + [fillcolor=lightgray, + filloffset=\!!zeropoint, + linecolor=blue, + linewidth=1pt] + +\startuseMPgraphic{mpos:common:ec} + path pa ; pair ca ; color lc ; numeric lw ; + lw := \MPvar{linewidth} ; + lc := \MPvar{linecolor} ; + initialize_box(\MPpos{\MPvar{self}}) ; + pa := pxy ; ca := cxy ; pa := boundingbox pa enlarged 2lw ; + pa := llcorner pa...lrcorner pa...urcorner pa...ulcorner pa...cycle ; + drawoptions (withpen pencircle scaled lw withcolor lc) ; +\stopuseMPgraphic + +\startMPpositiongraphic{mpos:encircle}{linecolor,fillcolor,linewidth} + \includeMPgraphic{mpos:common:ec} + fill pa withcolor \MPvar{fillcolor} ; draw pa ; + anchor_box(\MPanchor{\MPvar{self}}) ; +\stopMPpositiongraphic + +\startMPpositiongraphic{mpos:connect}{linecolor,linewidth} + path pb, pc ; pair cb, cc ; + \includeMPgraphic{mpos:common:ec} + initialize_box(\MPpos{\MPvar{to}}) ; + pb := pxy ; cb := cxy ; pb := boundingbox pb enlarged 2lw ; + pb := llcorner pb...lrcorner pb...urcorner pb...ulcorner pb...cycle ; + pc := ca {up} .. {down} cb ; + cc := (pc intersection_point pa) ; + if intersection_found : + pc := pc cutbefore cc ; + cc := (pc intersection_point pb) ; + if intersection_found : + pc := pc cutafter cc ; + drawarrow pc ; drawarrow reverse pc ; + fi ; + fi ; + anchor_box(\MPanchor{\MPvar{self}}) ; +\stopMPpositiongraphic + +%D \macros +%D {stackposdown, stackposup, stackposleft,stackposright} +%D +%D A non graphic example of the use of positioning, is to stack +%D text in for instance the margin. +%D +%D \stackposdown \inleft {some text}The text \type {some text} +%D goes into the left margin, and \stackposdown \inleft {some +%D more}\type {some more} as well. When they overlap, they +%D will not touch. +%D +%D Here we said \type {\stackposdown \inleft{some text}}. Instead +%D of \stackposleft \inleft {one}stacking \stackposleft \inleft +%D {two}vertically, one can stack horizontally by \stackposleft +%D \inleft {three}using \type {\stackposleft}. +%D +%D We can go in all four directions, using \type {\stackposdown}, +%D \type {\stackposup}, \type {\stackposleft} and \type +%D {\stackposright}. + +\def\stackposdistance{.5em} + +\newcounter\currentautopos + +\def\POSstackprefix{stack:} + +\def\dostackposbox#1#2% + {\dowithnextbox + {#2{\let\previousautopos\currentautopos + \doglobal\increment\currentautopos + \hpos{\POSstackprefix\currentautopos} + {\doifoverlappingelse{\POSstackprefix\currentautopos}{\POSstackprefix\previousautopos} + {#1} + {\flushnextbox}}}}% + \hbox} + +\def\stackposup {\dostackposbox{\raise\lineheight\flushnextbox}} +\def\stackposdown {\dostackposbox{\lower\lineheight\flushnextbox}} +\def\stackposleft {\dostackposbox{\copy\nextbox\hskip\nextboxwd\hskip\stackposdistance}} +\def\stackposright{\dostackposbox{\hskip\stackposdistance\hskip\nextboxwd\flushnextbox}} + +%D \macros +%D {stackeddown} +%D +%D However, a better implementation is possible with the +%D following macro. We now have an extra key \type {stack} for +%D margin settings. When set to \type {yes}, this macro comes +%D into action. + +% \def\stackeddown +% {\dowithnextbox +% {\doglobal\increment\currentautopos +% \hpos{\POSstackprefix\currentautopos} +% {\edef\next +% {\nextboxht\the\nextboxht +% \nextboxdp\the\nextboxdp +% \nextboxwd\the\nextboxwd}% +% \let\previousautopos\currentautopos +% \scratchdimen\zeropoint +% \doloop +% {\decrement\previousautopos +% \doifoverlappingelse{\POSstackprefix\currentautopos}{\POSstackprefix\previousautopos} +% {\advance\scratchdimen\MPh{\POSstackprefix\previousautopos}% +% \advance\scratchdimen\MPd{\POSstackprefix\previousautopos}}% +% \exitloop +% \ifnum\previousautopos<\zerocount\exitloop\fi}% +% % \ifdim\scratchdimen>\zeropoint +% \setbox\nextbox\iftracepositions\@EA\ruledhbox\else\@EA\hbox\fi +% {\lower\scratchdimen\flushnextbox}% +% \next +% % \fi +% \flushnextbox}}} + +% Because there can be many stacked items in a line and successive lines, we +% play dirty and adapt the position and height of the current node so that +% this becomes visible to a next pass. +% +% \startbuffer +% \inleft {test 1} test 1 \inleft {test 2} test 2 \endgraf +% \inleft {test 3} test 3 +% \stopbuffer +% \getbuffer \typebuffer \flushstatus \page +% +% \startbuffer +% \inleft {test 1} test 1 \inleft {test 2} test 2 \inleft {test 3} test 3 \endgraf +% \inleft {test 4} test 4 +% \stopbuffer +% \getbuffer \typebuffer \flushstatus \page +% +% \startbuffer +% \inleft {test 1} test 1 \endgraf +% \inleft {test 2} test 2 \endgraf +% \inleft {test 3} test 3 +% \stopbuffer +% \getbuffer \typebuffer \flushstatus \page +% +% \startbuffer +% \inleft {test 1\\test 1} test 1 \inleft {test 2} test 2 \endgraf +% \inleft {test 3} test 3 +% \stopbuffer +% \getbuffer \typebuffer \flushstatus \page +% +% \startbuffer +% \inleft {test 1\\test 1\\test 1\\test 1\\test 1} test 1 \endgraf +% test 2 \endgraf +% \inleft {test 3} test 3 +% \stopbuffer +% \getbuffer \typebuffer \flushstatus \page +% +% \startbuffer +% \inleft{test 1} test \inleft{test 2} test \inleft{test 3\\test 3} test +% \stopbuffer +% \getbuffer \typebuffer \flushstatus \page +% +% \startbuffer +% \inleft{test 1\\test 1\\test 1} test \inleft{test 2\\test 2} test \inleft{test 3\\test 3\\test 3} test \endgraf +% \inleft{test 1\\test 1\\test 1} test \inleft{test 2\\test 2} test \inleft{test 3\\test 3\\test 3} test +% \stopbuffer +% \getbuffer \typebuffer \flushstatus \page + +\newdimen\laststackvmove + +\def\stackeddown + {\bgroup + % this macro assumes a few things and is meant to work for margin notes + \dowithnextbox + {\doglobal\increment\currentautopos + \global\laststackvmove\zeropoint + \hpos{\POSstackprefix\currentautopos} + {\edef\next + {\nextboxht\the\nextboxht + \nextboxdp\the\nextboxdp + \nextboxwd\the\nextboxwd}% + \let\previousautopos\currentautopos + \scratchdimen\zeropoint + \scratchcounter\zerocount + \doloop + {\decrement\previousautopos\relax + \edef\currentposition {\POSstackprefix\currentautopos}% + \edef\previousposition{\POSstackprefix\previousautopos}% + \ifnum\MPp\currentposition=\MPp\previousposition\relax + %\registerstatus{doing \currentautopos/\previousautopos}% + \doifoverlappingelse\currentposition\previousposition + {\scratchskip \MPy\currentposition + \advance\scratchskip-\MPy\previousposition + \advance\scratchskip-\MPd\currentposition % untested + \advance\scratchskip \MPd\previousposition % untested + \advance\scratchskip \MPh\currentposition + % todo: also take depth into account + \relax + \ifdim\scratchskip<\scratchdimen + %\registerstatus{no \the\scratchskip}% + \else + %\registerstatus{yes \the\scratchskip}% + \scratchdimen\scratchskip + \fi}% + \donothing % {\registerstatus{next}}% + \ifnum\previousautopos<\zerocount\exitloop\fi + \else + \exitloop + \fi}% + \ifdim\scratchdimen=\zeropoint \else + \bgroup + \edef\currentposition{\POSstackprefix\currentautopos}% + \scratchskip\scratchdimen + \advance\scratchskip\MPh\currentposition + \scratchdimen-\scratchdimen + \advance\scratchdimen\MPy\currentposition + %\registerstatus{old \currentautopos: \MPy\currentposition/\MPh\currentposition}% + \expanded{\replacepospxywhd + {\currentposition}{\MPp\currentposition}{\MPx\currentposition}{\the\scratchdimen}% + {\MPw\currentposition}{\the\scratchskip}{\MPd\currentposition}}% + %\registerstatus{new \currentautopos: \MPy\currentposition/\MPh\currentposition}% + \egroup + \global\laststackvmove\scratchdimen % new + \setbox\nextbox\iftracepositions\@EA\ruledhbox\else\@EA\hbox\fi + {\lower\scratchdimen\flushnextbox}% + \next + %\registerstatus{\strut}% + \fi + \flushnextbox}% + \egroup}} + +%D The next hack make sure that margin texts near faulty +%D strutted lines are handled ok. + +\newif\ifrepositionmarginbox % \repositionmarginboxtrue + +\newcounter\currentmarginpos + +% \def\dopositionmarginbox#1% +% {\bgroup +% \ifrepositionmarginbox +% \doglobal\increment\currentmarginpos +% \setposition{\s!margin:\currentmarginpos}% +% \scratchdimen=\MPy{\s!margin:\currentmarginpos}% +% \doglobal\increment\currentmarginpos +% \advance\scratchdimen by -\MPy{\s!margin:\currentmarginpos}% +% \advance\scratchdimen by -\strutdp +% \setbox#1=\hbox +% {\setposition{\s!margin:\currentmarginpos}\raise\scratchdimen\box#1}% +% \dp#1=\!!zeropoint +% \ht#1=\!!zeropoint +% \fi +% \vadjust{\box#1}% +% \egroup} + +\def\dopositionmarginbox#1% how about page boundaries ! + {\bgroup + \ifrepositionmarginbox + \doglobal\increment\currentmarginpos + \setposition{\s!margin:\currentmarginpos}% + \scratchdimen\MPy{\s!margin:\currentmarginpos}% + \doglobal\increment\currentmarginpos + \advance\scratchdimen -\MPy{\s!margin:\currentmarginpos}% + \advance\scratchdimen -\strutdp + % new + \setbox#1\hbox + {\hskip-\MPx{\s!margin:\currentmarginpos}% + \hskip\MPx{head:\realfolio}% + \box#1}% + % so far + \setbox#1\hbox + {\setposition{\s!margin:\currentmarginpos}% + \raise\scratchdimen\box#1}% + \dp#1\zeropoint + \ht#1\zeropoint + \fi + \graphicvadjust{\box#1}% + \egroup} + +%D For a right menu, a sequence of calls to \type +%D {right_menu_button} is generated. +%D +%D \starttyping +%D right_menu_button (n, p, s=0/1/2, x, y, w, h, d) ; +%D \stoptyping +%D +%D Here, n is the number of the button, s a status variable, +%D while the rest is positional info. The status variable is +%D 0, 1 or~2: not found, found and found but current page. + +% 0=not found 1=found 2=current page + +% geen leeg + +\newtoks\MPmenutoks + +\def\MPmenubuttons#1{\the\MPmenutoks} + +\appendtoks \global\MPmenutoks\emptytoks \to \everyshipout + +% 0=notfound 1=found 2=currentpage + +\def\do@@amposition#1#2#3% + {\doifelsevalue{\??am#1\c!position}\v!yes + {\doglobal\increment\currentamposition + \doifnumberelse{#2} + {\docheckrealreferencepage{#2}% + \global\chardef\currentamrealpage\ifrealreferencepage2\else1\fi} + {\doifreferencefoundelse{#2} + {\global\chardef\currentamrealpage\ifrealreferencepage2\else1\fi} + {\global\chardef\currentamrealpage0}}% % not found + \expanded + {\doglobal\noexpand\appendtoks + #1_menu_button(\currentamposition,\the\currentamrealpage,\noexpand\MPpos{#1:\currentamposition}) ; + \to \MPmenutoks}% + \hpos{#1:\currentamposition}{#3}} + {#3}} + +\def\do@@ammenuposition#1% + {\ifnum\currentamposition>0 + \dowithnextbox{\hpos{menu:#1:\realfolio}{\flushnextbox}}\hbox + \fi} + +%D \macros +%D {GFC, GTC, GSC} +%D +%D The next macros extend tables and tabulation with +%D backgrounds and position related features. Areas are +%D specified with symbolic names, and symbolic references to +%D the graphics involved. Each table has its own namespace. + +\newcounter\noftabpositions +\newtoks \posXCtoks + +\def\tbPOSprefix + {tbp:\noftabpositions:} + +\def\tablepos + {\scratchtoks\posXCtoks + \global\posXCtoks\emptytoks + \the\scratchtoks} + +\let\tabulatepos\tablepos + +\def\dodododoGSC[#1:#2]% + {\remappositionframed{#2}{\tbPOSprefix#1}% + \bpos{\tbPOSprefix#1}% + \doglobal\appendtoks\@EA\epos\@EA{\tbPOSprefix#1}\to\posXCtoks} + +\def\dododoGSC[#1:#2:#3]% + {\doglobal\appendtoks\dodododoGSC[#1:#2]\to\posXCtoks\NC} + +\def\dodoGSC[#1]% + {\def\docommando##1{\dododoGSC[##1:##1]}% + \processcommalist[#1]\docommando} + +\def\dodododoGFC[#1:#2:#3]% + {\remappositionframed{#2}{\tbPOSprefix#1}% + \bpos{\tbPOSprefix#1}} + +\def\dododoGFC[#1]% + {\def\docommando##1{\dodododoGFC[##1:##1]}% + \processcommalist[#1]\docommando} + +\def\dodoGFC[#1]% + {\doglobal\appendtoks\dododoGFC[#1]\to\posXCtoks\NC} + +\def\dododododoGTC[#1:#2]% + {\epos{\tbPOSprefix#1}} + +\def\dodododoGTC[#1]% + {\def\docommando##1{\dododododoGTC[##1:##1]}% + \processcommalist[#1]\docommando} + +\def\dododoGTC[#1]% + {\doglobal\appendtoks\dodododoGTC[#1]\to\posXCtoks} + +\def\dodoGTC[#1]% + {\doglobal\appendtoks\dododoGTC[#1]\to\posXCtoks\NC} + +\def\dodododoXC[#1#2]% + {\if#1>\dodoGFC [#2:#2]\else + \if#1+\dodoGFC [#2:#2]\else + \if#1<\dodoGTC [#2:#2]\else + \if#1-\dodoGTC [#2:#2]\else + \if#1=\dodoGSC [#2:#2]\else + \dodoGSC[#1#2:#1#2]\fi\fi\fi\fi\fi} + +\def\dododoXC#1% + {\dodododoXC[#1]} + +\def\dodoXC[#1]% + {{\let\NC\relax\processcommalist[#1]\dododoXC}} + +\def\doGSC[#1]{\iffirstargument\dodoGSC[#1]\else\expandafter\NC\fi} +\def\doGFC[#1]{\iffirstargument\dodoGFC[#1]\else\expandafter\NC\fi} +\def\doGTC[#1]{\iffirstargument\dodoGTC[#1]\else\expandafter\NC\fi} +\def\doXC [#1]{\iffirstargument\dodoXC [#1]\else\expandafter\fi\NC} + +\def\tbGSC{\dosingleempty\doGSC} +\def\tbGFC{\dosingleempty\doGFC} +\def\tbGTC{\dosingleempty\doGTC} +\def\tbXC {\dosingleempty\doXC } + +%D The amount of code to support tables and tabulation is +%D rather minimalistic. + +\let\tabulatepos\tablepos + +\def\tabulatenormalpos + {\hss\tabulatepos\hss} + +\def\tabulateequalpos + {\setbox\scratchbox\hbox{\tabulateEQ}% + \hbox to \wd\scratchbox{\hss\kern\zeropoint\tabulatepos\hss}% + \hskip-\wd\scratchbox + \box\scratchbox} + +\def\tabulatenormalcolumn#1% overloaded + {&\iftabulateequal\tabulateequalpos\else\tabulatenormalpos\fi + &\global\chardef\tabulatetype#1&} + +\def\tabulateequalcolumn#1% overloaded + {&\tabulateequalpos + &\global\chardef\tabulatetype#1&} + +\appendtoks + \doglobal\increment\noftabpositions +\to \everytabulate + +%D In order to prevent potential clashes with abbreviations, +%D postpone the mapping. + +\appendtoks + \let\GSC\tbGSC \let\GFC\tbGFC \let\GTC\tbGTC \let\XC\tbXC +\to \everytabulate + +%D \macros +%D {definepositionframed} +%D +%D The next example show how to provide backgrounds to table +%D cells. First we define some framed backgrounds. +%D +%D \startbuffer +%D \definepositionframed[x][background=color,backgroundcolor=red] +%D \definepositionframed[y][background=color,backgroundcolor=green] +%D \definepositionframed[z][background=color,backgroundcolor=blue] +%D \stopbuffer +%D +%D \typebuffer +%D +%D % \getbuffer +%D +%D \startbuffer +%D \starttabulate[|c|c|c|] +%D \GFC[f:x] this is a small \NC table \NC in which we \NC \FR +%D \NC will demonstrate \GFC[g:z] that this \GTC[g] positioning \NC \MR +%D \GSC[e:y] mechanism also \GTC[f] works quite well \NC in tables \NC \LR +%D \stoptabulate +%D \stopbuffer +%D +%D The table itself defines three areas (a, b and~c) using +%D these frames. +%D +%D \typebuffer +%D % \getbuffer +%D +%D Tables (based on \TABLE) are supported by: + +\def\normalTABLEsimplebar {\unskip\!ttRightGlue&\tablepos&} % | +\def\normalTABLEcomplexbar{\unskip\!ttRightGlue&\omit\tablepos\!ttAlternateVrule} % \| +\def\normalTABLEquote {\unskip\!ttRightGlue&\omit\tablepos&} % " + +\appendtoks + \doglobal\increment\noftabpositions +\to \everytable + +%D Since we don't want nameclashes: + +\appendtoks + \let\GSC\tbGSC \let\GFC\tbGFC \let\GTC\tbGTC \let\XC\tbXC +\to \everytable + +%D In the previous example, we could have provided an overlay to +%D the framed definition. A more direct approach is demonstrated +%D below: +%D +%D \startbuffer +%D \def\cw#1{\color[white]{#1}} +%D +%D \startMPpositiongraphic{tableshade} +%D initialize_area(\MPpos{\MPvar{from}},\MPpos{\MPvar{to}}) ; +%D color c ; c := \MPvar{color} ; +%D linear_shade(pxy,0,.4c,.9c) ; +%D anchor_area(\MPanchor{\MPvar{from}}) ; +%D \stopMPpositiongraphic +%D +%D \setMPpositiongraphic{b:x}{tableshade}{from=b:x,to=e:x,color=red} +%D \setMPpositiongraphic{b:y}{tableshade}{from=b:y,to=e:y,color=green} +%D \setMPpositiongraphic{b:z}{tableshade}{from=b:z,to=e:z,color=blue} +%D \stopbuffer +%D +%D \typebuffer \getbuffer +%D +%D The definition of the table looks about the same as the +%D previous one: +%D +%D \startbuffer +%D \starttable[|c|c|c|] +%D \GFC[b:z] \cw{this is a small} \NC \cw{table} \NC in which we \NC \FR +%D \NC \cw{will demonstrate} \GFC[c:y] \cw{that this} \GTC[c] \cw{positioning} \NC \MR +%D \GSC[a:x] \cw{mechanism also} \GTC[b] \cw{works quite well} \NC in tables \NC \LR +%D \stoptable +%D \stopbuffer +%D +%D \typebuffer +%D +%D \getbuffer + +% \definepositionframed[w][background=color,backgroundcolor=yellow] +% \definepositionframed[x][background=color,backgroundcolor=red] +% \definepositionframed[y][background=color,backgroundcolor=green] +% \definepositionframed[z][background=color,backgroundcolor=blue] +% +% \starttabulate[|c|c|c|] +% \NC this is a small \NC table \NC in which we \NC \FR +% \NC will demonstrate \NC that this \NC positioning \NC \MR +% \NC mechanism also \NC works quite well \NC in tables \NC \LR +% \stoptabulate +% +% \starttabulate[|c|c|c|] +% \GFC[f:x] this is a small \GTC table \NC in which we \NC \FR +% \NC will demonstrate \GFC[g:z] that this \GTC[g] positioning \NC \MR +% \GSC[e:y] mechanism also \GTC[f] works quite well \NC in tables \NC \LR +% \stoptabulate +% +% \starttabulate[|c|c|c|] +% \GFC[f:x,d:w] this is a small \GTC[d] table \NC in which we \NC \FR +% \NC will demonstrate \GFC[g:z] that this \GTC[g] positioning \NC \MR +% \GSC[e:y] mechanism also \GTC[f] works quite well \NC in tables \NC \LR +% \stoptabulate +% +% \starttabulate[|c|c|c|] +% \XC[+f:x] this is a small \XC table \NC in which we \NC \FR +% \NC will demonstrate \XC[+g:z] that this \XC[-g] positioning \NC \MR +% \XC[=e:y] mechanism also \XC[-f] works quite well \NC in tables \NC \LR +% \stoptabulate +% +% \starttabulate[|c|c|c|] +% \XC[+f:x,+d:w] this is a small \XC[-d] table \NC in which we \NC \FR +% \NC will demonstrate \XC[+g:z] that this \XC[-g] positioning \NC \MR +% \XC[=e:y] mechanism also \XC[-f] works quite well \NC in tables \NC \LR +% \stoptabulate + +% evt [b:x] +% +% \definepositionframed[x][background=color,fillcolor=red] +% \definepositionframed[y][background=color,fillcolor=green] +% \definepositionframed[z][background=color,fillcolor=blue] + +\def\remappositionframed#1#2% from to + {\copyposition{b:#1}{b:#2}% + \copyposition{e:#1}{e:#2}% + \dosetpositionaction{b:#2}{\dopositionaction{b:#1}}} + +\def\definepositionframed + {\dodoubleargument\dodefinepositionframed} + +\def\dodefinepositionframed[#1][#2]% + {\dosetpositionaction{b:#1}{\dopositionframed[#1][#2]}} + +\def\positionframed + {\dodoubleempty\dopositionframed} + +\def\dopositionframed[#1][#2]% + {\bgroup + \setbox\scratchbox\hbox + {\dimen0=\MPx{e:#1}% + \advance\dimen0 -\MPx{b:#1}% + \dimen2=\MPy{b:#1}% + \advance\dimen2 -\MPy{e:#1}% + \advance\dimen2 \MPd{e:#1}% + \lower\dimen2\hbox + {\advance\dimen2 \MPh{b:#1}% + \framed + [\c!width=\dimen0,\c!height=\dimen2, + \c!offset=\v!overlay,#2]{}}}% + \smashedbox\scratchbox + \egroup} + +% \def\sethdistances#1% +% {\hbox{\lpos{ml:#1}\hpos{mh:#1}{\strut}\rpos{mr:#1}}} +% +% \def\gethdistances#1% +% {\scratchdimen\MPx{mh:#1}% +% \advance\scratchdimen -\MPx{ml#1}% +% \edef\lefthdistance{\the\scratchdimen}% +% \scratchdimen\MPx{mr:#1}% +% \advance\scratchdimen -\MPx{mh:#1}% +% \edef\righthdistance{\the\scratchdimen}} + +\protect \endinput + +% todo 1: shift down option + +\startuseMPgraphic{mpos:par:columnset} + \iftracepositions show_multi_pars \else draw_multi_pars \fi ; + path p ; p := boundingbox currentpicture ; + currentpicture := currentpicture shifted (0,-StrutDepth/2) ; + setbounds currentpicture to p ; +\stopuseMPgraphic + +\setupcolors[state=start] + +\definetextbackground[underline][location=text,alternative=1,background=,frame=off,distance=2pt] + +\definestartstop + [underline] + [before={\starttextbackground[underline]}, + after=\stoptextbackground] |