%D \module %D [ file=anch-pgr, % split off core-pos %D version=1999.08.01, %D title=\CONTEXT\ Anchoring Macros, %D subtitle=Positioning Graphics, %D author=Hans Hagen, %D date=\currentdate, %D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] %C %C This module is part of the \CONTEXT\ macro||package and is %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. \writestatus{loading}{ConTeXt Anchoring Macros / 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 \ifx\textheight\undefined \def\textheight{\vsize} \fi %D The next macros so some housekeeping. \def\pageanchor{page:0} % for the moment only one pagesize \def\textanchor{text:\realfolio} \def\headanchor{head:\realfolio} % virtual position \def\tailanchor{tail:\realfolio} % virtual position %D Anchors: \def\dopresetpositionanchors % also mkii {\bgroup \!!dimena\ifdim\topskip>\strutht\topskip\else\strutht\fi \!!dimenb\dimexpr\MPy\textanchor+\MPh\textanchor-\!!dimena\relax \!!dimenc\dimexpr\MPy\textanchor+\strutdp\relax \!!dimend\MPx\textanchor \!!dimene\MPw\textanchor \replacepospxywhd\headanchor\realfolio\!!dimend\!!dimenb\!!dimene\!!dimena\strutdp \replacepospxywhd\tailanchor\realfolio\!!dimend\!!dimenc\!!dimene\strutht \strutdp \egroup} \def\presetpositionanchors% compatibility hack (still needed?) {\ifpositioning \dopresetpositionanchors \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\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 % todo: change with each page size change \def\registerpageposition#1% this one is flushed first ! {\ifpositioning\ifcase\realpageno\or \ifdim\printpaperheight=\paperheight \ifdim\printpaperwidth=\paperwidth % not needed, \else \setbox#1\hbox{\hpos\pageanchor{\box#1}}% \fi \else \setbox#1\ruledhbox{\hpos\pageanchor{\box#1}}% \fi \fi\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 \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 {\ifcsname\POSactionprefix#1++\endcsname % \ifundefined{\POSactionprefix#1++}\else \the\everycleanpositionaction \iflocalpositioning \letgvalue{\POSactionprefix#1++}\empty \else \setxvalue{\POSactionprefix#1++}{\getvalue{\POSactionprefix#1++}}% \fi \fi} % \def\cleanuppositionaction#1% not in trialtypesetting % {\ifcsname\POSactionprefix#1++\endcsname % \the\everycleanpositionaction % \iflocalpositioning % \global\expandafter\let\csname\POSactionprefix#1++\endcsname\empty % \else % \global\expandafter\let\csname\POSactionprefix#1++\expandafter\endcsname\csname\POSactionprefix#1++\endcsname % \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 % can be sped up \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}}} \let\stopMPpositiongraphic\relax % \def\prepareMPpositionvariables % {\ifundefined{\@@meta self}\setvalue{\@@meta self}{\currentposition}\fi % \ifundefined{\@@meta from}\setvalue{\@@meta from}{\currentposition}\fi} \def\prepareMPpositionvariables {\ifcsname\@@meta self\endcsname\else\setvalue{\@@meta self}{\currentposition}\fi \ifcsname\@@meta from\endcsname\else\setvalue{\@@meta from}{\currentposition}\fi} \newif\ifcollectMPpositiongraphics \collectMPpositiongraphicstrue \long\def\useMPpositiongraphic#1#2#3% {\bgroup \prepareMPvariables{#2}% \prepareMPpositionvariables \enableincludeMPgraphics \ifcollectMPpositiongraphics % no longer needed in mkiv \expanded{\startMPdrawing#3\noexpand\stopMPdrawing}% \global\MPdrawingdonetrue \else\ifx\startMPgraphic\undefined \startMPcode#3\stopMPcode \else \startMPgraphic#3\stopMPgraphic \loadMPgraphic{\MPgraphicfile.\the\currentMPgraphic}{}% \deallocateMPslot\currentMPgraphic \placeMPgraphic \fi\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 \let\stopMPpositionmethod\relax %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 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, dashtype=0, % 1 = dashed, 2 = dashed with background %snaptops=true, % not that nice: true/false gridcolor=red, linecolor=blue, fillcolor=lightgray, filloffset=\!!zeropoint, linewidth=\linewidth, gridwidth=\linewidth, gridshift=\!!zeropoint, lineradius=.5\bodyfontsize, dashtype=1] \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} ; boxdashtype := \MPvar{dashtype} ; boxgridcolor := \MPvar{gridcolor} ; boxlinecolor := \MPvar{linecolor} ; boxfillcolor := \MPvar{fillcolor} ; boxfilloffset := \MPvar{filloffset} ; boxlinewidth := \MPvar{linewidth} ; boxgridwidth := \MPvar{gridwidth} ; boxgridshift := \MPvar{gridshift} ; boxlineradius := \MPvar{lineradius} ; %snap_multi_par_tops := \MPvar{snaptops} ; \stopuseMPgraphic \startuseMPgraphic{mpos:par:extra} % user stuff, like: % snap_multi_par_tops := false ; \stopuseMPgraphic \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,gridshift,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,gridshift,lineradius} initialize_par(\MPpos\MPbself, \MPpos\MPeself, \MPpos\textanchor, \MPpos\MPparanchor, \MPvv \MPparanchor{0pt,0pt,0pt,0pt,0,0pt}) ; \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 \startuseMPgraphic{mpos:par:sideline}{linecolor,lineoffset} for i=1 upto nofmultipars : fill leftboundary multipars[i] shifted (-\MPvar{lineoffset},0) rightenlarged 1mm withcolor \MPvar{linecolor} ; endfor ; \stopuseMPgraphic \startMPpositionmethod{mpos:par:columnset} \edef\MPparcounter{\MPv\MPbself{1}{0}}% \startMPpositiongraphic{mpos:par}{fillcolor,filloffset,linecolor,gridcolor,linewidth,gridwidth,gridshift,lineradius} \includeMPgraphic{mpos:par:setup} ; \includeMPgraphic{mpos:par:extra} ; prepare_multi_pars(\MPpos\MPbself,\MPpos\MPeself,\MPpos\MPwself, \MPpos\MPparanchor,\MPvv\MPparanchor{0pt,0pt,0pt,0pt,0,0pt}) ; 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 method=mpos:par:columnset] %D \stoptyping %D We need to treat floats in a special way. \startMPinitializations local_multi_par_area:=\iflocalpositioning true\else false\fi; \stopMPinitializations \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. \newcount\textbackgrounddepth \appendtoks \expanded{\savecurrentvalue\noexpand\totalnofparbackgrounds{\number\nofparbackgrounds}}% \to \everybye \appendtoks \initializeparbackgrounds \to \everystarttext \ifx\totalnofparbackgrounds\undefined \newcounter\totalnofparbackgrounds \fi \ifx\nofparbackgrounds \undefined \newcount \nofparbackgrounds \fi \def\initializeparbackgrounds {\ifcase\totalnofparbackgrounds\else \enableparpositions \fi} \unexpanded\def\starttextbackground {\bgroup \advance\textbackgrounddepth\plusone \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\textbackgroundparameter#1% {\csname\??td\currenttextbackground#1\endcsname} \let\backgroundvariable\textbackgroundparameter % will become obsolete % \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}% \global\advance\nofparbackgrounds\plusone \edef\currentparbackground{pbg:\number\nofparbackgrounds}% % \bgroup % \advance\nofparbackgrounds\plusone % \xdef\nextparbackground{pbg:\number\nofparbackgrounds}% % \egroup \xdef\nextparbackground{pbg:\number\numexpr\nofparbackgrounds+\plusone\relax}% still xdef ? % todo : \synchonizepositionpage{b:\currentparbackground}{s:\currentparbackground}% \setuptextbackground[#1][#2]% \let\dodostarttextbackground\relax \let\dodostoptextbackground \relax \doif{\textbackgroundparameter\c!state}\v!start{\dopresettextbackground{#1}}% \dodostarttextbackground} % todo \backgroundvariable\c!variant \def\dopresettextbackground#1% todo: \backgroundparameter {\ExpandFirstAfter\processaction % \EFA niet echt nodig [\textbackgroundparameter\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 \doifelse{\textbackgroundparameter\c!frame}\v!on {\doifelse{\textbackgroundparameter\c!corner}\v!round {\setvalue{\??td#1\c!frame}{2}} {\setvalue{\??td#1\c!frame}{1}}} {\setvalue{\??td#1\c!frame}{0}}% \doifelse{\textbackgroundparameter\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{\textbackgroundparameter\c!level}}% \expanded {\setMPpositiongraphicrange % moet veel efficienter {\btbanchor}% {b:\currentparbackground}% {\etbanchor}% {e:\currentparbackground}% {\textbackgroundparameter\c!method}% {self=\currentparbackground, mp=\textbackgroundparameter\c!mp, gridtype=\textbackgroundparameter\c!alternative, filltype=\textbackgroundparameter\c!background, linetype=\textbackgroundparameter\c!frame, dashtype=\textbackgroundparameter{dash}, % to be internationalized gridcolor=\textbackgroundparameter\c!framecolor, linecolor=\textbackgroundparameter\c!framecolor, lineoffset=\textbackgroundparameter\c!frameoffset, fillcolor=\textbackgroundparameter\c!backgroundcolor, filloffset=\textbackgroundparameter\c!backgroundoffset, gridwidth=\textbackgroundparameter\c!rulethickness, gridshift=\textbackgroundparameter\c!voffset, linewidth=\textbackgroundparameter\c!rulethickness, lineradius=\textbackgroundparameter\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 \dontleavehmode \fi % was leavevmode, brrr \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}} \newskip\textbackgroundskip \def\dostarttextbackgroundpar {\endgraf % new \textbackgroundparameter\c!before \noindent \ifgridsnapping \doassignsomeskip\textbackgroundparameter\c!topoffset\to\textbackgroundskip \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 \ifgridsnapping \else \doassignsomeskip\textbackgroundparameter\c!topoffset\to\textbackgroundskip \ifdim\textbackgroundskip>\zeropoint \kern\textbackgroundskip\nobreak \fi \fi \dosetleftskipadaption{\textbackgroundparameter\c!leftoffset}% \advance\leftskip\leftskipadaption \dosetleftskipadaption{\textbackgroundparameter\c!rightoffset}% \advance\rightskip\leftskipadaption % new \dosetraggedcommand{\textbackgroundparameter\c!align}% \raggedcommand % \dostartattributes{\??td\currenttextbackground}\c!style\c!color\empty \nowhitespace \nobreak % new per 23/04/2006 (else potential break when whitespace) \seteffectivehsize \doinhibitblank % \blank[\v!disable]% new \par} \def\dostoptextbackgroundpar {\par \removelastskip % new \dostopattributes \doassignsomeskip\textbackgroundparameter\c!bottomoffset\to\textbackgroundskip \ifdim\lastskip>\zeropoint \advance\textbackgroundskip-\lastskip \fi \ifgridsnapping \else \ifdim\textbackgroundskip>\zeropoint \kern\textbackgroundskip\nobreak \fi \fi \nobreak \vskip-\lineheight \nobreak \nowhitespace \egroup \bgroup \forgeteverypar % NOT REALLY NEEDED, SAVES HASH/MEM \nobreak \noindent \strut \hfill \kern\zeropoint \doassignsomeskip\textbackgroundparameter\c!bottomoffset\to\textbackgroundskip \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 \textbackgroundparameter\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% todo: dimexpr {\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 % - and then + ? \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,dash, % dash not yet internationalized \c!radius,\c!frame,\c!framecolor,\c!rulethickness,\c!voffset,\c!frameoffset, \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=\textbackgroundparameter\c!leftoffset, \c!topoffset=\!!zeropoint, % \v!medium, \c!bottomoffset=\textbackgroundparameter\c!topoffset, \c!level=-1, \c!alternative=0, \c!align=, dash=0, % to be internationalized \c!background=\v!color, \c!backgroundcolor=lightgray, \c!backgroundoffset=\!!zeropoint, \c!corner=\v!rectangular, \c!radius=.5\bodyfontsize, \c!voffset=\!!zeropoint, \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} \newcount\currentautopos \newcount\previousautopos \def\POSstackprefix{stack:} \def\dostackposbox#1#2% {\dowithnextbox {#2{\previousautopos\currentautopos \global\advance\currentautopos\plusone \edef\currentposition {\POSstackprefix\number\currentautopos}% \edef\previousposition{\POSstackprefix\number\previousautopos}% \hpos\currentposition{\doifoverlappingelse\currentposition\previousposition{#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. % 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 % use \scratchdimenone instead of skip \def\stackeddown {\bgroup % this macro assumes a few things and is meant to work for margin notes \dowithnextbox {\global\advance\currentautopos\plusone \global\laststackvmove\zeropoint \hpos{\POSstackprefix\number\currentautopos} {\edef\next {\nextboxht\the\nextboxht \nextboxdp\the\nextboxdp \nextboxwd\the\nextboxwd}% \previousautopos\currentautopos \scratchdimen\zeropoint \scratchcounter\zerocount \doloop {\advance\previousautopos\minusone \edef\currentposition {\POSstackprefix\number\currentautopos}% \edef\previousposition{\POSstackprefix\number\previousautopos}% \ifnum\MPp\currentposition=\MPp\previousposition\relax %\registerstatus{doing \number\currentautopos/\number\previousautopos}% \doifoverlappingelse\currentposition\previousposition {\scratchskip\dimexpr \MPy\currentposition -\MPy\previousposition -\MPd\currentposition % untested +\MPd\previousposition % untested +\MPh\currentposition \relax\relax % second relax realy needed, forgotten while dimexpressing % todo: also take depth into account \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\number\currentautopos}% \scratchskip\scratchdimen \advance\scratchskip\MPh\currentposition \scratchdimen-\scratchdimen \advance\scratchdimen\MPy\currentposition %\registerstatus{old \number\currentautopos: \MPy\currentposition/\MPh\currentposition}% \expanded{\replacepospxywhd {\currentposition}{\MPp\currentposition}{\MPx\currentposition}{\the\scratchdimen}% {\MPw\currentposition}{\the\scratchskip}{\MPd\currentposition}}% %\registerstatus{new \number\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 \newcount\currentmarginpos \def\dopositionmarginbox#1% {\bgroup \ifrepositionmarginbox \global\advance\currentmarginpos\plusone %\setposition{\s!margin:\number\currentmarginpos}% not always \ifcase\marginrepositionmethod % nothing \or % nothing \or % stack / page check yet untested \setposition{\s!margin:\number\currentmarginpos}% \scratchdimen\MPy{\s!margin:\number\currentmarginpos}% \global\advance\currentmarginpos\plusone \advance\scratchdimen -\MPy{\s!margin:\number\currentmarginpos}% \advance\scratchdimen -\strutdp % new but bugged % \setbox#1\hbox % {\hskip-\MPx{\s!margin:\number\currentmarginpos}% % \hskip\MPx{head:\realfolio}% % \box#1}% % so far \setbox#1\hbox {\setposition{\s!margin:\number\currentmarginpos}% \raise\scratchdimen\box#1}% \or % move up \setposition{\s!margin:\number\currentmarginpos}% \ifnum\MPp{p:\number\parposcounter}=\MPp{\s!margin:\number\currentmarginpos}\relax \scratchdimen\dimexpr\MPy{p:\number\parposcounter}-\MPy{\s!margin:\number\currentmarginpos}\relax \expanded{\setbox#1\hbox{\raise\scratchdimen\box#1}\ht#1\the\ht#1\dp#1\the\dp#1}% \fi \or % move up, assume end of par \setposition{\s!margin:\number\currentmarginpos}% \ifnum\MPp{p:\number\parposcounter}=\MPp{\s!margin:\number\currentmarginpos}\relax \getnoflines\margincontentheight \advance\noflines\minusone \scratchdimen\noflines\lineheight \else \scratchdimen\dimexpr\MPy{p:\number\parposcounter}-\MPy{\s!margin:\number\currentmarginpos}\relax \fi \expanded{\setbox#1\hbox{\raise\scratchdimen\box#1}\ht#1\the\ht#1\dp#1\the\dp#1}% \fi \dp#1\zeropoint \ht#1\zeropoint \fi \graphicvadjust{\box#1}% \egroup} \chardef\marginrepositionmethod\plusone % sidemethod \chardef\margincontentmethod \plusthree % textmethod % beware: 1 = old method \chardef\marginpagecheckmethod \plusone % splitmethod %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,\MPpos{#1:\currentamposition}) ; \to \MPmenutoks}% \hpos{#1:\currentamposition}{#3}} {#3}} \def\do@@ammenuposition#1% {\ifnum\currentamposition>0 \dowithnextbox{\hpos{menu:#1:\realfolio}{\flushnextbox}}\hbox % \hpos{menu:#1:\realfolio} % also ok if we skip over fi \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. \newcount\noftabpositions \newtoks \posXCtoks \def\tbPOSprefix {tbp:\number\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\docommand##1{\dododoGSC[##1:##1]}% \processcommalist[#1]\docommand} \def\dodododoGFC[#1:#2:#3]% {\remappositionframed{#2}{\tbPOSprefix#1}% \bpos{\tbPOSprefix#1}} \def\dododoGFC[#1]% {\def\docommand##1{\dodododoGFC[##1:##1]}% \processcommalist[#1]\docommand} \def\dodoGFC[#1]% {\doglobal\appendtoks\dododoGFC[#1]\to\posXCtoks\NC} \def\dododododoGTC[#1:#2]% {\epos{\tbPOSprefix#1}} \def\dodododoGTC[#1]% {\def\docommand##1{\dododododoGTC[##1:##1]}% \processcommalist[#1]\docommand} \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 \global\advance\noftabpositions\plusone \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 \global\advance\noftabpositions\plusone \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 \definetextbackground[underline] [location=text,alternative=1,background=,frame=off] \definetextbackground[overstrike] [location=text,alternative=2,background=,frame=off] \definetextbackground[exlines] [location=text,alternative=3,background=,frame=off] \definetextbackground[strikethrough][location=text,alternative=4,background=,frame=off] \definestartstop [underline] [before={\starttextbackground[underline]}, after=\stoptextbackground] \definestartstop [overstrike] [before={\starttextbackground[overstrike]}, after=\stoptextbackground] \definestartstop [exlines] [before={\starttextbackground[exlines]}, after=\stoptextbackground] \definestartstop [strikethrough] [before={\starttextbackground[strikethrough]}, after=\stoptextbackground] \definetextbackground [sideline] [mp=mpos:par:sideline, location=paragraph, framecolor=red, frameoffset=5mm] \definestartstop [sideline] [before={\starttextbackground[sideline]}, after=\stoptextbackground] \starttext \startunderline \input tufte \stopunderline \blank \startoverstrike \input tufte \stopoverstrike \blank \startexlines \input tufte \stopexlines \blank \startstrikethrough \input tufte \stopstrikethrough \blank \startsideline \input tufte \stopsideline \blank \stoptext