diff options
author | Karl Berry <karl@freefriends.org> | 2006-01-12 23:45:13 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2006-01-12 23:45:13 +0000 |
commit | 92a15e15b276458e10aa05016bf472e8c6dd3eb0 (patch) | |
tree | af0343097e5f497167cefa16ed45c03475b98c37 /Master/texmf-dist/tex/context/base/core-pos.tex | |
parent | df014cf02a62504f6b3e7a4398fb1e093b84f114 (diff) |
context
git-svn-id: svn://tug.org/texlive/trunk@608 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/context/base/core-pos.tex')
-rw-r--r-- | Master/texmf-dist/tex/context/base/core-pos.tex | 2731 |
1 files changed, 2731 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/core-pos.tex b/Master/texmf-dist/tex/context/base/core-pos.tex new file mode 100644 index 00000000000..429aefeec15 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/core-pos.tex @@ -0,0 +1,2731 @@ +%D \module +%D [ file=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. + +% needs a cleanup, things may change + +% shorter tags, ..:achtergrond:.. etc in pos actions + +% dubbele text- * pos's eruit + +% class pos -> als gelijk aan vorige, dan niet niet definieren +% en erven, maw: +% +% 1 -> opslaan +% 2 -> undef, dus == prev +% 3 -> undef, dus == prev +% 4 -> opslaan + +\writestatus{loading}{Context Positioning Support} + +% todo: topskip als optie voor eerste regel achtergrond +% todo: build pos layers on top of layers +% todo: positionlayer pos van text-1 etc delen + +%D Although \TEX\ has a rather powerful channel to the outside +%D world, called \type {\special}, real communication with +%D other programs is complicated by the fact that no positional +%D information is available. Mid 1999, I discussed this with +%D \THANH, the author of \PDFTEX, and after some experiments, +%D \PDFTEX\ was extended with a simple but effective mechanism, +%D that provided positional information. The interesting +%D thought is that, although \TEX\ is frozen, similar +%D functionality could have been achieved with \type +%D {\specials} and an additional \DVI\ postprocessor. +%D +%D Since we want to be as compatible as can be, \CONTEXT\ will +%D support both methods, although the development is primarily +%D driven by the \PDFTEX\ way of doing things. Since the +%D mechanism is basically not limited to one application, for +%D the moment we stick to building the functionality around one +%D \CONTEXT\ special command, but at the same time we keep our +%D eyes open for extensions in other directions. +%D +%D A question that may arise when one reads this module, is to +%D what extend these macros are generic, in the sense that they +%D could be collected in a support module instead of a core +%D module. Since the mechanism described here will closely +%D cooperate with the \METAPOST\ support built in \CONTEXT, +%D which in turn will be tightly integrated with the \CONTEXT\ +%D overlay mechanisms, I decided to write a core module instead +%D of a support one. This makes even more sense, when one takes +%D into account that this kind of support depends on special +%D drivers. + +\unprotect + +%D The first application of positional information was embedded +%D graphics. Since we are interacting with text, it made sense +%D to take the current line height and depth into account too. +%D This is why we have two basic position macros: one for +%D simple positions, and one for boxes. +%D +%D We could have sticked to one special, and actually did so in +%D earlier experiments, but for convenience, as well for +%D clearness, we now have two alternatives. This approach will +%D save us quite some bytes when storing large quantities of +%D positional information. We save as less information as +%D needed, that is, we save no dimensions, in a \METAPOST\ +%D friendly way. +%D +%D The three specials involved are: +%D +%D \starttyping +%D \dosetposition {identifier} +%D \dosetpositionwhd {identifier} {width} {height} {depth} +%D \dosetpositionplus {identifier} {width} {height} {depth} {list} +%D \dosetpositionpapersize {width} {height} +%D \stoptyping +%D +%D Either directly, when using \PDFTEX, or by means of a +%D postprocessor, when using \DVI\ output, these end up in the +%D utility file as: +%D +%D \starttyping +%D \pospxy {identifier} {page} {x} {y} +%D \pospxywhd {identifier} {page} {x} {y} {w} {h} {d} +%D \pospxylist {identifier} {page} {x} {y} {w} {h} {d} {list} +%D \stoptyping +%D +%D This means that we have to provide both a utility set and +%D reset macro for positions. + +\def\POSprefix{POS::} + +\def\pxypos {\pospxy} % obsolete +\def\pxyposwhd {\pospxywhd} % obsolete +\def\pxyposplus{\pospxyplus} % obsolete + +\def\resetpositions + {\let\pospxy \gobblefourarguments + \let\pospxywhd \gobblesevenarguments + \let\pospxyplus\gobbleeightarguments} + +\def\setpositions + {\let\pospxy \setpospxy + \let\pospxywhd \setpospxywhd + \let\pospxyplus\setpospxyplus} + +\addutilityreset{positions} + +%D This is real tricky! The page anchor is applied to the +%D page box and therefore flushed first. So, when present, it +%D is applied to all positions except itself. + +\chardef\positionanchormode=0 % don't relocate page origin +\chardef\positionanchormode=1 % relocate page origin once + +\def\pageanchor{page:0} + +% todo: change with each page size change + +\def\registerpageposition#1% this one is flushed first ! + {\ifpositioning\ifcase\realpageno\or + \ifdim\printpaperheight=\paperheight\else + \ifdim\printpaperwidth=\paperwidth\else + \setbox#1\hbox{\hpos\pageanchor{\box#1}}% + \fi + \fi + \fi\fi} + +\def\setpospxy#1#2#3#4% + {\dosetpositionnm\@@posp{#2}% + \dosetpositionxy\@@posx{#3}\MPx + \dosetpositionxy\@@posy{#4}\MPy + \@EA\xdef\csname\POSprefix#1\endcsname{\@@posp,\@@posx,\@@posy}} + +\def\setpospxywhd#1#2#3#4#5#6#7% + {\dosetpositionnm\@@posp{#2}% + \dosetpositionxy\@@posx{#3}\MPx + \dosetpositionxy\@@posy{#4}\MPy + \dosetpositionpt\@@posw{#5}% + \dosetpositionpt\@@posh{#6}% + \dosetpositionpt\@@posd{#7}% + \@EA\xdef\csname\POSprefix#1\endcsname{\@@posp,\@@posx,\@@posy,\@@posw,\@@posh,\@@posd}} + +\def\setpospxyplus#1#2#3#4#5#6#7#8% + {\dosetpositionnm\@@posp{#2}% + \dosetpositionxy\@@posx{#3}\MPx + \dosetpositionxy\@@posy{#4}\MPy + \dosetpositionpt\@@posw{#5}% + \dosetpositionpt\@@posh{#6}% + \dosetpositionpt\@@posd{#7}% + \@EA\xdef\csname\POSprefix#1\endcsname{\@@posp,\@@posx,\@@posy,\@@posw,\@@posh,\@@posd,#8}} + +%D Sometimes we want to trick the position handler a bit: + +\def\replacepospxywhd#1#2#3#4#5#6#7% + {\begingroup + \nosetpositionnm\@@posp{#2}% + \nosetpositionpt\@@posx{#3}% + \nosetpositionpt\@@posy{#4}% + \nosetpositionpt\@@posw{#5}% + \nosetpositionpt\@@posh{#6}% + \nosetpositionpt\@@posd{#7}% + \@EA\xdef\csname\POSprefix#1\endcsname{\@@posp,\@@posx,\@@posy,\@@posw,\@@posh,\@@posd}% + \endgroup} + +% slower, as many tokens, etc: +% +% \def\replacepospxywhd#1#2#3#4#5#6#7% +% {\begingroup +% \let\dosetpositionnm\nosetpositionnm +% \let\dosetpositionpt\nosetpositionpt +% \let\dosetpositionxy\nosetpositionpt +% \setpospxywhd{#1}{#2}{#3}{#4}{#5}{#6}{#7}% +% \endgroup} + +%D We need to initialize. + +\resetpositions + +%D For postprocessing purposes, we save the number of +%D positions. + +\newcounter\currentpositions % current number of positions +\newcounter\totalnofpositions % total from previous run + +\appendtoks + \savecurrentvalue\totalnofpositions\currentpositions +\to \everybye + +%D The next switch can be used to communicate a special +%D situation. Positioning and associated actions can be +%D executed any time. However, in for instance backgrounds +%D they can be collected in a layer, for instance the text +%D layer (especially the hidden text layer). In the case of +%D floats, we run into problems, since the page information is +%D not applicable when the content floats indeed. In such +%D situations one can treat positions and graphics local. + +\newif\iflocalpositioning + +%D Watch out: sometimes a pagebreak occurs inside a float +%D placement, so there we need to disable local mode. + +\appendtoks + \localpositioningtrue +\to \everyinsidefloat + +\appendtoks + \localpositioningfalse +\to \everypagebody + +%D We save positionional information without dimensions, which +%D saves some bytes. The conversion too saves some bytes, but +%D is primarily needed because we want to pass those values to +%D \METAPOST\ too. + +\def\dosetpositionpt#1#2% + {\scratchdimen\number#2\scaledpoint + \xdef#1{\withoutpt\the\scratchdimen}} + +\def\dosetpositionnm#1#2% + {\xdef#1{\number#2}} + +\def\dosetpositionxy#1#2#3% todo: scaled points + {\scratchdimen\number#2\scaledpoint + \ifcase\positionanchormode\or + \advance\scratchdimen-#3\pageanchor + \fi + \xdef#1{\withoutpt\the\scratchdimen}} + +\def\nosetpositionnm#1#2{\xdef#1{\number#2}} +\def\nosetpositionpt#1#2{\scratchdimen#2\xdef#1{\withoutpt\the\scratchdimen}} + +\beginETEX \dimexpr + + \def\dosetpositionpt#1#2{\xdef#1{\withoutpt\the\dimexpr(\number#2\scaledpoint)}} + \def\nosetpositionpt#1#2{\xdef#1{\withoutpt\the\dimexpr(#2)}} + +\endETEX + +\def\checkpositions + {\startnointerference + \protectlabels + \doutilities{positions}\jobname\empty\relax\relax + \global\let\checkpositions\relax + \stopnointerference} + +%D Since the positional values are to be fully expandable, we +%D need to preload them as soon as possible, which is why we +%D load the data when we start a text. + +\appendtoks \checkpositions \to \everystarttext + +%D Positions are either generated at a delayed write time +%D (in \PDFTEX), or derived from the dvi file. The actual +%D method is implemented in a special driver. If needed, the +%D driver can fall back on the following macros. + +\def\dolazysaveposition#1#2#3#4% tag page x y + {\expanded{\writeutilitycommand{\noexpand\pospxy + {#1}{#2}{#3}{#4}}}} + +\def\dolazysavepositionwhd#1#2#3#4#5#6#7% tag page x y w h d + {\expanded{\writeutilitycommand{\noexpand\pospxywhd + {#1}{#2}{#3}{#4}{#5}{#6}{#7}}}} + +\def\dolazysavepositionplus#1#2#3#4#5#6#7#8% tag page x y w h d list + {\expanded{\writeutilitycommand{\noexpand\pospxyplus + {#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}}}} + +\def\dosaveposition#1#2#3#4% tag page x y + {\expanded{\immediatewriteutilitycommand{\noexpand\pospxy + {#1}{#2}{#3}{#4}}}} + +\def\dosavepositionwhd#1#2#3#4#5#6#7% tag page x y w h d + {\expanded{\immediatewriteutilitycommand{\noexpand\pospxywhd + {#1}{#2}{#3}{#4}{#5}{#6}{#7}}}} + +\def\dosavepositionplus#1#2#3#4#5#6#7#8% tag page x y w h d list + {\expanded{\immediatewriteutilitycommand{\noexpand\pospxyplus + {#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}}}} + +%D \macros +%D {MPp, MPx, MPy, MPw, MPh, MPd, +%D MPxy, MPll, MPlr, MPur, MPul, MPpos} +%D +%D Access to the positional information is provided by macros +%D with short names that are clearly meant for \METAPOST. + +\def\MPp {\doMPxyhdwlr\doMPp } +\def\MPx {\doMPxyhdwlr\doMPx } +\def\MPy {\doMPxyhdwlr\doMPy } +\def\MPw {\doMPxyhdwlr\doMPw } +\def\MPh {\doMPxyhdwlr\doMPh } +\def\MPd {\doMPxyhdwlr\doMPd } +\def\MPxy {\doMPxyhdwlr\doMPxy } +\def\MPll {\doMPxyhdwlr\doMPll } +\def\MPlr {\doMPxyhdwlr\doMPlr } +\def\MPur {\doMPxyhdwlr\doMPur } +\def\MPul {\doMPxyhdwlr\doMPul } +\def\MPpos{\doMPxyhdwlr\doMPpos} + +%D So \type {\MPx{identifier}} returns a position, specified +%D in points. When unknown, \type {0pt} is returned. From the +%D next definitions, we can see that some positions are +%D expressions. + +\def\doMPp #1,#2,#3,#4,#5,#6,#7\relax{#1} +\def\doMPx #1,#2,#3,#4,#5,#6,#7\relax{#2\s!pt} +\def\doMPy #1,#2,#3,#4,#5,#6,#7\relax{#3\s!pt} +\def\doMPw #1,#2,#3,#4,#5,#6,#7\relax{#4\s!pt} +\def\doMPh #1,#2,#3,#4,#5,#6,#7\relax{#5\s!pt} +\def\doMPd #1,#2,#3,#4,#5,#6,#7\relax{#6\s!pt} +\def\doMPxy #1,#2,#3,#4,#5,#6,#7\relax{(#2\s!pt,#3\s!pt)} +\def\doMPll #1,#2,#3,#4,#5,#6,#7\relax{(#2\s!pt,#3\s!pt-#6\s!pt)} +\def\doMPlr #1,#2,#3,#4,#5,#6,#7\relax{(#2\s!pt+#4\s!pt,#3\s!pt-#6\s!pt)} +\def\doMPur #1,#2,#3,#4,#5,#6,#7\relax{(#2\s!pt+#4\s!pt,#3\s!pt+#5\s!pt)} +\def\doMPul #1,#2,#3,#4,#5,#6,#7\relax{(#2\s!pt,#3\s!pt+#5\s!pt)} +\def\doMPpos#1,#2,#3,#4,#5,#6,#7\relax{#1,#2\s!pt,#3\s!pt,#4\s!pt,#5\s!pt,#6\s!pt} + +%D As said, we will default to zero (dimensions) when a +%D position is unknown. + +\def\doMPxyhdwlr#1#2% + {\ifundefined{\POSprefix#2}% + #10,0,0,0,0,0,0\relax + \else + \@EA\@EA\@EA#1\csname\POSprefix#2\endcsname,0,0,0,0\relax + \fi} + +\beginETEX + +\def\doMPxyhdwlr#1#2% evt kan \s!unknown leeg zijn + {\@EA\@EA\@EA#1\csname\POSprefix + \ifcsname\POSprefix#2\endcsname#2\else\s!unknown\fi\endcsname + ,0,0,0,0\relax} + +\setvalue{\POSprefix\s!unknown}{0,0,0} + +\endETEX + +%D \macros +%D {MPplus, MPrest, MPv, MPvv} +%D +%D Since we will probably keep on extending, we provide a +%D general extension macro. The plus alternative takes an +%D extra argument, denoting what additional parameter to pick +%D up. So, the third extra is fetched with, +%D +%D \starttyping +%D \MPplus{identifier}{3}{default} +%D \stoptyping +%D +%D All extras (comma separated) are fetched with: +%D +%D \starttyping +%D \MPrest{identifier} +%D \stoptyping +%D +%D The extra parameters are not treated. + +\def\MPplus {\MPdoplus\doMPplus} \let\MPv \MPplus +\def\MPrest#1{\MPdoplus\doMPrest{#1}{}} \let\MPvv\MPrest + +\def\MPdoplus#1#2#3#4% + {\ifundefined{\POSprefix#2}#4\else + \@EA\@EA\@EA#1\csname\POSprefix#2\endcsname,,,,,,,,,\relax{#3}% + \fi} + +% \beginETEX +% +% \def\MPdoplus#1#2#3#4% +% {\ifcsname\POSprefix#2\endcsname +% \@EA\@EA\@EA#1\csname\POSprefix#2\endcsname,,,,,,,,,\relax{#3}% +% \else +% #4% +% \fi} +% +% \endETEX + +\def\doMPplus#1,#2,#3,#4,#5,#6,% + {\dodoMPplus} + +\def\dodoMPplus#1,#2,#3,#4,#5,#6,#7,#8\relax#9% + {\ifcase#9\or#1\or#2\or#3\or#4\or#5\or#6\or#7\else + \dododoMPplus#8\relax{#9}\fi} + +\def\dododoMPplus#1,#2,#3,#4,#5,#6,#7,#8\relax#9% + {\ifcase#9\or \or \or \or \or \or \or \or + #1\or#2\or#3\or#4\or#5\or#6\or#7\fi} + +\def\doMPrest#1,#2,#3,#4,#5,#6,#7,,#8\relax#9% + {#7} + +% We can now remap the normal whd onto this. + +%D \macros +%D {MPanchor} +%D +%D For readability we define a few synonyms: + +\let\MPanchor\MPpos + +%D \macros +%D {POSp, POSx, POSy, POSh, POSd, POSw} +%D +%D and: + +\let\POSp\MPp \let\POSx\MPx \let\POSy\MPy +\let\POSh\MPh \let\POSd\MPd \let\POSw\MPw + +\newbox\positionbox \newif\ifpositioning + +%D There are two low level positioning macros. Both store the +%D position as well as execute an action associated with that +%D position. + +\def\initializenextposition + {\ifpositioning \else + \global\positioningtrue + \dosetpositionpapersize + {\number\printpaperwidth}% + {\number\printpaperheight }% + \fi + \doglobal\increment\currentpositions} + +% \def\setposition#1% +% {\initializenextposition +% \dosetposition{#1}% +% \dopositionaction{#1}} +% +% \def\setpositionbox#1% +% {\dowithnextbox +% {\hbox to \nextboxwd +% {\initializenextposition +% \def\currentposition{#1}% +% \dosetpositionwhd \currentposition +% {\number\nextboxwd}% +% {\number\nextboxht}% +% {\number\nextboxdp}% +% \traceposstring\llap\green{\currentposition>}% +% \setbox\positionbox\flushnextbox +% \dopositionaction\currentposition +% \box\positionbox +% \hss}}} +% +% \def\setpositionplus#1#2% +% {\dowithnextbox +% {\hbox to \nextboxwd +% {\initializenextposition +% \def\currentposition{#1}% +% \dosetpositionplus \currentposition +% {\number\nextboxwd}% +% {\number\nextboxht}% +% {\number\nextboxdp}% +% {#2}% +% \traceposstring\rlap\magenta{<\currentposition}% +% \setbox\positionbox\flushnextbox +% \dopositionaction\currentposition +% \box\positionbox +% \hss}}} + +\def\setpositiononly#1% + {\iftrialtypesetting + % nothing + \else + \initializenextposition + \def\currentposition{#1}% + \dosetposition\currentposition + \fi} + +\def\setposition#1% + {\iftrialtypesetting + % nothing + \else + \initializenextposition + \def\currentposition{#1}% + \dosetposition\currentposition + \traceposstring\llap\green{\currentposition>}% + \dopositionaction\currentposition + \fi} + +\def\setpositiondata#1#2#3#4% + {\iftrialtypesetting \else + \initializenextposition + \hbox + {\def\currentposition{#1}% + \dosetpositionwhd\currentposition + {\number#2}% + {\number#3}% + {\number#4}% + \traceposstring\llap\green{\currentposition>}% + \dopositionaction\currentposition + \hss}% + \fi} + +\def\setpositionbox#1% + {\dowithnextbox + {\iftrialtypesetting + \flushnextbox + \else + \initializenextposition + \hbox to \nextboxwd + {\edef\currentposition{#1}% + \dosetpositionwhd\currentposition + {\number\nextboxwd}% + {\number\nextboxht}% + {\number\nextboxdp}% + \traceposstring\llap\green{\currentposition>}% + \setbox\positionbox\flushnextbox + \dopositionaction\currentposition + \box\positionbox + \hss}% + \fi}} + +\def\setpositiondataplus#1#2#3#4#5% + {\iftrialtypesetting \else + \initializenextposition + \hbox to \nextboxwd + {\edef\currentposition{#1}% + \dosetpositionplus\currentposition + {\number#2}% + {\number#3}% + {\number#4}% + {#5}% + \traceposstring\rlap\magenta{<\currentposition}% + \dopositionaction\currentposition + \hss}% + \fi} + +\def\setpositionplus#1#2% + {\dowithnextbox + {\iftrialtypesetting + \flushnextbox + \else + \initializenextposition + \hbox to \nextboxwd + {\edef\currentposition{#1}% + \dosetpositionplus\currentposition + {\number\nextboxwd}% + {\number\nextboxht}% + {\number\nextboxdp}% + {#2}% + \traceposstring\rlap\magenta{<\currentposition}% + \setbox\positionbox\flushnextbox + \dopositionaction\currentposition + \box\positionbox + \hss}% + \fi}} + +\let\currentposition\s!unknown + +%D A few more low level macros take care of defining and +%D recalling actions. We could save this information in the +%D position containers themselves, this would save hash +%D entries, but at the cost of much more time consuming +%D expansion. Actions are saved globally! + +\newtoks\everypositionaction + +\let\POSactionprefix\POSprefix + +\def\dosetpositionaction#1% + {\setgvalue{\POSactionprefix#1::}} + +%D The lists can become quite long (also because there can +%D be lots of parameters passed on) so we provide a hook +%D to clean up the list afterwards. + +\let\cleanuppositionaction\gobbleoneargument + +%D The next one will be overloaded later. +%D +%D \starttyping +%D \def\dopositionaction#1% test saves hash entry in etex +%D {\ifundefined{\POSactionprefix#1::}\else +%D \ifnum\MPp{#1}>\zerocount % new +%D \setbox\scratchbox\hbox \bgroup +%D \traceposstring\clap\red{<#1>}% +%D \the\everyinsertpositionaction +%D \the\everypositionaction +%D \ifcollectMPpositiongraphics +%D % can save a lot of run time +%D \pushMPdrawing +%D \MPshiftdrawingtrue +%D \resetMPdrawing +%D \getvalue{\POSactionprefix#1::}% +%D \ifMPdrawingdone +%D \getMPdrawing +%D \fi +%D \resetMPdrawing +%D \popMPdrawing +%D \else +%D \getvalue{\POSactionprefix#1::}% +%D \fi +%D \cleanuppositionaction{#1}% +%D \egroup +%D \smashedbox\scratchbox +%D \else +%D % shouldn't happen too often +%D \traceposstring\clap\cyan{<#1>}% +%D \fi +%D \fi} +%D \stoptyping + +\def\doifpositionaction#1% + {\ifundefined{\POSactionprefix#1::}% + \@EA\gobbleoneargument + \else + \@EA\firstofoneargument + \fi} + +\def\doifpositionactionelse#1% + {\ifundefined{\POSactionprefix#1::}% + \@EA\secondoftwoarguments + \else + \@EA\firstoftwoarguments + \fi} + +%D We can copy a position with: +%D +%D \starttyping +%D \copyposition {to} {from} +%D \stoptyping +%D +%D Again, this is a global action. + +\def\copyposition#1#2% + {\bgroup + %\edef\to {\POSprefix#1}% + \edef\from{\POSprefix#2}% + \ifundefined\from\else + % \global\@EA\@EA\@EA\let\@EA\csname\@EA\to\@EA\endcsname\csname\from\endcsname + \global\@EA\let\csname\POSprefix#1\@EA\endcsname\csname\from\endcsname + \fi + \egroup} + +%D The fact that handling positions is a two pass operation, is +%D one of the reasons why we need to be able to test for +%D existence, using: +%D +%D \starttyping +%D \doifpositionelse {identifier} {found action} {not found action} +%D \stoptyping + +% \def\doifpositionelse#1% +% {\doifdefinedelse{\POSprefix#1}} + +\def\doifpositionelse#1% + {\ifundefined{\POSprefix#1}% + \expandafter\secondoftwoarguments + \else + \expandafter\firstoftwoarguments + \fi} + +%D We have now arrived at a few macros that would make sense as +%D support macros, but ended up in the core. + +%D \macros +%D {xypos} +%D +%D We have several macros available to save positions. Later +%D we will see applications. +%D +%D \starttabulate[|l|l||] +%D \NC \type {\xypos} \NC \NC simple position with no dimensions \NC \NR +%D \NC \type {\hpos} \NC \NC position and characteristics of a \type {\hbox} \NC \NR +%D \NC \type {\vpos} \NC \NC position and characteristics of a \type {\vbox} \NC \NR +%D \NC \type {\bpos} \NC b: \NC begin point in a line \NC \NR +%D \NC \type {\epos} \NC e: \NC end point in a line \NC \NR +%D \NC \type {\fpos} \NC f: \NC begin point in a paragraph \NC \NR +%D \NC \type {\tpos} \NC t: \NC end point in a paragraph \NC \NR +%D \stoptabulate +%D +%D Each macro takes an identifier as argument, and the \type +%D {\hpos} and \type {\vpos} also expect box content. + +% \def\xypos{\initializenextposition\dosetposition} + +\let\xypos\setpositiononly + +\def\hpos#1{\dontleavehmode\setpositionbox{#1}\hbox} +\def\vpos#1{\setpositionbox{#1}\vbox} + +\def\bpos#1{\hpos{b:#1}{\strut}\ignorespaces} +\def\epos#1{\removelastspace\hpos{e:#1}{\strut}} + +\def\fpos#1% + {\setpositionplus{b:#1}\parposcounter\horizontalstrut + \ignorespaces} + +\def\tpos#1% + {\removelastspace + \setpositionplus{e:#1}\parposcounter\horizontalstrut} + +\def\ffpos#1% + {\setpositionplus{b:#1}\parposcounter\horizontalstrut\wpos{#1}% + \ignorespaces} + +\def\ttpos#1% + {\removelastspace + \setpositionplus{e:#1}\parposcounter\horizontalstrut} + +\def\wpos#1% + {\dontleavehmode\vadjust % may disappear if buried + {\setbox0\hbox{\raise\strutdp\hbox{\rawwpos{#1}}}% + \rlap{\smashedbox0}}} + +\def\wwpos#1% \hsmashed{\llap{\rawwpos{#1}}} + {\rlap + {\setbox0\hbox{\rawwpos{#1}}% + \smashedbox0}} + +\def\rawwpos#1% + {\hpos{w:#1} + {\strut + \hskip-\leftskip + \hskip\hsize + \hskip-\rightskip}} + +% the next macro disables par positions (in inner boxes) and +% only registers the width + +\def\setinnerparpositions + {\let\fpos\ffpos + \let\tpos\ttpos + \let\wpos\wwpos} + +% example of usage: (see for application "techniek") +% +% \appendtoks +% \setinnerparpositions +% \to \everytabulate + +%D When we want to calculate more complex backgrounds, we +%D need to know what the current indentation scheme is. At +%D the cost of many positions and memory, we can keep track +%D of them. This mechanism is activated automatically +%D based on information collected in the previous pass. + +\newcounter\parposcounter + +\newif\ifpositioningpar + +\def\efficientdimen#1% + {\the#1} % \ifdim#1=\zeropoint\string\!!zeropoint\else\the#1\fi} + +% we can check for used entries, and if not, then not add one + +\def\registerparoptions + {\ifpositioningpar \ifpositioning \iftrialtypesetting \else + \ifinpagebody \else \ifmmode \else \ifinformula \else + \ifprocessingverbatim + \iflinepar \doregisterparoptions \fi + \else + \doregisterparoptions + \fi + \fi \fi \fi + \fi \fi \fi} + +\chardef\parposstrut=1 % 0 => no strut data, so fall backs used + +\def\doregisterparoptions + {\doglobal\increment\parposcounter + \begingroup + \leftskip 1\leftskip + \rightskip1\rightskip + \setpositiondataplus + {p:\parposcounter}% % identifier + {\zeropoint}% + {\strutht}% + {\strutdp}% + {\efficientdimen\hsize ,% 1 + \efficientdimen\leftskip ,% 2 + \efficientdimen\rightskip ,% 3 + \efficientdimen\hangindent,% 4 + \the\hangafter ,% 5 + \efficientdimen\parindent }% 6 + %\normalhbox{\registerparsymbol}% + \registerparsymbol + \endgroup} + +\newif\iftracepositions + +\def\traceposstring#1#2#3% + {\iftracepositions\smashedhbox{#1{\infofont#2#3}}\fi} + +\def\registerparsymbol + {\iftracepositions + \smashedhbox to \zeropoint + {\hss + \blue + \llap{\infofont\number\parposcounter}% + \scratchdimen\onepoint + \vrule + \!!width 4\scratchdimen + \!!height2\scratchdimen + \!!depth 2\scratchdimen + \hss}% + \fi} + +% \appendtoks \registerparoptions \to \everypar + +%D \macros +%D {doifoverlappingelse} +%D +%D A first application of positional information, is to +%D determine if two boxes do overlap: +%D +%D \starttyping +%D \doifoverlappingelse{point a}{point b} +%D {action when overlapping} +%D {action when not overlapping} +%D \stoptyping + +% \def\doifoverlappingelse#1#2#3#4% +% {\relax\ifnum\MPp{#1}=\MPp{#2}\relax +% \bgroup +% \donefalse +% \def\check##1##2% +% {\ifdone\else +% \ifdim\dimen1##1<\dimen0 \else \ifdim\dimen1##1>\dimen2 \else +% \ifdim\dimen1##2<\dimen4 \else \ifdim\dimen1##2>\dimen6 \else +% \donetrue +% \fi\fi +% \fi\fi +% \fi}% +% \dimen 0=\MPx{#1}% +% \dimen 2=\MPx{#1}\advance\dimen 2 \MPw{#1}% +% \dimen 4=\MPy{#1}\advance\dimen 4 -\MPd{#1}% +% \dimen 6=\MPy{#1}\advance\dimen 6 \MPh{#1}% +% \dimen10=\MPx{#2}% +% \dimen12=\MPx{#2}\advance\dimen12 \MPw{#2}% +% \dimen14=\MPy{#2}\advance\dimen14 -\MPd{#2}% +% \dimen16=\MPy{#2}\advance\dimen16 \MPh{#2}% +% %\message{\the\dimen 0-\the\dimen 2,\the\dimen 4-\the\dimen 6}\wait +% %\message{\the\dimen10-\the\dimen12,\the\dimen14-\the\dimen16}\wait +% \check04\check24\check26\check06\ifdone\egroup#3\else\egroup#4\fi +% \else +% #4% +% \fi} + +% \newdimen\overlappingmargin \overlappingmargin\zeropoint +% +% \overlappingmargin-2sp % better + +\def\overlappingmargin{-2\scaledpoint} + +\def\doifoverlappingelse#1#2% + {\begingroup + \donefalse + \edef\!!stringa{#1}\edef\!!stringb{#2}% + \ifnum\MPp\!!stringa=\MPp\!!stringb\relax + \!!dimena\MPx\!!stringa + \!!dimenb\MPx\!!stringa\advance\!!dimenb \MPw\!!stringa + \!!dimenc\MPy\!!stringa\advance\!!dimenc-\MPd\!!stringa + \!!dimend\MPy\!!stringa\advance\!!dimend \MPh\!!stringa + \!!dimene\MPx\!!stringb + \!!dimenf\MPx\!!stringb\advance\!!dimenf \MPw\!!stringb + \!!dimeng\MPy\!!stringb\advance\!!dimeng-\MPd\!!stringb + \!!dimenh\MPy\!!stringb\advance\!!dimenh \MPh\!!stringb + \ifdim\overlappingmargin=\zeropoint\else + \advance\!!dimena-\overlappingmargin + \advance\!!dimenb+\overlappingmargin + \advance\!!dimenc-\overlappingmargin + \advance\!!dimend+\overlappingmargin + \advance\!!dimene-\overlappingmargin + \advance\!!dimenf+\overlappingmargin + \advance\!!dimeng-\overlappingmargin + \advance\!!dimenh+\overlappingmargin + \fi + % more often eh fb eg fg + \def\checkone##1##2% + {\ifdim##1<\!!dimena \else \ifdim##1>\!!dimenb \else + \ifdim##2<\!!dimenc \else \ifdim##2>\!!dimend \else + \donetrue + \fi\fi + \fi\fi}% + \def\checktwo##1##2% + {\ifdim##1<\!!dimene \else \ifdim##1>\!!dimenf \else + \ifdim##2<\!!dimeng \else \ifdim##2>\!!dimenh \else + \donetrue + \fi\fi + \fi\fi}% + \checkone\!!dimene\!!dimeng \ifdone \else + \checkone\!!dimene\!!dimenh \ifdone \else + \checkone\!!dimenf\!!dimeng \ifdone \else + \checkone\!!dimenf\!!dimenh \ifdone \else + \checktwo\!!dimena\!!dimenc \ifdone \else + \checktwo\!!dimena\!!dimend \ifdone \else + \checktwo\!!dimenb\!!dimene \ifdone \else + \checktwo\!!dimenb\!!dimenc \fi \fi \fi \fi \fi \fi \fi + \fi + \ifdone + \endgroup\expandafter\firstoftwoarguments + \else + \endgroup\expandafter\secondoftwoarguments + \fi} + +%D \macros +%D {doifpositionsonsamepageelse, +%D doifpositionsonthispageelse} +%D +%D Instead of letting the user handle fuzzy expansion, we +%D provide a simple test on positione being on the same page. +%D +%D \starttyping +%D \doifpositionsonsamepageelse{point a}{point b} +%D {action when on same page} +%D {action when not on same page} +%D \doifpositionsonthispageelse{point a}{point b} +%D {action when on this page} +%D {action when not on this page} +%D \stoptyping + +\def\dodoifpositionsonsamepageelse#1#2#3#4% + {\bgroup + \scratchcounter#1\donefalse + \def\docommando##1% + {\ifcase\scratchcounter + \scratchcounter\MPp{##1}\donetrue + \else + \ifnum\scratchcounter=\MPp{##1}\relax\else\donefalse\fi + \fi}% + \rawprocesscommalist[#2]\docommando + \ifdone\egroup#3\else\egroup#4\fi} + +\def\doifpositionsonsamepageelse% + {\dodoifpositionsonsamepageelse{0}} + +\def\doifpositionsonthispageelse#1#2#3% + {\dodoifpositionsonsamepageelse\realfolio} + +%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. + +% in the future, the depth of tail will reflect page depth + +\def\textanchor{text:\realfolio} + +% \def\placepositionanchors % todo : depth pagebox +% {\ifpositioning +% \setbox\scratchbox\vbox to \teksthoogte +% {\topskipcorrection +% \hbox{\strut\dopositionaction\headanchor}% +% \vfill +% \hbox{\strut\dopositionaction\tailanchor}}% +% \dp\scratchbox\zeropoint +% \wd\scratchbox\zetbreedte % not \zeropoint, else wrong text backgrounds +% \hpos\textanchor{\box\scratchbox}% +% \else +% \vskip\teksthoogte +% \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 +% \dimen0=\ifdim\topskip>\strutht\topskip\else\strutht\fi +% \dimen2=\MPy\textanchor +% \dimen4=\dimen2 +% \advance\dimen2 \MPh\textanchor % space is essential +% \advance\dimen2 -\dimen0 +% \advance\dimen4 \strutdp +% \dimen6=\MPx\textanchor +% \dimen8=\MPw\textanchor +% \setxvalue{\POSprefix\headanchor}% +% {\realfolio,\withoutpt\the\dimen6,\withoutpt\the\dimen2,% +% \withoutpt\the\dimen8,\withoutpt\the\dimen0,\withoutpt\the\strutdp}% +% \setxvalue{\POSprefix\tailanchor}% +% {\realfolio,\withoutpt\the\dimen6,\withoutpt\the\dimen4,% +% \withoutpt\the\dimen8,\withoutpt\the\strutht,\withoutpt\the\strutdp}% +% %\showanchor\textanchor\showanchor\headanchor\showanchor\tailanchor\wait +% \egroup} + +\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. + +% \def\positionoverlay#1% +% {\ifpositioning +% \vbox to \overlayheight +% {\edef\MPanchor##1{\MPpos{#1::\MPanchoridentifier:\realfolio}}% +% \the\everyinsertpositionaction +% \copyposition{#1::\MPanchoridentifier}{#1::\MPanchoridentifier:\realfolio}% +% \hpos +% {#1::\MPanchoridentifier:\realfolio} +% {\hbox to \overlaywidth{\dopositionaction{#1::\MPanchoridentifier}\hss}}% +% \vfill}% +% \fi} + +\let\MPanchornumber\realfolio + +% \def\positionoverlay#1% +% {\ifpositioning +% \vbox to \overlayheight +% {\edef\MPanchorid{#1::\MPanchoridentifier:\MPanchornumber}% +% \edef\MPanchor##1{\MPpos{\MPanchorid}}% +% \the\everyinsertpositionaction +% \copyposition{#1::\MPanchoridentifier}{#1::\MPanchoridentifier:\MPanchornumber}% +% \hpos +% {#1::\MPanchoridentifier:\MPanchornumber} +% {\hbox to \overlaywidth{\dopositionaction{#1::\MPanchoridentifier}\hss}}% +% \vfill}% +% \fi} + +% \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}% +% {\hbox to \overlaywidth{\dopositionaction{#1::\MPanchoridentifier}\hss}}}% +% {\hbox to \overlaywidth{\hss}}% +% \vfill}% +% \fi} + +\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% +% {\doifdefined{\POSactionprefix#1++} +% {\the\everycleanpositionaction +% \setxvalue{\POSactionprefix#1++}{\getvalue{\POSactionprefix#1++}}}} + +%\def\cleanuppositionaction#1% +% {\ifundefined{\POSactionprefix#1++}\else +% \the\everycleanpositionaction +% \setxvalue{\POSactionprefix#1++}{\getvalue{\POSactionprefix#1++}}% +% \fi} + +\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 +% {\doifundefined{\@@meta self}{\setvalue{\@@meta self}{\currentposition}}% +% \doifundefined{\@@meta from}{\setvalue{\@@meta from}{\currentposition}}} + +\def\prepareMPpositionvariables + {\ifundefined{\@@meta self}\setvalue{\@@meta self}{\currentposition}\fi + \ifundefined{\@@meta from}\setvalue{\@@meta from}{\currentposition}\fi} + +% \long\def\useMPpositiongraphic#1#2#3% +% {\bgroup +% \prepareMPvariables{#2}% +% \prepareMPpositionvariables +% \enableincludeMPgraphics +% \startMPgraphic#3\stopMPgraphic +% \loadMPgraphic{\MPgraphicfile.\the\currentMPgraphic}{}% +% \deallocateMPslot\currentMPgraphic +% \placeMPgraphic +% \egroup} + +\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 +% \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 +% \else +% % shouldn't happen too often +% \traceposstring\clap\cyan{<#1>}% +% \fi +% \fi} + +\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{\getvalue{MPG:##1}}% temp hack +% \setbox\positiongraphicbox\hbox +% {\ignorespaces +% \executeifdefined{MPM:#1}{\executeifdefined{MPG:#1}\donothing}% +% \removelastspace}% +% \smashbox\positiongraphicbox +% \box\positiongraphicbox +% \egroup} + +\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 +% {\donefalse +% \ifnum\MPp{#1}=\realpageno\relax \donetrue +% \else\ifnum\MPp{#2}=\realpageno\relax \donetrue +% \else\ifnum\MPp{#1}<\realpageno\relax\ifnum\MPp{#2}>\realpageno\donetrue +% \fi\fi\fi\fi \ifdone +% \def\currentposition{#1}\MPpositiongraphic{#3}{#4}% +% \fi} + +\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{background:0} +% \def\nextparbackground {background:1} + +\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] |