%D \module
%D   [       file=core-vis,
%D        version=1996.06.01,
%D          title=\CONTEXT\ Core Macros,
%D       subtitle=Visualization,
%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. 

%D This module adds some more visualization cues to the ones 
%D supplied in the support module. 
%D 
%D %\everypar   dual character, \the\everypar and \everypar=
%D %\hrule      cannot be grabbed in advance, switches mode
%D %\vrule      cannot be grabbed in advance, switches mode
%D %
%D %\indent     only explicit ones
%D %\noindent   only explicit ones
%D %\par        only explicit ones
%D
%D %\leftskip   only if explicit one
%D %\rightskip  only if explicit one

\writestatus{loading}{Context Support Macros / Visualization}

\unprotect

%D \macros
%D   {indent, noindent,
%D    leavevmode,
%D    par}
%D 
%D \TeX\ acts upon paragraphs. In mosts documents paragraphs 
%D are separated by empty lines, which internally are handled as
%D \type{\par}. Paragraphs can be indented or not, depending on
%D the setting of \type{\parindent}, the first token of a 
%D paragraph and/or user suppressed or forced indentation. 
%D 
%D Because the actual typesetting is based on both explicit
%D user and implicit system actions, visualization is only
%D possible for the user supplied \type{\indent},
%D \type{\noindent}, \type{\leavevmode} and \type{\par}. Other
%D 'clever' tricks will quite certainly lead to more failures
%D than successes, so we only support these three explicit 
%D primitives and one macro: 

\let\normalnoindent   = \noindent
\let\normalindent     = \indent
\let\normalpar        = \par

\let\normalleavevmode = \leavevmode

\def\showparagraphcue#1#2#3#4#5%
  {\bgroup
   \scratchdimen#1\relax
   \dontinterfere
   \dontcomplain
   \boxrulewidth5\testrulewidth 
   #3#4\relax
   \setbox0\normalhbox to \scratchdimen
     {#2{\ruledhbox to \scratchdimen
           {\vrule #5 20\testrulewidth \!!width \zeropoint
            \normalhss}}}%
   \smashbox0
   \normalpenalty\!!tenthousand
   \box0
   \egroup}

\def\ruledhanging
  {\ifdim\hangindent>\zeropoint
     \ifnum\hangafter<\zerocount
       \normalhbox 
         {\boxrulewidth5\testrulewidth
          \setbox0\ruledhbox to \hangindent
            {\scratchdimen\ht\strutbox
             \advance\scratchdimen \dp\strutbox
             \vrule
               \!!width  \zeropoint
               \!!height \zeropoint
               \!!depth -\hangafter\scratchdimen}%
          \normalhskip-\hangindent
          \smashbox0
          \raise\ht\strutbox\box0}%
     \fi
   \fi}

\def\ruledparagraphcues
  {\bgroup
   \dontcomplain
   \normalhbox to \zeropoint
     {\ifdim\leftskip>\zeropoint\relax
        \showparagraphcue\leftskip\llap\relax\relax\!!depth
        \normalhskip-\leftskip
      \fi
      \ruledhanging
      \normalhskip\hsize
      \ifdim\rightskip>\zeropoint\relax
        \normalhskip-\rightskip
        \showparagraphcue\rightskip\relax\relax\relax\!!depth
      \fi}%
   \egroup}

\def\ruledpar
  {\relax
   \ifhmode 
     \showparagraphcue{40\testrulewidth}\relax\rightrulefalse\relax\!!height 
   \fi
   \normalpar}

\def\rulednoindent
  {\relax
   \normalnoindent
   \ruledparagraphcues
   \showparagraphcue{40\testrulewidth}\llap\leftrulefalse\relax\!!height}

\def\ruledindent  
  {\relax 
   \normalnoindent 
   \ruledparagraphcues
   \ifdim\parindent>\zeropoint
     \showparagraphcue\parindent\relax\relax\relax\!!height 
   \else
     \showparagraphcue{40\testrulewidth}\llap\relax\relax\!!height 
   \fi
   \normalhskip\parindent}

