supp-vis.mkiv /size: 49 Kb    last modification: 2021-10-28 13:50
1%D \module
2%D   [       file=supp-vis,
3%D        version=1996.10.21,
4%D          title=\CONTEXT\ Support Macros,
5%D       subtitle=Visualization,
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\endinput
15
16%D This module is no longer generic \unknown\ but who cares. Maybe
17%D the code will be moved out of the core (apart from ruled boxes).
18
19%D \gdef\ShowBufferedExample% private typeseting macro
20%D   {\startlinecorrection
21%D    \bgroup
22%D    \setuptyping[margin=0pt,option=color]
23%D    \showmakeup
24%D    \centeredvcuetrue
25%D    \dontinterfere
26%D    \baselinerulefalse
27%D    \normalvbox
28%D      {\normalhbox to \hsize
29%D         {$\hsize=.5\hsize
30%D          \advance\hsize by -.5em
31%D          \normalvcenter{\vbox{\getbuffer}}\normalhss
32%D          \normalvcenter{\vbox{\dontshowcomposition\typebuffer}}$}}
33%D    \egroup
34%D    \stoplinecorrection}
35%D
36%D \gdef\ShowBufferedExampleBox% private typeseting macro
37%D   {\startlinecorrection
38%D    \bgroup
39%D    \setuptyping[margin=0pt,option=color]
40%D    \showmakeup
41%D    \centeredvcuetrue
42%D    \dontinterfere
43%D    \baselinerulefalse
44%D    \normalvbox
45%D      {\normalhbox to \hsize
46%D         {$\hsize=.5\hsize
47%D          \advance\hsize by -.5em
48%D          \normalvcenter{\baselineruletrue\vbox{\getbuffer}}\normalhss
49%D          \normalvcenter{\vbox{\dontshowcomposition\typebuffer}}$}}
50%D    \egroup
51%D    \stoplinecorrection}
52
53%D Depending on my personal needs and those of whoever uses it,
54%D the macros will be improved in terms of visualization,
55%D efficiency and compatibility. These rather low level
56%D visualization macros are supplemented by ones that can
57%D visualize baselines, the page layout and whatever deserves
58%D attention. Most of those macros can be found in \type
59%D {core-vis} and other core modules. Their integration in
60%D \CONTEXT\ prohibits generic applications.
61%D
62%D We no longer assume usage outside context so we no longer
63%D load support modules.
64%D
65%D One of the strong points of \TEX\ is abstraction of textual
66%D input. When macros are defined well and do what we
67%D want them to do, we will seldom need the tools present in
68%D What You See Is What You Get systems. For instance, when
69%D entering text we don't need rulers, because no manual
70%D shifting and/or alignment of text is needed. On the other
71%D hand, when we are designing macros or specifying layout
72%D elements, some insight in \TEX's advanced spacing, kerning,
73%D filling, boxing and punishment abilities will be handy.
74%D That's why we've implemented a mechanism that shows some of
75%D the inner secrets of \TEX.
76
77\writestatus{loading}{ConTeXt Support Macros / Visualization}
78
79%D In this module we are going to redefine some \TEX\
80%D primitives and \PLAIN\ macro's. Their original meaning is
81%D saved in macros with corresponding names, preceded by
82%D \type{normal}. These original macros are (1)~used to
83%D temporary restore the old values when needed and
84%D (2)~used to prevent recursive calls in the macros that
85%D replace them.
86
87\unprotect
88
89\let\visualvrule\vrule
90\let\visualhrule\hrule
91
92%D \macros
93%D   {dontinterfere}
94%D
95%D Indentation, left and/or right skips, redefinition of
96%D \type{\par} and assignments to \type{\everypar} can lead to
97%D  unwanted results. We can therefore turn all those things
98%D off with \type{\dontinterfere}.
99
100\protected\def\dontinterfere % or maybe just forgetall
101  {\reseteverypar
102   \parindent\zeropoint
103   \parskip  \zeropoint
104   \leftskip \zeropoint
105   \rightskip\zeropoint
106   \relax}
107
108%D \macros
109%D   {dontcomplain}
110%D
111%D In this module we do a lot of box manipulations. Because we
112%D don't want to be confronted with to many over- and underfull
113%D messages we introduce \type{\dontcomplain}.
114
115\ifdefined\dontcomplain \else
116
117    \protected\def\dontcomplain
118      {\hbadness\plustenthousand
119       \vbadness\plustenthousand
120       \hfuzz   \maxdimen
121       \vfuzz   \maxdimen}
122
123\fi
124
125%D \macros
126%D   {normaloffinterlineskip}
127%D
128%D The next hack is needed because in \CONTEXT\ we redefine
129%D \type{\offinterlineskip}.
130
131\ifdefined\normaloffinterlineskip \else
132    \let\normaloffinterlineskip\offinterlineskip
133\fi
134
135%D \macros
136%D   {normalhbox,
137%D    normalvbox,normalvtop}
138%D
139%D There are three types of boxes, one horizontal and two
140%D vertical in nature. As we will see later on, all three types
141%D are to be handled according to their orientation and
142%D baseline behavior. Especially \type{\vtop}'s need our
143%D special attention.
144
145%D \macros
146%D   {normalhskip,
147%D    normalvskip}
148%D
149%D Next come the flexible skips, which come in two flavors
150%D too. Like boxes these are handled with \TEX\ primitives.
151
152%D \macros
153%D   {normalpenalty,
154%D    normalkern}
155%D
156%D Both penalties and kerns are taken care of by mode sensitive
157%D primitives. This means that when making them visible, we
158%D have to take the current mode into account.
159
160%D \macros
161%D   {normalhglue,
162%D    normalvglue}
163%D
164%D Glues on the other hand are macro's defined in \PLAIN\ \TEX.
165%D As we will see, their definitions make the implementation of
166%D their visible counterparts a bit more \TeX{}nical.
167
168\let\normalhglue\hglue
169\let\normalvglue\vglue
170
171%D \macros
172%D   {normalmkern,
173%D    normalmskip}
174%D
175%D Math mode has its own spacing primitives, preceded by
176%D \type{m}. Due to the relation with the current font and the
177%D way math is typeset, their unit \type{mu} is not compatible
178%D with other dimensions. As a result, the visual appearance
179%D of these primitives is kept primitive too.
180
181%D \macros
182%D   {hfilneg,
183%D    vfilneg}
184%D
185%D Fills can be made visible quite easy. We only need some
186%D additional negation macros. Because \PLAIN\ \TEX\ only
187%D offers \type{\hfilneg} and \type{\vfilneg}, we define our
188%D own alternative double \type{ll}'ed ones.
189
190\def\hfilneg  {\normalhskip\zeropoint\s!plus-1\s!fil\relax}
191\def\vfilneg  {\normalvskip\zeropoint\s!plus-1\s!fil\relax}
192\def\hfillneg {\normalhskip\zeropoint\s!plus-1\s!fill\relax}
193\def\vfillneg {\normalvskip\zeropoint\s!plus-1\s!fill\relax}
194\def\hfilllneg{\normalhskip\zeropoint\s!plus-1\s!filll\relax}
195\def\vfilllneg{\normalvskip\zeropoint\s!plus-1\s!filll\relax}
196
197%D \macros
198%D   {normalhss,normalhfil,normalhfill,
199%D    normalvss,normalvfil,normalvfill}
200%D
201%D The positive stretch primitives are used independant and in
202%D combination with \type{\leaders}.
203
204% already saved
205
206%D \macros
207%D   {normalhfilneg,normalhfillneg,
208%D    normalvfilneg,normalvfillneg}
209%D
210%D Keep in mind that both \type{\hfillneg} and \type{\vfillneg}
211%D are not part of \PLAIN\ \TEX\ and therefore not documented
212%D in standard \TEX\ documentation. They can nevertheless be
213%D used at will.
214
215\let\normalhfillneg\hfillneg
216\let\normalvfillneg\vfillneg
217
218%D Visualization is not always wanted. Instead of turning this
219%D option off in those (unpredictable) situations, we just
220%D redefine a few \PLAIN\ macros.
221
222% \ifx\tlap\undefined
223%
224%   \def\rlap#1{\normalhbox to \zeropoint{#1\normalhss}}
225%   \def\llap#1{\normalhbox to \zeropoint{\normalhss#1}}
226%   \def\blap#1{\normalvbox to \zeropoint{#1\normalvss}}
227%   \def\tlap#1{\normalvbox to \zeropoint{\normalvss#1}}
228%
229% \fi
230
231%D \macros
232%D   {makeruledbox}
233%D
234%D Ruled boxes can be typeset is many ways. Here we present
235%D just one alternative. This implementation may be a little
236%D complicated, but it supports all three kind of boxes. The
237%D next command expects a \BOX\ specification, like:
238%D
239%D \starttyping
240%D \makeruledbox0
241%D \stoptyping
242
243%D \macros
244%D   {baselinerule,baselinefill}
245%D
246%D We can make the baseline of a box visible, both dashed and
247%D as a rule. The line is drawn on top of the baseline. All
248%D we have to say is:
249%D
250%D \starttyping
251%D \baselineruletrue
252%D \baselinefilltrue
253%D \stoptyping
254%D
255%D At the cost of some overhead these alternatives are
256%D implemented using \type{\if}'s:
257
258\newif\ifbaselinerule\baselineruletrue
259\newif\ifbaselinefill\baselinefillfalse
260
261%D \macros
262%D   {iftoprule,ifbottomrule,ifleftrule,ifrightrule}
263%D
264%D Rules can be turned on and off, but by default we have:
265%D
266%D \starttyping
267%D \topruletrue
268%D \bottomruletrue
269%D \leftruletrue
270%D \rightruletrue
271%D \stoptyping
272%D
273%D As we see below:
274
275\newif\iftoprule   \topruletrue
276\newif\ifbottomrule\bottomruletrue
277\newif\ifleftrule  \leftruletrue
278\newif\ifrightrule \rightruletrue
279
280%D \macros
281%D   {boxrulewidth}
282%D
283%D The width in the surrounding rules can be specified by
284%D assigning an apropriate value to the dimension used. This
285%D module defaults the width to:
286%D
287%D \starttyping
288%D \boxrulewidth=.2pt
289%D \stoptyping
290
291\newdimen \boxrulewidth \boxrulewidth=.2pt
292
293\newdimen \boxruleht
294\newdimen \boxruledp
295\newdimen \boxrulewd
296
297\newbox   \boxrulescratchbox
298
299%D The core macro \type{\makeruledbox} looks a bit hefty. The
300%D manipulation at the end is needed because we want to
301%D preserve both the mode and the baseline. This means that
302%D \type{\vtop}'s and \type{\vbox}'es behave the way we expect
303%D them to do.
304%D
305%D \startlinecorrection
306%D \hbox
307%D   {\ruledhbox to 5em{\strut test\normalhss}\hskip1em
308%D    \ruledvbox{\hsize 5em\strut test \par test\strut}\hskip1em
309%D    \ruledvtop{\hsize 5em\strut test \par test\strut}}
310%D \stoplinecorrection
311%D
312%D The \type{\cleaders} part of the macro is responsible for
313%D the visual baseline. The \type{\normalhfill} belongs to this
314%D primitive too. By storing and restoring the height and depth
315%D of box \type{#1}, we preserve the mode.
316
317\let\dowithruledbox\relax % hook
318
319\protected\def\makeruledbox#1%
320  {\boxruleht\ht#1%
321   \boxruledp\dp#1%
322   \boxrulewd\wd#1%
323   \setbox\boxrulescratchbox\normalvbox
324     {\dontcomplain
325      \normaloffinterlineskip
326      \visualhrule
327        \s!height\boxrulewidth
328        \iftoprule\else\s!width\zeropoint\fi
329      \normalvskip-\boxrulewidth
330      \normalhbox to \boxrulewd
331        {\visualvrule
332           \s!height\boxruleht
333           \s!depth \boxruledp
334           \s!width \ifleftrule\boxrulewidth\else\zeropoint\fi
335         \ifdim\boxruleht>\zeropoint \else \baselinerulefalse \fi
336         \ifdim\boxruledp>\zeropoint \else \baselinerulefalse \fi
337         \ifbaselinerule
338           \ifdim\boxrulewd<20\boxrulewidth
339             \baselinefilltrue
340           \fi
341           \cleaders
342             \ifbaselinefill
343               \visualhrule
344                 \s!height\boxrulewidth
345             \else
346               \normalhbox
347                 {\normalhskip2.5\boxrulewidth
348                  \visualvrule
349                    \s!height\boxrulewidth
350                    \s!width5\boxrulewidth
351                  \normalhskip2.5\boxrulewidth}%
352             \fi
353         \fi
354         \normalhfill
355         \visualvrule
356           \s!width\ifrightrule\boxrulewidth\else\zeropoint\fi}%
357       \normalvskip-\boxrulewidth
358       \visualhrule
359         \s!height\boxrulewidth
360         \ifbottomrule\else\s!width\zeropoint\fi}%
361   \wd#1\zeropoint
362   \setbox#1=\ifhbox#1\normalhbox\else\normalvbox\fi
363     {\normalhbox
364        {\box#1%
365         \lower\boxruledp\normalhbox{\dowithruledbox{\box\boxrulescratchbox}}}}%
366   \ht#1\boxruleht
367   \wd#1\boxrulewd
368   \dp#1\boxruledp}
369
370%D Just in case one didn't notice: the rules are in fact layed
371%D over the box. This way the contents of a box cannot
372%D visually interfere with the rules around (upon) it. A more
373%D advanced version of ruled boxes can be found in one of the
374%D core modules of \CONTEXT. There we take offsets, color,
375%D rounded corners, backgrounds and alignment into account too.
376
377%D \macros
378%D   {ruledhbox,
379%D    ruledvbox,ruledvtop,
380%D    ruledvcenter}
381%D
382%D These macro's can be used instead of \type{\hbox},
383%D \type{\vbox}, \type{\vtop} and, when in math mode,
384%D \type{\vcenter}. They just do what their names state. Using
385%D an auxiliary macro would save us a few words of memory, but
386%D it would make their appearance even more obscure.
387%D
388%D \startbuffer
389%D \hbox
390%D   {\strut
391%D    one
392%D    two
393%D    \hbox{three}
394%D    four
395%D    five}
396%D \stopbuffer
397%D
398%D \ShowBufferedExampleBox
399
400\protected\def\ruledhbox
401  {\normalhbox\bgroup
402   \dowithnextboxcs\supp_visualizers_hbox_finish\normalhbox}
403
404\def\supp_visualizers_hbox_finish
405  {\makeruledbox\nextbox
406   \box\nextbox
407   \egroup}
408
409%D \startbuffer
410%D \vbox
411%D   {\strut
412%D    first line  \par
413%D    second line \par
414%D    third line  \par
415%D    fourth line \par
416%D    fifth line
417%D    \strut }
418%D \stopbuffer
419%D
420%D \ShowBufferedExampleBox
421
422\protected\def\ruledvbox
423  {\normalvbox\bgroup
424   \dowithnextboxcs\supp_visualizers_vbox_finish\normalvbox}
425
426\def\supp_visualizers_vbox_finish
427  {\makeruledbox\nextbox
428   \box\nextbox
429   \egroup}
430
431%D \startbuffer
432%D \vtop
433%D   {\strut
434%D    first line  \par
435%D    second line \par
436%D    third line  \par
437%D    fourth line \par
438%D    fifth line
439%D    \strut }
440%D \stopbuffer
441%D
442%D \ShowBufferedExampleBox
443
444\protected\def\ruledvtop
445  {\normalvtop\bgroup
446   \dowithnextboxcs\supp_visualizers_vtop_finish\normalvtop}
447
448\def\supp_visualizers_vtop_finish
449  {\makeruledbox\nextbox
450   \box\nextbox
451   \egroup}
452
453%D \startbuffer
454%D \hbox
455%D   {$\vcenter{\hsize.2\hsize
456%D       alfa \par beta}$
457%D    $\vcenter to 3cm{\hsize.2\hsize
458%D       alfa \par beta \par gamma}$
459%D    $\vcenter{\hsize.2\hsize
460%D       alfa \par beta}$}
461%D \stopbuffer
462%D
463%D \ShowBufferedExampleBox
464
465\protected\def\ruledvcenter
466  {\normalvbox\bgroup
467   \dontinterfere
468   \dowithnextboxcs\supp_visualizers_vcenter_finish\normalvbox}
469
470\def\supp_visualizers_vcenter_finish
471  {\scratchdimen.5\dimexpr\ht\nextbox+\dp\nextbox\relax
472   \ht\nextbox\scratchdimen
473   \dp\nextbox\scratchdimen
474  %\ruledhbox{\box\nextbox}%
475   \makeruledbox\nextbox
476   \box\nextbox
477   \egroup}
478
479%D \macros
480%D   {ruledbox,
481%D    setruledbox}
482%D
483%D Of the next two macros the first can be used to precede a
484%D box of ones own choice. One can for instance prefix boxes
485%D with \type{\ruledbox} and afterwards --- when the macro
486%D satisfy the needs --- let it to \type{\relax}.
487%D
488%D \starttyping
489%D \ruledbox\hbox{What rules do you mean?}
490%D \stoptyping
491%D
492%D The macro \type{\setruledbox} can be used to directly
493%D rule a box.
494%D
495%D \starttyping
496%D \setruledbox12=\hbox{Who's talking about rules here?}
497%D \stoptyping
498%D
499%D At the cost of some extra macros we can implement a
500%D variant that does not need the~\type{=}, but we stick to:
501
502\protected\def\ruledbox
503  {\dowithnextboxcs\supp_visualizers_box_finish}
504
505\def\supp_visualizers_box_finish
506  {\makeruledbox\nextbox\box\nextbox}
507
508% \def\setruledbox#1=%
509%   {\dowithnextbox{\makeruledbox\nextbox\setbox#1\nextbox}}
510
511\def\setruledbox#1=% not nice, better
512  {\afterassignment\supp_visualizers_setruledbox_indeed\scratchcounter}
513
514\def\supp_visualizers_setruledbox_indeed
515  {\dowithnextboxcs\supp_visualizers_setruledbox_finish}
516
517\def\supp_visualizers_setruledbox_finish
518  {\makeruledbox\nextbox
519   \setbox\scratchcounter\nextbox}
520
521%D \macros
522%D   {investigateskip,
523%D    investigatecount,
524%D    investigatemuskip}
525%D
526%D Before we meet the visualizing macro's, we first implement
527%D ourselves some handy utility ones. Just for the sake of
528%D efficiency and readability, we introduce some status
529%D variables, that tell us a bit more about the registers we
530%D use:
531%D
532%D \starttyping
533%D \ifflexible
534%D \ifzero
535%D \ifnegative
536%D \ifpositive
537%D \stoptyping
538%D
539%D These status variables are set when we call for one of the
540%D investigation macros, e.g.
541%D
542%D \starttyping
543%D \investigateskip\scratchskip
544%D \stoptyping
545%D
546%D We use some dirty trick to check stretchability of \SKIPS.
547%D Users of these macros are invited to study their exact
548%D behavior first. The positive and negative states both
549%D include zero and are in fact non-negative ($\geq0$) and
550%D non-positive ($\leq0$). Well, no dirty trick is needed
551%D any longer as we have \ETEX\ functionality.
552
553\newif\ifflexible
554\newif\ifzero
555\newif\ifnegative
556\newif\ifpositive
557
558\def\investigateskip#1%
559  {\relax
560   \ifdim#1=\zeropoint
561     \ifdim\gluestretch#1=\zeropoint
562       \ifdim\glueshrink#1=\zeropoint
563         \flexiblefalse
564       \else
565         \flexibletrue
566       \fi
567     \else
568       \flexibletrue
569     \fi
570   \else
571     \flexibletrue
572   \fi
573   \ifdim#1=\zeropoint\relax
574     \zerotrue      \else
575     \zerofalse     \fi
576   \ifdim#1<\zeropoint\relax
577     \positivefalse \else
578     \positivetrue  \fi
579   \ifdim#1>\zeropoint\relax
580     \negativefalse \else
581     \negativetrue  \fi}
582
583\def\investigatecount#1%
584  {\relax
585   \flexiblefalse
586   \ifnum#1=\zerocount
587     \zerotrue      \else
588     \zerofalse     \fi
589   \ifnum#1<\zerocount
590     \positivefalse \else
591     \positivetrue  \fi
592   \ifnum#1>\zerocount
593     \negativefalse \else
594     \negativetrue  \fi}
595
596\def\investigatemuskip#1% etex ?
597  {\relax
598   \edef\!!stringa{\the#1}%
599   \edef\!!stringb{0mu}%
600   \def\!!stringc##1##2\\{##1}%
601   \expandafter\edef\expandafter\!!stringc\expandafter
602     {\expandafter\!!stringc\!!stringa\\}%
603   \edef\!!stringd{-}%
604   \flexiblefalse
605   \ifx\!!stringa\!!stringb
606     \zerotrue
607     \negativefalse
608     \positivefalse
609   \else
610     \zerofalse
611     \ifx\!!stringc\!!stringd
612       \positivefalse
613       \negativetrue
614     \else
615       \positivetrue
616       \negativefalse
617     \fi
618   \fi}
619
620%D Now the neccessary utility macros are defined, we can make a
621%D start with the visualizing ones. The implementation of these
622%D macros is a compromise between readability, efficiency of
623%D coding and processing speed. Sometimes we do in steps what
624%D could have been done in combination, sometimes we use a few
625%D boxes more or less then actually needed, and more than once
626%D one can find the same piece of rule drawing code twice.
627
628%D \macros
629%D   {ifcenteredvcue,normalvcue}
630%D
631%D Depending on the context, one can force visual vertical cues
632%D being centered along \type{\hsize} or being put at the
633%D current position. Although centering often looks better,
634%D we've chosen the second alternative as default. The main
635%D reason for doing so is that often when we don't set the
636%D \type{\hsize} ourselves, \TEX\ takes the value of the
637%D surrounding box. As a result the visual cues can migrate
638%D outside the current context.
639%D
640%D This behavior is accomplished by a small but effective
641%D auxiliary macro, which behavior can be influenced by the
642%D boolean \type{\centeredvcue}. By saying
643%D
644%D \starttyping
645%D \centeredvcuetrue
646%D \stoptyping
647%D
648%D one turns centering on. As said, we turn it off.
649
650\newif\ifcenteredvcue  \centeredvcuefalse
651
652\def\normalvcue#1%
653  {\normalhbox \ifcenteredvcue to \hsize \fi {\normalhss#1\normalhss}}
654
655%D We could have used the more robust version
656%D
657%D \starttyping
658%D \def\normalvcue%
659%D   {\normalhbox \ifcenteredvcue to \hsize \fi
660%D    \bgroup\bgroup\normalhss
661%D    \aftergroup\normalhss\aftergroup\egroup
662%D    \let\next=}
663%D \stoptyping
664%D
665%D or the probably best one:
666%D
667%D \starttyping
668%D \def\normalvcue%
669%D   {\hbox \ifcenteredvcue to \hsize
670%D      \bgroup\bgroup\normalhss
671%D      \aftergroup\normalhss\aftergroup\egroup
672%D    \else
673%D      \bgroup
674%D    \fi
675%D    \let\next=}
676%D \stoptyping
677%D
678%D Because we don't have to preserve \CATCODES\ and only use
679%D small arguments, we stick to the first alternative.
680
681%D \macros
682%D   {testrulewidth}
683%D
684%D We build our visual cues out of rules. At the cost of a much
685%D bigger \DVI\ file, this is to be prefered over using
686%D characters (1)~because we cannot be sure of their
687%D availability and (2)~because their dimensions are fixed.
688%D
689%D As with ruled boxes, we use a \DIMENSION\ to specify the
690%D width of the ruled elements. This dimension defaults to:
691%D
692%D \starttyping
693%D \testrulewidth=\boxrulewidth
694%D \stoptyping
695%D
696%D Because we prefer whole numbers for specifying the
697%D dimensions, we often use even multiples of
698%D \type{\testrulewidth}.
699
700%D \macros
701%D   {visiblestretch}
702%D
703%D A second variable is introduced because of the stretch
704%D components of \SKIPS. At the cost of some accuracy we can
705%D make this stretch visible.
706%D
707%D \starttyping
708%D \visiblestretchtrue
709%D \stoptyping
710
711\newdimen\testrulewidth  \testrulewidth=\boxrulewidth
712\newif\ifvisiblestretch  \visiblestretchfalse
713
714%D \macros
715%D   {ruledhss,
716%D    ruledhfil,ruledhfilneg,
717%D    ruledhfill,ruledhfillneg}
718%D
719%D We start with the easiest part, the fills. The scheme we
720%D follow is {\em visual filling -- going back -- normal
721%D filling}. Visualizing is implemented using \type{\cleaders}.
722%D Because the \BOX\ that follows this command is constructed
723%D only once, the \type{\copy} is not really a prerequisite. We
724%D prefer using a \type{\normalhbox} here instead of a
725%D \type{\hbox}.
726
727\def\setvisiblehfilbox#1\to#2#3#4%
728  {\setbox#1\normalhbox
729     {\visualvrule
730        \s!width #2\testrulewidth
731        \s!height#3\testrulewidth
732        \s!depth #4\testrulewidth}%
733   \smashbox#1}
734
735\def\doruledhfiller#1#2#3#4%
736  {#1#2%
737   \bgroup
738     \dontinterfere
739     \dontcomplain
740     \setvisiblehfilbox0\to{4}{#3}{#4}%
741     \setvisiblehfilbox2\to422%
742     \copy0\copy2
743     \bgroup
744       \setvisiblehfilbox0\to422%
745       \cleaders
746         \normalhbox to 12\testrulewidth
747           {\normalhss\copy0\normalhss}%
748         #1%
749     \egroup
750     \setbox0\normalhbox
751       {\normalhskip-4\testrulewidth\copy0\copy2}%
752     \smashbox0%
753     \box0
754   \egroup}
755
756%D The horizontal fillers differ in their boundary
757%D visualization. Watch the small dots. Fillers can be
758%D combined within reasonable margins.
759%D
760%D \startlinecorrection
761%D \baselinerulefalse
762%D \ruledhbox to \hsize
763%D   {\strut\type{\hss}\ruledhss test}
764%D \stoplinecorrection
765%D
766%D \startlinecorrection
767%D \baselinerulefalse
768%D \ruledhbox to \hsize
769%D   {\strut\type{\hfil}\ruledhfil test}
770%D \stoplinecorrection
771%D
772%D \startlinecorrection
773%D \baselinerulefalse
774%D \ruledhbox to \hsize
775%D   {\strut\type{\hfill}\ruledhfill test}
776%D \stoplinecorrection
777%D
778%D \startlinecorrection
779%D \baselinerulefalse
780%D \ruledhbox to \hsize
781%D   {\strut
782%D    \type{\hfil}\type{\hfil}\ruledhfil\ruledhfil
783%D    test%
784%D    \ruledhfil\type{\hfil}}
785%D \stoplinecorrection
786%D
787%D The negative counterparts are visualizes, but seldom
788%D become visible, apart from their boundaries.
789%D
790%D \startlinecorrection
791%D \baselinerulefalse
792%D \ruledhbox to \hsize
793%D   {\strut\type{\hfilneg}\ruledhfilneg test}
794%D \stoplinecorrection
795%D
796%D \startlinecorrection
797%D \baselinerulefalse
798%D \ruledhbox to \hsize
799%D   {\strut\type{\hfillneg}\ruledhfillneg test}
800%D \stoplinecorrection
801%D
802%D Although leaders are used for visualizing, they are
803%D visualized themselves correctly as the next example shows.
804%D
805%D \startlinecorrection
806%D \baselinerulefalse
807%D \ruledhbox to \hsize
808%D   {\strut\cleaders\normalhbox to 2em{\normalhss$\circ$\normalhss}\ruledhfill}
809%D \stoplinecorrection
810%D
811%D All five substitutions use the same auxiliary macro. Watch
812%D the positive first -- negative next approach.
813
814\protected\def\ruledhss     {\doruledhfiller\normalhss     \normalhfilneg  {0}{0}}
815\protected\def\ruledhfil    {\doruledhfiller\normalhfil    \normalhfilneg {10}{-6}}
816\protected\def\ruledhfill   {\doruledhfiller\normalhfill   \normalhfillneg{18}{-14}}
817\protected\def\ruledhfilneg {\doruledhfiller\normalhfilneg \normalhfil    {-6}{10}}
818\protected\def\ruledhfillneg{\doruledhfiller\normalhfillneg\normalhfill  {-14}{18}}
819
820%D \macros
821%D   {ruledvss,
822%D    ruledvfil,ruledvfilneg,
823%D    ruledvfill,ruledvfillneg}
824%D
825%D The vertical mode commands adopt the same visualization
826%D scheme, but are implemented in a slightly different way.
827
828\def\setvisiblevfilbox#1\to#2#3#4%
829  {\setbox#1\normalhbox
830     {\visualvrule
831        \s!width #2\testrulewidth
832        \s!height#3\testrulewidth
833        \s!depth #4\testrulewidth}%
834   \smashbox#1}%
835
836\def\doruledvfiller#1#2#3%
837  {#1#2%
838   \bgroup
839     \dontinterfere
840     \dontcomplain
841     \normaloffinterlineskip
842     \setvisiblevfilbox0\to422%
843     \setbox2\normalvcue
844       {\normalhskip -#3\testrulewidth\copy0}%
845     \smashbox2%
846     \copy2
847     \bgroup
848       \setbox2\normalvcue
849         {\normalhskip -2\testrulewidth\copy0}%
850       \smashbox2%
851       \copy2
852       \cleaders
853         \normalvbox to 12\testrulewidth
854           {\normalvss\copy2\normalvss}%
855         #1%
856       \setbox2\normalvbox
857         {\normalvskip-2\testrulewidth\copy2}%
858       \smashbox2%
859       \box2
860     \egroup
861     \box2
862   \egroup}
863
864%D Because they act the same as their horizontal counterparts
865%D we only show a few examples.
866%D
867%D \startlinecorrection
868%D \hbox to \hsize
869%D   {\dontinterfere
870%D    \baselinerulefalse
871%D    \centeredvcuetrue
872%D    \ruledvbox to 10ex
873%D      {\hsize.18\hsize
874%D       \type{\vss}\ruledvss last line}\normalhss
875%D    \ruledvbox to 10ex
876%D      {\hsize.18\hsize
877%D       \type{\vfil}\ruledvfil last line}\normalhss
878%D    \ruledvbox to 10ex
879%D      {\hsize.18\hsize
880%D       \type{\vfill}\ruledvfill last line}\normalhss
881%D    \ruledvbox to 10ex
882%D      {\hsize.18\hsize
883%D       \type{\vfilneg}\ruledvfilneg last line}\normalhss
884%D    \ruledvbox to 10ex
885%D      {\hsize.18\hsize
886%D       \type{\vfillneg}\ruledvfillneg last line}}
887%D \stoplinecorrection
888%D
889%D Keep in mind that \type{\vfillneg} is not part of \PLAIN\
890%D \TEX, but are mimmicked by a macro.
891
892\protected\def\ruledvss     {\doruledvfiller\normalvss     \normalvfilneg   {2}}
893\protected\def\ruledvfil    {\doruledvfiller\normalvfil    \normalvfilneg  {-4}}
894\protected\def\ruledvfill   {\doruledvfiller\normalvfill   \normalvfillneg{-12}}
895\protected\def\ruledvfilneg {\doruledvfiller\normalvfilneg \normalvfil      {8}}
896\protected\def\ruledvfillneg{\doruledvfiller\normalvfillneg\normalvfill    {16}}
897
898%D \macros
899%D   {ruledhskip}
900%D
901%D Skips differ from kerns in two important aspects:
902%D
903%D \startitemize[packed]
904%D \item  line and pagebreaks are allowed at a skip
905%D \item  skips can have a positive and/or negative
906%D       stretchcomponent
907%D \stopitemize
908%D
909%D Stated a bit different: kerns are fixed skips at which no
910%D line or pagebreak can occur. Because skips have a more open
911%D character, they are visualized in a open way.
912%D
913%D \startbuffer
914%D one
915%D \hskip +30pt plus 5pt
916%D two
917%D \hskip +30pt
918%D \hskip -10pt plus 5pt
919%D three
920%D \hskip   0pt
921%D four
922%D \hskip +30pt
923%D five
924%D \stopbuffer
925%D
926%D \ShowBufferedExample
927%D
928%D When skips have a stretch component, this is visualized by
929%D means of a dashed line. Positive skips are on top of the
930%D baseline, negative ones are below it. This way we can show
931%D the combined results. An alternative visualization of
932%D stretch could be drawing the mid line over a length of the
933%D stretch, in positive or negative direction.
934
935\def\supp_visualizers_hskip_indeed
936  {\relax
937   \dontinterfere
938   \dontcomplain
939   \investigateskip\scratchskip
940   \ifzero
941     \setbox0\normalhbox
942       {\normalhskip-\testrulewidth
943        \visualvrule
944          \s!width4\testrulewidth
945          \s!height16\testrulewidth
946          \s!depth16\testrulewidth}%
947   \else
948     \setbox0\normalhbox to \ifnegative-\fi\scratchskip
949       {\visualvrule
950          \s!width2\testrulewidth
951          \ifnegative\s!depth\else\s!height\fi16\testrulewidth
952        \cleaders
953          \visualhrule
954            \ifnegative
955              \s!depth2\testrulewidth
956              \s!height\zeropoint
957            \else
958              \s!height2\testrulewidth
959              \s!depth\zeropoint
960            \fi
961          \normalhfill
962        \ifflexible
963          \normalhskip\ifnegative\else-\fi\scratchskip
964          \normalhskip2\testrulewidth
965          \cleaders
966            \normalhbox
967              {\normalhskip 2\testrulewidth
968               \visualvrule
969                 \s!width2\testrulewidth
970                 \s!height\ifnegative-7\else9\fi\testrulewidth
971                 \s!depth\ifnegative9\else-7\fi\testrulewidth
972               \normalhskip 2\testrulewidth}%
973            \normalhfill
974        \fi
975        \visualvrule
976          \s!width2\testrulewidth
977          \ifnegative\s!depth\else\s!height\fi16\testrulewidth}%
978     \setbox0\normalhbox
979       {\ifnegative\else\normalhskip-\scratchskip\fi
980        \box0}%
981   \fi
982   \smashbox0%
983   \ifvisiblestretch \else
984     \flexiblefalse
985   \fi
986   \ifflexible
987     % breaks ok but small displacements can occur
988     \skip2\scratchskip
989     \advance\skip2 -1\scratchskip
990     \divide\skip2 2
991     \advance\scratchskip -\skip2
992     \normalhskip\scratchskip
993     \normalpenalty\plustenthousand
994     \box0
995     \normalhskip\skip2
996   \else
997     \normalhskip\scratchskip
998     \box0
999   \fi
1000   \egroup}
1001
1002\protected\def\ruledhskip
1003  {\bgroup
1004   \afterassignment\supp_visualizers_hskip_indeed
1005   \scratchskip=}
1006
1007%D The visual skip is located at a feasible point. Normally
1008%D this does not interfere with the normaltypesetting process.
1009%D The next examples show (1)~the default behavior, (2)~the
1010%D (not entirely correct) distributed stretch and (3)~the way
1011%D the text is typeset without cues.
1012%D
1013%D \startbuffer
1014%D \dorecurse
1015%D   {15}
1016%D   {test\hskip1em plus .5em minus .5em
1017%D    test\hskip2em
1018%D    test}
1019%D \stopbuffer
1020%D
1021%D \startlinecorrection
1022%D \showmakeup
1023%D \getbuffer
1024%D \stoplinecorrection
1025%D
1026%D \startlinecorrection
1027%D \showmakeup
1028%D \visiblestretchtrue
1029%D \getbuffer
1030%D \stoplinecorrection
1031%D
1032%D \startlinecorrection
1033%D \getbuffer
1034%D \stoplinecorrection
1035
1036%D \macros
1037%D   {ruledvskip}
1038%D
1039%D We are less fortunate when implementing the vertical skips.
1040%D This is a direct result of interference between the boxes that
1041%D visualize the skip and skip removal at a pagebreak. Normally
1042%D skips disappear at the top of a page, but not of course when
1043%D visualized in a \type{\vbox}. A quite perfect simulation
1044%D could have been built if we would have had available two
1045%D more primitives: \type{\hnop} and \type{\vnop}. These new
1046%D primitives could stand for boxes that are visible but are
1047%D not taken into account in any way. They are there for us,
1048%D but not for \TEX.
1049%D
1050%D \startbuffer
1051%D first line
1052%D \vskip +30pt plus 5pt
1053%D second line
1054%D \vskip +30pt
1055%D \vskip -10pt plus 5pt
1056%D third line
1057%D \par
1058%D fourth line
1059%D \vskip +30pt
1060%D fifth line
1061%D \vskip   0pt
1062%D sixth line
1063%D \stopbuffer
1064%D
1065%D \ShowBufferedExample
1066%D
1067%D We have to postpone \type{\prevdepth}. Although this
1068%D precaution probably is not completely waterproof, it works
1069%D quite well.
1070
1071\def\dodoruledvskip
1072  {\nextdepth\prevdepth
1073   \dontinterfere
1074   \dontcomplain
1075   \normaloffinterlineskip
1076   \investigateskip\scratchskip
1077   \ifzero
1078     \setbox0\normalvcue
1079       {\visualvrule
1080          \s!width32\testrulewidth
1081          \s!height2\testrulewidth
1082          \s!depth2\testrulewidth}%
1083   \else
1084     \setbox0\normalvbox to \ifnegative-\fi\scratchskip
1085       {\visualhrule
1086          \s!width16\testrulewidth
1087          \s!height2\testrulewidth
1088        \ifflexible
1089          \cleaders
1090            \normalhbox to 16\testrulewidth
1091              {\normalhss
1092               \normalvbox
1093                 {\normalvskip 2\testrulewidth
1094                  \visualhrule
1095                  \s!width2\testrulewidth
1096                  \s!height2\testrulewidth
1097                  \normalvskip 2\testrulewidth}%
1098               \normalhss}%
1099            \normalvfill
1100        \else
1101          \normalvfill
1102        \fi
1103        \visualhrule
1104          \s!width16\testrulewidth
1105          \s!height2\testrulewidth}%
1106     \setbox2\normalvbox to \ht0
1107       {\visualhrule
1108          \s!width2\testrulewidth
1109          \s!height\ht0}%
1110     \ifnegative
1111       \ht0\zeropoint
1112       \setbox0\normalhbox
1113         {\normalhskip2\testrulewidth % will be improved
1114          \normalhskip-\wd0\box0}%
1115     \fi
1116     \smashbox0%
1117     \smashbox2%
1118     \setbox0\normalvcue
1119       {\box2\box0}%
1120     \setbox0\normalvbox
1121       {\ifnegative\normalvskip\scratchskip\fi\box0}%
1122     \smashbox0%
1123   \fi
1124   \ifvisiblestretch
1125     \ifflexible
1126       \skip2\scratchskip
1127       \advance\skip2 -1\scratchskip
1128       \divide\skip2 2
1129       \advance\scratchskip -\skip2
1130       \normalvskip\skip2
1131     \fi
1132   \fi
1133   \normalpenalty\plustenthousand
1134   \box0
1135   \prevdepth\nextdepth % not \dp0=\nextdepth
1136   \normalvskip\scratchskip}
1137
1138%D We try to avoid interfering at the top of a page. Of course
1139%D we only do so when we are in the main vertical list.
1140
1141\def\doruledvskip
1142  {\endgraf % \par
1143   \ifdim\pagegoal=\maxdimen
1144     \ifinner
1145       \dodoruledvskip
1146     \fi
1147   \else
1148     \dodoruledvskip
1149   \fi
1150   \egroup}
1151
1152\protected\def\ruledvskip
1153  {\bgroup
1154   \afterassignment\doruledvskip
1155   \scratchskip=}
1156
1157%D \macros
1158%D   {ruledkern}
1159%D
1160%D The macros that implement the kerns are a bit more
1161%D complicated than needed, because they also serve the
1162%D visualization of glue, our \PLAIN\ defined kerns with
1163%D stretch or shrink. We've implemented both horizontal and
1164%D vertical kerns as ruled boxes.
1165%D
1166%D \startbuffer
1167%D one
1168%D \kern +30pt
1169%D two
1170%D \kern +30pt
1171%D \kern -10pt
1172%D three
1173%D \kern   0pt
1174%D four
1175%D \kern +30pt
1176%D five
1177%D \stopbuffer
1178%D
1179%D \ShowBufferedExample
1180%D
1181%D Positive and negative kerns are placed on top or below the
1182%D baseline, so we are able to track their added result. We
1183%D didn't mention spacings of 0~pt yet. Zero values are
1184%D visualized a bit different, because we want to see them
1185%D anyhow.
1186
1187\def\supp_visualizers_hkern_indeed
1188  {\dontinterfere
1189   \dontcomplain
1190   \baselinerulefalse
1191   \investigateskip\scratchskip
1192   \boxrulewidth2\testrulewidth
1193   \ifzero
1194     \setbox0\ruledhbox to 8\testrulewidth
1195       {\visualvrule
1196          \s!width\zeropoint
1197          \s!height16\testrulewidth
1198          \s!depth16\testrulewidth}%
1199     \setbox0\normalhbox
1200       {\normalhskip-4\testrulewidth\box0}%
1201   \else
1202     \setbox0\ruledhbox to \ifnegative-\fi\scratchskip
1203       {\visualvrule
1204          \s!width\zeropoint
1205          \ifnegative\s!depth\else\s!height\fi16\testrulewidth
1206        \ifflexible
1207          \normalhskip2\testrulewidth
1208          \cleaders
1209            \normalhbox
1210              {\normalhskip 2\testrulewidth
1211               \visualvrule
1212                 \s!width2\testrulewidth
1213                 \s!height\ifnegative-7\else9\fi\testrulewidth
1214                 \s!depth\ifnegative9\else-7\fi\testrulewidth
1215               \normalhskip 2\testrulewidth}%
1216            \normalhfill
1217        \else
1218          \normalhfill
1219        \fi}%
1220     \testrulewidth2\testrulewidth
1221     \setbox0\ruledhbox{\box0}%  \make...
1222   \fi
1223   \smashbox0%
1224   \normalpenalty\plustenthousand
1225   \normalhbox to \zeropoint
1226     {\ifnegative\normalhskip1\scratchskip\fi
1227      \box0}%
1228   \afterwards\scratchskip
1229   \egroup}
1230
1231\protected\def\ruledhkern#1%
1232  {\bgroup
1233   \let\afterwards#1%
1234   \afterassignment\supp_visualizers_hkern_indeed
1235   \scratchskip=}
1236
1237%D After having seen the horizontal ones, the vertical kerns
1238%D will not surprise us. In this example we use \type{\par} to
1239%D switch to vertical mode.
1240%D
1241%D \startbuffer
1242%D first line
1243%D \par \kern +30pt
1244%D second line
1245%D \par \kern +30pt
1246%D \par \kern -10pt
1247%D third line
1248%D \par
1249%D fourth line
1250%D \par \kern +30pt
1251%D fifth line
1252%D \par \kern   0pt
1253%D sixth line
1254%D \stopbuffer
1255%D
1256%D \ShowBufferedExample
1257%D
1258%D Like before, we have to postpone \type{\prevdepth}. If we
1259%D leave out this trick, we got ourselves some wrong spacing.
1260
1261\def\supp_visualizers_vkern_finish
1262  {\nextdepth\prevdepth
1263   \dontinterfere
1264   \dontcomplain
1265   \baselinerulefalse
1266   \normaloffinterlineskip
1267   \investigateskip\scratchskip
1268   \boxrulewidth2\testrulewidth
1269   \ifzero
1270     \setbox0\ruledhbox to 32\testrulewidth
1271       {\visualvrule
1272          \s!width\zeropoint
1273          \s!height4\testrulewidth
1274          \s!depth4\testrulewidth}%
1275   \else
1276     \setbox0\ruledvbox to \ifnegative-\fi\scratchskip
1277       {\hsize16\testrulewidth
1278        \ifflexible
1279          \cleaders
1280            \normalhbox to 16\testrulewidth
1281              {\normalhss
1282               \normalvbox
1283                 {\normalvskip 2\testrulewidth
1284                  \visualhrule
1285                    \s!width2\testrulewidth
1286                    \s!height2\testrulewidth
1287                  \normalvskip 2\testrulewidth}%
1288               \normalhss}%
1289            \normalvfill
1290        \else
1291          \visualvrule
1292            \s!width\zeropoint
1293            \s!height\ifnegative-\fi\scratchskip
1294          \normalhfill
1295        \fi}
1296   \fi
1297   \testrulewidth2\testrulewidth
1298   \setbox0\ruledvbox{\box0}%  \make...
1299   \smashbox0%
1300   \setbox0\normalvbox
1301     {\ifnegative\normalvskip\scratchskip\fi
1302      \normalvcue
1303       {\ifnegative\normalhskip-16\testrulewidth\fi\box0}}%
1304   \smashbox0%
1305   \normalpenalty\plustenthousand
1306   \box0
1307   \prevdepth\nextdepth} % not \dp0=\nextdepth
1308
1309\def\supp_visualizers_vkern_indeed
1310  {\ifdim\pagegoal=\maxdimen
1311     \ifinner
1312       \supp_visualizers_vkern_finish
1313     \fi
1314   \else
1315     \supp_visualizers_vkern_finish
1316   \fi
1317   \afterwards\scratchskip
1318   \egroup}
1319
1320\protected\def\ruledvkern#1%
1321  {\bgroup
1322   \let\afterwards#1\relax
1323   \afterassignment\supp_visualizers_vkern_indeed
1324   \scratchskip=}
1325
1326\protected\def\ruledkern
1327  {\ifvmode
1328     \expandafter\ruledvkern
1329   \else
1330     \expandafter\ruledhkern
1331   \fi
1332   \normalkern}
1333
1334%D A a bit more \TEX nice solution is:
1335%D
1336%D \starttyping
1337%D \protected\def\ruledkern%
1338%D   {\csname ruled\ifvmode v\else h\fi kern\endcsname\normalkern}
1339%D \stoptyping
1340
1341%D \macros
1342%D   {ruledhglue,ruledvglue}
1343%D
1344%D The non-primitive glue commands are treated as kerns with
1345%D stretch. This stretch is presented as a dashed line. I
1346%D have to admit that until now, I've never used these glue
1347%D commands.
1348%D
1349%D \startbuffer
1350%D one
1351%D \hglue +30pt plus 5pt
1352%D two
1353%D \hglue +30pt
1354%D \hglue -10pt plus 5pt
1355%D three
1356%D \hglue   0pt
1357%D four
1358%D \hglue +30pt
1359%D five
1360%D \stopbuffer
1361%D
1362%D \ShowBufferedExample
1363
1364\def\supp_visualizers_hglue_indeed
1365  {\leavevmode % plain tex uses this
1366   \scratchcounter\spacefactor
1367   \visualvrule\s!width\zeropoint
1368   \normalpenalty\plustenthousand
1369   \ruledhkern\normalhskip\scratchskip
1370   \spacefactor\scratchcounter
1371   \egroup}
1372
1373\protected\def\ruledhglue
1374  {\bgroup
1375   \afterassignment\supp_visualizers_hglue_indeed\scratchskip=}
1376
1377%D \startbuffer
1378%D first line
1379%D \vglue +30pt plus 5pt
1380%D second line
1381%D \vglue +30pt
1382%D \vglue -10pt plus 5pt
1383%D third line
1384%D \par
1385%D fourth line
1386%D \vglue +30pt
1387%D fifth line
1388%D \vglue   0pt
1389%D sixth line
1390%D \stopbuffer
1391%D
1392%D \ShowBufferedExample
1393
1394\def\supp_visualizers_vglue_indeed
1395  {\endgraf % \par
1396   \nextdepth\prevdepth
1397   \visualhrule\s!height\zeropoint
1398   \normalpenalty\plustenthousand
1399   \ruledvkern\normalvskip\scratchskip
1400   \prevdepth\nextdepth
1401   \egroup}
1402
1403\protected\def\ruledvglue
1404  {\bgroup
1405   \afterassignment\supp_visualizers_vglue_indeed\scratchskip=}
1406
1407%D \macros
1408%D   {ruledmkern,ruledmskip}
1409%D
1410%D Mathematical kerns and skips are specified in mu. This
1411%D font related unit is incompatible with those of \DIMENSIONS\
1412%D and \SKIPS. Because in math mode spacing is often a very
1413%D subtle matter, we've used a very simple, not overloaded way
1414%D to show them.
1415
1416\def\supp_visualizers_mkern_finish#1%
1417  {\dontinterfere
1418   \dontcomplain
1419   \setbox\boxrulescratchbox\normalhbox
1420     {\normalstartimath
1421      \normalmkern\ifnegative-\fi\scratchskip
1422      \normalstopimath}%
1423   \setbox\boxrulescratchbox\normalhbox to \wd\boxrulescratchbox
1424     {\visualvrule
1425        \s!height16\testrulewidth
1426        \s!depth 16\testrulewidth
1427        \s!width   \testrulewidth
1428      \leaders
1429        \visualhrule
1430          \s!height\ifpositive 16\else-14\fi\testrulewidth
1431          \s!depth \ifpositive-14\else 16\fi\testrulewidth
1432        \normalhfill
1433      \ifflexible
1434        \normalhskip-\wd\boxrulescratchbox
1435        \leaders
1436          \visualhrule
1437            \s!height\testrulewidth
1438            \s!depth \testrulewidth
1439          \normalhfill
1440      \fi
1441      \visualvrule
1442        \s!height16\testrulewidth
1443        \s!depth 16\testrulewidth
1444        \s!width   \testrulewidth}%
1445   \smashbox0%
1446   \ifnegative
1447      #1\scratchskip
1448     \box\boxrulescratchbox
1449   \else
1450     \box\boxrulescratchbox
1451      #1\scratchskip
1452   \fi
1453   \egroup}
1454
1455%D \startbuffer
1456%D $a \mkern3mu = \mkern3mu
1457%D  b \quad
1458%D  \mkern-2mu + \mkern-2mu
1459%D  \quad c$
1460%D \stopbuffer
1461%D
1462%D \ShowBufferedExample
1463
1464\protected\def\ruledmkern
1465  {\bgroup
1466   \afterassignment\supp_visualizers_mkern_indeed
1467   \scratchmuskip=}
1468
1469\def\supp_visualizers_mkern_indeed
1470  {\investigatemuskip\scratchmuskip
1471   \flexiblefalse
1472   \supp_visualizers_mkern_finish\normalmkern}
1473
1474%D \startbuffer
1475%D $a \mskip3mu = \mskip3mu
1476%D  b \quad
1477%D  \mskip-2mu + \mskip-2mu
1478%D  \quad c$
1479%D \stopbuffer
1480%D
1481%D \ShowBufferedExample
1482
1483\def\supp_visualizers_mskip_indeed
1484  {\investigatemuskip\scratchmuskip
1485   \flexibletrue
1486   \supp_visualizers_mkern_finish\normalmskip}
1487
1488\protected\def\ruledmskip
1489  {\bgroup
1490   \afterassignment\supp_visualizers_mskip_indeed
1491   \scratchmuskip=}
1492
1493%D \macros
1494%D   {penalty}
1495%D
1496%D After presenting fills, skip, kerns and glue we've come to
1497%D see penalties. In the first implementation --- most of the
1498%D time needed to develop this set of macros went into testing
1499%D different types of visualization --- penalties were mere
1500%D small blocks with one black half, depending on the sign.
1501%D This most recent version also gives an indication of the
1502%D amount of penalty. Penalties can go from less than $-10000$
1503%D to over $+10000$, and their behavior is somewhat
1504%D non-lineair, with some values having special meanings. We
1505%D therefore decided not to use its value for a lineair
1506%D indicator.
1507%D
1508%D \startbuffer
1509%D one
1510%D \penalty +100
1511%D two
1512%D \penalty +100
1513%D \penalty -100
1514%D three
1515%D \penalty    0
1516%D four
1517%D \penalty +100
1518%D five
1519%D \stopbuffer
1520%D
1521%D \ShowBufferedExample
1522%D
1523%D The small sticks at the side of the penalty indicate it
1524%D size. The next example shows the positive and negative
1525%D penalties of 0, 1, 10, 100, 1000 and 10000.
1526%D
1527%D \startlinecorrection
1528%D \hbox
1529%D   {test \ruledhpenalty0
1530%D    test \ruledhpenalty1
1531%D    test \ruledhpenalty10
1532%D    test \ruledhpenalty100
1533%D    test \ruledhpenalty1000
1534%D    test \ruledhpenalty10000
1535%D    test}
1536%D \stoplinecorrection
1537%D
1538%D \blank
1539%D
1540%D \startlinecorrection
1541%D \hbox
1542%D   {test \ruledhpenalty0
1543%D    test \ruledhpenalty-1
1544%D    test \ruledhpenalty-10
1545%D    test \ruledhpenalty-100
1546%D    test \ruledhpenalty-1000
1547%D    test \ruledhpenalty-10000
1548%D    test}
1549%D \stoplinecorrection
1550%D
1551%D \blank
1552%D
1553%D This way stacked penalties of different severance can be
1554%D shown in combination.
1555%D
1556%D test \ruledhpenalty10 \ruledhpenalty100
1557%D test
1558%D test \ruledhpenalty1000 \ruledhpenalty-1000
1559%D test
1560
1561\def\supp_visualizers_penalty_box#1#2#3#4#5#6%
1562  {\setbox#1\normalhbox
1563     {\ifnum#2=\zerocount \else
1564        \edef\sign{\ifnum#2>\zerocount +\else-\fi}%
1565        \scratchdimen
1566          \ifnum\sign#2>9999 28\else
1567          \ifnum\sign#2>999  22\else
1568          \ifnum\sign#2>99   16\else
1569          \ifnum\sign#2>9    10\else
1570                              4\fi\fi\fi\fi \testrulewidth
1571        \ifnum#2<\zerocount
1572          \normalhskip-\scratchdimen
1573          \normalhskip-2\testrulewidth
1574          \visualvrule
1575            \s!width  2\testrulewidth
1576            \s!height#3\testrulewidth
1577            \s!depth #4\testrulewidth
1578        \fi
1579        \visualvrule
1580          \s!width \scratchdimen
1581          \s!height#5\testrulewidth
1582          \s!depth #6\testrulewidth
1583        \ifnum#2>\zerocount
1584          \visualvrule
1585            \s!width  2\testrulewidth
1586            \s!height#3\testrulewidth
1587            \s!depth #4\testrulewidth
1588         \fi
1589      \fi}%
1590   \smashbox#1}
1591
1592\protected\def\ruledhpenalty
1593  {\bgroup
1594   \afterassignment\supp_visualizers_hpenalty_indeed
1595   \scratchcounter=}
1596
1597\def\supp_visualizers_hpenalty_indeed
1598  {\dontinterfere
1599   \dontcomplain
1600   \investigatecount\scratchcounter
1601   \testrulewidth2\testrulewidth
1602   \boxrulewidth\testrulewidth
1603   \setbox0\ruledhbox to 8\testrulewidth
1604     {\ifnegative\else\normalhss\fi
1605      \visualvrule
1606        \s!depth8\testrulewidth
1607        \s!width\ifzero\zeropoint\else4\testrulewidth\fi
1608      \ifpositive\else\normalhss\fi}%
1609   \supp_visualizers_penalty_box{2}{\scratchcounter}{0}{8}{-3.5}{4.5}%
1610   \normalpenalty\plustenthousand
1611   \setbox0\normalhbox
1612     {\normalhskip-4\testrulewidth
1613      \ifnegative
1614        \box2\box0
1615      \else
1616        \box0\box2
1617      \fi}%
1618   \smashbox0%
1619   \box0
1620   \normalpenalty\scratchcounter
1621   \egroup}
1622
1623%D The size of a vertical penalty is also shown on the
1624%D horizontal axis. This way there is less interference with
1625%D the often preceding or following skips and kerns.
1626%D
1627%D \startbuffer
1628%D first line
1629%D \par \penalty +100
1630%D second line
1631%D \par \penalty +100
1632%D \par \penalty -100
1633%D third line
1634%D \par \penalty    0
1635%D fourth line
1636%D \par \penalty +100
1637%D fifth line
1638%D \stopbuffer
1639%D
1640%D \ShowBufferedExample
1641
1642\protected\def\ruledvpenalty
1643  {\bgroup
1644   \afterassignment\supp_visualizers_vpenalty_indeed
1645   \scratchcounter=}
1646
1647\def\supp_visualizers_vpenalty_indeed
1648  {\ifdim\pagegoal=\maxdimen \else
1649     \nextdepth\prevdepth
1650     \dontinterfere
1651     \dontcomplain
1652     \investigatecount\scratchcounter
1653     \testrulewidth2\testrulewidth
1654     \boxrulewidth\testrulewidth
1655     \setbox0\ruledhbox
1656       {\visualvrule
1657          \s!height4\testrulewidth
1658          \s!depth 4\testrulewidth
1659          \s!width  \zeropoint
1660        \visualvrule
1661          \s!height\ifnegative.5\else4\fi\testrulewidth
1662          \!!dept  \ifpositive.5\else4\fi\testrulewidth
1663          \s!width                      8\testrulewidth}%
1664     \supp_visualizers_penalty_box{2}{\scratchcounter}{4}{4}{.5}{.5}%
1665     \setbox0\normalhbox
1666       {\normalhskip-4\testrulewidth
1667        \ifnegative
1668          \box2\box0
1669        \else
1670          \box0\box2
1671        \fi
1672        \normalhss}%
1673     \smashbox0%
1674     \normalpenalty\plustenthousand
1675     \nointerlineskip
1676     \dp0\nextdepth  % not \prevdepth=\nextdepth
1677     \normalvbox
1678       {\normalvcue{\box0}}%
1679   \fi
1680   \normalpenalty\scratchcounter
1681   \egroup}
1682
1683%D This comes together in:
1684
1685\protected\def\ruledpenalty
1686  {\ifvmode
1687     \expandafter\ruledvpenalty
1688   \else
1689     \expandafter\ruledhpenalty
1690   \fi}
1691
1692%D \macros
1693%D   {showfils,dontshowfils,
1694%D    showboxes,dontshowboxes,
1695%D    showskips,dontshowskips,
1696%D    showpenalties,dontshowpenalties}
1697%D
1698%D For those who want to manipulate the visual cues in detail,
1699%D we have grouped them.
1700
1701\protected\def\showfils
1702  {\showingcompositiontrue
1703   \let\hss      \ruledhss
1704   \let\hfil     \ruledhfil
1705   \let\hfill    \ruledhfill
1706   \let\hfilneg  \ruledhfilneg
1707   \let\hfillneg \ruledhfillneg
1708   \let\vss      \ruledvss
1709   \let\vfil     \ruledvfil
1710   \let\vfill    \ruledvfill
1711   \let\vfilneg  \ruledvfilneg
1712   \let\vfillneg \ruledvfillneg}
1713
1714\protected\def\dontshowfils
1715  {\let\hss      \normalhss
1716   \let\hfil     \normalhfil
1717   \let\hfill    \normalhfill
1718   \let\hfilneg  \normalhfilneg
1719   \let\hfillneg \normalhfillneg
1720   \let\vss      \normalvss
1721   \let\vfil     \normalvfil
1722   \let\vfill    \normalvfill
1723   \let\vfilneg  \normalvfilneg
1724   \let\vfillneg \normalvfillneg}
1725
1726\protected\def\showboxes
1727  {\showingcompositiontrue
1728   \baselineruletrue
1729   \let\hbox     \ruledhbox
1730   \let\vbox     \ruledvbox
1731   \let\vtop     \ruledvtop
1732   \let\vcenter  \ruledvcenter}
1733
1734\protected\def\dontshowboxes
1735  {\let\hbox     \normalhbox
1736   \let\vbox     \normalvbox
1737   \let\vtop     \normalvtop
1738   \let\vcenter  \normalvcenter}
1739
1740\protected\def\showskips
1741  {\showingcompositiontrue
1742   \let\hskip    \ruledhskip
1743   \let\vskip    \ruledvskip
1744   \let\kern     \ruledkern
1745   \let\mskip    \ruledmskip
1746   \let\mkern    \ruledmkern
1747   \let\hglue    \ruledhglue
1748   \let\vglue    \ruledvglue}
1749
1750\protected\def\dontshowskips
1751  {\let\hskip    \normalhskip
1752   \let\vskip    \normalvskip
1753   \let\kern     \normalkern
1754   \let\mskip    \normalmskip
1755   \let\mkern    \normalmkern
1756   \let\hglue    \normalhglue
1757   \let\vglue    \normalvglue}
1758
1759\protected\def\showpenalties
1760  {\showingcompositiontrue
1761   \let\penalty  \ruledpenalty}
1762
1763\protected\def\dontshowpenalties
1764  {\let\penalty  \normalpenalty}
1765
1766%D \macros
1767%D   {showcomposition,dontshowcomposition,
1768%D    showingcomposition}
1769%D
1770%D All these nice options come together in three macros. One
1771%D for turning the options on, one for turning them off, and a
1772%D boolean for enabling the mechanism outside the scope of the
1773%D user. The first two macros only do their job when we are
1774%D actually showing the composition.
1775%D
1776%D \starttyping
1777%D \showingcompositiontrue
1778%D \showcomposition
1779%D \stoptyping
1780%D
1781%D Because the output routine can do tricky things, like
1782%D multiple column typesetting and manipulation of the
1783%D pagebody, shifting things around and so on, the macro
1784%D \type{\dontshowcomposition} best can be called when we enter
1785%D this routine. Too much visual cues just don't make sense. In
1786%D \CONTEXT\ this has been taken care of.
1787
1788\newif\ifshowingcomposition
1789
1790\protected\def\showcomposition
1791  {\ifshowingcomposition
1792     \showfils
1793     \showboxes
1794     \showskips
1795     \showpenalties
1796   \fi}
1797
1798\protected\def\dontshowcomposition
1799  {\ifshowingcomposition
1800     \dontshowfils
1801     \dontshowboxes
1802     \dontshowskips
1803     \dontshowpenalties
1804   \fi}
1805
1806%D \macros
1807%D   {showmakeup,
1808%D    defaulttestrulewidth}
1809%D
1810%D Just to make things even more easy, we have defined:
1811%D
1812%D \starttyping
1813%D \showmakeup
1814%D \stoptyping
1815%D
1816%D For the sake of those who don't (yet) use \CONTEXT\ we
1817%D preset \type{\defaulttestrulewidth} to the already set
1818%D value. Otherwise we default to a bodyfontsize related value.
1819%D
1820%D \starttyping
1821%D \def\defaulttestrulewidth{.2pt}
1822%D \stoptyping
1823%D
1824%D Beware, it's a macro not a \DIMENSION.
1825
1826\ifx\bodyfontsize\undefined
1827    \edef\defaulttestrulewidth{\the\testrulewidth}
1828\else
1829    \def\defaulttestrulewidth{.02\bodyfontsize}
1830\fi
1831
1832\protected\def\showmakeup
1833  {\testrulewidth\defaulttestrulewidth
1834   \showingcompositiontrue
1835   \showcomposition}
1836
1837\protect
1838
1839%D Lets end with some more advanced examples.
1840%D Definitions and enumerations come in many flavors. The
1841%D next one for instance is defined as:
1842%D
1843%D \starttyping
1844%D \definedescription[test][place=left,hang=3,width=6em]
1845%D \stoptyping
1846%D
1847%D When applied to some text, this would look like:
1848%D
1849%D \bgroup
1850%D \showmakeup
1851%D \definedescription[test][location=left,hang=3,width=6em]
1852%D
1853%D \test{visual\\debugger} I would be very pleased if \TEX\
1854%D had two more primitives: \type{\vnop} and \type{\hnop}. Both
1855%D should act and show up as normal boxes, but stay invisible
1856%D for \TEX\ when it's doing calculations. The \type{\vnop}
1857%D for instance should not interact with the internal mechanism
1858%D responsible for the disappearing skips, kerns and penalties
1859%D at a pagebreak. As long as we don't have these two boxtypes,
1860%D visual debugging will never be perfect.
1861%D
1862%D \egroup
1863%D
1864%D The index to this section looks like:
1865%D
1866%D {\setupreferencing[prefixprefix=dummy]\showmakeup\placeindex[criterium=local]}
1867%D
1868%D Although not impressive examples or typesetting, both
1869%D show us how and where things happen. When somehow the last
1870%D lines in this two column index don't allign, then this is
1871%D due to some still unknown interference.
1872
1873\endinput
1874