pack-mrl.mkxl /size: 25 Kb    last modification: 2025-02-21 11:03
1%D \module
2%D   [       file=pack-mrl, % was pack-rul/core-rul,
3%D        version=1998.10.16,
4%D          title=\CONTEXT\ Packaging Macros,
5%D       subtitle=More Rules,
6%D         author=Hans Hagen,
7%D           date=\currentdate,
8%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
9%C
10%C This module is part of the \CONTEXT\ macro||package and is
11%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
12%C details.
13
14\writestatus{loading}{ConTeXt Packaging Macros / More Rules}
15
16%D The (re)implementation of margin rules has been moved elsewhere.
17
18\unprotect
19
20%D \macros
21%D   {setupblackrules,blackrule}
22%D
23%D The graphic capabilities of \TEX\ do not go beyond simple filled rules, except of
24%D course when using specials or, in \MKIV, manipulate node lists. Let's start with
25%D a warning: using this commands is far more slower than using the \TEX\ primitives
26%D \type {\hrule} and \type {\vrule}, but they save us some tokens. The
27%D characteristics of these rule drawing command can be set by:
28%D
29%D \showsetup{setupblackrules}
30%D
31%D The simple command draws only one rule. Its optional argument can be used to
32%D specify the dimensions. By setting the width, height or depth to \type {max}, one
33%D gets the natural dimensions.
34%D
35%D \showsetup{blackrule}
36
37\installcorenamespace{blackrules}
38
39\installsimplecommandhandler \??blackrules {blackrules} \??blackrules
40
41\permanent\protected\def\blackrule
42  {% this was \hpack\bgroup\dontleavehmode but we want leader support
43   \begingroup
44   \doifelsenextoptionalcs\pack_black_rule_pickup\pack_black_rule_indeed}
45
46\def\pack_black_rule_pickup[#S#1]%
47  {\setupcurrentblackrules[#1]%
48   \pack_black_rule_indeed}
49
50\def\pack_black_rule_indeed
51  {\edef\p_width  {\directblackrulesparameter\c!width}%
52   \edef\p_height {\directblackrulesparameter\c!height}%
53   \edef\p_depth  {\directblackrulesparameter\c!depth}%
54   \edef\p_stretch{\directblackrulesparameter\c!stretch}%
55   \edef\p_shrink {\directblackrulesparameter\c!shrink}%
56   \edef\p_on     {\directblackrulesparameter\c!on}%
57   \edef\p_off    {\directblackrulesparameter\c!off}%
58   \ifx\p_height\v!max
59     \setstrut
60     \let\p_height\strutdp
61   \orelse\ifx\p_depth\v!max
62     \setstrut
63   \fi
64 % \ifx\p_height\v!max
65 %   \let\p_height\strutdp
66 % \fi
67   \ifx\p_depth\v!max
68     \let\p_depth\strutdp
69   \fi
70   \ifx\p_width\v!max
71     \let\p_width\emwidth
72   \fi
73   \useblackrulesstyleandcolor\c!style\c!color
74   \ifempty\p_stretch
75     \ifempty\p_shrink
76        \donefalse
77     \else
78        \donetrue
79        \leaders
80     \fi
81   \else
82      \donetrue
83      \leaders
84   \fi
85   \ifcsname\??blackruletype\directblackrulesparameter\c!type\endcsname
86     \lastnamedcs
87   \else
88     \vrule
89     \ifempty\p_on \else
90       on \p_on % todo: \s!on {\p_on}%
91     \fi
92     \ifempty\p_off \else
93       off \p_off % todo: \s!off {\p_off}%
94     \fi
95   \fi
96   \ifempty\p_height \else
97     \s!height {\p_height}%
98   \fi
99   \ifempty\p_depth \else
100     \s!depth {\p_depth}%
101   \fi
102   \ifdone
103     \hskip
104     \ifempty\p_width
105       \zeropoint
106     \else
107       {\p_width}%
108     \fi
109     \ifempty\p_stretch \else
110       \s!plus {\p_stretch}%
111     \fi
112     \ifempty\p_shrink \else
113       \s!minus {\p_shrink}%
114     \fi
115   \else
116     \ifempty\p_width \else
117       \s!width {\p_width}%
118     \fi
119   \fi
120   \endgroup}
121
122\setupblackrules
123  [\c!width=\emwidth,
124   \c!height=\exheight,
125   \c!depth=\zeropoint,
126  %\c!on=\zeropoint,
127  %\c!off=\zeropoint,
128   \c!color=]
129
130%D \macros
131%D   {blackrules}
132%D
133%D One can call for a sequence of black rules, if needed equally spaced over the
134%D given width.
135%D
136%D \showsetup{blackrules}
137%D
138%D The two alternative calls are therefore:
139%D
140%D \startbuffer
141%D Tell me, is this according to the \blackrules[n=6]?
142%D These \blackrules[alternativevariant=b,n=10,distance=.2em,width=4cm] are quite clear.
143%D \stopbuffer
144%D
145%D \typebuffer
146%D
147%D or:
148%D
149%D \startlines
150%D \getbuffer
151%D \stoplines
152%D
153%D We could of course have implemented this macro using \type {\leaders}, but this
154%D would probably have taken more tokens.
155
156\permanent\tolerant\protected\def\blackrules[#S#1]% probably never used
157  {\hpack\bgroup % we keep this because breaking into lines breaks compatibility
158   \ifarguments\or\setupcurrentblackrules[#1]\fi
159   \scratchwidth   {\directblackrulesparameter\c!width}%
160   \scratchheight  {\directblackrulesparameter\c!height}%
161   \scratchdepth   {\directblackrulesparameter\c!depth}%
162   \scratchdistance{\directblackrulesparameter\c!distance}%
163   \scratchcounter {\directblackrulesparameter\c!n}%
164   \edef\p_alternative{\blackrulesparameter\c!alternative}%
165   \ifx\p_alternative\c!b % why not just check distance
166     \ifnum\scratchcounter=\plusone
167       \scratchdistance\zeropoint
168     \else
169       \scratchwidth{(\scratchwidth-\scratchcounter\scratchdistance+\scratchdistance)/\scratchcounter}%
170     \fi
171   \fi
172   \useblackrulesstyleandcolor\c!style\c!color
173   % a typical case of where we can use a simple loop or even a leaders
174   \dorecurse\scratchcounter\pack_black_rules_step
175   \unskip
176   \egroup}
177
178\def\pack_black_rules_step
179  {\ifcsname\??blackruletype\directblackrulesparameter\c!type\endcsname
180     \lastnamedcs
181   \else
182     \vrule
183   \fi
184   \s!width \scratchwidth
185   \s!height\scratchheight
186   \s!depth \scratchdepth
187   \relax
188   \ifzeropt\scratchdistance\else
189     \kern\scratchdistance % hskip
190   \fi}
191
192\installcorenamespace{blackruletype}
193
194\defcsname\??blackruletype mp\endcsname
195  {\frule
196     type {mp}%
197     data {\includeMPgraphic{\directblackrulesparameter\c!mp}}%
198     line {\directblackrulesparameter\c!rulethickness}%
199   }
200
201\letcsname\??blackruletype\s!no \endcsname\novrule
202%letcsname\??blackruletype\s!yes\endcsname\vrule
203
204\setupblackrules
205  [\c!n=3,
206   \c!rulethickness=\linewidth,
207   \c!alternative=\c!a,
208   \c!distance=.25\emwidth,
209   \c!color=]
210
211%D \macros
212%D   {vl, hl}
213%D
214%D The command \type {\vl} draws a vertical rule \vl\ with strut dimensions,
215%D multiplied with the factor specified in the optional argument. The height and
216%D depth are clipped \vl [3] to the baselinedistance. Its horizontal counterpart
217%D \type {\hl} draws a horizontal rule \hl\ with a width of 1em, multiplied with the
218%D optional factor. The horizontal rule is drawn on top of the baseline.
219%D
220%D \showsetup{vl}
221%D \showsetup{hl}
222
223\protected\def\pack_rule_vl_indeed#1#2#3%
224  {\dontleavehmode
225   \begingroup
226   \setbox\scratchbox\hbox
227     {\vrule
228        \s!width #1\linewidth
229        \s!height#2\strutht
230        \s!depth #3\strutdp}%
231   \dp\scratchbox\strutdp
232   \ht\scratchbox\strutht
233   \box\scratchbox
234   \endgroup}
235
236\permanent\tolerant\protected\def\vl[#1]%
237  {\pack_rule_vl_indeed{#1}{#1}{#1}}
238
239\permanent\tolerant\protected\def\hl[#1]%
240  {\dontleavehmode
241   \hbox
242     {\vrule
243        \s!width #1\emwidth
244        \s!height\linewidth
245        \s!depth \zeropoint}}
246
247\let\dovlwdhtdp\pack_rule_vl_indeed % used elsewhere .. in font manual
248
249%D \macros
250%D   {hairline, thinrule, thinrules, setupthinrules}
251%D
252%D Drawing thin lines can of course easily be accomplished by the \TEX\
253%D primitives \type{\hrule} and \type{\vrule}. The next few macros however
254%D free us from some specifications.
255%D
256%D \startbuffer
257%D some text
258%D
259%D \hairline
260%D
261%D some more text
262%D
263%D \thinrule
264%D
265%D more and more text
266%D
267%D hi \thinrule\ there
268%D
269%D and then the final text
270%D \stopbuffer
271%D
272%D \typebuffer
273%D
274%D becomes
275%D
276%D \startexample
277%D \getbuffer
278%D \stopexample
279%D
280%D So we've got
281%D
282%D \showsetup{hairline}
283%D \showsetup{thinrule}
284%D
285%D Both can be set up with:
286%D
287%D \showsetup{setupthinrules}
288%D
289%D We also have
290%D
291%D \showsetup{thinrules}
292%D
293%D which looks like: \thinrules[n=2]
294
295\installcorenamespace{thinrules}
296\installcorenamespace{thinrulealternatives}
297
298\installdirectcommandhandler \??thinrules {thinrules}
299
300\setupthinrules
301  [\c!interlinespace=\v!small,
302   \c!n=3,
303   \c!before=,
304   \c!inbetween={\blank[\v!white]},
305   \c!after=,
306   \c!color=,
307   \c!height=.5\linewidth,
308   \c!depth=.5\linewidth,
309   \c!frame=\v!on, % compatible with textbackgrounds
310   \c!alternative=\v!b,
311   \c!backgroundcolor=,
312   \c!background=,
313   \c!rulethickness=\linewidth]
314
315\letcsname\??thinrulealternatives\v!a   \endcsname\zerocount
316\letcsname\??thinrulealternatives\v!b   \endcsname\plusone
317\letcsname\??thinrulealternatives\v!c   \endcsname\plustwo
318\letcsname\??thinrulealternatives\v!none\endcsname\zerocount
319
320\def\pack_textrule_check_dash#1%
321   {\edef\p_on  {#1\c!on}%
322    \edef\p_off {#1\c!off}%
323    \edef\p_dash{\ifempty\p_on \else on  \p_on \relaxedspace\fi
324                 \ifempty\p_off\else off \p_off\relaxedspace\fi}}
325
326\newconstant\c_pack_thinrules_type
327
328\permanent\tolerant\protected\def\thinrule[#1]%
329  {\strut
330   \bgroup
331   \ifparameter#1\or\setupthinrules[#1]\fi
332   \edef\p_height    {\directthinrulesparameter\c!height}%
333   \edef\p_depth     {\directthinrulesparameter\c!depth}%
334   \edef\p_background{\directthinrulesparameter\c!background}%
335   \edef\p_frame     {\directthinrulesparameter\c!frame}%
336   \pack_textrule_check_dash\directthinrulesparameter
337   \linewidth{\directthinrulesparameter\c!rulethickness/\plustwo}%
338   \ifzeropt\linewidth
339     \c_pack_thinrules_type\zerocount
340   \orelse\ifx\p_frame\v!on
341     \c_pack_thinrules_type{\expandnamespaceparameter\??thinrulealternatives\directthinrulesparameter\c!alternative\v!b}%
342   \else
343     \c_pack_thinrules_type\zerocount
344   \fi
345   \ifnum\c_pack_thinrules_type=\plusone
346     \ifx\p_height\v!max
347       \scratchheight\strutht
348     \else
349       \setdimensionwithunit\scratchheight\p_height\strutht
350     \fi
351     \ifx\p_depth\v!max
352        \scratchdepth\strutdp
353     \else
354        \setdimensionwithunit\scratchdepth\p_depth\strutdp
355     \fi
356   \else
357     \scratchheight\strutht
358     \scratchdepth \strutdp
359   \fi
360   \ifx\p_background\v!color
361     \startcolor[\directthinrulesparameter\c!backgroundcolor]%
362       \ifnum\c_pack_thinrules_type=\plustwo % prevent overshoot due to rounding
363         \leaders
364           \hrule
365             \s!height{\scratchheight-\linewidth}%
366             \s!depth {\scratchdepth -\linewidth}%
367             \p_dash
368           \relax
369           \hfill
370       \else
371         \leaders
372           \hrule
373             \s!height\scratchheight
374             \s!depth \scratchdepth
375             \p_dash
376           \relax
377           \hfill
378       \fi
379     \stopcolor
380     \ifcase\c_pack_thinrules_type
381       % no rule
382     \or
383       \startcolor[\directthinrulesparameter\c!color]%
384         \hfillneg
385         \leaders
386           \hrule
387             \s!height\linewidth
388             \s!depth \linewidth
389             \p_dash
390           \relax
391           \hfill
392       \stopcolor
393     \or
394       \startcolor[\directthinrulesparameter\c!color]%
395         \hfillneg
396         \leaders
397           \hrule
398             \s!height{-\scratchdepth+\linewidth}%
399             \s!depth \scratchdepth
400             \p_dash
401           \relax
402           \hfill
403         \hfillneg
404         \leaders
405           \hrule
406             \s!height\scratchheight
407             \s!depth {-\scratchheight+\linewidth}%
408             \p_dash
409           \relax
410           \hfill
411       \stopcolor
412     \fi
413   \orelse\ifcase\c_pack_thinrules_type
414     % no rule
415   \else
416     \startcolor[\directthinrulesparameter\c!color]%
417       \leaders
418         \hrule
419           \s!height\scratchheight
420           \s!depth \scratchdepth
421           \p_dash
422         \relax
423         \hfill
424     \stopcolor
425   \fi
426   \strut
427   \carryoverpar\egroup}
428
429\permanent\protected\def\hairline % can be overloaded
430  {\endgraf
431   \thinrule
432   \endgraf}
433
434\permanent\tolerant\protected\def\thinrules[#S#1]%
435  {\bgroup
436   \setupcurrentthinrules[#1]%
437   \scratchcounter\directthinrulesparameter\c!n\relax
438   \ifcase\scratchcounter
439     % nothing, not even before/after
440     \let\p_after\relax
441   \else
442     \assignvalue{\directthinrulesparameter\c!interlinespace}\m_pack_thinrules_interlinespace{1.0}{1.5}{2.0}%
443     \spacing\m_pack_thinrules_interlinespace
444     \edef\p_after    {\directthinrulesparameter\c!after}%
445     \edef\p_inbetween{\directthinrulesparameter\c!inbetween}%
446     \directthinrulesparameter\c!before
447     \ifcase\scratchcounter\or
448       \thinrule
449     \else
450       \dorecurse\scratchcounter
451         {\ifnum\recurselevel=\scratchcounter \directvspacing\v!samepage \else   % \penalty500
452          \ifnum\recurselevel=\plustwo        \directvspacing\v!samepage \fi\fi  % \penalty500
453          \thinrule
454          \ifnum\recurselevel<\scratchcounter\relax
455            % test needed, else messed up whitespace
456            \ifempty\p_inbetween
457              \softbreak % \ifhmode \hskip \parfillskip \break \fi
458            \else
459              \endgraf
460              \nowhitespace
461              \p_inbetween
462            \fi
463          \fi}%
464     \fi
465   \fi
466   \ifempty\p_after
467     \carryoverpar\egroup
468   \else
469     \p_after\egroup
470   \fi{}}
471
472%D A couple of examples are given below.
473%D
474%D \startbuffer
475%D \setupthinrules[n=3,inbetween=,color=gray]
476%D
477%D test test \thinrules\ test test \par
478%D test test \thinrules [color=green] test test \par
479%D test test \thinrules [height=max, depth=max] test test \par
480%D
481%D \setupthinrules[height=.9,depth=.9]
482%D
483%D test test \thinrules\ test test \par
484%D test test \thinrules [alternativevariant=b] test test \par
485%D test test \thinrules [alternativevariant=c] test test \par
486%D test test \thinrules [alternativevariant=c,inbetween=\vskip2ex] test test \par
487%D \stopbuffer
488%D
489%D \typebuffer {\getbuffer}
490%D
491%D There are a couple of alternative ways to visualize rules using backgrounds. At
492%D first sight these may look strange, but they make sense in educational settings.
493%D The alternatives are more or less compatible with the more advanced \METAPOST\
494%D based implementation.
495%D
496%D \startbuffer[a]
497%D \setupthinrules
498%D   [n=2,
499%D    backgroundcolor=gray  ,
500%D    rulethickness=1pt,
501%D    colorkleur=donkerblauw,
502%D    after=\blank,
503%D    before=\blank]
504%D \stopbuffer
505%D
506%D \typebuffer[a]
507%D
508%D \startbuffer[b]
509%D \thinrules[alternativevariant=a]
510%D \thinrules[alternativevariant=b]
511%D \thinrules[alternativevariant=c]
512%D \stopbuffer
513%D
514%D \typebuffer[b] \getbuffer[a,b]
515%D
516%D \startbuffer[b]
517%D \thinrules[alternativevariant=a,background=color]
518%D \thinrules[alternativevariant=b,background=color]
519%D \thinrules[alternativevariant=c,background=color]
520%D \stopbuffer
521%D
522%D \typebuffer[b] \getbuffer[a,b]
523%D
524%D \startbuffer[b]
525%D \thinrules[alternativevariant=a,height=.8,depth=.8,background=color]
526%D \thinrules[alternativevariant=b,height=.8,depth=.8,background=color]
527%D \thinrules[alternativevariant=c,height=.8,depth=.8,background=color]
528%D \stopbuffer
529%D
530%D \typebuffer[b] \getbuffer[a,b]
531
532%D \macros
533%D   {textrule, starttextrule, setuptextrules}
534%D
535%D Putting rules before and after a paragraph is very space sensitive, but the
536%D next command handles that quite well. It comes in two disguises:
537%D
538%D \startbuffer
539%D \textrule[top]{fragments}
540%D   \input reich
541%D \textrule
542%D \stopbuffer
543%D
544%D \start \typebuffer \getbuffer \stop
545%D
546%D \startbuffer
547%D \setuptextrules
548%D   [width=90pt,distance=12pt,rulecolor=blue,
549%D    bodyfont=small,style=\sc,color=red]
550%D
551%D \starttextrule{Ship Building Tools}
552%D   \nl \setuptolerance[tolerant] \input materie
553%D \stoptextrule
554%D \stopbuffer
555%D
556%D \bgroup \typebuffer \getbuffer \egroup
557%D
558%D \startbuffer
559%D \setuptextrules
560%D   [location=inmargin,
561%D    bodyfont=small,style=slantedbold]
562%D
563%D \starttextrule{wonderful}
564%D   \input tufte
565%D \stoptextrule
566%D \stopbuffer
567%D
568%D \bgroup \typebuffer \getbuffer \egroup
569%D
570%D The formal definition of these commands is:
571%D
572%D \showsetup{textrule}
573%D \showsetup{starttextrule}
574%D \showsetup{setuptextrules}
575%D
576%D The implementation looks a bit complicated due to the optional arguments.
577
578\installcorenamespace{textrules}
579\installcorenamespace{textrulealternatives}
580
581\installdirectcommandhandler \??textrules {textrules}
582
583\setuptextrules
584  [\c!location=\v!left,
585   \c!before=\blank,
586   \c!after=\blank,
587   \c!inbetween=,
588   \c!width=2\emwidth,
589   \c!style=\v!bold,
590   \c!color=,
591   \c!rulecolor=,
592   \c!bodyfont=,
593   \c!depthcorrection=\v!on,
594   \c!rulethickness=\linewidth,
595   \c!distance=.5\emwidth]
596
597% can be done nicer with futureexpandis
598
599\permanent\tolerant\protected\def\textrule[#1]%
600  {\ifarguments
601     \expandafter\pack_textrule_nop
602   \else
603     \expandafter\pack_textrule_yes
604   \fi[#1]}
605
606\def\pack_textrule_yes[#1]%
607  {\expandnamespacevalue\??textrulealternatives{#1}\v!bottom}
608
609% \tolerant\def\pack_textrule_nop[#1]#:#=%
610%   {\ifparameter#2\or
611%      \expandafter\pack_textrule_nop_indeed_yes
612%    \else
613%      \expandafter\pack_textrule_nop_indeed_nop
614%    \fi[#1]{#2}}
615
616\def\pack_textrule_nop[#1]%
617  {\doifelsenextbgroupcs\pack_textrule_nop_indeed_yes\pack_textrule_nop_indeed_nop}
618
619\def\pack_textrule_nop_indeed_yes{\csname\??textrulealternatives\v!top   \endcsname}
620\def\pack_textrule_nop_indeed_nop{\csname\??textrulealternatives\v!bottom\endcsname\empty}
621
622%D\startbuffer
623%D\showstruts
624%D
625%D\setupwhitespace[none]
626%D
627%D\textrule[top]{test} xxxxx\smash{\strut} \textrule[bottom]{test}
628%D\textrule[top]{test} xxxxx\strut         \textrule[bottom]{test}
629%D
630%D\setupwhitespace[big]
631%D
632%D\textrule[top]{test} xxxxx\smash{\strut} \textrule[bottom]{test}
633%D\textrule[top]{test} xxxxx\strut         \textrule[bottom]{test}
634%D\stoptyping
635%D
636%D \typebuffer \start \getbuffer \stop
637
638\defcsname\??textrulealternatives\v!top\endcsname#1%
639  {\page[\v!preference] % interferes
640   \directtextrulesparameter\c!before\relax
641   \blank[\v!samepage,\v!nowhite]%
642   \pack_textrule_with_text_yes{#1}%
643   \blank[\v!samepage,\v!nowhite]%
644   \directtextrulesparameter\c!inbetween\relax
645   \endgraf}
646
647\defcsname\??textrulealternatives\v!bottom\endcsname#1%
648  {\blank[\v!samepage,\v!nowhite]%
649   \pack_textrule_following{#1}%
650   \blank[\v!samepage,\v!nowhite]%
651   \directtextrulesparameter\c!after\relax
652   \page[\v!preference]}
653
654\defcsname\??textrulealternatives\v!middle\endcsname#1%
655  {\blank[\v!samepage,\v!nowhite]%
656   \directtextrulesparameter\c!inbetween\relax
657   \pack_textrule_following{#1}%
658   \blank[\v!samepage,\v!nowhite]%
659   \directtextrulesparameter\c!inbetween\relax
660   \page[\v!preference]}
661
662\def\pack_textrule_with_text_yes#1%
663  {\noindent % this will force side floats to be calculated
664   \bgroup
665   \setbox\scratchbox\hpack to \availablehsize
666     {\scratchwidth {\directtextrulesparameter\c!rulethickness}%
667      \scratchheight{.5\exheight+.5\scratchwidth}%
668      \scratchdepth {-.5\exheight+.5\scratchwidth}%
669      \pack_textrule_check_dash\directtextrulesparameter
670      \ifempty{#1}%
671        % nothing
672      \orelse\ifcstok{\directtextrulesparameter\c!location}\v!inmargin
673        \llap
674          {\usetextrulesstyleandcolor\c!style\c!color
675           #1%
676           \kern\leftmargindistance}% hskip
677      \else
678        \color[\directtextrulesparameter\c!rulecolor]
679          {\vrule
680             \s!height  \scratchheight
681             \s!depth   \scratchdepth
682             \s!width   {\directtextrulesparameter\c!width}%
683             \p_dash}%
684        \hbox \s!spread {(\directtextrulesparameter\c!distance)*2}%
685          {\hss
686           \usetextrulesstyleandcolor\c!style\c!color
687           \strut#1%
688           \hss}%
689      \fi
690      \color[\directtextrulesparameter\c!rulecolor]
691        {\leaders\hrule
692           \s!height\scratchheight
693           \s!depth \scratchdepth
694           \p_dash
695         \relax
696         \hfill}}%
697   \ht\scratchbox\strutht
698   \dp\scratchbox\strutdp
699   \box\scratchbox
700  %\carryoverpar
701   \egroup}
702
703\def\pack_textrule_with_text_nop#1%
704  {\ifhmode
705     \endgraf
706   \fi
707   \ifcstok{\directtextrulesparameter\c!depthcorrection}\v!on
708     \pack_textrule_correct_depth_yes
709   \else
710     \pack_textrule_correct_depth_nop
711   \fi
712   \nointerlineskip
713   \noindent\naturalvpack % was \dontleavehmode
714     {\color[\directtextrulesparameter\c!rulecolor]
715        {\pack_textrule_check_dash\directtextrulesparameter
716         \hrule
717           \s!depth {\directtextrulesparameter\c!rulethickness}%
718           \s!height\zeropoint
719           \s!width \availablehsize
720           \p_dash}}}
721
722\def\pack_textrule_correct_depth_yes
723  {\vskip{%
724     \strutdp +.5\exheight
725     \ifdim\prevdepth>\strutdp\else
726       \ifdim\prevdepth>\zeropoint
727         -\prevdepth
728       \fi
729     \fi
730   }\relax}
731
732\def\pack_textrule_correct_depth_nop
733  {\vskip{%
734     \strutdp +.5\exheight
735   }%
736   \relax}
737
738\def\pack_textrule_following#1%
739  {\ifempty{#1}
740     \expandafter\pack_textrule_with_text_nop
741   \else
742     \expandafter\pack_textrule_with_text_yes
743   \fi{#1}%
744   \ifvmode
745     \prevdepth\zeropoint
746   \fi}
747
748%D The grouped commands also supports bodyfont switching:
749
750\permanent\protected\def\starttextrule#1%
751  {\bgroup
752   \def\pack_textrule_nop_indeed_nop{\csname\??textrulealternatives\v!middle\endcsname}%
753  %\let\pack_textrule_nop_indeed_yes\pack_textrule_nop_indeed_nop % needs checking
754   \csname\??textrulealternatives\v!top\endcsname{#1}%
755   \bgroup
756   \usebodyfontparameter\directtextrulesparameter}
757
758\permanent\protected\def\stoptextrule
759  {\par
760   \egroup
761   \csname\??textrulealternatives\v!bottom\endcsname\empty
762   \egroup}
763
764%D \macros
765%D   {fillinrules, setupfillinrules}
766%D
767%D The next few commands do not really deserve a place in a core module, because
768%D they deal with specific typography. Nevertheless I decided to make them part of
769%D the core, because they permit us to make questionaires. Let's start with some
770%D examples.
771%D
772%D \fillinrules[n=2,width=fit]{first}
773%D \fillinrules[n=2,width=broad]{first}
774%D \fillinrules[n=2,width=3cm]{first}
775%D \fillinrules[n=2,width=3cm,distance=.5em,separator=:]{first}
776%D \fillinrules[n=2]{first}{last}
777%D \fillintext{first}{last} \input reich \par
778%D
779%D The main command is \type{\fillinrules}. This command takes one and an optional
780%D second argument and sets a paragraph with empty visualized lines.
781%D
782%D \showsetup{fillinrules}
783%D \showsetup{setupfillinrules}
784%D
785%D I NEED TO UPGRADE THIS!
786
787\installcorenamespace{fillinrules}
788
789\installdirectcommandhandler \??fillinrules {fillinrules}
790
791\setupfillinrules
792  [\c!width=\v!broad,
793   \c!distance=\emwidth,
794   \c!before=\blank,
795   \c!after=\blank,
796   \c!n=\plusone,
797   \c!interlinespace=\v!small,
798   \c!separator=,
799   \c!style=,
800   \c!color=]
801
802\def\pack_fillinrules_rule_indeed{\thinrules}
803
804\permanent\tolerant\protected\def\fillinrules[#S#1]#:#=#*#=%
805  {\endgraf
806   \begingroup
807   \setupcurrentfillinrules[#1]%
808   \directfillinrulesparameter\c!before
809   \setupcurrentthinrules
810     [\c!n=\directfillinrulesparameter\c!n,
811      \c!interlinespace=\directfillinrulesparameter\c!interlinespace,
812      \c!before=,
813      \c!after=]%
814   \scratchdistance{\directfillinrulesparameter\c!distance}%
815   \noindent
816   \ifempty{#2}\else
817     \edef\p_width{\directfillinrulesparameter\c!width}% todo: \lastnamedcs
818     \ifx\p_width\v!fit
819       \scratchdistance\zeropoint
820       \hbox
821     \orelse\ifx\p_width\v!broad
822       \hbox
823     \else
824       \hbox \s!to {\p_width}%
825     \fi
826     \bgroup
827       \usefillinrulesstyleandcolor\c!style\c!color
828       \strut
829       #2%
830       \hfill\directfillinrulesparameter\c!separator
831       \kern\scratchdistance % hskip
832     \egroup
833   \fi
834   \setupwhitespace[\v!big]%
835   \ignorespaces
836   \pack_fillinrules_rule_indeed
837   \ifempty{#3}\else
838     \kern\scratchdistance
839     \usefillinrulesstyleandcolor\c!style\c!color
840     #3%
841     \strut
842   \fi
843   \endgraf
844   \directfillinrulesparameter\c!after
845   \endgroup}
846
847%D \macros
848%D   {fillintext}
849%D
850%D To provide compatible layouts when texts and lines are mixed, one can typeset
851%D a paragraph by using the command \type {\fillintext}.
852%D
853%D \showsetup{fillintext}
854
855\permanent\tolerant\protected\def\fillintext[#S#1]#:#=#*#=%
856  {\endgraf
857   \begingroup
858   \def\pack_fillinrules_rule_indeed{\unhbox\nextbox\unskip}% hm, needs checking
859   \dowithnextbox{\fillinrules[#1]{#2}{\hfill#3}}%
860   \hbox\bgroup\enforced\let\par\egroup\ignorespaces} % bah, i will drop this compatibility hack
861
862%D \macros
863%D   {fillinline, setupfillinlines}
864%D
865%D Another member of the family takes care of putting a (often small) rule after
866%D a piece of text, like
867%D
868%D \startbuffer
869%D \fillinline \input reich \par
870%D \fillinline[margin=0cm] \input reich \par
871%D \stopbuffer
872%D
873%D \startexample
874%D \getbuffer
875%D \stopexample
876%D
877%D which was typeset by saying:
878%D
879%D \typebuffer
880%D
881%D The two commands that take care of this are:
882%D
883%D \showsetup{fillinline}
884%D \showsetup{setupfillinlines}
885%D
886%D Contrary to older implementations we now use the wrapper.
887
888\installcorenamespace{fillinlines}
889
890\installdirectcommandhandler \??fillinlines {fillinlines}
891
892\setupfillinlines
893  [\c!width=8\emwidth, % was 3cm
894   \c!margin=\directfillinlinesparameter\c!width,
895   \c!rulethickness=\linewidth,
896   \c!color=,
897   \c!distance=\emwidth,
898   \c!before=\blank,
899   \c!after=\blank]
900
901\protected\def\pack_fillinline_before#1%
902  {}
903
904\protected\def\pack_fillinline_after#1%
905  {\begingroup
906   \setupcurrentfillinlines[#1]%
907   \ifhmode\unskip\hfill\fi
908   \scratchdistance{\directfillinlinesparameter\c!distance}%
909   \scratchheight  {\directfillinlinesparameter\c!rulethickness/\plustwo}%
910   \scratchwidth   {\directfillinlinesparameter\c!width-\scratchdistance}%
911   \ifdim\scratchwidth>{\directfillinlinesparameter\c!margin}\else
912     \expandafter\rlap
913   \fi
914   {\kern\scratchdistance
915    \blackrule
916      [\c!color=\directfillinlinesparameter\c!color,
917       \c!width=\scratchwidth,
918       \c!height=\scratchheight,
919       \c!depth=\scratchheight]}%
920   \frozen\advanceby\rightskip{\directfillinlinesparameter\c!margin}\relax
921   \frozen\parfillskip\zeroskip\relax
922   \endgroup}
923
924\permanent\tolerant\protected\def\fillinline[#S#1]%
925  {\dontleavehmode
926   \registerparwrapper
927     {fillinline}%
928     {\pack_fillinline_before{#1}}%
929     {\pack_fillinline_after {#1}%
930      \unregisterparwrapper{fillinline}}}
931
932\protect \endinput
933