From 9ca92159ee8e762e295fc06fcb22dcb1006707cd Mon Sep 17 00:00:00 2001
From: Hans Hagen <pragma@wxs.nl>
Date: Wed, 17 Feb 1999 00:00:00 +0100
Subject: stable 1999.02.17

---
 tex/context/base/supp-box.tex | 2668 ++++++++++++++++++++++++-----------------
 1 file changed, 1560 insertions(+), 1108 deletions(-)

(limited to 'tex/context/base/supp-box.tex')

diff --git a/tex/context/base/supp-box.tex b/tex/context/base/supp-box.tex
index fb9e1e2d1..87c2c78f7 100644
--- a/tex/context/base/supp-box.tex
+++ b/tex/context/base/supp-box.tex
@@ -1,1108 +1,1560 @@
-% NEW
-
-\unprotect
-
-% limitatetext -> beter {text} als laatste !!
-
-% \limitvbox
-% \limithbox
-
-\def\limitatelines#1#2% size sentinel
-  {\dowithnextbox
-     {\dimen0=#1\hsize
-      \ifdim\wd\nextbox>\dimen0
-        \setbox\nextbox=\hbox
-          {\advance\dimen0 by -.1\hsize
-           \limitatetext{\unhbox\nextbox}{\dimen0}{\nobreak#2}}%
-      \fi
-      \unhbox\nextbox}
-     \hbox}
-
-\def\fittoptobaselinegrid% weg hier 
-  {\dowithnextbox
-     {\bgroup
-      \par
-      \dimen0=\ht\nextbox
-      \ht\nextbox=\ht\strutbox
-      \dp\nextbox=\dp\strutbox
-      \hbox{\box\nextbox}
-      \prevdepth\dp\strutbox
-      \doloop
-        {\advance\dimen0 by -\lineheight
-         \ifdim\dimen0<\!!zeropoint
-           \exitloop
-         \else
-           \nobreak
-           \hbox{\strut}
-         \fi}
-      \egroup}
-     \vbox}
-
-\protect
-
-%D \module
-%D   [       file=supp-box,
-%D        version=1995.10.10,
-%D          title=\CONTEXT\ Support Macros,
-%D       subtitle=Boxes,
-%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. Non||commercial use is
-%C granted.
-
-%D This module implements some box manipulation macros. Some
-%D are quite simple, some are more advanced and when understood
-%D well, all can be of use.
-
-\writestatus{loading}{Context Support Macros / Boxes}
-
-\unprotect
-
-%D \macros
-%D   {nextdepth}
-%D   {}
-%D
-%D Let's start with a rather simple declaration. Sometimes we
-%D need to save the \TEX\ \DIMENSION\ \type{\prevdepth} and
-%D append it later on. The name \type{\nextdepth} suits
-%D this purpose well.
-
-\newdimen\nextdepth
-
-%D \macros
-%D   {smashbox}
-%D   {}
-%D
-%D Smashing is introduced in \PLAIN\ \TEX, and stands for
-%D reducing the dimensions of a box to zero. The most resolute
-%D one is presented first.
-
-\def\smashbox#1%
-  {\wd#1=\!!zeropoint
-   \ht#1=\!!zeropoint
-   \dp#1=\!!zeropoint}
-
-%D \macros
-%D   {hsmashbox,vsmashbox}
-%D   {}
-%D
-%D Smashing can be used for overlaying boxes. Depending on
-%D the mode, horizontal or vertical, one can use:
-
-\def\hsmashbox#1%
-  {\wd#1=\!!zeropoint}
-
-\def\vsmashbox#1%
-  {\ht#1=\!!zeropoint
-   \dp#1=\!!zeropoint}
-
-%D \macros
-%D   {hsmash,vsmash,
-%D    hsmashed,vsmashed}
-%D   {}
-%D
-%D While the previous macros expected a \BOX, the next act on a
-%D content. They are some subtle differences betreen the smash
-%D and smashed alternatives. The later ones reduce all
-%D dimensions to zero.
-
-\def\hsmash#1%
-  {\bgroup
-   \setbox0=\normalhbox{#1}%
-   \hsmashbox0%
-   \box0
-   \egroup}
-
-\def\vsmash#1%
-  {\bgroup
-   \setbox0=\normalvbox{#1}%
-   \vsmashbox0%
-   \box0
-   \egroup}
-
-\def\hsmashed#1%
-  {\bgroup
-   \setbox0=\normalhbox{#1}%
-   \smashbox0%
-   \box0
-   \egroup}
-
-\def\vsmashed#1%
-  {\bgroup
-   \setbox0=\normalvbox{#1}%
-   \smashbox0%
-   \box0
-   \egroup}
-
-%D \macros
-%D   {getboxheight}
-%D   {}
-%D
-%D Although often needed, \TEX\ does not support arithmics
-%D like:
-%D
-%D \starttypen
-%D \dimen0 = \ht0 + \dp0
-%D \stoptypen
-%D
-%D so we implemented:
-%D
-%D \starttypen
-%D \getboxheight ... \of \box...
-%D \stoptypen
-%D
-%D For instance,
-%D
-%D \starttypen
-%D \getboxheight \dimen0 \of \box0
-%D \getboxheight \someheight \of \box \tempbox
-%D \stoptypen
-
-\def\getboxheight#1\of#2\box#3%
-  {#1=\ht#3%
-   \advance#1 by \dp#3\relax}
-
-%D \macros
-%D   {dowithnextbox,
-%D    nextbox}
-%D   {}
-%D
-%D Sometimes we want a macro to grab a box and do something
-%D on the content. One could pass an argument to a box, but
-%D this can violate the specific \CATCODES\ of its content and
-%D leads to unexpected results. The next macro treats the
-%D following braced text as the content of a box and
-%D manipulates it afterwards in a predefined way.
-%D
-%D The first argument specifies what to do with the content.
-%D This content is available in \type{\nextbox}. The second
-%D argument is one of \type{\hbox}, \type{\vbox} or
-%D \type{\vtop}. The third argument must be grouped with
-%D \type{\bgroup} and \type{\egroup}, \type{{...}} or can be
-%D a \type{\box} specification.
-%D
-%D In \CONTEXT\ this macro is used for picking up a box and
-%D treating it according to earlier specifications. We use for
-%D instance something like:
-%D
-%D \starttypen
-%D \def\getfloat%
-%D   {\def\handlefloat{...\box\nextbox...}
-%D    \dowithnextbox\handlefloat\vbox}
-%D \stoptypen
-%D
-%D in stead of:
-%D
-%D \starttypen
-%D \def\getfloat#1%
-%D   {...#1...}
-%D \stoptypen
-%D
-%D In this implementation the \type{\aftergroup} construction
-%D is needed because \type{\afterassignment} is executed inside
-%D the box.
-
-\newbox\nextbox
-
-\long\def\dowithnextbox#1%
-  {\long\def\dodowithnextbox{#1}%
-   \afterassignment\dododowithnextbox
-   \setbox\nextbox}
-
-\def\dododowithnextbox%
-  {\aftergroup\dodowithnextbox}
-
-%D So in fact we get:
-%D
-%D \starttypen
-%D \setbox\nextbox { \aftergroup\dodowithnextbox ... }
-%D \stoptypen
-%D
-%D or
-%D
-%D \starttypen
-%D \setbox\nextbox { ... } \dodowithnextbox
-%D \stoptypen
-%D
-%D A slower but more versatile implementation is:
-%D
-%D \starttypen
-%D \long\def\dowithnextbox#1#2%
-%D   {\long\def\dodowithnextbox{#1}%
-%D    \ifx#2\hbox
-%D      \afterassignment\dododowithnextbox
-%D    \else\ifx#2\vbox
-%D      \afterassignment\dododowithnextbox
-%D    \else\ifx#2\vtop
-%D      \afterassignment\dododowithnextbox
-%D    \else\ifx#2\vcenter
-%D      \afterassignment\dododowithnextbox
-%D    \else
-%D      \afterassignment\dodowithnextbox
-%D    \fi\fi\fi\fi
-%D    \setbox\nextbox#2}
-%D \stoptypen
-%D
-%D This alternative also accepts \type{\box0} and alike, but 
-%D we don't really need this functionality now.  
-
-%D \macros
-%D   {beginofshapebox,
-%D    reshapebox, doreshapebox,
-%D    flushshapebox,
-%D    shapebox,
-%D    ifreshapingbox}
-%D   {}
-%D
-%D The next utility macro originates from some linenumbering
-%D mechanism. Due to \TEX's advanced way of typesetting
-%D paragraphs, it's not easy to do things on a line||by||line
-%D basis. This macro is able to reprocess a given box and can
-%D act upon its vertical boxed components, such as lines. The
-%D unwinding sequence in this macro is inspired by a \NTG\
-%D workshop of David Salomon in June 1992.
-%D
-%D First we have to grab the piece of text we want to act
-%D upon. This is done by means of the duo macros:
-%D
-%D \starttypen
-%D \beginofshapebox
-%D a piece of text
-%D \endofshapebox
-%D \stoptypen
-%D
-%D When all texts is collected, we can call \type{\reshapebox}
-%D and do something with it's vertical components. We can make
-%D as much passes as needed. When we're done, the box can be
-%D unloaded with \type{\flushshapebox}. The only condition in
-%D this scheme is that \type{\reshapebox} must somehow unload
-%D the \BOX\ \type{\shapebox}.
-%D
-%D An important aspect is that the content is unrolled
-%D bottom||up. The next example illustrates this maybe
-%D unexpected characteristic.
-%D
-%D \startbuffer
-%D \beginofshapebox
-%D \em \input tufte
-%D \endofshapebox
-%D
-%D \newcounter\LineNumber
-%D
-%D \reshapebox
-%D   {\doglobal\increment\LineNumber
-%D    \hbox{\llap{\LineNumber\hskip2em}\box\shapebox}}
-%D
-%D \flushshapebox
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D \haalbuffer
-%D
-%D As we can see, when some kind of numbering is done, we have
-%D to add a second pass.
-%D
-%D \startbuffer
-%D \newcounter\LineNumber
-%D \newcounter\NumberOfLines
-%D
-%D \reshapebox
-%D   {\doglobal\increment\NumberOfLines
-%D    \box\shapebox}
-%D
-%D \reshapebox
-%D   {\doglobal\increment\LineNumber
-%D    \hbox
-%D      {\llap{\LineNumber\ (\NumberOfLines)\hskip2em}%
-%D       \box\shapebox}%
-%D    \doglobal\decrement\NumberOfLines}
-%D
-%D \flushshapebox
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D \haalbuffer
-%D
-%D This example shows that the content of the box is still
-%D available after flushing. Another feature is that only the
-%D last reshaping counts. Multiple reshaping can be done by:
-%D
-%D \startbuffer
-%D \beginofshapebox
-%D \flushshapebox
-%D \endofshapebox
-%D
-%D \reshapebox
-%D   {\doglobal\increment\LineNumber
-%D    \hbox{\llap{$\star$\hskip1em}\box\shapebox}%
-%D    \doglobal\decrement\NumberOfLines}
-%D
-%D \flushshapebox
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D \haalbuffer
-%D
-%D The macros are surprisingly easy to follow and in fact
-%D introduce no new concepts. Nearly all books on \TEX\ show
-%D similar solutions for unwinding \BOXES.
-%D
-%D Some macros, like footnote ones, can be sensitive for
-%D reshaping, which can result in an endless loop. We
-%D therefore offer:
-%D
-%D \starttypen
-%D \ifreshapingbox
-%D \stoptypen
-%D
-%D Some \CONTEXT\ commands are protected this way. Anyhow,
-%D reshaping is aborted after 100 dead cycles.
-%D
-%D By the way, changing the height and depth of \BOX\
-%D \type{\shapebox} results in bad spacing. This means that
-%D for instance linenumbers etc. should be given zero height
-%D and depth before being lapped into the margin. The
-%D previous examples ignore this side effect, but beware!
-
-\newif\ifsomeshapeleft
-\newif\ifreshapingbox
-
-\def\shapesignal {.12345678pt}
-
-\newbox   \shapebox
-\newcount \shapepenalty
-\newdimen \shapekern
-\newskip  \shapeskip
-
-\newbox\newshapebox
-\newbox\oldshapebox
-
-\newcount\shapecounter
-
-\def\reshapebox#1%
-  {\doreshapebox
-     {#1}
-     {\penalty\shapepenalty}
-     {\kern\shapekern}
-     {\vskip\shapeskip}}
-
-\def\doreshapebox#1#2#3#4% \shapebox, \shapepenalty, \shapekern, \shapeskip
-  {\setbox\newshapebox=\normalvbox
-     \bgroup
-       \unvcopy\oldshapebox
-       \setbox\newshapebox=\box\voidb@x
-       \shapecounter=0
-       \loop
-         \someshapelefttrue
-         \ifdim\lastskip=\!!zeropoint\relax
-           \ifdim\lastkern=\!!zeropoint\relax
-             \ifnum\lastpenalty=0
-               \setbox\shapebox=\lastbox
-               \ifvoid\shapebox
-                 \unskip\unpenalty\unkern
-               \else
-                 \ifdim\wd\shapebox=\shapesignal\relax
-                   \someshapeleftfalse
-                 \else
-                   \shapecounter=0
-                   \setbox\newshapebox=
-                     \normalvbox{#1\unvbox\newshapebox}
-                 \fi
-               \fi
-             \else
-               \shapepenalty=\lastpenalty
-               \setbox\newshapebox=
-                 \normalvbox{#2\unvbox\newshapebox}
-               \unpenalty
-             \fi
-           \else
-             \shapekern=\lastkern
-             \setbox\newshapebox=
-               \normalvbox{#3\unvbox\newshapebox}
-             \unkern
-           \fi
-         \else
-           \shapeskip=\lastskip
-           \setbox\newshapebox=
-             \normalvbox{#4\unvbox\newshapebox}
-           \unskip
-         \fi
-       \ifnum\shapecounter>100 % can be less
-         \message{<<forced exit from shapebox>>}%
-         \someshapeleftfalse
-       \else
-         \advance\shapecounter by 1
-       \fi
-       \ifsomeshapeleft \repeat
-       \unvbox\newshapebox
-     \egroup}
-
-\def\beginofshapebox%
-  {\setbox\oldshapebox=\normalvbox
-     \bgroup
-     \reshapingboxtrue
-     \hbox to \shapesignal{\hss}}
-
-\def\endofshapebox%
-  {\endgraf
-   \egroup}
-
-\let\beginshapebox=\beginofshapebox
-\let\endshapebox  =\endofshapebox
-
-\def\flushshapebox%
-  {\ifdim\ht\newshapebox=\!!zeropoint\relax
-   \else
-     % make \prevdepth legal
-     \par
-     % and take a look
-     \ifdim\prevdepth=\hideskip\relax
-       \prevdepth=\!!zeropoint
-     \fi
-     \ifdim\prevdepth<\!!zeropoint
-       % something like a line or a signal or ...
-     \else
-       \ifinner
-         % not watertight and not ok
-       \else\ifdim\pagegoal=\maxdimen\else
-         % give the previous line a normal depth
-         \vbox to \!!zeropoint{}
-         % go back one line
-         \vskip-\lineheight
-       \fi\fi
-     \fi
-     \unvcopy\newshapebox\relax
-     % \prevdepth=0pt and \dp\newshapebox depend on last line
-     \kern-\dp\newshapebox\relax
-     % now \prevdepth=0pt
-   \fi}
-
-%D For absolute control, one can use \type{\doreshapebox} 
-%D directly. This macro takes four arguments, that take care 
-%D of:
-%D 
-%D \startopsomming[n,opelkaar]
-%D \som \type{\shapebox}
-%D \som \type{\shapepenalty}
-%D \som \type{\shapekern}
-%D \som \type{\shapeskip}
-%D \stopopsomming 
-
-%D \macros
-%D   {hyphenatedword,
-%D    dohyphenateword}
-%D   {}
-%D
-%D The next one is a tricky one. \PLAIN\ \TEX\ provides
-%D \type{\showhyphens} for showing macros on the terminal. When
-%D preparing a long list of words we decided to show the
-%D hyphens, but had to find out that the \PLAIN\ alternative
-%D can hardly be used and|/|or adapted to typesetting. The next
-%D two macros do the job and a little more.
-%D
-%D The simple command \type{\hyphenatedword} accepts one
-%D argument and gives the hyphenated word. This macro calls for
-%D
-%D \starttypen
-%D \dohyphenateword {n} {pre} {word}
-%D \stoptypen
-%D
-%D The next examples tell more than lots of words:
-%D
-%D \startbuffer
-%D \dohyphenateword{0} {}    {dohyphenatedword}
-%D \dohyphenateword{1} {...} {dohyphenatedword}
-%D \dohyphenateword{2} {...} {dohyphenatedword}
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D Here, \type{\hyphenatedword{dohyphenatedword}} is the
-%D shorter alternative for the first line.
-%D
-%D \startvoorbeeld
-%D \haalbuffer
-%D \stopvoorbeeld
-%D
-%D These macros are slow but effective and not that hard to
-%D program at all.
-
-\def\dohyphenateword#1#2#3%
-  {\bgroup
-   \setbox0=\hbox
-     {\mindermeldingen
-      \widowpenalty=0
-      \clubpenalty=0
-      \setbox0=\vbox
-        {\hsize\!!zeropoint \ #3}%
-      \ifnum#1>0
-        \dorecurse{#1}
-          {\setbox2=\hbox
-             {\vsplit0 to \baselineskip}}%
-        #2%
-      \fi
-      \loop
-        \setbox2=\hbox
-          {\vsplit0 to \baselineskip}%
-        \hbox
-          {\unhbox2
-           \setbox2=\lastbox
-           \vbox
-             {\unvbox2
-              \setbox2=\lastbox
-              \hbox{\unhbox2}}}%
-        \ifdim\ht0>\!!zeropoint
-      \repeat}%
-    \ht0=\ht\strutbox
-    \dp0=\dp\strutbox
-    \box0
-    \egroup}
-
-\def\hyphenatedword%
-  {\dohyphenateword{0}{}}
-
-%D \macros
-%D   {doboundtext}
-%D   {}
-%D
-%D Sometimes there is not enough room to show the complete
-%D (line of) text. In such a situation we can strip of some
-%D characters by using \type{\doboundtext}. When the text is
-%D wider than the given width, it's split and the third
-%D argument is appended. When the text to be checked is packed
-%D in a command, we'll have to use \type{\expandafter}.
-%D
-%D \starttypen
-%D \doboundtext{a very, probably to long, text}{3cm}{...}
-%D \stoptypen
-%D
-%D When calculating the room needed, we take the width of the
-%D third argument into account, which leads to a bit more
-%D complex macro than needed at first sight.
-
-\def\dodoboundtext#1%
-  {\setbox0=\hbox{\unhcopy0 #1}%
-   \ifdim\wd0>\dimen0
-     \let\dodoboundtext=\gobbleoneargument
-   \else
-     #1\relax
-   \fi}
-
-\def\doboundtext#1#2#3%
-  {\hbox
-     {\setbox0=\hbox{#1}%
-      \dimen0=#2\relax
-      \ifdim\wd0>\dimen0
-        \setbox2=\hbox{#3}%
-        \advance\dimen0 by -\wd2
-        \setbox0=\hbox{}%
-        \processtokens
-          {\dodoboundtext}
-          {\dodoboundtext}
-          {}
-          {\space}
-          {#1}%
-        \box2
-      \else
-        \box0
-      \fi}}
-
-%D \macros
-%D   {limitatetext}
-%D   {}
-%D
-%D A bit more beautiful alternative for the previous command is
-%D the next one. This command is more robust because we let
-%D \TEX\ do most of the job. The previous command works better
-%D on text that cannot be hyphenated.
-%D
-%D \starttypen
-%D \limitatetext {text} {width} {sentinel}
-%D \stoptypen
-%D
-%D When no width is given, the whole text comes available. The
-%D sentinel is optional.
-
-\def\limitatetext#1#2#3%
-  {\doifelse{#2}{}
-     {#1}
-     {\bgroup
-      \setbox0=\hbox{#1}%
-      \dimen0=#2\relax
-      \ifdim\wd0>\dimen0
-        \setbox2=\hbox{\ #3}%
-        \advance\dimen0 by -\wd2
-        \setbox0=\vbox
-          {\hsize=\dimen0\relax
-           \hfuzz\maxdimen
-           \raggedright
-           \strut\unhbox0}%
-           \vbox % if omitted: missing brace reported
-             {\setbox0=\vsplit0 to \ht\strutbox
-              \unvbox0
-              \setbox0=\lastbox
-              \unhbox0\kern0pt\box2}%
-      \else
-        \unhbox0
-      \fi
-      \egroup}}
-
-%D \macros
-%D   {processisolatedwords,betweenisolatedwords}
-%D   {}
-%D
-%D References are often made up of one word or a combination
-%D of tightly connected words. The typeset text {\bf
-%D chapter~5} is for instance the results of the character
-%D sequence:
-%D
-%D \starttypen
-%D The typeset text \in{chapter}[texniques] is for instance
-%D \stoptypen
-%D
-%D When such words are made active in interactive texts, the
-%D combination cannot longer be hyphenated. Normally this is no
-%D problem, because \TEX\ tries to prevent hyphenation as best
-%D as can.
-%D
-%D Sometimes however we need a few more words to make things
-%D clear, like when we want to refer to {\bf \TEX\ by Topic}.
-%D The macros that are responsible for typesetting hyperlinks,
-%D take care of such sub||sentences by breaking them up in
-%D words. Long ago we processed words using the space as a
-%D separator, but the more advanced our interactive text became,
-%D the more we needed a robust solution. Well, here it is and
-%D it called as:
-%D
-%D \starttypen
-%D \processisolatedwords{some words}\someaction
-%D \stoptypen
-%D
-%D The second argument \type{someactions} handles the
-%D individual words, like in:
-%D
-%D \startbuffer
-%D \processisolatedwords{some more words}           \ruledhbox \par
-%D \processisolatedwords{and some $x + y = z$ math} \ruledhbox \par
-%D \processisolatedwords{and a \hbox{$x + y = z$}}  \ruledhbox \par
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D which let the words turn up as:
-%D
-%D \startvoorbeeld
-%D \haalbuffer
-%D \stopvoorbeeld
-%D
-%D The macro has been made a bit more clever than needed at
-%D first sight. This is due to the fact that we don't want to
-%D generate more overhead in terms of interactive commands than
-%D needed.
-%D
-%D \startbuffer
-%D \processisolatedwords{see this \ruledhskip1em}     \ruledhbox
-%D \processisolatedwords{and \ruledhskip1em this one} \ruledhbox
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D becomes:
-%D
-%D \startvoorbeeld
-%D \startregels
-%D \haalbuffer
-%D \stopregels
-%D \stopvoorbeeld
-%D
-%D Single word arguments are treated without further
-%D processing. This was needed because this command is used in
-%D the \type{\goto} command, to which we sometimes pass very
-%D strange and|/|or complicated arguments or simply boxes
-%D whose dimensions are to be left intact.
-%D
-%D First we build a \type{\hbox}. This enables us to save the
-%D last skip. Next we fill a \type{\vbox} without hyphenating
-%D words. After we've tested if there is more than one word, we
-%D start processing the individual lines (words). We need some
-%D splitting, packing and unpacking to get the spacing and
-%D dimensions right.
-%D
-%D Normally the isolated words are separated by space, but 
-%D one can overrule this separator by changing the next macros.
-
-\def\betweenisolatedwords%
-  {\hskip\fontdimen2\font\!!plus\fontdimen3\font\!!minus\fontdimen4\font}
-
-\def\processisolatedwords#1#2%
-  {\bgroup
-   \mindermeldingen
-   \forgetall
-   \setbox0=\hbox
-     {#1%
-      \xdef\isolatedlastskip{\the\lastskip}}%
-   \setbox2=\vbox
-     {\hyphenpenalty10000
-      \hsize\!!zeropoint
-      \unhcopy0}% == #1
-   \ifdim\ht0=\ht2
-      #2{\unhcopy0}% == #2{#1}
-   \else
-     \setbox0=\hbox
-       {\ignorespaces
-        \loop
-          \setbox4=\hbox
-            {\vsplit2 to \baselineskip}%
-          \hbox
-            {\unhbox4
-             \setbox4=\lastbox
-             \vbox                  % outer \hbox needed 
-               {\unvbox4            % for nested use   
-                \setbox4=\lastbox
-                \hbox{#2{\hbox{\unhbox4}}}}}% 
-        \ifdim\ht2>\!!zeropoint \betweenisolatedwords \repeat
-        \unskip}%
-      \unhbox0\unskip\hskip\isolatedlastskip
-    \fi
-    \egroup}
-
-%D \macros
-%D   {sbox}
-%D   {}
-%D
-%D This is a rather strange command. It grabs some box content
-%D and and limits the size to the height and depth of a
-%D \type{\strut}. The resulting bottom||alligned box can be used
-%D aside other ones, without disturbing the normal baseline
-%D distance.
-%D
-%D \startbuffer
-%D \ruledhbox to .5\hsize{\sbox{eerste\par tweede \par derde}}
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D Shows up as:
-%D
-%D \startvoorbeeld
-%D \vskip3\baselineskip
-%D \haalbuffer
-%D \stopvoorbeeld
-%D
-%D Before displaying the result we added some skip, otherwise
-%D the first two lines would have ended up in the text. This
-%D macro can be useful when building complicated menus, headers
-%D and footers and|/|or margin material.
-%D
-%D {\em This macro still needs some improvement.}
-
-\def\sbox%  in handleiding, voorbeeld \inlinker{xx} \extern..
-  {\dowithnextbox
-     {\setbox0=\hbox
-        {\strut
-         \dp\nextbox=0pt
-         \lower\strutdepth\box\nextbox}%
-      \dp0=\strutdepth
-      \ht0=\strutheight
-      \box0}%
-     \vbox}
-
-%D \macros
-%D   {centeredbox}
-%D   {}
-%D
-%D Here is another strange one. This one offers a sort of overlay
-%D with positive or negative offsets. This command can be used
-%D in well defined areas where no offset options are available.
-%D We first used it when building a button inside the margin
-%D footer, where the button should have a horizontal offset and
-%D should be centered with respect to the surrounding box. The
-%D last of the three examples we show below says:
-%D
-%D \starttypen
-%D \vsize=3cm
-%D \hsize=3cm
-%D \ruledvbox to \vsize
-%D   {\centeredbox height .5cm width -1cm
-%D      {\vrule width \hsize height \vsize}}}
-%D \stoptypen
-%D
-%D Here the \type{\ruledvbox} just shows the surrounding box
-%D and \type{\vrule} is used to show the centered box.
-%D
-%D \def\AnExample#1#2%
-%D   {\vsize=3cm
-%D    \hsize=3cm
-%D    \ruledvbox to \vsize
-%D      {\centeredbox height #1 width #2
-%D         {\color[groen]{\vrule width \hsize height \vsize}}}}
-%D
-%D \startregelcorrectie
-%D \startcombinatie[3*1]
-%D   {\AnExample {-1cm}  {.5cm}} {}
-%D   {\AnExample {.5cm}  {-1cm}} {}
-%D   {\AnExample {-1cm} {-.5cm}} {}
-%D \stopcombinatie
-%D \stopregelcorrectie
-%D
-%D This command takes two optional arguments: \type{width} and
-%D \type{height}. Observing readers can see that we use \TEX's
-%D own scanner for grabbing these arguments: \type{#1#} reads
-%D everyting till the next brace and passes it to both rules.
-%D The setting of the box dimensions at the end is needed for
-%D special cases. The dimensions of the surounding box are kept
-%D intact. This commands handles positive and negative
-%D dimensions (which is why we need two boxes with rules).
-
-\def\centeredbox#1#%   height +/-dimen width +/-dimen
-  {\bgroup
-   \setbox0=\vbox to \vsize
-     \bgroup
-       \mindermeldingen
-       \forgetall
-       \setbox0=\hbox{\vrule\!!width\!!zeropoint#1}%
-       \setbox2=\vbox{\hrule\!!height\!!zeropoint#1}%
-       \advance\vsize by \ht2
-       \advance\hsize by \wd0
-       \vbox to \vsize
-         \bgroup
-           \vskip-\ht2
-           \vss
-           \hbox to \hsize
-             \bgroup
-               \dowithnextbox
-                 {\hskip-\wd0
-                  \hss
-                  \box\nextbox
-                  \hss
-             \egroup
-           \vss
-         \egroup
-     \egroup
-     \wd0=\hsize
-     \ht0=\vsize
-     \box0
-     \egroup}
-   \hbox}
-
-%D \macros
-%D   {setrigidcolumnhsize,rigidcolumnbalance}
-%D
-%D These macros are copied from the \TEX book, page~397, and
-%D extended by a macro that sets the \type{\hsize}.
-%D
-%D \starttypen
-%D \setrigidcolumnhsize {total width} {distance} {n}
-%D \rigidcolumnbalance  {box} {n}
-%D \stoptypen
-%D
-%D Both these macros are for instance used in typesetting
-%D footnotes.
-%D
-%D Men kan het proces van breken enigzins beinvloeden met de 
-%D volgende twee swithes:
-
-\newif\ifalignrigidcolumns      
-\newif\ifstretchrigidcolumns    
-
-%D De eerste switch bepaald het uitlijnen, de tweede rekt de 
-%D individuele kolommen op naar \type{\vsize}.
-
-\def\setrigidcolumnhsize#1#2#3%
-  {\hsize=#1\relax
-   \scratchdimen=-#2\relax
-   \multiply\scratchdimen by #3\relax
-   \advance\scratchdimen by #2\relax
-   \advance\hsize by \scratchdimen
-   \divide\hsize by #3\relax}
-
-\def\rigidcolumnbalance#1#2%
-  {\global\chardef\rigidcolumnbox=#1\relax
-   \global\chardef\rigidcolumns=#2\relax
-   \ifnum\rigidcolumns=1
-     \ifinner\ifhmode\box\else\unvbox\fi\else\unvbox\fi\rigidcolumnbox
-   \else
-     \line
-       {\vbadness=10000
-        \tabskip\!!zeropoint
-        \splittopskip=\ht\strutbox
-        %\scratchdimen=\ht\rigidcolumnbox      % sensitive for overflow
-        %\divide\scratchdimen by \rigidcolumns % therefore we need the hack:
-        \scratchdimen=1pt 
-        \divide\scratchdimen by \rigidcolumns
-        \expanded{\scratchdimen=\withoutpt{\the\scratchdimen}\ht\rigidcolumnbox}%
-        \advance\scratchdimen by \ht\strutbox 
-        \valign{##\vfill\cr\dorigidcolumnsplits}}%
-   \fi}
-
-\def\dorigidcolumnsplits%
-  {\ifnum\rigidcolumns>0
-     \setbox\scratchbox=\vsplit\rigidcolumnbox to \scratchdimen
-     \ifalignrigidcolumns
-       \vbox to \ifstretchrigidcolumns\vsize\else\scratchdimen\fi
-         {\unvbox\scratchbox}%
-     \else
-       \vbox{\unvbox\scratchbox}%
-     \fi
-     \doglobal\decrement\rigidcolumns
-     \cr
-     \ifnum\rigidcolumns>0\noalign{\hfil}\fi
-     \expandafter\dorigidcolumnsplits
-   \fi}
-
-%D \macros
-%D   {startvboxtohbox,stopvboxtohbox,convertvboxtohbox}
-%D
-%D Here is another of Knuth's dirty tricks, as presented on
-%D pages 398 and 399 of the \TEX book. These macros can be used
-%D like:
-%D
-%D \starttypen
-%D \vbox
-%D   \bgroup
-%D     \startvboxtohbox ... \stopvboxtohbox
-%D     \startvboxtohbox ... \stopvboxtohbox
-%D     \startvboxtohbox ... \stopvboxtohbox
-%D   \egroup
-%D
-%D \vbox
-%D   \bgroup
-%D     \converthboxtovbox
-%D   \egroup
-%D \stoptypen
-%D
-%D These macros are used in reformatting footnotes, so they do
-%D what they're meant for.
-
-\def\setvboxtohbox%
-  {\bgroup
-   \ifdim\baselineskip<16pt \relax
-     \dimen0=\baselineskip
-     \multiply\dimen0 by 1024
-   \else
-     \message{cropping \baselineskip to 16pt}%
-     \baselineskip=\maxdimen
-   \fi
-   \divide\dimen0 by \hsize
-   \multiply\dimen0 by 64
-   \xdef\vboxtohboxfactor{\expandafter\withoutpt\the\dimen0}%
-   \egroup}
-
-\def\startvboxtohbox%
- {\bgroup
-  \setvboxtohbox
-  \setbox0=\hbox\bgroup}
-
-\def\stopvboxtohbox%
-  {\egroup
-   \dp0=\!!zeropoint
-   \ht0=\vboxtohboxfactor\wd0
-   \box0
-   \egroup}
-
-\def\convertvboxtohbox%
-  {\setvboxtohbox
-   \makehboxofhboxes
-   \setbox0=\hbox{\unhbox0 \removehboxes}%
-   \noindent\unhbox0\par}
-
-\def\makehboxofhboxes%
-  {\setbox0=\hbox{}%
-   \loop
-     \setbox2=\lastbox
-     \ifhbox2
-       \setbox0=\hbox{\box2\unhbox0}%
-   \repeat}
-
-\def\removehboxes%
-  {\setbox0=\lastbox
-   \ifhbox0
-     {\removehboxes}%
-     \unhbox0
-   \fi}
-
-%D \macros
-%D   {doifcontent}
-%D
-%D When processing depends on the availability of content, one
-%D can gove the next macro a try.
-%D
-%D \starttypen
-%D \doifcontent{pre content}{post content}{no content}\somebox
-%D \stoptypen
-%D
-%D Where \type{\somebox} is either a \type{\hbox} or
-%D \type{\vbox}. If the dimension of this box suggest some
-%D content, the resulting box is unboxed and surrounded by the
-%D first two arguments, else the third arguments is executed.
-
-\def\doifcontent#1#2#3%
-  {\dowithnextbox
-     {\ifhbox\nextbox
-        \ifdim\wd\nextbox>\!!zeropoint
-          #1\unhbox\nextbox#2\relax
-        \else
-          #3\relax
-        \fi
-      \else
-        \ifdim\ht\nextbox>\!!zeropoint
-          #1\unvbox\nextbox#2\relax
-        \else
-          #3\relax
-        \fi
-      \fi}}
-
-%D So when we say:
-%D
-%D \startbuffer
-%D \doifcontent{[}{]}{}\hbox{content sensitive typesetting}
-%D
-%D \doifcontent{}{\pagina}{}\vbox{content sensitive typesetting}
-%D
-%D \doifcontent{}{}{\message{Didn't you forget something?}}\hbox{}
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D We get:
-%D
-%D \haalbuffer
-%D
-%D Where the last call of course does not show up in this
-%D document, but definitely generates a confusing message.
-
-% maybe some day we need this
-%
-% \def\appendvbox#1%  % uses \box8
-%   {\bgroup
-%    \ifdim\prevdepth<\!!zeropoint
-%      \ifdim\pagetotal=\!!zeropoint
-%        \setbox8=\vtop{\unvcopy#1}%
-%        \hrule\c!!height\!!zeropoint
-%        \kern-\ht8
-%        \box#1\relax
-%      \else
-%        \box#1\relax
-%      \fi
-%    \else
-%      \dimen0=\prevdepth
-%      \hrule\c!!height\!!zeropoint
-%      \setbox8=\vtop{\unvcopy#1}%
-%      \dimen2=\baselineskip
-%      \advance\dimen2 by -\dimen0
-%      \advance\dimen2 by -\ht8
-%      \kern\dimen2
-%      \box#1\relax
-%    \fi
-%    \egroup}
-
-\protect
-
-\endinput
-
\ No newline at end of file
+%D \module
+%D   [       file=supp-box,
+%D        version=1995.10.10,
+%D          title=\CONTEXT\ Support Macros,
+%D       subtitle=Boxes,
+%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. Non||commercial use is
+%C granted.
+
+%D This module implements some box manipulation macros. Some
+%D are quite simple, some are more advanced and when understood
+%D well, all can be of use.
+
+\writestatus{loading}{Context Support Macros / Boxes}
+
+\unprotect
+
+%D \macros
+%D   {nextdepth}
+%D
+%D Let's start with a rather simple declaration. Sometimes we
+%D need to save the \TEX\ \DIMENSION\ \type{\prevdepth} and
+%D append it later on. The name \type{\nextdepth} suits
+%D this purpose well.
+
+\newdimen\nextdepth
+
+%D \macros
+%D   {smashbox}
+%D
+%D Smashing is introduced in \PLAIN\ \TEX, and stands for
+%D reducing the dimensions of a box to zero. The most resolute
+%D one is presented first.
+
+\def\smashbox#1%
+  {\wd#1=\!!zeropoint
+   \ht#1=\!!zeropoint
+   \dp#1=\!!zeropoint}
+
+%D \macros
+%D   {hsmashbox,vsmashbox}
+%D   {}
+%D
+%D Smashing can be used for overlaying boxes. Depending on
+%D the mode, horizontal or vertical, one can use:
+
+\def\hsmashbox#1%
+  {\wd#1=\!!zeropoint}
+
+\def\vsmashbox#1%
+  {\ht#1=\!!zeropoint
+   \dp#1=\!!zeropoint}
+
+%D \macros
+%D   {hsmash,vsmash,
+%D    hsmashed,vsmashed}
+%D   {}
+%D
+%D While the previous macros expected a \BOX, the next act on a
+%D content. They are some subtle differences betreen the smash
+%D and smashed alternatives. The later ones reduce all
+%D dimensions to zero.
+
+\def\hsmash#1%
+  {\bgroup
+   \setbox0=\normalhbox{#1}%
+   \hsmashbox0%
+   \box0
+   \egroup}
+
+\def\vsmash#1%
+  {\bgroup
+   \setbox0=\normalvbox{#1}%
+   \vsmashbox0%
+   \box0
+   \egroup}
+
+\def\hsmashed#1%
+  {\bgroup
+   \setbox0=\normalhbox{#1}%
+   \smashbox0%
+   \box0
+   \egroup}
+
+\def\vsmashed#1%
+  {\bgroup
+   \setbox0=\normalvbox{#1}%
+   \smashbox0%
+   \box0
+   \egroup}
+
+%D \macros
+%D   {getboxheight}
+%D
+%D Although often needed, \TEX\ does not support arithmics
+%D like:
+%D
+%D \starttypen
+%D \dimen0 = \ht0 + \dp0
+%D \stoptypen
+%D
+%D so we implemented:
+%D
+%D \starttypen
+%D \getboxheight ... \of \box...
+%D \stoptypen
+%D
+%D For instance,
+%D
+%D \starttypen
+%D \getboxheight \dimen0 \of \box0
+%D \getboxheight \someheight \of \box \tempbox
+%D \stoptypen
+
+\def\getboxheight#1\of#2\box#3%
+  {#1=\ht#3%
+   \advance#1 by \dp#3\relax}
+
+%D \macros 
+%D   {doiftextelse, doiftext}
+%D
+%D When \type {\doifelse} cum suis hopelessly fail, for 
+%D instance because we pass data, we can fall back on the next 
+%D macro: 
+%D 
+%D \starttypen
+%D \doiftextelse {data} {then branch} {else branch}
+%D \doiftext     {data} {then branch} 
+%D \stoptypen
+
+\def\doiftextelse#1#2#3%
+  {\bgroup
+   \setbox0=\hbox{#1}%
+   \ifdim\wd0>\!!zeropoint
+     \egroup#2%
+   \else
+     \egroup#3%
+   \fi}
+
+\def\doiftext#1#2%
+  {\doiftextelse{#1}{#2}{}}
+
+%D \macros
+%D   {dowithnextbox,
+%D    nextbox}
+%D
+%D Sometimes we want a macro to grab a box and do something
+%D on the content. One could pass an argument to a box, but
+%D this can violate the specific \CATCODES\ of its content and
+%D leads to unexpected results. The next macro treats the
+%D following braced text as the content of a box and
+%D manipulates it afterwards in a predefined way.
+%D
+%D The first argument specifies what to do with the content.
+%D This content is available in \type{\nextbox}. The second
+%D argument is one of \type{\hbox}, \type{\vbox} or
+%D \type{\vtop}. The third argument must be grouped with
+%D \type{\bgroup} and \type{\egroup}, \type{{...}} or can be
+%D a \type{\box} specification.
+%D
+%D In \CONTEXT\ this macro is used for picking up a box and
+%D treating it according to earlier specifications. We use for
+%D instance something like:
+%D
+%D \starttypen
+%D \def\getfloat%
+%D   {\def\handlefloat{...\box\nextbox...}
+%D    \dowithnextbox\handlefloat\vbox}
+%D \stoptypen
+%D
+%D in stead of:
+%D
+%D \starttypen
+%D \def\getfloat#1%
+%D   {...#1...}
+%D \stoptypen
+%D
+%D In this implementation the \type{\aftergroup} construction
+%D is needed because \type{\afterassignment} is executed inside
+%D the box.
+
+\newbox\nextbox
+
+\long\def\dowithnextbox#1%
+  {\long\def\dodowithnextbox{#1}%
+   \afterassignment\dododowithnextbox
+   \setbox\nextbox}
+
+% Better but first to be checked:
+%
+%\long\def\dowithnextbox#1%
+%  {\bgroup\long\def\dodowithnextbox{#1\egroup}%
+%   \afterassignment\dododowithnextbox
+%   \setbox\nextbox}
+
+\def\dododowithnextbox%
+  {\aftergroup\dodowithnextbox}
+
+%D So in fact we get:
+%D
+%D \starttypen
+%D \setbox\nextbox { \aftergroup\dodowithnextbox ... }
+%D \stoptypen
+%D
+%D or
+%D
+%D \starttypen
+%D \setbox\nextbox { ... } \dodowithnextbox
+%D \stoptypen
+%D
+%D A slower but more versatile implementation is:
+%D
+%D \starttypen
+%D \long\def\dowithnextbox#1#2%
+%D   {\long\def\dodowithnextbox{#1}%
+%D    \ifx#2\hbox
+%D      \afterassignment\dododowithnextbox
+%D    \else\ifx#2\vbox
+%D      \afterassignment\dododowithnextbox
+%D    \else\ifx#2\vtop
+%D      \afterassignment\dododowithnextbox
+%D    \else\ifx#2\vcenter
+%D      \afterassignment\dododowithnextbox
+%D    \else
+%D      \afterassignment\dodowithnextbox
+%D    \fi\fi\fi\fi
+%D    \setbox\nextbox#2}
+%D \stoptypen
+%D
+%D This alternative also accepts \type{\box0} and alike, but 
+%D we don't really need this functionality now.  
+
+%D \macros
+%D   {beginofshapebox,
+%D    reshapebox, doreshapebox,
+%D    flushshapebox,
+%D    innerflushshapebox,
+%D    shapebox,
+%D    ifreshapingbox}
+%D
+%D The next utility macro originates from some linenumbering
+%D mechanism. Due to \TEX's advanced way of typesetting
+%D paragraphs, it's not easy to do things on a line||by||line
+%D basis. This macro is able to reprocess a given box and can
+%D act upon its vertical boxed components, such as lines. The
+%D unwinding sequence in this macro is inspired by a \NTG\
+%D workshop of David Salomon in June 1992.
+%D
+%D First we have to grab the piece of text we want to act
+%D upon. This is done by means of the duo macros:
+%D
+%D \starttypen
+%D \beginofshapebox
+%D a piece of text
+%D \endofshapebox
+%D \stoptypen
+%D
+%D When all texts is collected, we can call \type{\reshapebox}
+%D and do something with it's vertical components. We can make
+%D as much passes as needed. When we're done, the box can be
+%D unloaded with \type{\flushshapebox}. The only condition in
+%D this scheme is that \type{\reshapebox} must somehow unload
+%D the \BOX\ \type{\shapebox}.
+%D
+%D An important aspect is that the content is unrolled
+%D bottom||up. The next example illustrates this maybe
+%D unexpected characteristic.
+%D
+%D \startbuffer
+%D \beginofshapebox
+%D \em \input tufte
+%D \endofshapebox
+%D
+%D \newcounter\LineNumber
+%D
+%D \reshapebox
+%D   {\doglobal\increment\LineNumber
+%D    \hbox{\llap{\LineNumber\hskip2em}\box\shapebox}}
+%D
+%D \flushshapebox
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \haalbuffer
+%D
+%D As we can see, when some kind of numbering is done, we have
+%D to add a second pass.
+%D
+%D \startbuffer
+%D \newcounter\LineNumber
+%D \newcounter\NumberOfLines
+%D
+%D \reshapebox
+%D   {\doglobal\increment\NumberOfLines
+%D    \box\shapebox}
+%D
+%D \reshapebox
+%D   {\doglobal\increment\LineNumber
+%D    \hbox
+%D      {\llap{\LineNumber\ (\NumberOfLines)\hskip2em}%
+%D       \box\shapebox}%
+%D    \doglobal\decrement\NumberOfLines}
+%D
+%D \flushshapebox
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \haalbuffer
+%D
+%D This example shows that the content of the box is still
+%D available after flushing. Another feature is that only the
+%D last reshaping counts. Multiple reshaping can be done by:
+%D
+%D \startbuffer
+%D \beginofshapebox
+%D \flushshapebox 
+%D \endofshapebox
+%D
+%D \reshapebox
+%D   {\doglobal\increment\LineNumber
+%D    \hbox{\llap{$\star$\hskip1em}\box\shapebox}%
+%D    \doglobal\decrement\NumberOfLines}
+%D
+%D \flushshapebox
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \haalbuffer
+%D
+%D The macros are surprisingly easy to follow and in fact
+%D introduce no new concepts. Nearly all books on \TEX\ show
+%D similar solutions for unwinding \BOXES.
+%D
+%D Some macros, like footnote ones, can be sensitive for
+%D reshaping, which can result in an endless loop. We
+%D therefore offer:
+%D
+%D \starttypen
+%D \ifreshapingbox
+%D \stoptypen
+%D
+%D Some \CONTEXT\ commands are protected this way. Anyhow,
+%D reshaping is aborted after 100 dead cycles.
+%D
+%D By the way, changing the height and depth of \BOX\
+%D \type{\shapebox} results in bad spacing. This means that
+%D for instance linenumbers etc. should be given zero height
+%D and depth before being lapped into the margin. The
+%D previous examples ignore this side effect, but beware!
+
+\newif\ifsomeshapeleft
+\newif\ifreshapingbox
+
+\def\shapesignal {.12345678pt}
+
+\newbox   \shapebox
+\newcount \shapepenalty
+\newdimen \shapekern
+\newskip  \shapeskip
+
+\newbox\newshapebox
+\newbox\oldshapebox
+
+\newcount\shapecounter
+
+\def\reshapebox#1%
+  {\doreshapebox
+     {#1}
+     {\penalty\shapepenalty}
+     {\kern\shapekern}
+     {\vskip\shapeskip}}
+
+\def\doreshapebox#1#2#3#4% \shapebox, \shapepenalty, \shapekern, \shapeskip
+  {\setbox\newshapebox=\normalvbox
+     \bgroup
+       \unvcopy\oldshapebox
+       \setbox\newshapebox=\box\voidb@x
+       \shapecounter=0
+       \loop
+         \someshapelefttrue
+         \ifdim\lastskip=\!!zeropoint\relax
+           \ifdim\lastkern=\!!zeropoint\relax
+             \ifnum\lastpenalty=0
+               \setbox\shapebox=\lastbox
+               \ifvoid\shapebox
+                 \unskip\unpenalty\unkern
+               \else
+                 \ifdim\wd\shapebox=\shapesignal\relax
+                   \someshapeleftfalse
+                 \else
+                   \shapecounter=0
+                   \setbox\newshapebox=
+                     \normalvbox{#1\unvbox\newshapebox}
+                 \fi
+               \fi
+             \else
+               \shapepenalty=\lastpenalty
+               \setbox\newshapebox=
+                 \normalvbox{#2\unvbox\newshapebox}
+               \unpenalty
+             \fi
+           \else
+             \shapekern=\lastkern
+             \setbox\newshapebox=
+               \normalvbox{#3\unvbox\newshapebox}
+             \unkern
+           \fi
+         \else
+           \shapeskip=\lastskip
+           \setbox\newshapebox=
+             \normalvbox{#4\unvbox\newshapebox}
+           \unskip
+         \fi
+       \ifnum\shapecounter>100 % can be less
+         \message{<<forced exit from shapebox>>}%
+         \someshapeleftfalse
+       \else
+         \advance\shapecounter by 1
+       \fi
+       \ifsomeshapeleft \repeat
+       \unvbox\newshapebox
+     \egroup}
+
+\def\beginofshapebox%
+  {\setbox\oldshapebox=\normalvbox
+     \bgroup
+     \reshapingboxtrue
+     \hbox to \shapesignal{\hss}}
+
+\def\endofshapebox%
+  {\endgraf
+   \egroup}
+
+\let\beginshapebox=\beginofshapebox
+\let\endshapebox  =\endofshapebox
+
+\def\flushshapebox%
+  {\ifdim\ht\newshapebox=\!!zeropoint\relax
+   \else
+     % make \prevdepth legal
+     % \par before the next \vskip gives far worse results
+     \ifdim\parskip>\!!zeropoint\vskip\parskip\else\par\fi 
+     % and take a look
+     \ifdim\prevdepth=-1000pt 
+       \prevdepth=\!!zeropoint
+     \fi
+     \ifdim\prevdepth<\!!zeropoint\relax
+       % something like a line or a signal or ...
+       \donetrue
+     \else\ifinner
+       % not watertight and not ok
+       \donefalse
+     \else\ifdim\pagegoal=\maxdimen
+       \donetrue
+     \else
+       % give the previous line a normal depth
+       \donetrue
+       \vbox{\forgetall\strut}\nobreak\kern-\lineheight % geen \vskip
+       \vskip-\dp\strutbox 
+     \fi\fi\fi
+     \unvcopy\newshapebox\relax
+     % \prevdepth=0pt and \dp\newshapebox depend on last line
+     \kern-\dp\newshapebox\relax
+     % now \prevdepth=0pt
+     \ifdone
+       \kern\dp\strutbox 
+       \prevdepth\dp\strutbox 
+     \fi
+   \fi}
+
+%D In real inner situations we can use: 
+%D
+%D \starttypen
+%D \flushinnershapebox
+%D \stoptypen
+%D
+%D This one is used in \type{\framed}. 
+
+\def\innerflushshapebox%
+  {\ifdim\ht\newshapebox=\!!zeropoint\relax
+   \else
+     \unvcopy\newshapebox\relax
+     \kern-\dp\newshapebox\relax
+   \fi}
+
+%D For absolute control, one can use \type{\doreshapebox} 
+%D directly. This macro takes four arguments, that take care 
+%D of:
+%D 
+%D \startopsomming[n,opelkaar]
+%D \som \type{\shapebox}
+%D \som \type{\shapepenalty}
+%D \som \type{\shapekern}
+%D \som \type{\shapeskip}
+%D \stopopsomming 
+
+%D \macros
+%D   {hyphenatedword,
+%D    dohyphenateword}
+%D
+%D The next one is a tricky one. \PLAIN\ \TEX\ provides
+%D \type{\showhyphens} for showing macros on the terminal. When
+%D preparing a long list of words we decided to show the
+%D hyphens, but had to find out that the \PLAIN\ alternative
+%D can hardly be used and|/|or adapted to typesetting. The next
+%D two macros do the job and a little more.
+%D
+%D The simple command \type{\hyphenatedword} accepts one
+%D argument and gives the hyphenated word. This macro calls for
+%D
+%D \starttypen
+%D \dohyphenateword {n} {pre} {word}
+%D \stoptypen
+%D
+%D The next examples tell more than lots of words:
+%D
+%D \startbuffer
+%D \dohyphenateword{0} {}    {dohyphenatedword}
+%D \dohyphenateword{1} {...} {dohyphenatedword}
+%D \dohyphenateword{2} {...} {dohyphenatedword}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D Here, \type{\hyphenatedword{dohyphenatedword}} is the
+%D shorter alternative for the first line.
+%D
+%D \startvoorbeeld
+%D \haalbuffer
+%D \stopvoorbeeld
+%D
+%D These macros are slow but effective and not that hard to
+%D program at all.
+
+\def\dohyphenateword#1#2#3%
+  {\bgroup
+   \setbox0=\hbox
+     {\mindermeldingen
+      \widowpenalty=0
+      \clubpenalty=0
+      \setbox0=\vbox
+        {\hsize\!!zeropoint \ #3}%
+      \ifnum#1>0
+        \dorecurse{#1}
+          {\setbox2=\hbox
+             {\splittopskip=\openstrutheight
+              \vsplit0 to \baselineskip}}%
+        #2%
+      \fi
+      \loop
+        \setbox2=\hbox
+          {\splittopskip=\openstrutheight
+           \vsplit0 to \baselineskip}%
+        \hbox
+          {\unhbox2
+           \setbox2=\lastbox
+           \vbox
+             {\unvbox2
+              \setbox2=\lastbox
+              \hbox{\unhbox2}}}%
+        \ifdim\ht0>\!!zeropoint
+      \repeat}%
+    \ht0=\ht\strutbox
+    \dp0=\dp\strutbox
+    \box0
+    \egroup}
+
+\def\hyphenatedword%
+  {\dohyphenateword{0}{}}
+
+%D \macros
+%D   {doboundtext}
+%D
+%D Sometimes there is not enough room to show the complete
+%D (line of) text. In such a situation we can strip of some
+%D characters by using \type{\doboundtext}. When the text is
+%D wider than the given width, it's split and the third
+%D argument is appended. When the text to be checked is packed
+%D in a command, we'll have to use \type{\expandafter}.
+%D
+%D \starttypen
+%D \doboundtext{a very, probably to long, text}{3cm}{...}
+%D \stoptypen
+%D
+%D When calculating the room needed, we take the width of the
+%D third argument into account, which leads to a bit more
+%D complex macro than needed at first sight.
+
+\def\dodoboundtext#1%
+  {\setbox0=\hbox{\unhcopy0 #1}%
+   \ifdim\wd0>\dimen0
+     \let\dodoboundtext=\gobbleoneargument
+   \else
+     #1\relax
+   \fi}
+
+\def\doboundtext#1#2#3%
+  {\hbox
+     {\setbox0=\hbox{#1}%
+      \dimen0=#2\relax
+      \ifdim\wd0>\dimen0
+        \setbox2=\hbox{#3}%
+        \advance\dimen0 by -\wd2
+        \setbox0=\hbox{}%
+        \processtokens
+          {\dodoboundtext}
+          {\dodoboundtext}
+          {}
+          {\space}
+          {#1}%
+        \box2
+      \else
+        \box0
+      \fi}}
+
+%D \macros
+%D   {limitatetext}
+%D
+%D A bit more beautiful alternative for the previous command is
+%D the next one. This command is more robust because we let
+%D \TEX\ do most of the job. The previous command works better
+%D on text that cannot be hyphenated.
+%D
+%D \starttypen
+%D \limitatetext {text} {width} {sentinel}
+%D \stoptypen
+%D
+%D When no width is given, the whole text comes available. The
+%D sentinel is optional. This is about the third version. 
+
+\ifx\fakecompoundhyphen\undefined \let\fakecompoundhyphen\relax \fi
+
+\unexpanded\def\limitatetext%
+  {\bgroup
+   \dowithnextbox\dolimitatetext\hbox}
+
+\def\dolimitatetext#1#2%
+  {\doifelsenothing{#1}
+     {\unhbox\nextbox}
+     {\fakecompoundhyphen
+      \scratchdimen=#1\relax
+      \ifdim\wd\nextbox>\scratchdimen
+        \setbox\scratchbox=\hbox{ #2}%
+        \advance\scratchdimen by -\wd\scratchbox
+        \setbox\nextbox=\vbox
+          {\hsize=\scratchdimen
+           \hfuzz\maxdimen
+           \veryraggedright
+           \strut\unhbox\nextbox}%
+        \setbox\nextbox=\vbox % if omitted: missing brace reported
+          {\splittopskip=\openstrutheight
+           \setbox\nextbox=\vsplit\nextbox to \ht\strutbox
+           \unvbox\nextbox
+           \setbox\nextbox=\lastbox
+           \global\setbox1=\hbox
+             {\unhbox\nextbox\unskip\kern\!!zeropoint\box\scratchbox\unskip}}%
+        \unhbox1
+      \else
+        \unhbox\nextbox
+      \fi}%
+   \egroup}
+
+%D \macros
+%D   {processisolatedwords,
+%D    betweenisolatedwords,nothingbetweenisolatedwords}
+%D
+%D References are often made up of one word or a combination
+%D of tightly connected words. The typeset text {\bf
+%D chapter~5} is for instance the results of the character
+%D sequence:
+%D
+%D \starttypen
+%D The typeset text \in{chapter}[texniques] is for instance
+%D \stoptypen
+%D
+%D When such words are made active in interactive texts, the
+%D combination cannot longer be hyphenated. Normally this is no
+%D problem, because \TEX\ tries to prevent hyphenation as best
+%D as can.
+%D
+%D Sometimes however we need a few more words to make things
+%D clear, like when we want to refer to {\bf \TEX\ by Topic}.
+%D The macros that are responsible for typesetting hyperlinks,
+%D take care of such sub||sentences by breaking them up in
+%D words. Long ago we processed words using the space as a
+%D separator, but the more advanced our interactive text became,
+%D the more we needed a robust solution. Well, here it is and
+%D it called as:
+%D
+%D \starttypen
+%D \processisolatedwords{some words}\someaction
+%D \stoptypen
+%D
+%D The second argument \type{someactions} handles the
+%D individual words, like in:
+%D
+%D \startbuffer
+%D \processisolatedwords{some more words}           \ruledhbox \par
+%D \processisolatedwords{and some $x + y = z$ math} \ruledhbox \par
+%D \processisolatedwords{and a \hbox{$x + y = z$}}  \ruledhbox \par
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D which let the words turn up as:
+%D
+%D \startvoorbeeld
+%D \haalbuffer
+%D \stopvoorbeeld
+%D
+%D The macro has been made a bit more clever than needed at
+%D first sight. This is due to the fact that we don't want to
+%D generate more overhead in terms of interactive commands than
+%D needed.
+%D
+%D \startbuffer
+%D \processisolatedwords{see this \ruledhskip1em}     \ruledhbox
+%D \processisolatedwords{and \ruledhskip1em this one} \ruledhbox
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D becomes:
+%D
+%D \startvoorbeeld
+%D \startregels
+%D \haalbuffer
+%D \stopregels
+%D \stopvoorbeeld
+%D
+%D Single word arguments are treated without further
+%D processing. This was needed because this command is used in
+%D the \type{\goto} command, to which we sometimes pass very
+%D strange and|/|or complicated arguments or simply boxes
+%D whose dimensions are to be left intact.
+%D
+%D First we build a \type{\hbox}. This enables us to save the
+%D last skip. Next we fill a \type{\vbox} without hyphenating
+%D words. After we've tested if there is more than one word, we
+%D start processing the individual lines (words). We need some
+%D splitting, packing and unpacking to get the spacing and
+%D dimensions right.
+%D
+%D Normally the isolated words are separated by space, but 
+%D one can overrule this separator by changing the next macros.
+%D
+%D When needed, spacing can be suppressed by \type 
+%D {\nothingbetweenisolatedwords}.
+
+\newif\ifisolatedwords
+
+\def\betweenisolatedwords%
+  {\hskip\currentspaceskip} 
+
+\def\setbetweenisolatedwords#1%
+  {\gdef\localbetweenisolatedwords{#1}}
+
+\def\processisolatedwords#1#2%
+  {\bgroup
+   \fakecompoundhyphen
+   \mindermeldingen
+   \forgetall
+   \global\let\localbetweenisolatedwords\betweenisolatedwords
+   \setbox0=\hbox
+     {\ignorespaces#1%
+      \xdef\isolatedlastskip{\the\lastskip}}%
+   \setbox2=\vbox
+     {%\hyphenpenalty10000       % this one fails in \url breaking, 
+      \lefthyphenmin=\!!maxcard  % but this trick works ok, due to them
+      \righthyphenmin=\!!maxcard % total>63, when no hyphenation is done
+      \hsize\!!zeropoint
+      \unhcopy0}% == #1
+   \ifdim\ht0=\ht2
+      \isolatedwordsfalse
+      #2{\unhcopy0}% == #2{#1}
+   \else
+     \isolatedwordstrue
+     \setbox0=\hbox
+       {\ignorespaces
+        \loop
+          \setbox4=\hbox
+            {\splittopskip=\openstrutheight
+             \vsplit2 to \baselineskip}%
+          \hbox
+            {\unhbox4\unskip % recently added 
+             \setbox4=\lastbox
+             \vbox                  % outer \hbox needed 
+               {\unvbox4            % for nested use   
+                \setbox4=\lastbox
+                \hbox{#2{\hbox{\unhbox4}}}}}% 
+        \ifdim\ht2>\!!zeropoint \localbetweenisolatedwords \repeat
+        \unskip}%
+      \unhbox0\unskip\hskip\isolatedlastskip
+    \fi
+    \egroup}
+
+%D \macros
+%D   {sbox}
+%D
+%D This is a rather strange command. It grabs some box content
+%D and and limits the size to the height and depth of a
+%D \type{\strut}. The resulting bottom||alligned box can be used
+%D aside other ones, without disturbing the normal baseline
+%D distance.
+%D
+%D \startbuffer
+%D \ruledhbox to .5\hsize{\sbox{eerste\par tweede \par derde}}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D Shows up as:
+%D
+%D \startvoorbeeld
+%D \vskip3\baselineskip
+%D \haalbuffer
+%D \stopvoorbeeld
+%D
+%D Before displaying the result we added some skip, otherwise
+%D the first two lines would have ended up in the text. This
+%D macro can be useful when building complicated menus, headers
+%D and footers and|/|or margin material.
+%D
+%D {\em This macro still needs some improvement.}
+
+\def\sbox%  in handleiding, voorbeeld \inlinker{xx} \extern..
+  {\dowithnextbox
+     {\setbox0=\hbox
+        {\strut
+         \dp\nextbox=0pt
+         \lower\strutdepth\box\nextbox}%
+      \dp0=\strutdepth
+      \ht0=\strutheight
+      \box0}%
+     \vbox}
+
+%D \macros
+%D   {centeredbox, centerednextbox}
+%D
+%D Here is another strange one. This one offers a sort of overlay
+%D with positive or negative offsets. This command can be used
+%D in well defined areas where no offset options are available.
+%D We first used it when building a button inside the margin
+%D footer, where the button should have a horizontal offset and
+%D should be centered with respect to the surrounding box. The
+%D last of the three examples we show below says:
+%D
+%D \starttypen
+%D \vsize=3cm
+%D \hsize=3cm
+%D \ruledvbox to \vsize
+%D   {\centeredbox height .5cm width -1cm
+%D      {\vrule width \hsize height \vsize}}}
+%D \stoptypen
+%D
+%D Here the \type{\ruledvbox} just shows the surrounding box
+%D and \type{\vrule} is used to show the centered box.
+%D
+%D \def\AnExample#1#2%
+%D   {\vsize=3cm
+%D    \hsize=3cm
+%D    \ruledvbox to \vsize
+%D      {\centeredbox height #1 width #2
+%D         {\color[groen]{\vrule width \hsize height \vsize}}}}
+%D
+%D \startregelcorrectie
+%D \startcombinatie[3*1]
+%D   {\AnExample {-1cm}  {.5cm}} {}
+%D   {\AnExample {.5cm}  {-1cm}} {}
+%D   {\AnExample {-1cm} {-.5cm}} {}
+%D \stopcombinatie
+%D \stopregelcorrectie
+%D
+%D This command takes two optional arguments: \type{width} and
+%D \type{height}. Observing readers can see that we use \TEX's
+%D own scanner for grabbing these arguments: \type{#1#} reads
+%D everyting till the next brace and passes it to both rules.
+%D The setting of the box dimensions at the end is needed for
+%D special cases. The dimensions of the surrounding box are kept
+%D intact. This commands handles positive and negative
+%D dimensions (which is why we need two boxes with rules).
+
+\def\centeredbox#1#%   height +/-dimen width +/-dimen
+  {\bgroup
+   \setbox0=\vbox to \vsize
+     \bgroup
+       \mindermeldingen
+       \forgetall
+       \setbox0=\hbox{\vrule\!!width\!!zeropoint#1}%
+       \setbox2=\vbox{\hrule\!!height\!!zeropoint#1}%
+       \advance\vsize by \ht2
+       \advance\hsize by \wd0
+       \vbox to \vsize
+         \bgroup
+           \vskip-\ht2
+           \vss
+           \hbox to \hsize
+             \bgroup
+               \dowithnextbox
+                 {\hskip-\wd0
+                  \hss
+                  \box\nextbox
+                  \hss
+             \egroup
+           \vss
+         \egroup
+     \egroup
+     \wd0=\hsize
+     \ht0=\vsize
+     \box0
+     \egroup}
+   \hbox}
+
+%D For those who don't want to deal with \type {\hsize}
+%D and \type {\vsize}, we have: 
+%D 
+%D \starttypen
+%D \centerednextbox width 2bp height 2bp 
+%D   {\framed[width=100bp,height=100bp]{}}
+%D \stoptypen
+%D 
+%D Do you see what we call this one \type {next}?
+
+\def\centerednextbox#1#%
+  {\bgroup
+   \dowithnextbox
+     {\hsize\wd\nextbox
+      \vsize\ht\nextbox
+      \centeredbox#1{\box\nextbox}%
+      \egroup}
+   \hbox}
+
+%D \macros 
+%D   {centerbox}
+%D
+%D Centering on the available space is done by: 
+%D
+%D \starttypen
+%D \centeredbox <optional specs> {content}
+%D \stoptypen
+%D
+%D When omitted, the current \type {\hsize} and \type 
+%D {\vsize} are used. Local dimensions are supported. 
+
+\def\centerbox#1#%   optional height +/-dimen width +/-dimen
+  {\bgroup
+   \dowithnextbox
+     {\setlocalhsize
+      \setbox0=\hbox{\vrule\!!width\!!zeropoint#1}%
+      \setbox2=\vbox{\hrule\!!height\!!zeropoint#1}%
+      \hsize\ifdim\wd0=\!!zeropoint\hsize\else\wd0\fi
+      \vsize\ifdim\ht2=\!!zeropoint\vsize\else\ht2\fi
+      \vbox to \vsize{\vss\hbox to \hsize{\hss\box\nextbox\hss}\vss}%
+      \egroup}%
+     \hbox}
+
+%D \macros
+%D   {setrigidcolumnhsize,rigidcolumnbalance}
+%D
+%D These macros are copied from the \TEX book, page~397, and
+%D extended by a macro that sets the \type{\hsize}.
+%D
+%D \starttypen
+%D \setrigidcolumnhsize {total width} {distance} {n}
+%D \rigidcolumnbalance  {box}
+%D \stoptypen
+%D
+%D Both these macros are for instance used in typesetting
+%D footnotes.
+%D
+%D Men kan het proces van breken enigzins beinvloeden met de 
+%D volgende twee swithes:
+
+\newif\ifalignrigidcolumns      
+\newif\ifstretchrigidcolumns    
+
+%D De eerste switch bepaald het uitlijnen, de tweede rekt de 
+%D individuele kolommen op naar \type{\vsize}.
+
+\def\setrigidcolumnhsize#1#2#3%
+  {\hsize=#1\relax
+   \global\chardef\rigidcolumns=#3\relax
+   \scratchdimen=-#2\relax
+   \multiply\scratchdimen by #3\relax
+   \advance\scratchdimen by #2\relax
+   \advance\hsize by \scratchdimen
+   \divide\hsize by #3\relax}
+
+\def\rigidcolumnbalance#1%
+  {\global\chardef\rigidcolumnbox=#1\relax
+   \ifnum\rigidcolumns=1
+     \ifinner\ifhmode\box\else\unvbox\fi\else\unvbox\fi\rigidcolumnbox
+   \else
+     \line
+       {\vbadness=10000
+        \tabskip\!!zeropoint
+        \splittopskip=\openstrutheight
+        %\scratchdimen=\ht\rigidcolumnbox      % sensitive for overflow
+        %\divide\scratchdimen by \rigidcolumns % therefore we need the hack:
+        \scratchdimen=1pt 
+        \divide\scratchdimen by \rigidcolumns
+        \expanded{\scratchdimen=\withoutpt{\the\scratchdimen}\ht\rigidcolumnbox}%
+        \advance\scratchdimen by \ht\strutbox 
+        \valign{##\vfill\cr\dorigidcolumnsplits}}%
+   \fi}
+
+\def\dorigidcolumnsplits%
+  {\ifnum\rigidcolumns>0
+     \setbox\scratchbox=\vsplit\rigidcolumnbox to \scratchdimen
+     \ifalignrigidcolumns
+       \vbox to \ifstretchrigidcolumns\vsize\else\scratchdimen\fi
+         {\unvbox\scratchbox}%
+     \else
+       \vbox{\unvbox\scratchbox}%
+     \fi
+     \doglobal\decrement\rigidcolumns
+     \cr
+     \ifnum\rigidcolumns>0\noalign{\hfil}\fi
+     \expandafter\dorigidcolumnsplits
+   \fi}
+
+%D \macros
+%D   {startvboxtohbox,stopvboxtohbox,convertvboxtohbox}
+%D
+%D Here is another of Knuth's dirty tricks, as presented on
+%D pages 398 and 399 of the \TEX book. These macros can be used
+%D like:
+%D
+%D \starttypen
+%D \vbox
+%D   \bgroup
+%D     \startvboxtohbox ... \stopvboxtohbox
+%D     \startvboxtohbox ... \stopvboxtohbox
+%D     \startvboxtohbox ... \stopvboxtohbox
+%D   \egroup
+%D
+%D \vbox
+%D   \bgroup
+%D     \converthboxtovbox
+%D   \egroup
+%D \stoptypen
+%D
+%D These macros are used in reformatting footnotes, so they do
+%D what they're meant for.
+
+\def\setvboxtohbox%
+  {\bgroup
+   \ifdim\baselineskip<16pt \relax
+     \dimen0=\baselineskip
+     \multiply\dimen0 by 1024
+   \else
+     \message{cropping \baselineskip to 16pt}%
+     \baselineskip=\maxdimen
+   \fi
+   \divide\dimen0 by \hsize
+   \multiply\dimen0 by 64
+   \xdef\vboxtohboxfactor{\expandafter\withoutpt\the\dimen0}%
+   \egroup}
+
+\def\startvboxtohbox%
+ {\bgroup
+  \setvboxtohbox
+  \setbox0=\hbox\bgroup}
+
+\def\stopvboxtohbox%
+  {\egroup
+   \dp0=\!!zeropoint
+   \ht0=\vboxtohboxfactor\wd0
+   \box0
+   \egroup}
+
+\def\convertvboxtohbox%
+  {\setvboxtohbox
+   \makehboxofhboxes
+   \setbox0=\hbox{\unhbox0 \removehboxes}%
+   \noindent\unhbox0\par}
+
+\def\makehboxofhboxes%
+  {\setbox0=\hbox{}%
+   \loop                  % \doloop { .. \exitloop .. } 
+     \setbox2=\lastbox
+     \ifhbox2
+       \setbox0=\hbox{\box2\unhbox0}%
+   \repeat}
+
+\def\removehboxes%
+  {\setbox0=\lastbox
+   \ifhbox0
+     {\removehboxes}%
+     \unhbox0
+   \fi}
+
+%D \macros 
+%D   {unhhbox}
+%D
+%D The next macro is used in typesetting inline headings. 
+%D Let's first look at the macro and then show an example. 
+
+\newbox   \unhhedbox
+\newbox   \hhbox
+\newdimen \lasthhboxwidth
+\newskip  \hhboxindent
+
+\def\unhhbox#1\with#2%
+  {\bgroup
+   \mindermeldingen
+   \forgetall
+   \setbox\unhhedbox=\vbox{\hskip\hhboxindent\strut\unhbox#1}% => \hsize 
+   \doloop
+     {\setbox\hhbox=\vsplit\unhhedbox to \lineheight 
+      \ifvoid\unhhedbox
+        \setbox\hhbox=\hbox{\strut\hboxofvbox\hhbox}%
+      \fi
+      \ht\hhbox=\ht\strutbox
+      \dp\hhbox=\dp\strutbox
+      \ifdim\hhboxindent=\!!zeropoint\else
+        \setbox\hhbox=\hbox{\hskip-\hhboxindent\box\hhbox}%
+        \hhboxindent=\!!zeropoint
+      \fi
+      \global\lasthhboxwidth=\wd\hhbox
+      #2\relax
+      \ifvoid\unhhedbox
+        \exitloop
+      \else
+        \hskip\!!zeropoint \!!plus \!!zeropoint 
+      \fi}%
+   \egroup}
+
+\def\dohboxofvbox%
+  {\setbox0=\vbox{\unvbox\scratchcounter\global\setbox1=\lastbox}%
+   \unhbox1
+   \egroup}
+
+\def\hboxofvbox%
+  {\bgroup
+   \afterassignment\dohboxofvbox
+   \scratchcounter=}
+
+%D This macro can be used to break a paragraph apart and treat
+%D each line seperately, for instance, making it clickable. The
+%D main complication is that we want to be able to continue the
+%D paragraph, something that's needed in the in line section
+%D headers. 
+%D 
+%D \startbuffer
+%D \setbox0=\hbox{\input tufte \relax}
+%D \setbox2=\hbox{\input knuth \relax}
+%D \unhhbox0\with{\ruledhbox{\box\hhbox}}
+%D \hskip1em plus 1em minus 1em 
+%D \hhboxindent=\lasthhboxwidth 
+%D \advance\hhboxindent by \lastskip
+%D \unhhbox2\with{\ruledhbox{\box\hhbox}}
+%D \stopbuffer
+%D 
+%D \haalbuffer
+%D 
+%D This piece of text was typeset by saying:
+%D 
+%D \typebuffer
+%D 
+%D Not that nice a definition, but effective. Note the stretch 
+%D we've build in the line that connects the two paragraphs. 
+
+%D \macros
+%D   {doifcontent}
+%D
+%D When processing depends on the availability of content, one
+%D can give the next macro a try.
+%D
+%D \starttypen
+%D \doifcontent{pre content}{post content}{no content}\somebox
+%D \stoptypen
+%D
+%D Where \type{\somebox} is either a \type{\hbox} or
+%D \type{\vbox}. If the dimension of this box suggest some
+%D content, the resulting box is unboxed and surrounded by the
+%D first two arguments, else the third arguments is executed.
+
+\def\doifcontent#1#2#3%
+  {\dowithnextbox
+     {\ifhbox\nextbox
+        \ifdim\wd\nextbox>\!!zeropoint
+          #1\unhbox\nextbox#2\relax
+        \else
+          #3\relax
+        \fi
+      \else
+        \ifdim\ht\nextbox>\!!zeropoint
+          #1\unvbox\nextbox#2\relax
+        \else
+          #3\relax
+        \fi
+      \fi}}
+
+%D So when we say:
+%D
+%D \startbuffer
+%D \doifcontent{[}{]}{}\hbox{content sensitive typesetting}
+%D
+%D \doifcontent{}{\pagina}{}\vbox{content sensitive typesetting}
+%D
+%D \doifcontent{}{}{\message{Didn't you forget something?}}\hbox{}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D We get:
+%D
+%D \haalbuffer
+%D
+%D Where the last call of course does not show up in this
+%D document, but definitely generates a confusing message.
+
+%D \macros 
+%D   {processboxes}
+%D
+%D The next macro gobble boxes and is for instance used for 
+%D overlays. First we show the general handler.
+
+\newbox\processbox
+
+\def\processboxes#1% 
+  {\bgroup
+   \def\doprocessbox{#1}% #1 can be redefined halfway
+   \setbox\processbox=\box\voidb@x
+   \afterassignment\dogetprocessbox\let\next=}
+
+\def\endprocessboxes%
+  {\ifhmode\unskip\fi
+   \box\processbox
+   \next
+   \egroup}
+
+\def\dogetprocessbox%
+  {\ifx\next\bgroup
+     \expandafter\dodogetprocessbox
+   \else
+     \expandafter\endprocessboxes
+   \fi}
+
+\def\dodogetprocessbox%
+  {\dowithnextbox
+     {\ifhmode\unskip\fi\doprocessbox % takes \nextbox makes \processbox 
+      \afterassignment\dogetprocessbox\let\next=}
+   \hbox\bgroup}
+
+%D \macros 
+%D   {startoverlay}
+%D 
+%D We can overlay boxes by saying:
+%D 
+%D \startbuffer
+%D \startoverlay
+%D   {\omlijnd{hans}}
+%D   {\omlijnd[breedte=3cm]{ton}}
+%D   {\omlijnd[hoogte=2cm]{oeps}}
+%D \stopoverlay
+%D \stopbuffer
+%D 
+%D \typebuffer
+%D
+%D shows up as: 
+%D
+%D \leavevmode\haalbuffer
+
+% \def\dooverlaybox%
+%   {\ifhmode\unskip\fi 
+%    \ifdim\ht\nextbox>\ht\processbox
+%      \setbox\processbox=\vbox to \ht\nextbox
+%        {\vss\box\processbox\vss}%
+%    \else
+%      \setbox\nextbox=\vbox to \ht\processbox
+%        {\vss\box\nextbox\vss}%
+%    \fi
+%    \scratchdimen=\wd
+%      \ifdim\wd\nextbox>\wd\processbox 
+%        \nextbox
+%      \else
+%        \processbox
+%      \fi        
+%    \setbox\processbox=\hbox to \scratchdimen
+%      {\hbox to \scratchdimen{\hss\box\processbox\hss}%
+%       \hskip-\scratchdimen
+%       \hbox to \scratchdimen{\hss\box\nextbox\hss}}}
+%  
+% \def\startoverlay%
+%   {\bgroup
+%    \let\stopoverlay\egroup
+%    \processboxes\dooverlaybox}
+
+\def\dooverlaybox%
+  {\ifhmode\unskip\fi
+   \scratchdimen=\dp
+     \ifdim\dp\nextbox>\dp\processbox
+       \nextbox
+     \else
+       \processbox
+     \fi
+   \ifdim\ht\nextbox>\ht\processbox
+     \setbox\processbox=\vbox to \ht\nextbox
+       {\dp\processbox=\!!zeropoint\vss\box\processbox\vss}%
+   \else
+     \setbox\nextbox=\vbox to \ht\processbox
+       {\dp\nextbox=\!!zeropoint\vss\box\nextbox\vss}%
+   \fi
+   \dp\nextbox=\scratchdimen
+   \dp\processbox=\scratchdimen
+   \scratchdimen=\wd
+     \ifdim\wd\nextbox>\wd\processbox
+       \nextbox
+     \else
+       \processbox
+     \fi
+   \setbox\processbox=\hbox to \scratchdimen
+     {\hbox to \scratchdimen{\hss\box\processbox\hss}%
+      \hskip-\scratchdimen
+      \hbox to \scratchdimen{\hss\box\nextbox\hss}}}
+
+\def\startoverlay%
+  {\bgroup
+   \let\stopoverlay\egroup
+   \processboxes\dooverlaybox}
+
+% %D \macros 
+% %D   {starthspread}
+% %D 
+% %D In a similar way we can build a horizontal box, spread 
+% %D over the available width.
+% %D 
+% %D \startbuffer
+% %D \starthspread
+% %D   {hans}
+% %D   {ton}
+% %D   {oeps}
+% %D \stophspread
+% %D 
+% %D \stopbuffer
+% %D 
+% %D \typebuffer
+% %D
+% %D shows up as: 
+% %D
+% %D \leavevmode\haalbuffer
+% 
+% \def\dohspread%
+%   {\box\nextbox
+%    \def\dohspread{\hfil\box\nextbox}}
+% 
+% \def\starthspread%
+%   {\hbox to \hsize \bgroup
+%    \let\stophspread\egroup
+%    \processboxes\dohspread}
+
+%D \macros
+%D   {fakebox}
+%D 
+%D The next macro is a rather silly one, but saves space. 
+%D
+%D \starttypen
+%D \hbox{\fakebox0} 
+%D \stoptypen
+%D
+%D returns an empty box with the dimensions of the box 
+%D specified, here being zero. 
+
+\def\dofakebox%
+  {\setbox\scratchbox=\null
+   \wd\scratchbox=\wd\scratchcounter
+   \ht\scratchbox=\ht\scratchcounter
+   \dp\scratchbox=\dp\scratchcounter
+   \ifhbox\scratchcounter\hbox\else\vbox\fi{\box\scratchbox}%
+   \egroup}
+
+\def\fakebox%
+  {\bgroup
+   \afterassignment\dofakebox\scratchcounter}
+
+%D \macros 
+%D   {lbox,rbox,cbox,tbox,bbox}
+%D
+%D Here are some convenient alternative box types:
+%D
+%D \starttypen
+%D \lbox{text ...}
+%D \cbox{text ...}
+%D \rbox{text ...}
+%D \stoptypen
+%D 
+%D Are similar to \type {\vbox}, which means that they also 
+%D accept something like \type{to 3cm}, but align to the left, 
+%D middle and right. These box types can be used to typeset 
+%D paragraphs. 
+
+\def\lbox{\lrcbox\raggedleft}
+\def\cbox{\lrcbox\raggedcenter}
+\def\rbox{\lrcbox\raggedright}
+
+\def\lrcbox#1#2#%
+  {\vbox#2\bgroup
+   \let\\=\endgraf
+   \forgetall#1\let\next=}
+
+%D The alternatives \type {\tbox} and \type {\bbox} can be used 
+%D to properly allign boxes, like in:
+%D 
+%D \startbuffer 
+%D \starttabel[|||]
+%D \HL
+%D \VL \tbox{\externfiguur[koe][hoogte=3cm,kader=aan]} \VL top aligned    \VL\SR
+%D \HL
+%D \VL \bbox{\externfiguur[koe][hoogte=3cm,kader=aan]} \VL bottom aligned \VL\SR
+%D \HL
+%D \stoptabel
+%D \stopbuffer
+%D 
+%D \typebuffer
+%D 
+%D The positioning depends on the strut settings: 
+%D 
+%D \haalbuffer
+
+\def\tbox{\tbbox\ht\dp}
+\def\bbox{\tbbox\dp\ht}
+
+\def\tbbox#1#2%  
+  {\hbox\bgroup
+   \dowithnextbox 
+     {\scratchdimen=\ht\nextbox   
+      \advance\scratchdimen\dp\nextbox
+      \advance\scratchdimen-#1\strutbox
+      #1\nextbox=#1\strutbox
+      #2\nextbox=\scratchdimen
+      \setbox\nextbox=\hbox
+        {\lower\dp\nextbox\box\nextbox}%
+      #1\nextbox=#1\strutbox
+      #2\nextbox=\scratchdimen
+      \box\nextbox
+      \egroup}
+     \hbox}
+
+%D Some new, still undocumented features:
+
+% limitatetext -> beter {text} als laatste !!
+%
+% \limitvbox
+% \limithbox
+
+\def\limitatelines#1#2% size sentinel
+  {\dowithnextbox
+     {\dimen0=#1\hsize
+      \ifdim\wd\nextbox>\dimen0
+        \setbox\nextbox=\hbox
+          {\advance\dimen0 by -.1\hsize
+           \limitatetext{\unhbox\nextbox}{\dimen0}{\nobreak#2}}%
+      \fi
+      \unhbox\nextbox}
+     \hbox}
+
+\def\fittoptobaselinegrid% weg hier 
+  {\dowithnextbox
+     {\bgroup
+      \par
+      \dimen0=\ht\nextbox
+      \ht\nextbox=\ht\strutbox
+      \dp\nextbox=\dp\strutbox
+      \hbox{\box\nextbox}
+      \prevdepth\dp\strutbox
+      \doloop
+        {\advance\dimen0 by -\lineheight
+         \ifdim\dimen0<\!!zeropoint
+           \exitloop
+         \else
+           \nobreak
+           \hbox{\strut}
+         \fi}
+      \egroup}
+     \vbox}
+
+% Handy:
+
+\def\removedepth%
+  {\ifvmode\ifdim\prevdepth>\!!zeropoint
+     \kern-\prevdepth
+   \fi\fi}
+
+% maybe some day we need this
+%
+% \def\appendvbox#1%  % uses \box8
+%   {\bgroup
+%    \ifdim\prevdepth<\!!zeropoint
+%      \ifdim\pagetotal=\!!zeropoint
+%        \setbox8=\vtop{\unvcopy#1}%
+%        \hrule\c!!height\!!zeropoint
+%        \kern-\ht8
+%        \box#1\relax
+%      \else
+%        \box#1\relax
+%      \fi
+%    \else
+%      \dimen0=\prevdepth
+%      \hrule\c!!height\!!zeropoint
+%      \setbox8=\vtop{\unvcopy#1}%
+%      \dimen2=\baselineskip
+%      \advance\dimen2 by -\dimen0
+%      \advance\dimen2 by -\ht8
+%      \kern\dimen2
+%      \box#1\relax
+%    \fi
+%    \egroup}
+
+%D Also new:
+%D
+%D \startbuffer
+%D \normbox[1cm][bba]{m}  % b(efore) a(fter) v(box) s(trut) f(rame)
+%D \normbox[1cm][bba]{m}
+%D \normbox[1cm][bba]{m}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D \haalbuffer
+% 
+% \def\dodonormbox#1#2#3#4#5#6#7%
+%   {\doifnumberelse{#1}
+%      {\dimen0=#1}{\setbox0=#3{#1}\dimen0=#50}% 
+%    \doifinstringelse{f}{#2}
+%      {\let\next#4}{\let\next#3}%
+%    \next to \dimen0
+%      {\counttoken b\in#2\to\!!counta\dorecurse{\!!counta}{#6}#6%
+%       #7\nextbox                   
+%       \counttoken a\in#2\to\!!counta\dorecurse{\!!counta}{#6}#6}}
+% 
+% \def\donormbox[#1][#2]%
+%   {\bgroup
+%    \doifinstringelse{v}{#2}
+%      {\let\next\vbox}
+%      {\let\next\hbox}%
+%    \dowithnextbox
+%      {\ifvbox\nextbox
+%         \let\\=\par
+%         \dodonormbox{#1}{#2}\vbox\ruledvbox\ht\vfil\unvbox
+%       \else
+%         \let\\=\space
+%         \dodonormbox{#1}{#2}\hbox\ruledhbox\wd\hfil\unhbox
+%       \fi
+%       \egroup}%
+%    \next}
+% 
+% \def\normbox%
+%   {\dodoubleempty\donormbox}
+
+\protect
+
+\endinput
-- 
cgit v1.2.3

