%D \module
%D   [       file=pack-mrl, % was pack-rul/core-rul,
%D        version=1998.10.16,
%D          title=\CONTEXT\ Packaging Macros,
%D       subtitle=More Rules,
%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 Packaging Macros / More Rules}

%D The (re)implementation of margin rules has been moved elsewhere.

\unprotect

%D \macros
%D   {setupblackrules,blackrule}
%D
%D The graphic capabilities of \TEX\ do not go beyond simple filled rules, except of
%D course when using specials or, in \MKIV, manipulate node lists. Let's start with
%D a warning: using this commands is far more slower than using the \TEX\ primitives
%D \type {\hrule} and \type {\vrule}, but they save us some tokens. The
%D characteristics of these rule drawing command can be set by:
%D
%D \showsetup{setupblackrules}
%D
%D The simple command draws only one rule. Its optional argument can be used to
%D specify the dimensions. By setting the width, height or depth to \type {max}, one
%D gets the natural dimensions.
%D
%D \showsetup{blackrule}

\installcorenamespace{blackrules}

\installsimplecommandhandler \??blackrules {blackrules} \??blackrules

\permanent\protected\def\blackrule
  {% this was \hpack\bgroup\dontleavehmode but we want leader support
   \begingroup
   \doifelsenextoptionalcs\pack_black_rule_pickup\pack_black_rule_indeed}

