anch-snc.mkii / last modification: 2020-01-30 14:15
%D \module
%D   [       file=anch-snc,
%D        version=2003.12.01,
%D          title=\CONTEXT\ Anchoring Macros,
%D       subtitle=Synchronization,
%D         author=Hans Hagen,
%D           date=\currentdate,
%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

\writestatus{loading}{ConTeXt Anchoring Macros / Synchronization}

\unprotect

\ifx\s!set    \undefined \def\s!set    {set}     \fi
\ifx\s!reset  \undefined \def\s!reset  {reset}   \fi
\ifx\s!preset \undefined \def\s!preset {preset}  \fi
\ifx\s!syncpos\undefined \def\s!syncpos{syncpos} \fi

\def\definesyncpositions[#1]%
  {\setcounter{\s!num:\s!syncpos:#1}{0}%
   \doglobal\appendtoksonce\getvalue {\s!reset:\s!syncpos:#1}\to\resetsyncpositions
   \doglobal\appendtoksonce\getvalue{\s!preset:\s!syncpos:#1}\to\presetsyncpositions
   \setgvalue{\s!syncpos:#1}{sync_n[#1] := 0 ;}%
   \setgvalue{\s!set:\s!syncpos:#1}{\dosetsyncpositions{#1}}}

\def\syncposition
  {\dodoubleempty\dosyncposition}

\def\dosyncposition[#1][#2]%
  {\letgvalue{\s!reset:\s!syncpos:#1}\relax
   \letgvalue{\s!preset:\s!syncpos:#1}\relax
   \dontleavehmode
   \dodosyncposition{#1}{#2}\s!set
   \ignorespaces}

\def\doifelselastsyncposition#1#2%
  {\doifelse{\lastsyncclass\lastsyncposition}{#1#2}}

\def\dodosyncposition#1#2#3%
  {\letgvalue{\s!reset:\s!syncpos:#1}\relax
   \letgvalue{\s!preset:\s!syncpos:#1}\relax
   \ifundefined{\s!syncpos:#1}%
     \strut
   \else
     \pluscounter{\s!num:\s!syncpos:#1}%
     \setsyncpositions{#1}%
     % option: geen w/h, alleen p 0 0 0 data
     \setpositionplus
       {\s!syncpos:#1:\countervalue{\s!num:\s!syncpos:#1}}%
       {#2}%
       \hbox{\strut\traceposstring\llap\green{#3/\countervalue{\s!num:\s!syncpos:#1}/#1/#2>>}}%
   \fi}

\def\setsyncpositions#1%
  {\enabletextarearegistration
   \getvalue {\s!set:\s!syncpos:#1}%
   \letgvalue{\s!set:\s!syncpos:#1}\relax}

\def\dosetsyncpositions#1%
  {\startnointerference % removing out of sync can best be done in mp
   \!!dimena\maxdimen
   \!!counta\zerocount
   \!!countc\zerocount
   \doloop
     {\doifpositionelse{\s!syncpos:#1:\recurselevel}
        {\!!dimenb\MPy{\s!syncpos:#1:\recurselevel}\relax
         \!!countb\MPp{\s!syncpos:#1:\recurselevel}\relax
         \ifnum\!!countb=\!!counta % same page
           \ifdim\!!dimenb>\!!dimena
             \donefalse % out of order nodes
           \else
             \donetrue % nodes in order
           \fi
         \else
           \donetrue % different page
         \fi
         \ifdone
           \!!counta\!!countb
           \!!dimena\!!dimenb
           \advance\!!countc\plusone
           \edef\!!stringa{[#1][\the\!!countc]:=}%
           \edef\!!stringc{\s!syncpos:#1:\the\!!countc}%
           \edef\!!stringd{\MPplus\!!stringc{1}{0}}%
           \setxvalue{\s!syncpos:#1}%
             {\getsyncpositions{#1}%
              sync_p \!!stringa \MPp \!!stringc ;
              sync_xy\!!stringa \MPxy\!!stringc ;
              sync_w \!!stringa \MPw \!!stringc ;
              sync_h \!!stringa \MPh \!!stringc ;
              sync_d \!!stringa \MPd \!!stringc ;
              \ifx\!!stringd\empty \else sync_t \!!stringa \MPplus\!!stringc{1}{0} ; \fi}%
          \fi}
        {\setxvalue{\s!syncpos:#1}%
           {\getsyncpositions{#1}%
            sync_n[#1] := \the\!!countc ;}
         \exitloop}}%
   \stopnointerference}

\def\getsyncpositions#1%
  {\getvalue{\s!syncpos:#1}}

\newtoks\resetsyncpositions
\newtoks\presetsyncpositions

\def\resyncposition {\dodoubleargument\doresyncposition}
\def\presyncposition{\dodoubleargument\dopresyncposition}

\def\dodoresyncposition #1#2{\dodosyncposition{#1}{#2}\s!reset}
\def\dodopresyncposition#1#2{\dodosyncposition{#1}{#2}\s!preset}

\def\doresyncposition [#1][#2]{\setxvalue{\s!reset :\s!syncpos:#1}{\noexpand\dodoresyncposition{#1}{#2}}}
\def\dopresyncposition[#1][#2]{\setxvalue{\s!preset:\s!syncpos:#1}{\noexpand\dodopresyncposition{#1}{#2}}}

\def\flushsyncpositions % this order !
  {\begingroup
   \the\presetsyncpositions
   \the\resetsyncpositions
   \endgroup}

\def\flushsyncxxsets#1%
  {\setbox\scratchbox\hbox{\the#1}%
   \ifvoid\scratchbox\else
     \prewordbreak \let\prewordbreak\relax % only once
     \smashbox\scratchbox
     \box\scratchbox
   \fi}

\def\flushsyncresets {\flushsyncxxsets\resetsyncpositions }
\def\flushsyncpresets{\flushsyncxxsets\presetsyncpositions}

% \appendtoks \flushsyncpositions \to \everypar
% \appendtoks \flushsyncpositions \to \everyheadstart

% \explicitneverypar -> in grid snapper, eerst testen
%
% \appendtoks \flushsyncpositions \to \neverypar

\protect \endinput

\starttext

\definesyncpositions[1]

\startuseMPgraphic{sync}
  StartPage ;
    \getsyncpositions{1} ;
    SyncThreshold := 2LineHeight ;
    SyncLeftOffset := -.5LeftMarginDistance ;
  % SetSyncThreshold(1,3,3LineHeight) ;
    SyncWidth := - (BackSpace + SyncLeftOffset) ;
    SetSyncColor(1,1,\MPcolor{red}) ;
    SetSyncColor(1,2,\MPcolor{green}) ;
    SetSyncColor(1,3,\MPcolor{blue}) ;
    SetSyncColor(1,4,\MPcolor{yellow}) ;
    PrepareSyncTasks(1,true,true,false) ;
    for i = 1 upto NOfSyncPaths :
      fill SyncPaths[i]
        withcolor TheSyncColor(CurrentSyncClass,sync_t[CurrentSyncClass][SyncTasks[i]]) ;
    endfor ;
    setbounds currentpicture to Page ;
  StopPage ;
\stopuseMPgraphic

\defineoverlay[tempoverlay][\useMPgraphic{sync}]

\setupbackgrounds[page][background=tempoverlay]

\syncposition[1][1] \input ward \endgraf
\syncposition[1][2] \input ward \endgraf
\syncposition[1][3] \input ward \endgraf
\syncposition[1][4] \input ward \endgraf

\stoptext