%D \module
%D   [       file=anch-bar,
%D        version=2003.03.16,
%D          title=\CONTEXT\ Anchoring Macros,
%D       subtitle=Margin Bars and alike,
%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 / Margin Bars}

\unprotect

%D We will implement a sidebar mechanism using the functionality from \type
%D {core-pos}.
%D
%D \starttyping
%D \definesidebar[whow][rulecolor=green,distance=0pt]
%D
%D \input tufte \par
%D \startsidebar
%D   \input tufte \par
%D   \input tufte \par
%D   \startsidebar[whow]
%D     \input tufte \par
%D     \input tufte \par
%D     \input tufte
%D   \stopsidebar \par
%D   \input tufte \par
%D   \input tufte
%D \stopsidebar \par
%D \input tufte \par
%D \input tufte \par
%D \startsidebar
%D   \input tufte \par
%D   \input tufte \par
%D   \input tufte \par
%D   \input tufte \par
%D   \input tufte
%D \stopsidebar \par
%D \input tufte \par
%D \input tufte \par
%D \startsidebar
%D   \input tufte
%D   \input tufte
%D   \input tufte
%D   \input tufte
%D   \input tufte
%D \stopsidebar
%D \stoptyping
%D
%D This can be done better now ... maybe also by using the syncpos features.

\installcorenamespace{sidebar}

\installcommandhandler \??sidebar {sidebar} \??sidebar

\newinteger  \c_anch_sidebars_n
\newinteger  \c_anch_sidebars_current % local
\newdimension\d_anch_sidebars_distance
\newinteger  \c_anch_sidebars_level

% \setupMPvariables
%   [mpos:sidebar]
%   [linecolor=red,
%    linewidth=2pt,
%    distance=5pt]

\setupsidebar
  [\c!rulethickness=\bodyfontsize/6, % 2pt default
   \c!rulecolor=\s!black,
   \c!alternative=0,
   \c!topoffset=\zeropoint,
   \c!bottomoffset=\zeropoint,
   \c!distance=.5\bodyfontsize,
   \c!level=,
   \c!location=\v!left,
   \c!leftmargindistance=\zeropoint]

\aliased\let\setupsidebars\setupsidebar