\def\ruledleavevmode
  {\relax
   \normalleavevmode
   \ifdim\parindent>\zeropoint
     \normalhskip-\parindent
     \ruledparagraphcues
     \showparagraphcue\parindent\relax\leftrulefalse\rightrulefalse\!!height 
     \normalhskip\parindent
   \else
     \ruledparagraphcues
     \showparagraphcue{40\testrulewidth}\llap\leftrulefalse\rightrulefalse\!!height 
   \fi}

\def\dontshowimplicits
  {\let\noindent   \normalnoindent  
   \let\indent     \normalindent    
   \let\leavevmode \normalleavevmode
   \let\par        \normalpar}

\def\showimplicits
  {\testrulewidth  \defaulttestrulewidth
   \let\noindent   \rulednoindent  
   \let\indent     \ruledindent    
   \let\leavevmode \ruledleavevmode
   \let\par        \ruledpar}

%D The next few||line examples show the four cues. Keep in 
%D mind that we only see them when we explicitly open or close
%D a paragraph. 
%D 
%D \bgroup
%D \def\voorbeeld#1%
%D   {#1Visualizing some \TeX\ primitives and Plain \TeX\
%D    macros can be very instructive, at least it is to me.
%D    Here we see {\tt\string#1} and {\tt\string\ruledpar} in
%D    action, while {\tt\string\parindent} equals
%D    {\tt\the\parindent}.\ruledpar} 
%D 
%D \showimplicits
%D 
%D \voorbeeld \indent   
%D \voorbeeld \noindent   
%D \voorbeeld \leavevmode 
%D 
%D \parindent=60pt
%D 
%D \voorbeeld \indent     
%D \voorbeeld \noindent   
%D \voorbeeld \leavevmode 
%D
%D \startsmaller
%D \voorbeeld \indent     
%D \voorbeeld \noindent   
%D \voorbeeld \leavevmode 
%D \stopsmaller
%D \egroup
%D
%D These examples also demonstrate the visualization of 
%D \type {\leftskip} and \type {\rightskip}. The macro 
%D \type {\nofruledbaselines} determines the number of lines
%D shown. 

\newcounter\ruledbaselines

\def\nofruledbaselines{3}

\def\debuggertext#1%
  {\ifx\ttxx\undefined
     $\scriptscriptstyle#1$%
   \else
     {\ttxx#1}%
   \fi}

\def\ruledbaseline
  {\vrule \!!width \zeropoint
   \bgroup
   \dontinterfere
   \doglobal\increment\ruledbaselines
   \scratchdimen\nofruledbaselines\baselineskip
   \setbox\scratchbox\normalvbox to 2\scratchdimen
     {\leaders
        \normalhbox
          {\strut
           \vrule
             \!!height \testrulewidth
             \!!depth \testrulewidth
             \!!width 120pt}
      \normalvfill}%
   \smashbox\scratchbox
   \advance\scratchdimen \strutheightfactor\baselineskip
   \setbox\scratchbox\normalhbox
     {\normalhskip -48pt
      \normalhbox to 24pt
        {\normalhss\debuggertext\ruledbaselines\normalhskip6pt}%
      \raise\scratchdimen\box\scratchbox}%
   \smashbox\scratchbox
   \box\scratchbox
   \egroup}

\def\showbaselines
  {\testrulewidth\defaulttestrulewidth
   \EveryPar{\ruledbaseline}}

%D \macros 
%D   {showpagebuilder}
%D
%D The next tracing option probaly is only of use to me and a
%D few \CONTEXT\ hackers. 

\def\showpagebuilder
  {\EveryPar{\doshowpagebuilder}}

\def\doshowpagebuilder
  {\strut\llap{\blue                  \vl 
     \high{\infofont v:\the\vsize    }\vl 
     \high{\infofont g:\the\pagegoal }\vl 
     \high{\infofont t:\the\pagetotal}\vl}}

%D \macros 
%D   {makecutbox, cuthbox, cutvbox, cutvtop}
%D 
%D Although mainly used for marking the page, these macros can 
%D also serve local use. 
%D 
%D \startbuffer
%D \setbox0=\vbox{a real \crlf vertical box} \makecutbox0
%D \stopbuffer
%D 
%D \typebuffer
%D 
%D This marked \type{\vbox} shows up as:
%D 
%D \startregelcorrectie
%D \haalbuffer
%D \stopregelcorrectie
%D 
%D The alternative macros are used as:
%D 
%D \startbuffer
%D \cuthbox{a made cut box}
%D \stopbuffer
%D 
%D \typebuffer
%D 
%D This is typeset as:
%D 
%D \startregelcorrectie
%D \haalbuffer
%D \stopregelcorrectie
%D 
%D By setting the next macros one can influence the length of
%D the marks as well as the horizontal and vertical divisions. 

\def\cutmarklength           {2\bodyfontsize}
\chardef\horizontalcutmarks = 2
\chardef\verticalcutmarks   = 2
\chardef\cutmarkoffset      = 1
\let\cutmarksymbol          = \relax

\def\horizontalcuts
  {\normalhbox to \ruledwidth
     {\dorecurse\horizontalcutmarks
        {\vrule\!!width\boxrulewidth\!!height\cutmarklength\normalhfill}%
      \unskip}}

\def\verticalcuts
  {\scratchdimen\ruledheight
   \advance\scratchdimen \ruleddepth 
   \normalvbox to \scratchdimen
     {\hsize\cutmarklength
      \dorecurse\verticalcutmarks
        {\vrule\!!height\boxrulewidth\!!width\hsize\normalvfill}%
      \unskip}}

\def\baselinecuts
  {\ifdim\ruleddepth>\zeropoint
     \scratchdimen\ruledheight
     \advance\scratchdimen \ruleddepth 
     \normalvbox to \scratchdimen
       {\scratchdimen\cutmarklength
        \divide\scratchdimen 2
        \hsize\scratchdimen
        \normalvskip\zeropoint\!!plus\ruledheight
        \vrule\!!height\boxrulewidth\!!width\hsize
        \normalvskip\zeropoint\!!plus\ruleddepth}%
   \fi}

\def\cutmarksymbols
  {\setbox\scratchbox\normalvbox to \cutmarklength
     {\normalvfill
      \normalhbox to \cutmarklength
        {\normalhfill\ssxx\cutmarksymbol\normalhfill}%
      \normalvfill}%
   \normalhbox to \ruledwidth
     {\scratchdimen\cutmarklength
      \divide\scratchdimen 2
      \llap{\copy\scratchbox\normalhskip\cutmarkoffset\scratchdimen}%
      \normalhfill
      \rlap{\normalhskip\cutmarkoffset\scratchdimen\copy\scratchbox}}}

\def\makecutbox#1%
  {\edef\ruledheight{\the\ht#1}%
   \edef\ruleddepth {\the\dp#1}%
   \edef\ruledwidth {\the\wd#1}%
   \setbox#1\normalhbox
     {\dontcomplain
      \forgetall
      \boxmaxdepth\maxdimen
      \offinterlineskip
      \scratchdimen\cutmarklength
      \divide\scratchdimen 2
      \hsize\ruledwidth
      \setbox\scratchbox\normalvbox 
        {\setbox\scratchbox\normalhbox{\horizontalcuts}%
         \normalvskip-\cutmarkoffset\scratchdimen
         \normalvskip-2\scratchdimen
         \copy\scratchbox
         \normalvskip\cutmarkoffset\scratchdimen
         \hbox to \ruledwidth
           {\setbox\scratchbox\normalhbox{\verticalcuts}%
            \llap{\copy\scratchbox\normalhskip\cutmarkoffset\scratchdimen}%
            \bgroup
            \setbox\scratchbox\normalhbox{\baselinecuts}%
            \llap{\copy\scratchbox\normalhskip\cutmarkoffset\scratchdimen}%
            \normalhfill
            \rlap{\normalhskip\cutmarkoffset\scratchdimen\copy\scratchbox}%
            \egroup
            \rlap{\normalhskip\cutmarkoffset\scratchdimen\copy\scratchbox}}%
         \normalvskip\cutmarkoffset\scratchdimen
         \copy\scratchbox}%
      \ht\scratchbox\ruledheight
      \dp\scratchbox\ruleddepth
      \wd\scratchbox\zeropoint
      \resetcolorseparation
      \localstartcolor[\defaulttextcolor]%
      \box\scratchbox
      \ifx\cutmarksymbol\relax \else
        \setbox\scratchbox\normalvbox 
          {\setbox\scratchbox\normalhbox{\cutmarksymbols}%
           \vskip-\cutmarkoffset\scratchdimen
           \vskip-\cutmarklength
           \copy\scratchbox
           \vskip\cutmarkoffset\scratchdimen
           \vskip\ruledheight
           \vskip\ruleddepth
           \vskip\cutmarkoffset\scratchdimen
           \copy\scratchbox}%
        \ht\scratchbox\ruledheight
        \dp\scratchbox\ruleddepth
        \wd\scratchbox\zeropoint
        \box\scratchbox
      \fi
      \localstopcolor
      \box#1}%
   \wd#1=\ruledwidth
   \ht#1=\ruledheight
   \dp#1=\ruleddepth}

\def\cuthbox
  {\normalhbox\bgroup
   \dowithnextbox{\makecutbox\nextbox\box\nextbox\egroup}\normalhbox}

\def\cutvbox
  {\normalvbox\bgroup
   \dowithnextbox{\makecutbox\nextbox\box\nextbox\egroup}\normalvbox}

\def\cutvtop
  {\normalvtop\bgroup
   \dowithnextbox{\makecutbox\nextbox\box\nextbox\egroup}\normalvtop}

%D \macros
%D   {colormarkbox,rastermarkbox}
%D
%D This macro is used in the pagebody routine. No other use 
%D is advocated here.
%D
%D \starttypen
%D \colormarkbox0
%D \stoptypen

\def\colormarkoffset{\cutmarkoffset}
\def\colormarklength{\cutmarklength}

\def\colorrangeA#1#2#3#4%
  {\vbox
     {\scratchdimen-\colormarklength
      \multiply\scratchdimen 4
      \advance\scratchdimen \ruledheight 
      \advance\scratchdimen \ruleddepth
      \divide\scratchdimen 21
      \def\docommando##1%
        {\vbox
           {\hsize3em % \scratchdimen
            \definecolor 
              [\s!dummy]
              [\c!c=#2##1\else0\fi, 
               \c!m=#3##1\else0\fi,
               \c!y=#4##1\else0\fi,
               \c!k=0]%
            \localstartcolor[\s!dummy]%
            \hrule 
              \!!width 3em 
              \!!height \scratchdimen 
              \!!depth  \zeropoint
            \localstopcolor
            \ifdim\scratchdimen>1ex
              \vskip-\scratchdimen 
              \vbox to \scratchdimen 
                {\vss 
                 \hbox to 3em 
                   {\hss
                    \localstartcolor[white]%
                    \ifdim##1\s!pt=\zeropoint#1\else##1\fi
                    \localstopcolor
                    \hss}%
                 \vss}%
            \fi}}%
      \offinterlineskip
      \processcommalist[1.00,0.95,0.75,0.50,0.25,0.05,0.00]\docommando}}

\def\colorrangeB
  {\hbox
     {\scratchdimen-\colormarklength
      \multiply\scratchdimen 2
      \advance\scratchdimen \ruledwidth
      \divide\scratchdimen 11
      \def\docommando ##1 ##2 ##3##4##5##6%
        {\definecolor 
           [\s!dummy]
           [\c!c=##3##2\else0\fi,
            \c!m=##4##2\else0\fi,
            \c!y=##5##2\else0\fi,
            \c!k=##6##2\else0\fi]%
         \localstartcolor[\s!dummy]%
         \vrule 
           \!!width  \scratchdimen 
           \!!height \colormarklength
           \!!depth  \zeropoint
         \localstopcolor
         \ifdim\scratchdimen>2em 
           \hskip-\scratchdimen 
           \vbox to \colormarklength
             {\vss 
              \hbox to \scratchdimen
                {\hss
                 \localstartcolor[white]%
                 \ifdim##2\s!pt=.5\s!pt##2~\fi##1%
                 \localstopcolor
                 \hss}
              \vss}%
         \fi}%
      \docommando C .5 \iftrue \iffalse\iffalse\iffalse
      \docommando M .5 \iffalse\iftrue \iffalse\iffalse
      \docommando Y .5 \iffalse\iffalse\iftrue \iffalse
      \docommando K .5 \iffalse\iffalse\iffalse\iftrue
      \docommando C 1  \iftrue \iffalse\iffalse\iffalse
      \docommando G 1  \iftrue \iffalse\iftrue \iffalse
      \docommando Y 1  \iffalse\iffalse\iftrue \iffalse
      \docommando R 1  \iffalse\iftrue \iftrue \iffalse
      \docommando M 1  \iffalse\iftrue \iffalse\iffalse
      \docommando B 1  \iftrue \iftrue \iffalse\iffalse
      \docommando K 1  \iffalse\iffalse\iffalse\iftrue}}

\def\colorrangeC
  {\hbox
     {\resetcolorseparation
      \scratchdimen-\colormarklength
      \multiply\scratchdimen 2
      \advance\scratchdimen \ruledwidth
      \divide\scratchdimen 14
      \def\docommando##1%
        {\definecolor[\s!dummy][\c!s=##1]%
         \localstartcolor[\s!dummy]%
         \vrule 
           \!!width  \scratchdimen 
           \!!height \colormarklength
           \!!depth  \zeropoint
         \localstopcolor
         \ifdim\scratchdimen>2em
           \hskip-\scratchdimen 
           \vbox to \colormarklength
             {\vss
              \localstartcolor[white]%
              \hbox to \scratchdimen{\hss##1\hss}
              \localstopcolor
             \vss}%
         \fi}%
      \processcommalist
        [1.00,0.95,0.90,0.85,0.80,0.75,0.70,%
         0.60,0.50,0.40,0.30,0.20,0.10,0.00]\docommando}}

\def\docolormarkbox#1#2%
  {\edef\ruledheight{\the\ht#2}%
   \edef\ruleddepth {\the\dp#2}%
   \edef\ruledwidth {\the\wd#2}%
   \setbox#2\hbox
     {\scratchdimen\colormarklength
      \divide\scratchdimen 2
      \forgetall
      \ssxx
      \setbox\scratchbox\vbox 
        {\offinterlineskip
         \vskip-\colormarkoffset\scratchdimen
         \vskip-2\scratchdimen\relax % relax needed 
         % beware: no \ifcase, due to nested \iftrue/\iffalse
         % and lacking \fi's 
         \doifelse{#1}{0}% 
           {\vskip\colormarklength
            \vskip\colormarkoffset\scratchdimen
            \vskip\ruledheight} 
           {\hbox to \ruledwidth{\hss\hbox{\colorrangeB}\hss}%
            \vskip\colormarkoffset\scratchdimen
            \vbox to \ruledheight 
              {\vss
               \hbox to \ruledwidth
                 {\llap{\colorrangeA C\iftrue\iffalse\iffalse\hskip\colormarkoffset\scratchdimen}%
                  \hfill
                  \rlap{\hskip\colormarkoffset\scratchdimen\colorrangeA R\iffalse\iftrue\iftrue}}%
               \vss
               \hbox to \ruledwidth
                 {\llap{\colorrangeA M\iffalse\iftrue\iffalse\hskip\colormarkoffset\scratchdimen}% 
                  \hfill
                  \rlap{\hskip\colormarkoffset\scratchdimen\colorrangeA G\iftrue\iffalse\iftrue}}%
               \vss
               \hbox to \ruledwidth
                 {\llap{\colorrangeA Y\iffalse\iffalse\iftrue\hskip\colormarkoffset\scratchdimen}%
                  \hfill
                  \rlap{\hskip\colormarkoffset\scratchdimen\colorrangeA B\iftrue\iftrue\iffalse}}%
               \vss}}% 
         \vskip\colormarkoffset\scratchdimen
         \hbox to \ruledwidth
           {\hss\lower\ruleddepth\hbox{\colorrangeC}\hss}}%
      \ht\scratchbox\ruledheight
      \dp\scratchbox\ruleddepth
      \wd\scratchbox\zeropoint
      \box\scratchbox
      \box#2}%
   \wd#2=\ruledwidth
   \ht#2=\ruledheight
   \dp#2=\ruleddepth}

\def\colormarkbox % #1 
  {\ifincolor\@EA\docolormarkbox\else\@EA\gobbletwoarguments\fi1}

\def\rastermarkbox % #1 
  {\ifincolor\@EA\docolormarkbox\else\@EA\gobbletwoarguments\fi0}

%D \macros
%D   {showwhatsits, dontshowwhatsits}
%D
%D \TEX\ has three so called whatsits: \type {\mark}, \type 
%D {\write} and \type {\special}. The first one keeps track of 
%D the current state at page boundaries, the last two are used 
%D to communicate to the outside world. Due to fact that 
%D especially \type {\write} is often used in conjunction with 
%D \type {\edef}, we can only savely support that one in \ETEX. 
%D
%D \bgroup \showwhatsits \stelkleurenin[status=start]
%D 
%D Whatsits show up \color[blue]{in color} and are 
%D characterized bij their first character.\voetnoot [some note]
%D {So we may encounter \type {w}, \type {m} and \type{s}.} 
%D They are \writestatus{dummy}{demo}\color[yellow]{stacked}.
%D 
%D \egroup

\newif\ifimmediatewrite 

\ifx\eTeXversion\undefined

  \let\showwhatsits\relax
  \let\dontshowwhatsits\relax

\else

  \let\supernormalmark  \normalmark  % mark may already superseded
  \let\supernormalmarks \normalmarks % mark may already superseded

  \def\showwhatsits
    {\protected\def\normalmark {\visualwhatsit100+m\supernormalmark }%
     \protected\def\normalmarks{\visualwhatsit100+m\supernormalmarks}%
     \protected\def\special    {\visualwhatsit0100s\normalspecial   }%
     \protected\def\write      {\visualwhatsit001-w\normalwrite     }%
     \let\immediate\immediatewhatsit
     \appendtoks\dontshowwhatsits\to\everystoptext}

  \def\immediatewhatsit 
    {\bgroup\futurelet\next\doimmediatewhatsit}
 
  \def\doimmediatewhatsit
    {\ifx\next\write
       \egroup\immediatewritetrue
     \else
       \egroup\expandafter\normalimmediate
     \fi}

  \def\dontshowwhatsits
    {\let\immediate \normalimmediate
     \let\normalmark\supernormalmark 
     \let\special   \normalspecial
     \let\write     \normalwrite}
      
  \def\visualwhatsit#1#2#3#4#5%
    {\bgroup
     \pushwhatsit
     \dontinterfere
     \dontcomplain
     \dontshowcomposition
     \dontshowwhatsits
     \ttx
     \ifvmode\donetrue\else\donefalse\fi
     \setbox\scratchbox\hbox
       {\ifdone\dostartgraycolormode0\else\dostartrgbcolormode#1#2#3\fi
        #5\dostopcolormode}%
     \setbox\scratchbox\hbox
       {\ifdone\dostartrgbcolormode#1#2#3\else\dostartgraycolormode0\fi
        \vrule\!!width\wd\scratchbox\dostopcolormode
        \hskip-\wd\scratchbox\box\scratchbox}%
     \scratchdimen1ex
     \ifdone
       \setbox\scratchbox\hbox
         {\hskip#4\scratchdimen\box\scratchbox}%
     \else
       \setbox\scratchbox\hbox
         {\raise#4\scratchdimen\box\scratchbox}%
     \fi 
     \smashbox\scratchbox
     \ifdone\nointerlineskip\fi
     \box\scratchbox
     \ifvmode\nointerlineskip\fi
     \popwhatsit
     \egroup
     \ifimmediatewrite
       \immediatewritefalse
       \expandafter\normalimmediate
     \fi}

  \def\pushwhatsit
    {\ifzeropt\lastskip
       \ifcase\lastpenalty
         \ifzeropt\lastkern
           \ifhmode
             \let\popwhatsit\relax
           \else
             \edef\popwhatsit{\prevdepth\the\prevdepth}%
           \fi
         \else
           \ifhmode
             \edef\popwhatsit{\kern\the\lastkern}\unkern
           \else
             \edef\popwhatsit{\kern\the\lastkern\prevdepth\the\prevdepth} 
             \kern-\lastkern
           \fi
         \fi
       \else
         \ifhmode
           \edef\popwhatsit{\the\lastpenalty}%
           \unpenalty
         \else
           \edef\popwhatsit{\penalty\the\lastpenalty\prevdepth\the\prevdepth}%
          %\nobreak
         \fi
       \fi
     \else
       \ifhmode
         \edef\popwhatsit{\hskip\the\lastskip}\unskip
       \else
         \edef\popwhatsit{\vskip\the\lastskip\prevdepth\the\prevdepth} 
         \vskip-\lastskip
       \fi
     \fi}

\fi

%D The next macro can be used to keep track of classes of 
%D boxes (handy for development cq.\ tracing). 

\def\dodotagbox#1#2#3% can be reimplemented 
  {\def\next##1##2##3##4%
     {\vbox to \ht#2{##3\hbox to \wd#2{##1#3##2}##4}}%
   \processaction
     [#1]
     [        l=>\next\relax\hfill\vfill\vfill,
              r=>\next\hfill\relax\vfill\vfill,
              t=>\next\hfill\hfill\relax\vfill,
              b=>\next\hfill\hfill\vfill\relax,
             lt=>\next\relax\hfill\relax\vfill,
             lb=>\next\relax\hfill\vfill\relax,
             rt=>\next\hfill\relax\relax\vfill,
             rb=>\next\hfill\relax\vfill\relax,
             tl=>\next\relax\hfill\relax\vfill,
             bl=>\next\relax\hfill\vfill\relax,
             tr=>\next\hfill\relax\relax\vfill,
             br=>\next\hfill\relax\vfill\relax,
     \s!default=>\next\hfill\hfill\vfill\vfill,
     \s!unknown=>\next\hfill\hfill\vfill\vfill]}

\def\dotagbox[#1]#2%
  {\bgroup
   \dowithnextbox
     {\setbox\scratchbox\box\nextbox
      \setbox\nextbox\ifhbox\nextbox\hbox\else\vbox\fi
        \bgroup 
          \startoverlay
            {\copy\scratchbox}
            {\dodotagbox{#1}\scratchbox{\framed
               [\c!achtergrond=\v!raster,\c!achtergrondraster=1]{#2}}}
          \stopoverlay 
        \egroup
      \wd\nextbox\the\wd\scratchbox
      \ht\nextbox\the\ht\scratchbox
      \dp\nextbox\the\dp\scratchbox
      \box\nextbox
      \egroup}}

\def\tagbox
  {\dosingleempty\dotagbox}

\protect \endinput
