%D \module
%D   [       file=core-grd,
%D        version=1998.03.10,
%D          title=\CONTEXT\ Core Macros,
%D       subtitle=Grid Snapping (Experimental),
%D         author=Hans Hagen,
%D           date=\currentdate,
%D      copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for 
%C details. 

\writestatus{loading}{Context Core Macros / Grid Snapping}

\unprotect

%D Moved from supp-box:

%D \macros
%D  {startbaselinecorrection,baselinecorrection,
%D   showbaselinecorrection,offbaselinecorrection}
%D
%D Spacing around ruled boxes can get pretty messed up. The
%D next macro tries as good as possible to fix this.
%D
%D \startbuffer[1]
%D \startbaselinecorrection
%D \ruledhbox{Rule Brittanica}
%D \stopbaselinecorrection
%D \stopbuffer
%D
%D \typebuffer[1]
%D
%D The macros put some white space around the box:
%D
%D \haalbuffer[1]
%D
%D A simple alternative is \type {\baselinecorrection}, which
%D only looks at the previous line.
%D
%D \startbuffer[2]
%D \baselinecorrection
%D \ruledhbox{Rule Brittanica}
%D \baselinecorrection
%D \stopbuffer
%D
%D \typebuffer[2]
%D
%D This time the last preceding line gets a correction,%
%D dependant on the depth.
%D
%D \haalbuffer[2]
%D
%D One can make the correction visible by saying \type
%D {\showbaselinecorrection}. Part of the correction is
%D calculated from the dimensions of a~(. One can disble the
%D correction by calling \type {\offbaselinecorrection}.
%D
%D When visualize the first example looks like:
%D
%D {\showbaselinecorrection\haalbuffer[1]}
%D
%D and the second one comes out as:
%D
%D {\showbaselinecorrection\haalbuffer[2]}

% \definecolor[GridLineColor][red]
% \definecolor[GridTextColor][blue]

\definepalet
  [grid]
  [  one=red,
     two=green,
   three=blue,
    four=gray]

\def\setbaselinecorrections
  {\setbox0\hbox{\setstrut\strut}%
   \setbox2\hbox{(}%
   \dimen0\ht0\advance\dimen0 -\ht2
   \ifdim\dimen0<\zeropoint\dimen0\zeropoint\fi
   \dimen2\dp0\advance\dimen2 -\dp2
   \ifdim\dimen2<\zeropoint\dimen2\zeropoint\fi
   \edef\thetopbaselinecorrection   {\the\dimen0}\dimen0-\dimen0
   \edef\thebotbaselinecorrection   {\the\dimen2}\dimen2-\dimen2
   \edef\thenegtopbaselinecorrection{\the\dimen0}%
   \edef\thenegbotbaselinecorrection{\the\dimen2}}

\def\dotopbaselinecorrection   {\kern\thetopbaselinecorrection}
\def\dobotbaselinecorrection   {\kern\thebotbaselinecorrection}
\def\donegtopbaselinecorrection{\kern\thenegtopbaselinecorrection}
\def\donegbotbaselinecorrection{\kern\thenegbotbaselinecorrection}

\def\showbaselinecorrection
  {\def\dobaselinecorrection % visualization is not watertight!
     {\bgroup
\ifdim\prevdepth>\zeropoint\kern-\prevdepth\fi 
      \setbox0\null
      \wd0\hsize
      \dp0\dp\strutbox
      \nointerlineskip
      \ruledvbox{\box0}%
      \egroup
      \prevdepth\dp\strutbox}%
   \def\dotopbaselinecorrection
     {\hrule\!!height\thetopbaselinecorrection}%
   \def\dobotbaselinecorrection
     {\hrule\!!height\thebotbaselinecorrection}}

\def\dobaselinecorrection
  {\ifdim\prevdepth>\zeropoint\kern-\prevdepth\fi
   \kern\dp\strutbox
   \prevdepth\dp\strutbox}

\def\baselinecorrection
  {\endgraf
   \ifvmode
     \ifdim\prevdepth<\maxdimen
       \ifdim\prevdepth<\zeropoint \else
         \ifdim\prevdepth<\dp\strutbox
           \dobaselinecorrection
         \fi
       \fi
     \fi
   \fi}

% Beware, keep this one as it is, see for instance module
% m-steps.tex, where we apply a \localhsize to the \vbox, in
% order to follow narrower and side floats !

\def\startbaselinecorrection
  {\baselinecorrection
   \ifvmode
     \bgroup
     \setbox\scratchbox\vbox\bgroup
     \ignorespaces
     \let\stopbaselinecorrection\dostopbaselinecorrection
   \else
     \let\stopbaselinecorrection\relax
   \fi}

%D We do a bit more checking than needed. The pageborder check
%D is not needed, but I want to look the visualization as good
%D as possible too.

\def\dostopbaselinecorrection % I have to check columns yet.
  {\endgraf
   \egroup
   \topbaselinecorrection
   \box\scratchbox
   \botbaselinecorrection
   \egroup}

\let\stopbaselinecorrection=\relax

\def\offbaselinecorrection % Can be used inside correction.
  {\def\startbaselinecorrection
     {\bgroup\let\stopbaselinecorrection\egroup}}

%D \macros
%D  {topbaselinecorrection,botbaselinecorrection}
%D
%D The actual top and bottom corrections are implemented as:

% \def\topbaselinecorrection
%   {\ifvmode
%      \bgroup
%      \setbaselinecorrections
%      \ifdim\pagegoal<\maxdimen
%        \ifdim\pagetotal<\pagegoal
%          \dimen2=\ht\scratchbox
%          \advance\dimen2 \dp\scratchbox
%          \advance\dimen2 \parskip
%          \advance\dimen2 \thetopbaselinecorrection
%          \advance\dimen2 \thebotbaselinecorrection
%          \dimen0=\pagetotal
%          \advance\dimen0 \dimen2
% %        \ifdim\dimen0<\pagegoal % does more harm than good
%            \witruimte
%            \nointerlineskip
%            \dotopbaselinecorrection
% %        \else
% %          \ifbinnenkolommen      
% %            % \vskip\dimen2           % this could definitely
% %            % \penalty\outputpenalty  % be improved
% %          \else
% %            %                         % 
% %            % \vfill\eject            % pretty old and wrong
% %            %
% %            % \nobreak                % needed for headings
% %            % \vskip\parskip          % but often splits 
% %            % \vskip\dimen2           % normal paragraphs
% %            % \penalty\outputpenalty  % and therefore 
% %            % \vskip-\dimen2          % obsolete
% %            %
% %            % do nothing, sub optimal spacing after headings 
% %            % still to be sorted out; use manuals as test case
% %          \fi
% %        \fi
%        \else                           % probably a preceding
%          \witruimte                    % one-liner
%          \nointerlineskip
%          \dotopbaselinecorrection
%        \fi
%      \fi
%      \egroup
%    \fi}

\def\topbaselinecorrection
  {\ifvmode \ifdim\pagegoal<\maxdimen
     \bgroup
     \setbaselinecorrections
     \witruimte
     \nointerlineskip
     \dotopbaselinecorrection
     \egroup
   \fi \fi}

\def\botbaselinecorrection
  {\ifvmode
     \bgroup
     \setbaselinecorrections
     \dobotbaselinecorrection
     \allowbreak % new, otherwise problems when many in a row
     \prevdepth\dp\strutbox
     \egroup
   \fi}

%D Still very experimental and therefore undocumented.

\newif\ifgridsnapping  % UNDER DEVELOPMENT, USE WITH CARE
\newif\ifforcepresnap  \forcepresnaptrue  % false in mixed single/double
\newif\ifstrutsnapping \strutsnappingtrue % sometimes handy to be false

\def\positiveextrasnap {\gdef\extrasnapsign{+}}
\def\negativeextrasnap {\gdef\extrasnapsign{-}}

\def\extrasnapreset  {\global\chardef\@@extrasnap0
                      \positiveextrasnap}
\def\extrasnapbefore {\global\chardef\@@extrasnap1 }
\def\extrasnaparound {\global\chardef\@@extrasnap2 }
\def\extrasnapafter  {\global\chardef\@@extrasnap3 }

\def\enablepresnapcorrection  {\global\chardef\@@presnap\zerocount}
\def\disablepresnapcorrection {\global\chardef\@@presnap\plusone}

\extrasnapreset \enablepresnapcorrection

\newif\iftracegridsnapping
\newif\ifshowgridboxes
\newif\ifshowfuzzyskips

\let\showgridboxes\showgridboxestrue

\chardef\@@alignsnap   =0
\chardef\@@alignsnapbox=0

\let\presnapskip \!!zeropoint  \def\presnap {-}
\let\postsnapskip\!!zeropoint  \let\postsnap\presnap

\def\tracedsnapping
  {\iftracegridsnapping
     \llap
       {\infofont
        \doglobal\increment\currentsnap
        \color[grid:three]{\vl\presnapskip
                    \vl\presnap
                    \vl\postsnap
                    \ifcase\@@alignsnapbox\relax
                      \vl\ifcase\@@extrasnap
                              00\or
                 \extrasnapsign0\or  
    \extrasnapsign\extrasnapsign\or
                 0\extrasnapsign\fi
                    \fi
                    \vl\currentsnap\vl}}%
   \fi}

\def\snaptogrid% [#1]#2 -> #2 == \hbox|\vbox
  {\dosingleempty\dosnaptogrid}

\def\dosnaptogrid[#1]% 
  {\ifgridsnapping
     \iffirstargument\doifsomething{#1}{\verplaatsopgrid[#1]}\fi
     \expandafter\dodosnaptogrid
   \fi}

% \def\forcedpresnapcorrection
%   {\ifforcepresnap
%      % we don't want top of page space  when 'top' option 
%      %\vbox{\strut}\nobreak\vskip-\openlineheight
%      \vbox{\strut}\vskip-\openlineheight
%    \fi}
% 
%\def\forcedpresnapcorrection
%  {\ifforcepresnap
%     \ifvmode \else \par \fi
%     \ifdim\prevdepth<\zeropoint \else
%       \vskip-\prevdepth
%       \vskip\strutdepth 
%       \prevdepth\strutdepth 
%     \fi
%   \fi}

\def\forcedpresnapcorrection % test this on 'details'
  {\ifforcepresnap
     \ifvmode \else \par \fi % new 
     % we don't want top of page space  when 'top' option 
     %\vbox{\strut}\nobreak\vskip-\openlineheight
     %\vbox{\strut}\vskip-\openlineheight
     % nobreak really needed 
     \allowbreak\vbox{\strut}\nobreak\vskip-\openlineheight 
     %\ifdim\pagetotal>\topskip \else
       % eigenlijk signal 
       %\writestatus{grid}{removing dummy at top of page}%
       %\bgroup
       %\output{\setbox\scratchbox\box255}%
       %\penalty\outputpenalty
       %\egroup
     %\fi
   \fi}

\newif\ifboxedsnapping \boxedsnappingtrue 

\def\dodosnaptogrid
  {\dowithnextbox
     {\bgroup
      \ifdim\ht\nextbox<\teksthoogte % handle special case (like page fig)
        \ifcase\@@alignsnapbox\relax
          \ifcase\@@alignsnap\else % 1=top 2=high 3=middle 4=low
            \ifshowgridboxes
              \setbox\nextbox\hbox{\color[grid:two]{\ruledhbox{\black\box\nextbox}}}%
            \fi
            \getnoflines{\ht\nextbox}%
            \setbox\nextbox\vbox to \noflines\lineheight
              {\ifnum\@@alignsnap=1 \kern\lineheight\kern-\topskip\fi
               \ifnum\@@alignsnap>2 \vfill\fi
               \box\nextbox
             \ifnum\@@alignsnap<4 \vfill\fi}%
          \fi
          \ifshowgridboxes      
            \setbox\nextbox\hbox{\color[grid:three]{\ruledhbox{\black\box\nextbox}}}%
          \fi
          \forgetall
          \par
          \ifvbox\nextbox
            \setbox\nextbox\hbox{\box\nextbox}% don't ask
          \fi
          \scratchskip\lastskip
          \edef\presnapskip{\the\lastskip}%
          % mixing single/double columns sometimes goes wrong,
          % check 'som' document
          \ifbinnenkolommen
            \forcepresnaptrue
          \fi
          \forcedpresnapcorrection
          \ifdim\ht\nextbox>\ht\strutbox
            \scratchdimen\ht\nextbox
            \ifcase\@@presnap\relax
              \ifdim\scratchskip>\zeropoint\relax
                \scratchcounter\scratchskip
                \advance\scratchcounter -\openlineheight
                \ifnum\scratchcounter<0
                  \scratchcounter-\scratchcounter
                \fi
                \ifnum\scratchcounter<10 % \lastkip is about \openlineheight
                  \advance\scratchdimen -\openstrutdepth
                  \edef\presnapskip{*\presnapskip}%
                \else\ifdim\scratchskip>\openlineheight
                                      %<\openlineheight \else
                  \advance\scratchdimen -\openstrutdepth
                  \edef\presnapskip{*\presnapskip}%
                \fi\fi
              \fi
            \fi
            \getnoflines\scratchdimen % maybe raw ? 
            \advance\noflines -1
            \ifnum\noflines>0
              \scratchdimen\noflines\lineheight
            \else
              \scratchdimen\zeropoint
            \fi
          \else
            \scratchdimen\zeropoint
          \fi
          \ifnum\@@extrasnap=1 \advance\scratchdimen \extrasnapsign\lineheight \fi
          \ifnum\@@extrasnap=2 \advance\scratchdimen \extrasnapsign.5\lineheight \fi
          \edef\presnap{\the\scratchdimen}%
          \ifstrutsnapping
            \ifboxedsnapping 
              \getrawnoflines\scratchdimen
              \advance\scratchdimen-\noflines\lineheight
              \vskip\scratchdimen % disappears at top of page
              \dorecurse\noflines{\vbox{\strut}\nobreak}%
            \else \ifdim\scratchdimen=\zeropoint
              % nothing to skip 
            \else % disappears at top of page 
              \vskip\scratchdimen
            \fi \fi
          \fi
          \ifdim\dp\nextbox>\dp\strutbox
            \getnoflines{\dp\nextbox}%
            \advance\noflines -1
            \ifnum\noflines>0
              \scratchdimen\noflines\lineheight
            \else
              \scratchdimen\zeropoint
            \fi
          \else
            \scratchdimen\zeropoint
          \fi
          \ifnum\@@extrasnap=2 \advance\scratchdimen \extrasnapsign.5\lineheight \fi
          \ifnum\@@extrasnap=3 \advance\scratchdimen \extrasnapsign\lineheight \fi
          \edef\postsnap{\the\scratchdimen}%
          \ifstrutsnapping
            \ht\nextbox\ht\strutbox
            \dp\nextbox\dp\strutbox
          \else
            \scratchdimen\presnap
            \advance\scratchdimen \ht\strutbox
            \ht\nextbox\scratchdimen
            \scratchdimen\postsnap
            \advance\scratchdimen \dp\strutbox
            \dp\nextbox\scratchdimen
          \fi
          \hbox{\tracedsnapping\box\nextbox}%
          \ifstrutsnapping
            \ifdim\scratchdimen=\zeropoint\else\vskip\scratchdimen\fi
          \fi
        \else
          \scratchdimen\ht\nextbox\relax
          \ifcase\@@alignsnapbox
            % can't happen here
          \or
            \getrawnoflines\scratchdimen 
          \else
            \getnoflines   \scratchdimen
          \fi  
          \scratchdimen\noflines\lineheight\relax
          \advance\scratchdimen-\strutdepth
          \ifnum\pagetotal>\zeropoint
          \else % disable this as option 
            \advance\scratchdimen-\strutheight
            \advance\scratchdimen+\topskip
          \fi
          \dimen0=\scratchdimen
          \dimen2=\strutdepth
          \ifshowgridboxes
            \setbox\nextbox\hbox{\color[grid:two]{\ruledhbox{\black\box\nextbox}}}%
          \fi
          \dp\nextbox\dp\strutbox
          \dimen4=\ht\nextbox
          \dimen6=\dp\nextbox
          \setbox\nextbox\vbox to \scratchdimen
            {\forgetall
             \ifnum\@@alignsnap>2 \vfill\fi % 3 4 
             \iftracegridsnapping
               \scratchdimen\@@alignsnapamount\relax
               \setbox\scratchbox\hbox
                 {\ifdim\scratchdimen<\zeropoint
                    \tracedgridamount\zeropoint{-\scratchdimen}%
                  \else
                    \tracedgridamount\scratchdimen\zeropoint
                  \fi}%
               \smashbox\scratchbox 
               \setbox\nextbox\hbox{\box\scratchbox\box\nextbox}%
             \fi
             \setbox\nextbox\hbox
               {\scratchdimen\@@alignsnapamount\relax
                \ifcase\@@alignsnapdepth\or
                  % don't change this ever ! 
                  \ifdim\dimen0<\lineheight
                    % otherwise it is ok, but ending up inside 
                    % the next paragraph is seldom what we want,
                    % so we move one line up
                    \advance\scratchdimen-\lineheight
                    \advance\scratchdimen\strutheight
                  \else
                    % otherwise we can move down to the 
                    % baseline 
                    \advance\scratchdimen\dimen6
                  \fi
                \fi
                \lower\scratchdimen\box\nextbox}%
             \ht\nextbox\dimen4
             \dp\nextbox\dimen6
             \box\nextbox
             \nointerlineskip % \offinterlineskip
             \ifnum\@@alignsnap<4 \vfill\fi % 2 3 
             \kern\zeropoint}% 
          \ifshowgridboxes
            \setbox\nextbox\vbox{\color[grid:three]{\ruledhbox{\black\box\nextbox}}}%
          \fi
          \scratchdimen\@@alignsnapamount
          \edef\presnapskip{\the\scratchdimen}%
          \ifnum\@@alignsnap>2 \def\presnap {+}\fi 
          \ifnum\@@alignsnap<4 \def\postsnap{+}\fi 
          \setbox\nextbox\hbox{\tracedsnapping\box\nextbox}%
          \par
          \ht\nextbox\dimen0
          \dp\nextbox\dimen2
          \forcedpresnapcorrection
          \nointerlineskip
          \box\nextbox 
        \fi
      \else
        \setbox\nextbox\vbox to \teksthoogte
          {\ifdim\nextboxdp=\zeropoint
             \hbox{\lower\strutdepth\box\nextbox}
           \else % this branch is yet untested 
             \vss
             \hbox{\lower\nextboxdp\box\nextbox}
             \vskip-\strutdepth
           \fi}%
        \nextboxdp\strutdepth
        \box\nextbox 
      \fi
      \extrasnapreset
      \enablepresnapcorrection
      \global\chardef\@@alignsnap\zerocount
      \global\chardef\@@alignsnapbox\zerocount
      \egroup}}

\def\tracedgridamount#1#2%
  {\color[grid:four]{\vrule\!!width\wd\nextbox\!!height#1\!!depth#2}}

\def\snaptomathgrid % probably not working ok, also kind of obsolete
  {\ifgridsnapping
     \dowithnextbox
       {\blanko[\v!regel]\snaptogrid\vbox{\box\nextbox}\blanko[\v!regel]}
     \vbox\bgroup
       \let\setdisplayskips\relax
       \abovedisplayskip\zeropoint
       \abovedisplayshortskip\zeropoint
       \belowdisplayskip\zeropoint
       \belowdisplayshortskip\zeropoint
       \@EA\let\@EA\next
   \fi}

\def\topsnaptogrid
  {\ifgridsnapping
     \dowithnextbox
       {\scratchdimen\ht\nextbox
        \advance\scratchdimen -\ht\strutbox
        \advance\scratchdimen \topskip
        \ht\nextbox\scratchdimen
        \dp\nextbox\zeropoint
        \box\nextbox
        \kern\lineheight
        \kern-\topskip
        \nointerlineskip}
       \hbox
   \fi}

% The old one (to be kept):
% 
% \def\centertogrid
%   {\ifgridsnapping
%      \dowithnextbox
%        {\bgroup
%         \par
%         \scratchdimen\ht\nextbox
%         \advance\scratchdimen \dp\nextbox
%         \getnoflines\scratchdimen
%         \setbox\nextbox\vbox to \noflines\lineheight
%           {\forgetall
%            \vskip\zeropoint \!!plus \ht\nextbox
%            \copy\nextbox
%            \kern.5\dp\strutbox % VOORLOPIGE WAARDE
%            \vskip\zeropoint \!!plus \dp\nextbox}
%         \noindent\snaptogrid\vbox{\box\nextbox}%
%         \egroup}
%        \hbox
%    \fi}
%
% The new implementation, using one of the placement 
% options, will be configurable some day ... 

\def\centertogrid % usage: see ie pascal / stepcharts 
  {\snaptogrid[\v!midden,.5\dp\strutbox]\vbox} 

\ifx\startbaselinecorrection\undefined \wait \fi % change order

\let\normalstartbaselinecorrection=\startbaselinecorrection

\def\startbaselinecorrection
  {\ifgridsnapping
     \centertogrid\bgroup
     \let\stopbaselinecorrection\egroup
   \else
     \normalstartbaselinecorrection
   \fi}

\def\setgridbox#1#2#3%
  {\setbox#1\ruledvbox to #3 % given size 
     {\forgetall
      \resetteststrut 
      \offinterlineskip
      \hsize#2%
      \baselinerulefalse
      \ruledvbox % calculated size 
        {\getrawnoflines{#3}% \getnoflines{#3}%
         \vskip\topskip
         \vskip-\ht\strutbox
         \scratchdimen#2\advance\scratchdimen \lineheight
         \dorecurse\noflines
           {\strut
            \hskip-.5\lineheight
            \rlap
              {\hskip\scratchdimen
               \hskip2pt\infofont
               \hbox to 1em{\hss\recurselevel}}%
            \vrule
              \!!height .5\testrulewidth
              \!!depth  .5\testrulewidth
              \!!width    \scratchdimen
            \par}}
      \vfill}}

%D Some intervention macros:

\def\gridwarning#1{\message{[beware of #1 extra snap]}}

\global\let\@@alignsnapamount\!!zeropoint
\global\chardef\@@alignsnapdepth0

\def\@@unknowngriddisplacement 
  {\global\chardef\@@alignsnapbox3
   \global\let\@@alignsnapamount\commalistelement}

\def\doverplaatsopgrid[#1]% 
  {\ifgridsnapping\doifsomething{#1}{\dodoverplaatsopgrid[#1]}\fi}

\def\dodoverplaatsopgrid[#1]% some day : speed up 
  {\global\chardef\@@alignsnap\zerocount 
   \global\chardef\@@alignsnapbox\zerocount  
   \global\chardef\@@alignsnapdepth\zerocount 
   \global\let\@@alignsnapamount\!!zeropoint
   \donefalse 
   \expanded{\processallactionsinset[#1]}
     [\v!standaard=>,
        \v!normaal=>, % to be sure 
             \v!ja=>, % to be sure 
          \v!boven=>\gridwarning+\positiveextrasnap\extrasnapbefore,
          \v!onder=>\gridwarning+\positiveextrasnap\extrasnapafter,
          \v!beide=>\positiveextrasnap\extrasnaparound,
         -\v!boven=>\gridwarning-\negativeextrasnap\extrasnapbefore,
         -\v!onder=>\gridwarning-\negativeextrasnap\extrasnapafter,
         -\v!beide=>\negativeextrasnap\extrasnaparound,
         \v!pagina=>\global\chardef\@@alignsnap1, % topskip
           \v!hoog=>\global\chardef\@@alignsnap2, 
         \v!midden=>\global\chardef\@@alignsnap3, 
           \v!laag=>\global\chardef\@@alignsnap4, 
        \v!passend=>\global\chardef\@@alignsnapbox1, % new 
           \v!ruim=>\global\chardef\@@alignsnapbox2, % new
         \v!diepte=>\global\chardef\@@alignsnapdepth1, % new 
          \v!regel=>\global\chardef\@@alignsnapbox3
                    \global\chardef\@@alignsnap4 
                    \global\chardef\@@alignsnapdepth1, 
          \v!reset=>\positiveextrasnap\extrasnapreset,
           \v!geen=>\global\chardef\@@alignsnap0
                    \global\chardef\@@alignsnapbox0,
        \s!default=>,
        \s!unknown=>\@@unknowngriddisplacement]}

\def\verplaatsopgrid
  {\dosingleempty\doverplaatsopgrid}

\def\doplaatsopgrid[#1]%
  {\doverplaatsopgrid[#1]\snaptogrid\vbox}

\def\plaatsopgrid
  {\dosingleempty\doplaatsopgrid}

%D Snapping is rather robust as long as we use whole lines.
%D Half lines of white space can however be handled when they
%D come in pairs. The corrections needed when crossing page
%D boundaries in the middle of such a pair, are handled by
%D macros that are (named) sort of fuzzy. This fuzzy mechanism
%D was written as an extension to the grid typesetting needed
%D for typesetting (part of) the \MAPS.
%D
%D \starttypen
%D \setuptyping
%D   [before={\blank[halfline]},
%D    after={\blank[halfline]}]
%D \stoptypen

\newif\iffuzzysnapdone
\newif\iffuzzysnapping
\newif\iffuzzysnapped

\chardef\fuzzysnappedleft=0 % ==1 when fuzzybegin still open

\newpersistentmark\fuzzymark % (!)
\newcount\fuzzymarker
\newbox\fuzzysnapbox
\newbox\fuzzysnapsplit

%\def\dosyncfuzzyvskip
%  {\ifvmode\ifdim\lastskip<\lineheight\ifdim\lastskip>\zeropoint
%     \bgroup
%     \endgraf
%     \forgetall
%     \vbox{\strut}
%     \kern-2\lineheight
%     \nobreak
%     \vskip\lineheight 
%     \egroup
%   \fi\fi\fi}

%\def\fuzzyvskip#1%
%  {\iffuzzysnapdone
%     \endfuzzysnapping
%     \vskip#1\relax
%     \dosyncfuzzyvskip  % NEW
%     \global\fuzzysnapdonefalse
%   \else
%     \vskip#1\relax
%     \beginfuzzysnapping
%     \global\fuzzysnapdonetrue
%   \fi}

\def\dosyncfuzzyvskip
  {\ifvmode\ifdim\lastskip<\lineheight\ifdim\lastskip>\zeropoint
     \bgroup
       \endgraf\forgetall\vbox{\strut}\nobreak\vskip\lineheight 
     \egroup
   \fi\fi\fi}

\def\fuzzyvskip#1%
  {\iffuzzysnapdone
     \dosyncfuzzyvskip  % NEWER
     \endfuzzysnapping
     \vskip#1\relax
     \global\fuzzysnapdonefalse
   \else
     \vskip#1\relax
     \beginfuzzysnapping
     \global\fuzzysnapdonetrue
   \fi}

\def\setfuzzymark#1#2#3% #1/#2 => error recovery
  {\ifgridsnapping
     \global\fuzzysnappingtrue
     \global\advance\fuzzymarker \ifodd\fuzzymarker#1\else#2\fi
     \nobreak
     \ifshowfuzzyskips
       \hbox{\color[grid:three]
         {\llap{\infofont#3\vl\the\fuzzymarker}\nobreak
          \vrule\!!width\hsize\!!height.1\lineheight}}
       \nobreak
     \fi
    %[\the\fuzzymarker]
    %\expandafter\fuzzymark\expandafter{\the\fuzzymarker}%
     \expandafter\rawsetmark\expandafter\fuzzymark\expandafter{\the\fuzzymarker}%
     \nobreak
  \fi}

\def\beginfuzzysnapping{\setfuzzymark21\v!start} % odd
\def\endfuzzysnapping  {\setfuzzymark12\v!stop } % even

\def\removelastfuzzyvskip
  {\ifgridsnapping
     \iffuzzysnapping
       \ifdim\lastskip<\openlineheight
       \else
         \removelastskip
       \fi
     \else
       \removelastskip
     \fi
   \else
     \removelastskip
   \fi}

\def\docheckfuzzysnap#1%
  {\bgroup
   \mindermeldingen
   \setbox\fuzzysnapbox\copy#1\relax
   \setbox\fuzzysnapsplit\vsplit\fuzzysnapbox to 1\lineheight
   \let\topfuzzymark\empty % indeed here ... no real mark
   \getsplitmarks\fuzzymark
%   \ifcase0\topfuzzymark
   \ifcase0\rawgetsplittopmark\fuzzymark
     \global\chardef\fuzzysnappedleft\zerocount
     \global\fuzzysnappedfalse
%   \else\ifodd\topfuzzymark
   \else\ifodd\rawgetsplittopmark\fuzzymark
     \global\chardef\fuzzysnappedleft\plusone
     \global\fuzzysnappedtrue
   \else
     \global\chardef\fuzzysnappedleft=2
     \global\fuzzysnappedtrue
   \fi\fi
   \iffuzzysnapped \else
     \doloop
       {\ifvoid\fuzzysnapbox
          \exitloop
        \else
          \setbox\fuzzysnapsplit=\vsplit\fuzzysnapbox to \lineheight
         %\let\topfuzzymark=\empty % ... but not here
          \getsplitmarks\fuzzymark
%          \ifcase0\topfuzzymark
          \ifcase0\rawgetsplittopmark\fuzzymark
            % continue
%          \else\ifodd\topfuzzymark
          \else\ifodd\rawgetsplittopmark\fuzzymark
            \exitloop
          \else
            \global\chardef\fuzzysnappedleft\plusone
            \global\fuzzysnappedtrue
            \exitloop
          \fi\fi
        \fi}%
   \fi
   \egroup}

\def\getfuzzysnapcorrection#1%
  {\global\let\presnapcorrection \relax
   \global\let\postsnapcorrection\relax
   \ifgridsnapping\iffuzzysnapping 
     \docheckfuzzysnap{#1}%
     \iffuzzysnapped
       \iftracegridsnapping
         \gdef\presnapcorrection
           {\color[grid:four]{\hrule\!!height.5\openlineheight\!!width\hsize}}%
       \else
         \gdef\presnapcorrection{\kern.5\openlineheight}%
       \fi
       \gdef\postsnapcorrection{\kern-.5\openlineheight}% get the height ok
     \fi
   \fi\fi}

\def\fuzzysnappedbox#1#2% \box<n> \unvbox<n>
  {\getfuzzysnapcorrection{#2}%
   \presnapcorrection
   #1#2%
   \postsnapcorrection}

\def\adaptfuzzypagegoal
  {\ifgridsnapping\iffuzzysnapping\ifcase\fuzzysnappedleft\or % see dopagecontents
     \scratchdimen\pagegoal
     \advance\scratchdimen -.5\openlineheight
     \global\pagegoal\scratchdimen
     \global\advance\vsize -.5\openlineheight
     \global\chardef\fuzzysnappedleft0
   \fi\fi\fi}

%D New: 

\let\checkgridsnapping\relax

\protect \endinput