\permanent\tolerant\protected\def\startsidebar[#S#1]#*[#S#2]%
  {\bgroup
   \dontleavehmode
   \advanceby\c_anch_sidebars_level\plusone
   \global\advanceby\c_anch_sidebars_n\plusone
   \c_anch_sidebars_current\c_anch_sidebars_n\relax % relax needed
   \ifhastok={#1}%
     \cdef\currentsidebar{\the\c_anch_sidebars_level}%
     \checksidebarparent
     \setupcurrentsidebar[#1]%
   \else
     \cdef\currentsidebar{#1}%
     \setupcurrentsidebar[#2]%
   \fi
   \scratchdistance{\sidebarparameter\c!distance}%
   \scratchdimen{\sidebarparameter\c!leftmargindistance}%
   \edef\p_level{\sidebarparameter\c!level}%
   \ifempty\p_level
     \ifnum\c_anch_sidebars_level=\plusone
       \ifzeropt\scratchdimen
         \advanceby\d_anch_sidebars_distance\scratchdistance\relax
       \else
         \d_anch_sidebars_distance\scratchdimen
       \fi
     \else
       \advanceby\d_anch_sidebars_distance\scratchdistance\relax
     \fi
   \orelse\ifnum\p_level=\plusone
     \ifzeropt\scratchdimen
       \advanceby\d_anch_sidebars_distance\scratchdistance\relax
     \else
       \d_anch_sidebars_distance\scratchdimen
     \fi
   \else
     % test: {\scratchdimen+(\p_level-\plusone)*\scratchdistance}
     \d_anch_sidebars_distance{\scratchdimen+\numexpr\p_level-\plusone\relax\dimexpr\scratchdistance\relax}%
   \fi
   \startpositionoverlay{\v!text-1}%
     \expanded{\setMPpositiongraphicrange % maybe expand in definition
       {b:sidebar:\tointeger\c_anch_sidebars_n}%
       {e:sidebar:\tointeger\c_anch_sidebars_n}%
       {mpos:sidebar}%
       {self=sidebar:\tointeger\c_anch_sidebars_n,
        location=\mplocation{\sidebarparameter\c!location},
        linewidth=\todimension{\sidebarparameter\c!rulethickness},
        linecolor=\sidebarparameter\c!rulecolor,
        alternative=\sidebarparameter\c!alternative,
        topoffset=\todimension{\sidebarparameter\c!topoffset},
        bottomoffset=\todimension{\sidebarparameter\c!bottomoffset},
        distance=\todimension\d_anch_sidebars_distance}%
     }%
   \stoppositionoverlay
   \bpos{sidebar:\the\c_anch_sidebars_current}%
   \ignorespaces}

\permanent\protected\def\stopsidebar
  {\removelastspace
   \epos{sidebar:\the\c_anch_sidebars_current}
   \carryoverpar\egroup}

%D Let's keep this nice and simple (okay, we could pass the 6 variables in
%D one lua call).

\startMPpositionmethod{mpos:sidebar}
    \startMPpositiongraphic{mpos:sidebar}{linecolor,linewidth,distance,alternative}
        anch_sidebars_draw("\MPbself", "\MPeself", "\textanchor") ;
    \stopMPpositiongraphic
    \MPpositiongraphic{mpos:sidebar}{}%
\stopMPpositionmethod

%D We now reimplement the \MKII\ margin rules handler in a more modern way.
%D
%D \setupmarginrules
%D   [rulecolor=darkred,
%D    rulethickness=2pt]
%D
%D \setupmarginrules % sidebar
%D   [2]
%D   [rulecolor=darkblue]
%D
%D \startmarginrule[1]
%D     \input ward
%D     \startmarginrule[2]
%D         \input ward
%D         \startmarginrule[3]
%D             \input ward
%D             \startmarginrule[level=6,rulecolor=darkgreen]
%D                 \input ward
%D             \stopmarginrule
%D             \input ward
%D         \stopmarginrule
%D         \input ward
%D     \stopmarginrule
%D     \input ward
%D \stopmarginrule
%D
%D Compared to the old mechanism we now can pass settings too.

\definesidebar
  [\v!margin]
  [\c!leftmargindistance=\dimexpr\leftmargindistance+\sidebarparameter\c!rulethickness/2\relax]
 %[\c!leftmargindistance=\leftmargindistance+\sidebarparameter\c!rulethickness/2]

\dorecurse{5}{\definesidebar[\v!margin:#1][\v!margin]} % let's be nice and predefine 5 levels

\permanent\tolerant\protected\def\setupmarginrule[#S#1]#*[#S#2]%
  {\ifarguments\or
     \setupsidebar[\v!margin][#1]%
   \or
     \setupsidebar[\v!margin:#1][#2]%
   \fi}

\aliased\let\setupmarginrules\setupmarginrule

\permanent\tolerant\protected\def\startmarginrule[#S#1]% pretty inefficient checking
 %{\edef\m_anch_marginrules_kind{#1}%
 % \ifempty\m_anch_marginrules_kind
 % {\unless\ifparameter#1\or
  {\ifempty{#1}%
     \startsidebar[\v!margin][]%
   \orelse\ifhastok={#1}%
     \startsidebar[\v!margin][#1]%
   \else
     \anch_marginrules_check{#1}%
     \startsidebar[\v!margin:#1][\c!level=#1]%
   \fi}

\def\anch_marginrules_check#1%
  {\doifnotcommandhandler\??sidebar{\v!margin:#1}{\definesidebar[\v!margin:#1][\v!margin]}}

\aliased\let\stopmarginrule\stopsidebar

\protect \endinput