pack-mrl.mkiv / last modification: 2020-01-30 14:16
%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}

\unexpanded\def\blackrule
  {\hpack\bgroup
   \doifelsenextoptionalcs\pack_black_rule_pickup\pack_black_rule_indeed}

\def\pack_black_rule_pickup[#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 }%
   \ifx\p_height\v!max
     \setstrut
   \else\ifx\p_depth\v!max
     \setstrut
   \fi\fi
   \useblackrulesstyleandcolor\c!style\c!color
   \ifcsname\??blackruletype\directblackrulesparameter\c!type\endcsname
     \lastnamedcs
   \else
     \vrule
   \fi
   \ifx\p_width \v!max\s!width \emwidth\else\ifx\p_width \empty\else\s!width \p_width \fi\fi
   \ifx\p_height\v!max\s!height\strutht\else\ifx\p_height\empty\else\s!height\p_height\fi\fi
   \ifx\p_depth \v!max\s!depth \strutdp\else\ifx\p_depth \empty\else\s!depth \p_depth \fi\fi
   \egroup}

\setupblackrules
  [\c!width=\emwidth,
   \c!height=\exheight,
   \c!depth=\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.

\unexpanded\def\blackrules % probably never used
  {\hpack\bgroup
   \doifelsenextoptionalcs\pack_black_rules_pickup\pack_black_rules_indeed}

\def\pack_black_rules_pickup[#1]%
  {\setupcurrentblackrules[#1]%
   \pack_black_rules_indeed}

\def\pack_black_rules_indeed % no max handling here
  {\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\dimexpr(\scratchwidth-\scratchcounter\scratchdistance+\scratchdistance)/\scratchcounter\relax
     \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
     \hskip\scratchdistance
   \fi}

\installcorenamespace{blackruletype}

\setvalue{\??blackruletype mp}%
  {\frule
     type {mp}%
     data {\includeMPgraphic{\directblackrulesparameter\c!mp}}
     line \dimexpr\directblackrulesparameter\c!rulethickness\relax
   }

\letvalue{\??blackruletype\s!no }\novrule
%letvalue{\??blackruletype\s!yes}\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}

\unexpanded\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}

\def\pack_rule_vl[#1]%
  {\pack_rule_vl_indeed{#1}{#1}{#1}}

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

\unexpanded\def\vl{\dosingleempty\pack_rule_vl}
\unexpanded\def\hl{\dosingleempty\pack_rule_hl}

\let\dovlwdhtdp\pack_rule_vl_indeed % used elsewhere

%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]

\letvalue{\??thinrulealternatives\v!a   }\zerocount
\letvalue{\??thinrulealternatives\v!b   }\plusone
\letvalue{\??thinrulealternatives\v!c   }\plustwo
\letvalue{\??thinrulealternatives\v!none}\zerocount

\newconstant\c_pack_thinrules_type

\unexpanded\def\thinrule
  {\strut
   \bgroup
   \edef\p_height    {\directthinrulesparameter\c!height}%
   \edef\p_depth     {\directthinrulesparameter\c!depth}%
   \edef\p_background{\directthinrulesparameter\c!background}%
   \edef\p_frame     {\directthinrulesparameter\c!frame}%
   \linewidth\dimexpr\directthinrulesparameter\c!rulethickness/\plustwo\relax
   \ifzeropt\linewidth
     \c_pack_thinrules_type\zerocount
   \else\ifx\p_frame\v!on
     \c_pack_thinrules_type\expandnamespaceparameter\??thinrulealternatives\directthinrulesparameter\c!alternative\v!b\relax
   \else
     \c_pack_thinrules_type\zerocount
   \fi\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\dimexpr\scratchheight-\linewidth\relax
             \s!depth \dimexpr\scratchdepth -\linewidth\relax
           \hfill
       \else
         \leaders
           \hrule
             \s!height\scratchheight
             \s!depth \scratchdepth
           \hfill
       \fi
     \stopcolor
     \ifcase\c_pack_thinrules_type
       % no rule
     \or
       \startcolor[\directthinrulesparameter\c!color]%
         \hfillneg
         \leaders
           \hrule
             \s!height\linewidth
             \s!depth \linewidth
           \hfill
       \stopcolor
     \or
       \startcolor[\directthinrulesparameter\c!color]%
         \hfillneg
         \leaders
           \hrule
             \s!height\dimexpr-\scratchdepth+\linewidth\relax
             \s!depth \scratchdepth
           \hfill
         \hfillneg
         \leaders
           \hrule
             \s!height\scratchheight
             \s!depth \dimexpr-\scratchheight+\linewidth\relax
           \hfill
       \stopcolor
     \fi
   \else
     \ifcase\c_pack_thinrules_type
       % no rule
     \else
       \startcolor[\directthinrulesparameter\c!color]%
         \leaders
           \hrule
             \s!height\scratchheight
             \s!depth \scratchdepth
           \hfill
       \stopcolor
     \fi
   \fi
   \strut
   \carryoverpar\egroup}

\unexpanded\def\hairline
  {\endgraf
   \thinrule
   \endgraf}

\unexpanded\def\thinrules
  {\dosingleempty\pack_thinrules}

\def\pack_thinrules[#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
            \ifx\p_inbetween\empty
              \softbreak % \ifhmode \hskip \parfillskip \break \fi
            \else
              \endgraf
              \nowhitespace
              \p_inbetween
            \fi
          \fi}%
     \fi
   \fi
   \ifx\p_after\empty
     \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]

\unexpanded\def\textrule
  {\dosingleempty\pack_textrule}

\def\pack_textrule
  {\iffirstargument
     \expandafter\pack_textrule_yes
   \else
     \expandafter\pack_textrule_nop
   \fi}

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

\def\pack_textrule_nop[#1]%
  {\dosinglegroupempty\pack_textrule_nop_indeed}

\def\pack_textrule_nop_indeed
  {\iffirstargument
     \expandafter\pack_textrule_nop_indeed_yes
   \else
     \expandafter\pack_textrule_nop_indeed_nop
   \fi}

\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

\setvalue{\??textrulealternatives\v!top}#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}

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

\setvalue{\??textrulealternatives\v!middle}#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\relax
      \scratchheight\dimexpr .5\exheight+.5\scratchwidth\relax
      \scratchdepth \dimexpr-.5\exheight+.5\scratchwidth\relax
      \doifsomething{#1}
        {\doifelse{\directtextrulesparameter\c!location}\v!inmargin
           {\llap
              {\usetextrulesstyleandcolor\c!style\c!color
               #1%
               \hskip\leftmargindistance}}
           {\color[\directtextrulesparameter\c!rulecolor]
              {\vrule
                 \s!height\scratchheight
                 \s!depth \scratchdepth
                 \s!width \directtextrulesparameter\c!width}%
            \hbox spread 2\dimexpr\directtextrulesparameter\c!distance\relax
              {\hss
               \usetextrulesstyleandcolor\c!style\c!color
               \strut#1%
               \hss}}}%
      \color[\directtextrulesparameter\c!rulecolor]
        {\leaders\hrule
           \s!height\scratchheight
           \s!depth \scratchdepth
           \hfill}}%
   \ht\scratchbox\strutht
   \dp\scratchbox\strutdp
   \box\scratchbox
  %\carryoverpar
   \egroup}

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

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

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

\def\pack_textrule_following#1%
  {\doifelsenothing{#1}
     \pack_textrule_with_text_nop
     \pack_textrule_with_text_yes
     {#1}%
   \ifvmode
     \prevdepth\zeropoint
   \fi}

%D The grouped commands also supports bodyfont switching:

\unexpanded\def\starttextrule#1%
  {\bgroup
   \def\pack_textrule_nop_indeed{\csname\??textrulealternatives\v!middle\endcsname}%
   \csname\??textrulealternatives\v!top\endcsname{#1}%
   \bgroup
   \usebodyfontparameter\directtextrulesparameter}

\unexpanded\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}


\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=]

\unexpanded\def\fillinrules
  {\dosingleempty\pack_fillinrules}

\def\pack_fillinrules[#1]%
  {\endgraf
   \begingroup
   \setupcurrentfillinrules[#1]%
   \let\pack_fillinrules_rule\thinrules
   \dodoublegroupempty\pack_fillinrules_indeed}

\def\pack_fillinrules_indeed#1#2%
  {\directfillinrulesparameter\c!before
   \setupcurrentthinrules
     [\c!n=\directfillinrulesparameter\c!n,
      \c!interlinespace=\directfillinrulesparameter\c!interlinespace,
      \c!before=,
      \c!after=]%
   \scratchdistance\directfillinrulesparameter\c!distance\relax
   \edef\m_fillinrules_one{#1}%
   \edef\m_fillinrules_two{#2}%
   \noindent
   \ifx\m_fillinrules_one\empty \else
     \edef\p_width{\directfillinrulesparameter\c!width}%
     \ifx\p_width\v!fit
       \scratchdistance\zeropoint
       \hbox
     \else\ifx\p_width\v!broad
       \hbox
     \else
       \hbox to \directfillinrulesparameter\c!width
     \fi\fi
     \bgroup
       \usefillinrulesstyleandcolor\c!style\c!color
       \strut
       \m_fillinrules_one
       \hfill\directfillinrulesparameter\c!separator
       \hskip\scratchdistance
     \egroup
   \fi
   \setupwhitespace[\v!big]%
   \ignorespaces
   \pack_fillinrules_rule
   \ifx\m_fillinrules_two\empty \else
     \kern\scratchdistance
     \usefillinrulesstyleandcolor\c!style\c!color
     \m_fillinrules_two
     \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}

\unexpanded\def\fillintext
  {\dosingleempty\pack_fillintext}

\def\pack_fillintext[#1]% ugly
  {\endgraf
   \begingroup
   \setupcurrentfillinrules[#1]%
   \dodoublegroupempty\pack_fillintext_indeed}

\def\pack_fillintext_indeed#1#2%
  {\def\pack_fillinrules_rule{\unhbox\nextbox\unskip}%
   \dowithnextbox{\pack_fillinrules_indeed{#1}{\hfill#2}}%
   \hbox\bgroup\let\par\egroup\ignorespaces}

%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
%D \stopbuffer\fillinline \input reich \par
%D \fillinline[margin=0cm] \input reich \par
%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}

\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]

\unexpanded\def\fillinline
  {\dosingleempty\pack_fillinline}

% \ifdefined\endpar % experiment with \endpar
%
%     \def\pack_fillinline[#1]%
%       {% \endpar % no, as it interferes with \definedescription cum suis
%        \begingroup
%        \setupcurrentfillinlines[#1]%
%        \directfillinlinesparameter\c!before
%        \begingroup
%        \advance\rightskip \directfillinlinesparameter\c!margin\relax
%        \parfillskip\zeropoint
%        \pushmacro\endpar
%        \def\endpar
%          {\popmacro\endpar
%           \ifhmode\unskip\hfill\fi
%           \scratchwidth\dimexpr\directfillinlinesparameter\c!width-\directfillinlinesparameter\c!distance\relax
%           \ifdim\scratchwidth>\directfillinlinesparameter\c!margin\else\expandafter\rlap\fi
%             {\kern\directfillinlinesparameter\c!distance
%              \scratchheight\dimexpr\directfillinlinesparameter\c!rulethickness/\plustwo\relax
%              \color[\directfillinlinesparameter\c!color]{\vrule\s!width\scratchwidth\s!height\scratchheight\s!depth\scratchheight}}%
%           \endpar
%           \endgroup
%           \endpar
%           \directfillinlinesparameter\c!after
%           \endgroup}} % carryover ?
%
% \else

    \def\pack_fillinline[#1]%
      {%\endgraf % no, as it interferes with \definedescription cum suis
       \begingroup
       \setupcurrentfillinlines[#1]%
       \directfillinlinesparameter\c!before
       \begingroup
       \advance\rightskip \directfillinlinesparameter\c!margin\relax
       \parfillskip\zeropoint
       \def\par
         {\let\par\endgraf
          \ifhmode\unskip\hfill\fi
          \scratchwidth\dimexpr\directfillinlinesparameter\c!width-\directfillinlinesparameter\c!distance\relax
          \ifdim\scratchwidth>\directfillinlinesparameter\c!margin\else\expandafter\rlap\fi
            {\kern\directfillinlinesparameter\c!distance
             \scratchheight\dimexpr\directfillinlinesparameter\c!rulethickness/\plustwo\relax
             \color[\directfillinlinesparameter\c!color]{\vrule\s!width\scratchwidth\s!height\scratchheight\s!depth\scratchheight}}%
          \endgraf
          \endgroup
          \endgraf
          \directfillinlinesparameter\c!after
          \endgroup}} % carryover ?

% \fi

\protect \endinput