%D \module
%D   [       file=page-mar, % moved here from main-001
%D        version=1997.03.31,
%D          title=\CONTEXT\ Core Macros,
%D       subtitle=Marginal Things
%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 is still to be split and documented. 

\writestatus{loading}{Context Core Macros / Maginal Things}

\unprotect 

\newif\iflowinmargin

\def\stelinmargein
  {\dodoubleempty\dostelinmargein}

\def\dostelinmargein[#1][#2]%
  {\ifsecondargument
     \processcommalist[#1]{\dodostelinmargein[#2]}% becomes [#2]{##1}
   \else
     \getparameters[\??im][#1]%
   \fi}

\def\dodostelinmargein[#1]#2% [settings]{class}
  {\ifundefined{\??im#2\c!offset}%
     \presetlocalframed
       [\??im#2]%
     \getparameters
       [\??im#2]
       [\c!kader=\v!uit,
        \c!offset=\v!overlay,
        \c!regel=1,
        \c!scheider=,
        \c!breedte=\v!ruim,
        \c!afstand=\!!zeropoint,
        \c!letter=\@@imletter,
        \c!kleur=\@@imkleur,
        \c!plaats=\@@implaats,
        \c!uitlijnen=\@@imuitlijnen,
        \c!voor=\@@imvoor,
        \c!na=\@@imna,
        #1]%
   \else
     \getparameters[\??im#2][#1]%
   \fi}

\let\margetekstafstand  = \!!zeropoint
\def\margetekstregels     {1}
\def\margetekstnummer     {0}
\let\margetekstscheider = \empty

\def\margestrutheight{\strutht}

\def\maakmargetekstblok#1#2#3#4#5#6%
  {#4\relax
   \bgroup
   \forgetall % added, else problems with 'center' and nested itemize
   \mindermeldingen
   \hsize#1\relax
   \doifnumberelse\margetekstnummer
     {\ifcase\margetekstnummer\relax
        \def\margetekstnummer{#2}%
      \fi}
     \donothing
   \doifnumberelse\margetekstnummer
     {\ifnum\margetekstnummer>25 % to be translated 
        \writestatus\m!systems{potential margin stack overflow (\margetekstnummer)}%
      \fi}
     \donothing
   % todo
   \processallactionsinset
     [\getvalue{\??im\margetekstnummer\c!uitlijnen}]
     [     \v!ja=>\setvalue{\??im\margetekstnummer\c!uitlijnen}{#2},
          \v!nee=>\setvalue{\??im\margetekstnummer\c!uitlijnen}{\v!normaal},
       \v!binnen=>\setvalue{\??im\margetekstnummer\c!uitlijnen}{#2},
       \v!buiten=>\setvalue{\??im\margetekstnummer\c!uitlijnen}{#3},
        \v!links=>\setvalue{\??im\margetekstnummer\c!uitlijnen}{\v!links},
       \v!midden=>\setvalue{\??im\margetekstnummer\c!uitlijnen}{\v!midden},
       \v!rechts=>\setvalue{\??im\margetekstnummer\c!uitlijnen}{\v!rechts},
      \s!default=>\setvalue{\??im\margetekstnummer\c!uitlijnen}{#2}]%
   \setbox0\vbox\localframed
     [\??im\margetekstnummer]
     [\c!strut=\v!nee]
     {\decrement\margetekstregels
      \@@imvoor
      \dostartattributes{\??im\margetekstnummer}\c!letter\c!kleur\empty
        \dorecurse\margetekstregels{\strut\\}%
        \xdef\margestrutheight{\the\strutht}%
        \begstrut#6\endstrut\endgraf
      \dostopattributes
      \@@imna}%
   \doif\@@imstapel\v!ja    
     {\setbox0\vbox{\stackeddown\vbox{\box0}}}% new 
   \ht0\strutht
   \box0
   \egroup
   #5\relax}

%D The stacker permits constructs like:
%D 
%D \starttypen 
%D \stelinmargein[stapel=ja]
%D 
%D \inlinker{test 1}test\break
%D \inlinker{test 2}test\break
%D \inlinker{test 1} 
%D \input tufte
%D \inlinker{test 1} 
%D \inlinker{test 2} 
%D \inlinker{test 3}
%D \input tufte
%D \inlinker{test 1} 
%D \inlinker{test 2\endgraf test 3} 
%D \inlinker{test 4}
%D \input tufte
%D \inlinker{test 1}
%D \inlinker{test 2\endgraf test 3}
%D \inlinker{test 4\endgraf test 5\endgraf test 6}
%D \inlinker{test 7\endgraf test 8\endgraf test 9}
%D \input tufte
%D \stoptypen 

\def\plaatsmargetekstscheider
  {\ifnum\margincontent>\zerocount
     \bgroup
     \dimen0=\margetekstregels\lineheight
     \advance\dimen0 -\lineheight
     \lower\dimen0\hbox{\margetekstscheider}%
     \egroup
   \fi}

\def\linkermargetekstblok#1%
  {\maakmargetekstblok \leftmargintextwidth \v!links \v!rechts
     {\llap{\plaatsmargetekstscheider}}{\hskip\margetekstafstand}
     {#1}}

\def\rechtermargetekstblok#1%
  {\maakmargetekstblok \rightmargintextwidth \v!rechts \v!links
     {\hskip\margetekstafstand}{\rlap{\plaatsmargetekstscheider}}
     {#1}}

\def\doplacemargintext#1#2#3%
  {\strut
   \setbox0\hbox{#1}%
   \dimen0\ht0
   \advance\dimen0 \dp0
   \ifdim\dimen0>\marginheight
     \global\marginheight\dimen0
   \fi
   \setbox0\hbox
     {#2{\hskip#3\strut
         \iflowinmargin\else
           \dimen0\strutdp
           \advance\dimen0 \margestrutheight
           \advance\dimen0 -\strutht
           \raise\dimen0
         \fi
         \box0}}%
   \ht0\zeropoint
   \dp0\zeropoint
   \gdef\margestrutheight{\the\strutht}%
  %\graphicvadjust{\box0}} % fails in high math lines, let it be  
  %\hbox{\lower\strutdp\box0}} % alas, wrong lapping, therefore useless 
   \dopositionmarginbox0}

%D This approach permits us to implement a better mechanism 
%D later. We need the \type {\graphicvadjust} in order to 
%D handle: 
%D 
%D \starttypen 
%D \inlinker{test} {\red \dorecurse{40}{test }\par}
%D {\red \inlinker{test} \dorecurse{40}{test }\par}
%D \stoptypen
%D 
%D The outer margin color is either black or color set as 
%D main text color. 

\ifx\dopositionmarginbox\undefined
  \def\dopositionmarginbox#1{\graphicvadjust{\box#1}}
\fi

\def\leftmargintextdistance  {\getvalue{\??im\v!links \c!afstand}}
\def\rightmargintextdistance {\getvalue{\??im\v!rechts\c!afstand}}

\def\leftmargintextwidth     {\getvalue{\??im\v!links \c!breedte}}
\def\rightmargintextwidth    {\getvalue{\??im\v!rechts\c!breedte}}

\def\doinlinker#1%
  {\doplacemargintext
     {\linkermargetekstblok{#1}\hskip\leftmargintextdistance}
     \llap\zeropoint}

\def\doinrechter#1%
  {\doplacemargintext
     {\hskip\rightmargintextdistance\rechtermargetekstblok{#1}}
     \rlap\hsize}

\newcounter \nofmarginnotes
\newif      \iftrackingmarginnotes
\newif      \ifrightmargin            % documenteren

\definetwopasslist\s!margin

\def\domarginreference
  {\doglobal\increment\nofmarginnotes\relax
   \edef\writemarref
     {\writeutilitycommand%
        {\twopassentry%
           {\s!margin}%
           {\nofmarginnotes}%
           {\noexpand\realfolio}}}%
   \writemarref}

\def\dodoinmargenormal#1#2#3#4%
  {\iffirstsidefloatparagraph\geenwitruimte\fi % zo laat mogelijk
   \ifodd#1\relax
     \rightmargintrue
     #3{#4}%
   \else
     \rightmarginfalse
     #2{#4}%
   \fi}

\def\doinmargenormal#1#2#3%
  {\bgroup
   \iftrackingmarginnotes
     \gettwopassdata\s!margin
     \iftwopassdatafound
       \dodoinmargenormal\twopassdata#1#2{#3}%
     \else
       \dodoinmargenormal\realfolio#1#2{#3}%
     \fi
     \domarginreference
   \else
     \dodoinmargenormal\realfolio#1#2{#3}%
   \fi
   \egroup}

\def\doinmargereverse#1#2#3%
  {\dodoinmargenormal\realfolio#2#1{#3}}

\def\doinmarge[#1][#2][#3][#4][#5]#6%
  {\doifcommonelse{+,-,\v!laag}{#4}
     {\dodoinmarge[#1][#2][#3][#4][#5]{#6}}
     {\dodoinmarge[#1][#2][#3][][#4]{#6}}%
   \ignorespaces}

\def\dodoinmarge[#1][#2][#3][#4][#5]#6%
  {\ignorespaces
   \bgroup\postponefootnotes % group is (somehow) needed
   \doifinsetelse\v!laag{#4}
     \lowinmargintrue
     \lowinmarginfalse
   \processaction
     [#1]
     [  \v!links=>#2{#6},
       \v!rechts=>#3{#6},
      \s!unknown=>\ifdubbelzijdig
                    \doifcommonelse{+,-}{#4}
                      \doinmargereverse\doinmargenormal#2#3{#6}%
                  \else
                    #2{#6}%
                  \fi]%
   \rawpagereference\s!mar{#5}%
   \flushnotes\egroup % don't forget the group 
   \ignorespaces}

\def\inlinker
  {\indentation\doquintupleempty\doinmarge
     [\v!links][\doinlinker][\doinrechter]}

\def\inrechter
  {\indentation\doquintupleempty\doinmarge
     [\v!rechts][\doinlinker][\doinrechter]}

\def\inmarge
  {\doquintupleempty\doinmarge
     [\@@implaats][\doinlinker][\doinrechter]}

\def\inanderemarge
  {\doquintupleempty\doinmarge
     [\@@implaats][\doinrechter][\doinlinker]}

\newcounter\margincontent

\def\doflushmargincontent % [#1][#2]#3% hier plaats 'globaal' (geen 1,2 enz)
  {\doinmarge[\@@implaats][\doinlinker][\doinrechter]} % [#1][#2]{#3}}

\newdimen\marginheight

\let\restoreinterlinepenalty=\relax

\def\flushmargincontents % plural 
  {\restoreinterlinepenalty  % here?
   \ifcase\margincontent\else           % called quite often, so we
     \expandafter\doflushmargincontents % speed up the \fi scan by
   \fi}                                 % using a \do..

% for a manual flush in for instance headers

\def\placemargintexts % to be documented and translated
  {\ifcase\margincontent\else           
     \bgroup
       \let\normalvadjust\fakedvadjust
       \doflushmargincontents 
     \egroup
   \fi}                                 

% \def\doflushmargincontents% % links + rechts
%   {\bgroup
%    \forgetall
%    \global\marginheight\!!zeropoint
%    \dorecurse{\margincontent}
%      {\bgroup
%       \edef\margetekstafstand {\getvalue{\??im\recurselevel\c!afstand}}%
%       \edef\margetekstregels  {\getvalue{\??im\recurselevel\c!regel}}%
%       \edef\margetekstscheider{\getvalue{\??im\recurselevel\c!scheider}}%
%       \let\margetekstnummer=\recurselevel
%       \getvalue{\??im\recurselevel}%
%       \global\setvalue{\??im\recurselevel}{}%
%       \egroup}%
%    \ifdim\marginheight>\lineheight % This is something real dirty!
%      \advance\marginheight by \pagetotal
%      \advance\marginheight by \lineheight  % a sort of bonus
%      \ifdim\marginheight>\pagegoal
%        \xdef\restoreinterlinepenalty%
%          {\global\let\restoreinterlinepenalty\relax
%           \global\interlinepenalty=\the\interlinepenalty}%
%        \global\interlinepenalty=10000
%      \fi
%    \else % We need the above because interlinepenalties overrule vadjusted \nobreaks.
%      %\vadjust
%      %  {\forgetall
%      %   \global\advance\marginheight by \lineheight
%      %   \global\divide\marginheight by \lineheight
%      %   \dorecurse{\number\marginheight}
%      %     {\nobreak\vskip\lineheight}%
%      %   \kern-\number\marginheight\lineheight}%
%      \vadjust{\nobreak}%
%    \fi
%    \doglobal\newcounter\margincontent
%    \egroup}

\def\doflushmargincontents % links + rechts
  {\bgroup
   \forgetall
   \global\marginheight\zeropoint
   \dorecurse\margincontent
     {\bgroup
      \edef\margetekstafstand {\getvalue{\??im\recurselevel\c!afstand }}%
      \edef\margetekstregels  {\getvalue{\??im\recurselevel\c!regel   }}%
      \edef\margetekstscheider{\getvalue{\??im\recurselevel\c!scheider}}%
      \let\margetekstnummer\recurselevel
      \getvalue{\??im\recurselevel}%
      \letgvalue{\??im\recurselevel}\empty
      \egroup}%
\ifbinnenkolommen 
  \donetrue  % how fuzzy 
\else\ifdim\marginheight>\lineheight\relax 
  \donetrue  % how dirty 
\else 
  \donefalse % how needed
\fi\fi
\ifdone
     \advance\marginheight \pagetotal
     \advance\marginheight \lineheight  % a sort of bonus
     \ifdim\marginheight>\pagegoal
       \xdef\restoreinterlinepenalty
         {\global\let\restoreinterlinepenalty\relax
          \global\interlinepenalty=\the\interlinepenalty}% keep = here
       \global\interlinepenalty10000
     \fi
   \else % We need the above because interlinepenalties overrule vadjusted \nobreaks.
     %\vadjust
     %  {\forgetall
     %   \global\advance\marginheight by \lineheight
     %   \global\divide\marginheight by \lineheight
     %   \dorecurse{\number\marginheight}
     %     {\nobreak\vskip\lineheight}%
     %   \kern-\number\marginheight\lineheight}%
     \vadjust{\nobreak}%
   \fi
   \doglobal\newcounter\margincontent
   \egroup}

% Some day: \definieermarkering[\v!margetitel]

\def\docomplexmargewoord#1#2#3%
  {\@EA\setgvalue\@EA{\@EA\??im\@EA\margincontent\@EA}\@EA
     {\@EA\stelinmargein\@EA[\margincontent][]%  see next macro
      \doflushmargincontent[#1][#2]{#3}}}

\def\complexmargewoord[#1][#2]#3%
  {\doglobal\increment\margincontent
   \stelinmargein[\margincontent][]% see next macro
   \ifsecondargument
     \doifnumberelse{#1} % only one #3 (after test)
       {\docomplexmargewoord{#2}{#1}{#3}}
       {\docomplexmargewoord{#1}{#2}{#3}}%
   \else
     \doifnumberelse{#1}
       {\docomplexmargewoord{}{#1}{#3}}
       {\docomplexmargewoord{#1}{}{#3}}%
   \fi}

\def\margewoordpositie[#1]#2%
  {\ifnum#1>\margincontent
     \xdef\margincontent{#1}%
   \fi
   \stelinmargein[#1][]% when at outer level, saves local settings
   \setgvalue{\??im#1}%
     {\stelinmargein[#1][]% needed when par start outside group
      \doflushmargincontent[][]{#2}}}

\def\margewoord
  {\dodoubleempty\complexmargewoord}

\def\margetitel{\margewoord}
\def\margetekst{\margewoord}

\def\oplinker#1%
  {\strut
   \graphicvadjust
     {\mindermeldingen
      \setbox0\vtop{\forgetall\strut#1}%
      \getboxheight\dimen0\of\box0
      \vskip-\dimen0 % waarom stond hier een \ ? 
      \box0}}

\def\resetmargincontent % quick hack
  {\doglobal\newcounter\margincontent}

\def\resetmargetitels
  {\resetmargincontent} 

%D \macros
%D   {inleftside,inleftmargin,inrightmargin,inrightside}
%D
%D The fast and clean way of putting things in the margin is
%D using \type{\rlap} or \type{\llap}. Unfortunately these
%D macro's don't handle indentation, left and right skips. We
%D therefore embed them in some macro's that (force and)
%D remove the indentation and restore it afterwards.

% beware: no \hsize is set (yet)! 

\def\inleftmargin#1%
  {\pushindentation
   \llap{#1\hskip\leftskip\hskip\leftmargintextdistance}%
   \popindentation
   \ignorespaces}

\def\inrightmargin#1%
  {\pushindentation
   \rlap{\hskip\hsize\hskip-\rightskip\hskip\rightmargintextdistance#1}%
   \popindentation
   \ignorespaces}

\def\inleftedge#1%
  {\inleftmargin
     {#1\relax
      \hskip\linkermargebreedte
      \hskip\linkerrandafstand}}

\def\inrightedge#1%
  {\inrightmargin
     {\hskip\rechtermargebreedte
      \hskip\rechterrandafstand
      #1}}

\let\inleftside \inleftedge
\let\inrightside\inrightedge

%D We want to keep things efficient and therefore only handle
%D situations like:
%D
%D \startbuffer
%D                  \inleftside    {fine} some text \par
%D \strut           \inleftmargin  {fine} some text \par
%D \noindent        \inrightmargin {fine} some text \par
%D \noindent \strut \inrightside   {fine} some text \par
%D \stopbuffer
%D
%D \typebuffer
%D
%D which looks like:
%D
%D \bgroup
%D \haalbuffer
%D \parindent 30pt
%D \haalbuffer
%D \egroup

%D New, yet undocumented:
%D 
%D used for pascal: 
%D
%D \starttypen 
%D \index {test} test \index {west} west \index {rest} rest 
%D 
%D \startnarrower
%D \placeregister[index][alternative=b,command=\atleftmargin]
%D \stopnarrower
%D \stoptypen 

\def\atleftmargin#1%
  {\pushindentation
   \llap{\rlap{#1}\hskip\leftskip}%
   \popindentation
   \ignorespaces}

\def\atrightmargin#1%
  {\pushindentation
   \rlap{\hskip\hsize\hskip-\rightskip\llap{#1}}%
   \popindentation
   \ignorespaces}

% dit zijn voorlopig lokale commando's

\def\woordinlinker {\inleftmargin}  % vervallen
\def\woordinrechter{\inrechtermarge} % vervallen

\def\woordinmarge
  {\doquintupleempty\doinmarge
     [\@@implaats][\woordinlinker][\woordinrechter]}

%

\stelinmargein
  [\c!letter=\v!vet,
   \c!kleur=,
   \c!plaats=\v!beide,
   \c!uitlijnen=\v!binnen,
   \c!stapel=\v!nee,
   \c!voor=,
   \c!na=]

\stelinmargein
  [\v!links]
  [\c!afstand=\linkermargeafstand,
   \c!breedte=\linkermargebreedte,
  %\c!uitlijnen=\v!links, % njet
   \c!plaats=\v!links]

\stelinmargein
  [\v!rechts]
  [\c!afstand=\rechtermargeafstand,
   \c!breedte=\rechtermargebreedte,
  %\c!uitlijnen=\v!rechts, % njet
   \c!plaats=\v!rechts]

\newbox\facingbox
\newbox\facingpage

\newif\iffacingpages \facingpagesfalse

\def\shipoutfacingpage
  {\iffacingpages
     \ifnum\realpageno>\plusone
       \bgroup
       \global\pagebodyornamentsfalse
       \setbox\facingpage\vbox to \zethoogte
         {\unvbox\facingpage\vfil}%
       \myshipout{\buildpagebody\box\facingpage}%
       \egroup
     \else
       \global\setbox\facingpage\emptybox
     \fi
   \fi}

\def\naastpagina
  {\shipoutfacingpage}

\def\facefloat % redefined
  {\startnaast\box\floatbox\stopnaast}

\def\startnaast % beter: \dowithnextbox
  {\iffacingpages
     \global\setbox\facingbox\vbox
       \bgroup
       \hsize\zetbreedte
   \else
     \@EA\gobbleuntil\@EA\stopnaast
   \fi}

\def\stopnaast
  {\egroup
   \global\setbox\facingpage\vbox
     {\ifvoid\facingpage
        \vskip\openstrutdepth % \strutdp
      \else
        \unvbox\facingpage
      \fi
      \box\facingbox
      \blanko}}

\def\dostelnaastplaatsenin[#1]%
  {\getparameters[\??np][#1]%
   \doifelse\@@npstatus\v!start
     {\global\facingpagestrue}
     {\global\facingpagesfalse}}

\def\stelnaastplaatsenin
  {\dosingleargument\dostelnaastplaatsenin}

\stelnaastplaatsenin
  [\c!status=\v!stop]

\protect \endinput 