\def\pack_black_rule_pickup[#S#1]%
  {\setupcurrentblackrules[#1]%
   \pack_black_rule_indeed}

\def\pack_black_rule_indeed
  {\edef\p_width   {\directblackrulesparameter\c!width}%
   \edef\p_height  {\directblackrulesparameter\c!height}%
   \edef\p_depth   {\directblackrulesparameter\c!depth}%
   \edef\p_stretch {\directblackrulesparameter\c!stretch}%
   \edef\p_shrink  {\directblackrulesparameter\c!shrink}%
   \edef\p_on      {\directblackrulesparameter\c!on}%
   \edef\p_off     {\directblackrulesparameter\c!off}%
   \edef\p_snapping{\directblackrulesparameter\c!snapping}%
   \ifx\p_height\v!max
     \setstrut
     \let\p_height\strutdp
   \orelse\ifx\p_depth\v!max
     \setstrut
   \fi
 % \ifx\p_height\v!max
 %   \let\p_height\strutdp
 % \fi
   \ifx\p_depth\v!max
     \let\p_depth\strutdp
   \fi
   \ifx\p_width\v!max
     \let\p_width\emwidth
   \fi
   \useblackrulesstyleandcolor\c!style\c!color
   \ifempty\p_stretch
     \ifempty\p_shrink
        \donefalse
     \else
        \donetrue
        \leaders
     \fi
   \else
      \donetrue
      \leaders
   \fi
   \ifcsname\??blackruletype\directblackrulesparameter\c!type\endcsname
     \lastnamedcs
   \else
     \ifempty\p_snapping
       \vrule
     \orelse\ifcsname\??snapping\p_snapping\endcsname
       \hrule \s!linesnapping \lastnamedcs
     \else
       \vrule
     \fi
     \ifempty\p_on \else
       \s!on \p_on % todo: \s!on {\p_on}%
     \fi
     \ifempty\p_off \else
       \s!off \p_off % todo: \s!off {\p_off}%
     \fi
   \fi
   \ifempty\p_height \else
     \s!height {\p_height}%
   \fi
   \ifempty\p_depth \else
     \s!depth {\p_depth}%
   \fi
   \ifdone
     \hskip
     \ifempty\p_width
       \zeropoint
     \else
       {\p_width}%
     \fi
     \ifempty\p_stretch \else
       \s!plus {\p_stretch}%
     \fi
     \ifempty\p_shrink \else
       \s!minus {\p_shrink}%
     \fi
   \else
     \ifempty\p_width \else
       \s!width {\p_width}%
     \fi
   \fi
   \endgroup}

\setupblackrules
  [\c!width=\emwidth,
   \c!height=\exheight,
   \c!depth=\zeropoint,
  %\c!on=\zeropoint,
  %\c!off=\zeropoint,
   \c!color=]

%D \macros
%D   {blackrules}
%D
%D One can call for a sequence of black rules, if needed equally spaced over the
%D given width.
%D
%D \showsetup{blackrules}
%D
%D The two alternative calls are therefore:
%D
%D \startbuffer
%D Tell me, is this according to the \blackrules[n=6]?
%D These \blackrules[alternativevariant=b,n=10,distance=.2em,width=4cm] are quite clear.
%D \stopbuffer
%D
%D \typebuffer
%D
%D or:
%D
%D \startlines
%D \getbuffer
%D \stoplines
%D
%D We could of course have implemented this macro using \type {\leaders}, but this
%D would probably have taken more tokens.

\permanent\tolerant\protected\def\blackrules[#S#1]% probably never used
  {\hpack\bgroup % we keep this because breaking into lines breaks compatibility
   \ifarguments\or\setupcurrentblackrules[#1]\fi
   \scratchwidth   {\directblackrulesparameter\c!width}%
   \scratchheight  {\directblackrulesparameter\c!height}%
   \scratchdepth   {\directblackrulesparameter\c!depth}%
   \scratchdistance{\directblackrulesparameter\c!distance}%
   \scratchcounter {\directblackrulesparameter\c!n}%
   \edef\p_alternative{\blackrulesparameter\c!alternative}%
   \ifx\p_alternative\c!b % why not just check distance
     \ifnum\scratchcounter=\plusone
       \scratchdistance\zeropoint
     \else
       \scratchwidth{(\scratchwidth-\scratchcounter\scratchdistance+\scratchdistance)/\scratchcounter}%
     \fi
   \fi
   \useblackrulesstyleandcolor\c!style\c!color
   % a typical case of where we can use a simple loop or even a leaders
   \dorecurse\scratchcounter\pack_black_rules_step
   \unskip
   \egroup}

\def\pack_black_rules_step
  {\ifcsname\??blackruletype\directblackrulesparameter\c!type\endcsname
     \lastnamedcs
   \else
     \vrule
   \fi
   \s!width \scratchwidth
   \s!height\scratchheight
   \s!depth \scratchdepth
   \relax
   \ifzeropt\scratchdistance\else
     \kern\scratchdistance % hskip
   \fi}

\installcorenamespace{blackruletype}

\defcsname\??blackruletype mp\endcsname
  {\frule
     type {mp}%
     data {\includeMPgraphic{\directblackrulesparameter\c!mp}}%
     line {\directblackrulesparameter\c!rulethickness}%
   }

\letcsname\??blackruletype\s!no \endcsname\novrule
%letcsname\??blackruletype\s!yes\endcsname\vrule

\setupblackrules
  [\c!n=3,
   \c!rulethickness=\linewidth,
   \c!alternative=\c!a,
   \c!distance=.25\emwidth,
   \c!color=]

%D \macros
%D   {vl, hl}
%D
%D The command \type {\vl} draws a vertical rule \vl\ with strut dimensions,
%D multiplied with the factor specified in the optional argument. The height and
%D depth are clipped \vl [3] to the baselinedistance. Its horizontal counterpart
%D \type {\hl} draws a horizontal rule \hl\ with a width of 1em, multiplied with the
%D optional factor. The horizontal rule is drawn on top of the baseline.
%D
%D \showsetup{vl}
%D \showsetup{hl}

\protected\def\pack_rule_vl_indeed#1#2#3%
  {\dontleavehmode
   \begingroup
   \setbox\scratchbox\hbox
     {\vrule
        \s!width #1\linewidth
        \s!height#2\strutht
        \s!depth #3\strutdp}%
   \dp\scratchbox\strutdp
   \ht\scratchbox\strutht
   \box\scratchbox
   \endgroup}

\permanent\tolerant\protected\def\vl[#1]%
  {\pack_rule_vl_indeed{#1}{#1}{#1}}

\permanent\tolerant\protected\def\hl[#1]%
  {\dontleavehmode
   \hbox
     {\vrule
        \s!width #1\emwidth
        \s!height\linewidth
        \s!depth \zeropoint}}

\let\dovlwdhtdp\pack_rule_vl_indeed % used elsewhere .. in font manual

%D \macros
%D   {hairline, thinrule, thinrules, setupthinrules}
%D
%D Drawing thin lines can of course easily be accomplished by the \TEX\
%D primitives \type{\hrule} and \type{\vrule}. The next few macros however
%D free us from some specifications.
%D
%D \startbuffer
%D some text
%D
%D \hairline
%D
%D some more text
%D
%D \thinrule
%D
%D more and more text
%D
%D hi \thinrule\ there
%D
%D and then the final text
%D \stopbuffer
%D
%D \typebuffer
%D
%D becomes
%D
%D \startexample
%D \getbuffer
%D \stopexample
%D
%D So we've got
%D
%D \showsetup{hairline}
%D \showsetup{thinrule}
%D
%D Both can be set up with:
%D
%D \showsetup{setupthinrules}
%D
%D We also have
%D
%D \showsetup{thinrules}
%D
%D which looks like: \thinrules[n=2]

\installcorenamespace{thinrules}
\installcorenamespace{thinrulealternatives}

\installdirectcommandhandler \??thinrules {thinrules}

\setupthinrules
  [\c!interlinespace=\v!small,
   \c!n=3,
   \c!before=,
   \c!inbetween={\blank[\v!white]},
   \c!after=,
   \c!color=,
   \c!height=.5\linewidth,
   \c!depth=.5\linewidth,
   \c!frame=\v!on, % compatible with textbackgrounds
   \c!alternative=\v!b,
   \c!backgroundcolor=,
   \c!background=,
   \c!rulethickness=\linewidth]

\letcsname\??thinrulealternatives\v!a   \endcsname\zerocount
\letcsname\??thinrulealternatives\v!b   \endcsname\plusone
\letcsname\??thinrulealternatives\v!c   \endcsname\plustwo
\letcsname\??thinrulealternatives\v!none\endcsname\zerocount

\def\pack_textrule_check_dash#1%
   {\edef\p_on  {#1\c!on}%
    \edef\p_off {#1\c!off}%
    \edef\p_dash{\ifempty\p_on \else on  \p_on \relaxedspace\fi
                 \ifempty\p_off\else off \p_off\relaxedspace\fi}}

\newconstant\c_pack_thinrules_type

\permanent\tolerant\protected\def\thinrule[#1]%
  {\strut
   \bgroup
   \ifparameter#1\or\setupthinrules[#1]\fi
   \edef\p_height    {\directthinrulesparameter\c!height}%
   \edef\p_depth     {\directthinrulesparameter\c!depth}%
   \edef\p_background{\directthinrulesparameter\c!background}%
   \edef\p_frame     {\directthinrulesparameter\c!frame}%
   \pack_textrule_check_dash\directthinrulesparameter
   \linewidth{\directthinrulesparameter\c!rulethickness/\plustwo}%
   \ifzeropt\linewidth
     \c_pack_thinrules_type\zerocount
   \orelse\ifx\p_frame\v!on
     \c_pack_thinrules_type{\expandnamespaceparameter\??thinrulealternatives\directthinrulesparameter\c!alternative\v!b}%
   \else
     \c_pack_thinrules_type\zerocount
   \fi
   \ifnum\c_pack_thinrules_type=\plusone
     \ifx\p_height\v!max
       \scratchheight\strutht
     \else
       \setdimensionwithunit\scratchheight\p_height\strutht
     \fi
     \ifx\p_depth\v!max
        \scratchdepth\strutdp
     \else
        \setdimensionwithunit\scratchdepth\p_depth\strutdp
     \fi
   \else
     \scratchheight\strutht
     \scratchdepth \strutdp
   \fi
   \ifx\p_background\v!color
     \startcolor[\directthinrulesparameter\c!backgroundcolor]%
       \ifnum\c_pack_thinrules_type=\plustwo % prevent overshoot due to rounding
         \leaders
           \hrule
             \s!height{\scratchheight-\linewidth}%
             \s!depth {\scratchdepth -\linewidth}%
             \p_dash
           \relax
           \hfill
       \else
         \leaders
           \hrule
             \s!height\scratchheight
             \s!depth \scratchdepth
             \p_dash
           \relax
           \hfill
       \fi
     \stopcolor
     \ifcase\c_pack_thinrules_type
       % no rule
     \or
       \startcolor[\directthinrulesparameter\c!color]%
         \hfillneg
         \leaders
           \hrule
             \s!height\linewidth
             \s!depth \linewidth
             \p_dash
           \relax
           \hfill
       \stopcolor
     \or
       \startcolor[\directthinrulesparameter\c!color]%
         \hfillneg
         \leaders
           \hrule
             \s!height{-\scratchdepth+\linewidth}%
             \s!depth \scratchdepth
             \p_dash
           \relax
           \hfill
         \hfillneg
         \leaders
           \hrule
             \s!height\scratchheight
             \s!depth {-\scratchheight+\linewidth}%
             \p_dash
           \relax
           \hfill
       \stopcolor
     \fi
   \orelse\ifcase\c_pack_thinrules_type
     % no rule
   \else
     \startcolor[\directthinrulesparameter\c!color]%
       \leaders
         \hrule
           \s!height\scratchheight
           \s!depth \scratchdepth
           \p_dash
         \relax
         \hfill
     \stopcolor
   \fi
   \strut
   \carryoverpar\egroup}

\permanent\protected\def\hairline % can be overloaded
  {\endgraf
   \thinrule
   \endgraf}

\lettonothing\m_pack_thinrules_interlinespace

\permanent\tolerant\protected\def\thinrules[#S#1]%
  {\bgroup
   \setupcurrentthinrules[#1]%
   \scratchcounter\directthinrulesparameter\c!n\relax
   \ifcase\scratchcounter
     % nothing, not even before/after
     \let\p_after\relax
   \else
     \assignvalue{\directthinrulesparameter\c!interlinespace}\m_pack_thinrules_interlinespace{1.0}{1.5}{2.0}%
     \spacing\m_pack_thinrules_interlinespace
     \edef\p_after    {\directthinrulesparameter\c!after}%
     \edef\p_inbetween{\directthinrulesparameter\c!inbetween}%
     \directthinrulesparameter\c!before
     \ifcase\scratchcounter\or
       \thinrule
     \else
       \dorecurse\scratchcounter
         {\ifnum\recurselevel=\scratchcounter \directvspacing\v!samepage \else   % \penalty500
          \ifnum\recurselevel=\plustwo        \directvspacing\v!samepage \fi\fi  % \penalty500
          \thinrule
          \ifnum\recurselevel<\scratchcounter\relax
            % test needed, else messed up whitespace
            \ifempty\p_inbetween
              \softbreak % \ifhmode \hskip \parfillskip \break \fi
            \else
              \endgraf
              \nowhitespace
              \p_inbetween
            \fi
          \fi}%
     \fi
   \fi
   \ifempty\p_after
     \carryoverpar\egroup
   \else
     \p_after\egroup
   \fi{}}

%D A couple of examples are given below.
%D
%D \startbuffer
%D \setupthinrules[n=3,inbetween=,color=gray]
%D
%D test test \thinrules\ test test \par
%D test test \thinrules [color=green] test test \par
%D test test \thinrules [height=max, depth=max] test test \par
%D
%D \setupthinrules[height=.9,depth=.9]
%D
%D test test \thinrules\ test test \par
%D test test \thinrules [alternativevariant=b] test test \par
%D test test \thinrules [alternativevariant=c] test test \par
%D test test \thinrules [alternativevariant=c,inbetween=\vskip2ex] test test \par
%D \stopbuffer
%D
%D \typebuffer {\getbuffer}
%D
%D There are a couple of alternative ways to visualize rules using backgrounds. At
%D first sight these may look strange, but they make sense in educational settings.
%D The alternatives are more or less compatible with the more advanced \METAPOST\
%D based implementation.
%D
%D \startbuffer[a]
%D \setupthinrules
%D   [n=2,
%D    backgroundcolor=gray  ,
%D    rulethickness=1pt,
%D    colorkleur=donkerblauw,
%D    after=\blank,
%D    before=\blank]
%D \stopbuffer
%D
%D \typebuffer[a]
%D
%D \startbuffer[b]
%D \thinrules[alternativevariant=a]
%D \thinrules[alternativevariant=b]
%D \thinrules[alternativevariant=c]
%D \stopbuffer
%D
%D \typebuffer[b] \getbuffer[a,b]
%D
%D \startbuffer[b]
%D \thinrules[alternativevariant=a,background=color]
%D \thinrules[alternativevariant=b,background=color]
%D \thinrules[alternativevariant=c,background=color]
%D \stopbuffer
%D
%D \typebuffer[b] \getbuffer[a,b]
%D
%D \startbuffer[b]
%D \thinrules[alternativevariant=a,height=.8,depth=.8,background=color]
%D \thinrules[alternativevariant=b,height=.8,depth=.8,background=color]
%D \thinrules[alternativevariant=c,height=.8,depth=.8,background=color]
%D \stopbuffer
%D
%D \typebuffer[b] \getbuffer[a,b]

%D \macros
%D   {textrule, starttextrule, setuptextrules}
%D
%D Putting rules before and after a paragraph is very space sensitive, but the
%D next command handles that quite well. It comes in two disguises:
%D
%D \startbuffer
%D \textrule[top]{fragments}
%D   \input reich
%D \textrule
%D \stopbuffer
%D
%D \start \typebuffer \getbuffer \stop
%D
%D \startbuffer
%D \setuptextrules
%D   [width=90pt,distance=12pt,rulecolor=blue,
%D    bodyfont=small,style=\sc,color=red]
%D
%D \starttextrule{Ship Building Tools}
%D   \nl \setuptolerance[tolerant] \input materie
%D \stoptextrule
%D \stopbuffer
%D
%D \bgroup \typebuffer \getbuffer \egroup
%D
%D \startbuffer
%D \setuptextrules
%D   [location=inmargin,
%D    bodyfont=small,style=slantedbold]
%D
%D \starttextrule{wonderful}
%D   \input tufte
%D \stoptextrule
%D \stopbuffer
%D
%D \bgroup \typebuffer \getbuffer \egroup
%D
%D The formal definition of these commands is:
%D
%D \showsetup{textrule}
%D \showsetup{starttextrule}
%D \showsetup{setuptextrules}
%D
%D The implementation looks a bit complicated due to the optional arguments.

\installcorenamespace{textrules}
\installcorenamespace{textrulealternatives}

\installdirectcommandhandler \??textrules {textrules}

\setuptextrules
  [\c!location=\v!left,
   \c!before=\blank,
   \c!after=\blank,
   \c!inbetween=,
   \c!width=2\emwidth,
   \c!style=\v!bold,
   \c!color=,
   \c!rulecolor=,
   \c!bodyfont=,
   \c!depthcorrection=\v!on,
   \c!rulethickness=\linewidth,
   \c!distance=.5\emwidth]

% can be done nicer with futureexpandis

\permanent\tolerant\protected\def\textrule[#1]%
  {\ifarguments
     \expandafter\pack_textrule_nop
   \else
     \expandafter\pack_textrule_yes
   \fi[#1]}

\def\pack_textrule_yes[#1]%
  {\expandnamespacevalue\??textrulealternatives{#1}\v!bottom}

% \tolerant\def\pack_textrule_nop[#1]#:#=%
%   {\ifparameter#2\or
%      \expandafter\pack_textrule_nop_indeed_yes
%    \else
%      \expandafter\pack_textrule_nop_indeed_nop
%    \fi[#1]{#2}}

\def\pack_textrule_nop[#1]%
  {\doifelsenextbgroupcs\pack_textrule_nop_indeed_yes\pack_textrule_nop_indeed_nop}

\def\pack_textrule_nop_indeed_yes{\csname\??textrulealternatives\v!top   \endcsname}
\def\pack_textrule_nop_indeed_nop{\csname\??textrulealternatives\v!bottom\endcsname\empty}

%D\startbuffer
%D\showstruts
%D
%D\setupwhitespace[none]
%D
%D\textrule[top]{test} xxxxx\smash{\strut} \textrule[bottom]{test}
%D\textrule[top]{test} xxxxx\strut         \textrule[bottom]{test}
%D
%D\setupwhitespace[big]
%D
%D\textrule[top]{test} xxxxx\smash{\strut} \textrule[bottom]{test}
%D\textrule[top]{test} xxxxx\strut         \textrule[bottom]{test}
%D\stoptyping
%D
%D \typebuffer \start \getbuffer \stop

\defcsname\??textrulealternatives\v!top\endcsname#1%
  {\page[\v!preference] % interferes
   \directtextrulesparameter\c!before\relax
   \blank[\v!samepage,\v!nowhite]%
   \pack_textrule_with_text_yes{#1}%
   \blank[\v!samepage,\v!nowhite]%
   \directtextrulesparameter\c!inbetween\relax
   \endgraf}

\defcsname\??textrulealternatives\v!bottom\endcsname#1%
  {\blank[\v!samepage,\v!nowhite]%
   \pack_textrule_following{#1}%
   \blank[\v!samepage,\v!nowhite]%
   \directtextrulesparameter\c!after\relax
   \page[\v!preference]}

\defcsname\??textrulealternatives\v!middle\endcsname#1%
  {\blank[\v!samepage,\v!nowhite]%
   \directtextrulesparameter\c!inbetween\relax
   \pack_textrule_following{#1}%
   \blank[\v!samepage,\v!nowhite]%
   \directtextrulesparameter\c!inbetween\relax
   \page[\v!preference]}

\def\pack_textrule_with_text_yes#1%
  {\noindent % this will force side floats to be calculated
   \bgroup
   \setbox\scratchbox\hpack to \availablehsize
     {\scratchwidth {\directtextrulesparameter\c!rulethickness}%
      \scratchheight{.5\exheight+.5\scratchwidth}%
      \scratchdepth {-.5\exheight+.5\scratchwidth}%
      \pack_textrule_check_dash\directtextrulesparameter
      \ifempty{#1}%
        % nothing
      \orelse\ifcstok{\directtextrulesparameter\c!location}\v!inmargin
        \llap
          {\usetextrulesstyleandcolor\c!style\c!color
           #1%
           \kern\leftmargindistance}% hskip
      \else
        \color[\directtextrulesparameter\c!rulecolor]
          {\vrule
             \s!height  \scratchheight
             \s!depth   \scratchdepth
             \s!width   {\directtextrulesparameter\c!width}%
             \p_dash}%
        \hbox \s!spread {(\directtextrulesparameter\c!distance)*2}%
          {\hss
           \usetextrulesstyleandcolor\c!style\c!color
           \strut#1%
           \hss}%
      \fi
      \color[\directtextrulesparameter\c!rulecolor]
        {\leaders\hrule
           \s!height\scratchheight
           \s!depth \scratchdepth
           \p_dash
         \relax
         \hfill}}%
   \ht\scratchbox\strutht
   \dp\scratchbox\strutdp
   \box\scratchbox
  %\carryoverpar
   \egroup}

\def\pack_textrule_with_text_nop#1%
  {\ifhmode
     \endgraf
   \fi
   \ifcstok{\directtextrulesparameter\c!depthcorrection}\v!on
     \pack_textrule_correct_depth_yes
   \else
     \pack_textrule_correct_depth_nop
   \fi
   \nointerlineskip
   \noindent\naturalvpack % was \dontleavehmode
     {\color[\directtextrulesparameter\c!rulecolor]
        {\pack_textrule_check_dash\directtextrulesparameter
         \hrule
           \s!depth {\directtextrulesparameter\c!rulethickness}%
           \s!height\zeropoint
           \s!width \availablehsize
           \p_dash}}}

\def\pack_textrule_correct_depth_yes
  {\vskip{%
     \strutdp +.5\exheight
     \ifdim\prevdepth>\strutdp\else
       \ifdim\prevdepth>\zeropoint
         -\prevdepth
       \fi
     \fi
   }\relax}

\def\pack_textrule_correct_depth_nop
  {\vskip{%
     \strutdp +.5\exheight
   }%
   \relax}

\def\pack_textrule_following#1%
  {\ifempty{#1}
     \expandafter\pack_textrule_with_text_nop
   \else
     \expandafter\pack_textrule_with_text_yes
   \fi{#1}%
   \ifvmode
     \prevdepth\zeropoint
   \fi}

%D The grouped commands also supports bodyfont switching:

\permanent\protected\def\starttextrule#1%
  {\bgroup
   \def\pack_textrule_nop_indeed_nop{\csname\??textrulealternatives\v!middle\endcsname}%
  %\let\pack_textrule_nop_indeed_yes\pack_textrule_nop_indeed_nop % needs checking
   \csname\??textrulealternatives\v!top\endcsname{#1}%
   \bgroup
   \usebodyfontparameter\directtextrulesparameter}

\permanent\protected\def\stoptextrule
  {\par
   \egroup
   \csname\??textrulealternatives\v!bottom\endcsname\empty
   \egroup}

%D \macros
%D   {fillinrules, setupfillinrules}
%D
%D The next few commands do not really deserve a place in a core module, because
%D they deal with specific typography. Nevertheless I decided to make them part of
%D the core, because they permit us to make questionaires. Let's start with some
%D examples.
%D
%D \fillinrules[n=2,width=fit]{first}
%D \fillinrules[n=2,width=broad]{first}
%D \fillinrules[n=2,width=3cm]{first}
%D \fillinrules[n=2,width=3cm,distance=.5em,separator=:]{first}
%D \fillinrules[n=2]{first}{last}
%D \fillintext{first}{last} \input reich \par
%D
%D The main command is \type{\fillinrules}. This command takes one and an optional
%D second argument and sets a paragraph with empty visualized lines.
%D
%D \showsetup{fillinrules}
%D \showsetup{setupfillinrules}
%D
%D I NEED TO UPGRADE THIS!

\installcorenamespace{fillinrules}

\installdirectcommandhandler \??fillinrules {fillinrules}

\setupfillinrules
  [\c!width=\v!broad,
   \c!distance=\emwidth,
   \c!before=\blank,
   \c!after=\blank,
   \c!n=\plusone,
   \c!interlinespace=\v!small,
   \c!separator=,
   \c!style=,
   \c!color=]

\def\pack_fillinrules_rule_indeed{\thinrules}

\permanent\tolerant\protected\def\fillinrules[#S#1]#:#=#*#=%
  {\endgraf
   \begingroup
   \setupcurrentfillinrules[#1]%
   \directfillinrulesparameter\c!before
   \setupcurrentthinrules
     [\c!n=\directfillinrulesparameter\c!n,
      \c!interlinespace=\directfillinrulesparameter\c!interlinespace,
      \c!before=,
      \c!after=]%
   \scratchdistance{\directfillinrulesparameter\c!distance}%
   \noindent
   \ifempty{#2}\else
     \edef\p_width{\directfillinrulesparameter\c!width}% todo: \lastnamedcs
     \ifx\p_width\v!fit
       \scratchdistance\zeropoint
       \hbox
     \orelse\ifx\p_width\v!broad
       \hbox
     \else
       \hbox \s!to {\p_width}%
     \fi
     \bgroup
       \usefillinrulesstyleandcolor\c!style\c!color
       \strut
       #2%
       \hfill\directfillinrulesparameter\c!separator
       \kern\scratchdistance % hskip
     \egroup
   \fi
   \setupwhitespace[\v!big]%
   \ignorespaces
   \pack_fillinrules_rule_indeed
   \ifempty{#3}\else
     \kern\scratchdistance
     \usefillinrulesstyleandcolor\c!style\c!color
     #3%
     \strut
   \fi
   \endgraf
   \directfillinrulesparameter\c!after
   \endgroup}

%D \macros
%D   {fillintext}
%D
%D To provide compatible layouts when texts and lines are mixed, one can typeset
%D a paragraph by using the command \type {\fillintext}.
%D
%D \showsetup{fillintext}

\permanent\tolerant\protected\def\fillintext[#S#1]#:#=#*#=%
  {\endgraf
   \begingroup
   \def\pack_fillinrules_rule_indeed{\unhbox\nextbox\unskip}% hm, needs checking
   \dowithnextbox{\fillinrules[#1]{#2}{\hfill#3}}%
   \hbox\bgroup\enforced\let\par\egroup\ignorespaces} % bah, i will drop this compatibility hack

%D \macros
%D   {fillinline, setupfillinlines}
%D
%D Another member of the family takes care of putting a (often small) rule after
%D a piece of text, like
%D
%D \startbuffer
%D \fillinline \input reich \par
%D \fillinline[margin=0cm] \input reich \par
%D \stopbuffer
%D
%D \startexample
%D \getbuffer
%D \stopexample
%D
%D which was typeset by saying:
%D
%D \typebuffer
%D
%D The two commands that take care of this are:
%D
%D \showsetup{fillinline}
%D \showsetup{setupfillinlines}
%D
%D Contrary to older implementations we now use the wrapper.

\installcorenamespace{fillinlines}

\installdirectcommandhandler \??fillinlines {fillinlines}

\setupfillinlines
  [\c!width=8\emwidth, % was 3cm
   \c!margin=\directfillinlinesparameter\c!width,
   \c!rulethickness=\linewidth,
   \c!color=,
   \c!distance=\emwidth,
   \c!before=\blank,
   \c!after=\blank]

\protected\def\pack_fillinline_before#1%
  {}

\protected\def\pack_fillinline_after#1%
  {\begingroup
   \setupcurrentfillinlines[#1]%
   \ifhmode\unskip\hfill\fi
   \scratchdistance{\directfillinlinesparameter\c!distance}%
   \scratchheight  {\directfillinlinesparameter\c!rulethickness/\plustwo}%
   \scratchwidth   {\directfillinlinesparameter\c!width-\scratchdistance}%
   \ifdim\scratchwidth>{\directfillinlinesparameter\c!margin}\else
     \expandafter\rlap
   \fi
   {\kern\scratchdistance
    \blackrule
      [\c!color=\directfillinlinesparameter\c!color,
       \c!width=\scratchwidth,
       \c!height=\scratchheight,
       \c!depth=\scratchheight]}%
   \frozen\advanceby\rightskip{\directfillinlinesparameter\c!margin}\relax
   \frozen\parfillskip\zeroskip\relax
   \endgroup}

\permanent\tolerant\protected\def\fillinline[#S#1]%
  {\dontleavehmode
   \registerparwrapper
     {fillinline}%
     {\pack_fillinline_before{#1}}%
     {\pack_fillinline_after {#1}%
      \unregisterparwrapper{fillinline}}}

\protect \endinput
