%D \module %D [ file=supp-vis, %D version=1996.10.21, %D title=\CONTEXT\ Support Macros, %D subtitle=Visualization, %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. \endinput %D This module is no longer generic \unknown\ but who cares. Maybe %D the code will be moved out of the core (apart from ruled boxes). %D \gdef\ShowBufferedExample% private typeseting macro %D {\startlinecorrection %D \bgroup %D \setuptyping[margin=0pt,option=color] %D \showmakeup %D \centeredvcuetrue %D \dontinterfere %D \baselinerulefalse %D \normalvbox %D {\normalhbox to \hsize %D {$\hsize=.5\hsize %D \advance\hsize by -.5em %D \normalvcenter{\vbox{\getbuffer}}\normalhss %D \normalvcenter{\vbox{\dontshowcomposition\typebuffer}}$}} %D \egroup %D \stoplinecorrection} %D %D \gdef\ShowBufferedExampleBox% private typeseting macro %D {\startlinecorrection %D \bgroup %D \setuptyping[margin=0pt,option=color] %D \showmakeup %D \centeredvcuetrue %D \dontinterfere %D \baselinerulefalse %D \normalvbox %D {\normalhbox to \hsize %D {$\hsize=.5\hsize %D \advance\hsize by -.5em %D \normalvcenter{\baselineruletrue\vbox{\getbuffer}}\normalhss %D \normalvcenter{\vbox{\dontshowcomposition\typebuffer}}$}} %D \egroup %D \stoplinecorrection} %D Depending on my personal needs and those of whoever uses it, %D the macros will be improved in terms of visualization, %D efficiency and compatibility. These rather low level %D visualization macros are supplemented by ones that can %D visualize baselines, the page layout and whatever deserves %D attention. Most of those macros can be found in \type %D {core-vis} and other core modules. Their integration in %D \CONTEXT\ prohibits generic applications. %D %D We no longer assume usage outside context so we no longer %D load support modules. %D %D One of the strong points of \TEX\ is abstraction of textual %D input. When macros are defined well and do what we %D want them to do, we will seldom need the tools present in %D What You See Is What You Get systems. For instance, when %D entering text we don't need rulers, because no manual %D shifting and/or alignment of text is needed. On the other %D hand, when we are designing macros or specifying layout %D elements, some insight in \TEX's advanced spacing, kerning, %D filling, boxing and punishment abilities will be handy. %D That's why we've implemented a mechanism that shows some of %D the inner secrets of \TEX. \writestatus{loading}{ConTeXt Support Macros / Visualization} %D In this module we are going to redefine some \TEX\ %D primitives and \PLAIN\ macro's. Their original meaning is %D saved in macros with corresponding names, preceded by %D \type{normal}. These original macros are (1)~used to %D temporary restore the old values when needed and %D (2)~used to prevent recursive calls in the macros that %D replace them. \unprotect \let\visualvrule\vrule \let\visualhrule\hrule %D \macros %D {dontinterfere} %D %D Indentation, left and/or right skips, redefinition of %D \type{\par} and assignments to \type{\everypar} can lead to %D unwanted results. We can therefore turn all those things %D off with \type{\dontinterfere}. \unexpanded\def\dontinterfere % or maybe just forgetall {\reseteverypar \parindent\zeropoint \parskip \zeropoint \leftskip \zeropoint \rightskip\zeropoint \relax} %D \macros %D {dontcomplain} %D %D In this module we do a lot of box manipulations. Because we %D don't want to be confronted with to many over- and underfull %D messages we introduce \type{\dontcomplain}. \ifdefined\dontcomplain \else \unexpanded\def\dontcomplain {\hbadness\plustenthousand \vbadness\plustenthousand \hfuzz \maxdimen \vfuzz \maxdimen} \fi %D \macros %D {normaloffinterlineskip} %D %D The next hack is needed because in \CONTEXT\ we redefine %D \type{\offinterlineskip}. \ifdefined\normaloffinterlineskip \else \let\normaloffinterlineskip\offinterlineskip \fi %D \macros %D {normalhbox, %D normalvbox,normalvtop} %D %D There are three types of boxes, one horizontal and two %D vertical in nature. As we will see later on, all three types %D are to be handled according to their orientation and %D baseline behavior. Especially \type{\vtop}'s need our %D special attention. %D \macros %D {normalhskip, %D normalvskip} %D %D Next come the flexible skips, which come in two flavors %D too. Like boxes these are handled with \TEX\ primitives. %D \macros %D {normalpenalty, %D normalkern} %D %D Both penalties and kerns are taken care of by mode sensitive %D primitives. This means that when making them visible, we %D have to take the current mode into account. %D \macros %D {normalhglue, %D normalvglue} %D %D Glues on the other hand are macro's defined in \PLAIN\ \TEX. %D As we will see, their definitions make the implementation of %D their visible counterparts a bit more \TeX{}nical. \let\normalhglue\hglue \let\normalvglue\vglue %D \macros %D {normalmkern, %D normalmskip} %D %D Math mode has its own spacing primitives, preceded by %D \type{m}. Due to the relation with the current font and the %D way math is typeset, their unit \type{mu} is not compatible %D with other dimensions. As a result, the visual appearance %D of these primitives is kept primitive too. %D \macros %D {hfilneg, %D vfilneg} %D %D Fills can be made visible quite easy. We only need some %D additional negation macros. Because \PLAIN\ \TEX\ only %D offers \type{\hfilneg} and \type{\vfilneg}, we define our %D own alternative double \type{ll}'ed ones. \def\hfilneg {\normalhskip\zeropoint\s!plus-1\s!fil\relax} \def\vfilneg {\normalvskip\zeropoint\s!plus-1\s!fil\relax} \def\hfillneg {\normalhskip\zeropoint\s!plus-1\s!fill\relax} \def\vfillneg {\normalvskip\zeropoint\s!plus-1\s!fill\relax} \def\hfilllneg{\normalhskip\zeropoint\s!plus-1\s!filll\relax} \def\vfilllneg{\normalvskip\zeropoint\s!plus-1\s!filll\relax} %D \macros %D {normalhss,normalhfil,normalhfill, %D normalvss,normalvfil,normalvfill} %D %D The positive stretch primitives are used independant and in %D combination with \type{\leaders}. % already saved %D \macros %D {normalhfilneg,normalhfillneg, %D normalvfilneg,normalvfillneg} %D %D Keep in mind that both \type{\hfillneg} and \type{\vfillneg} %D are not part of \PLAIN\ \TEX\ and therefore not documented %D in standard \TEX\ documentation. They can nevertheless be %D used at will. \let\normalhfillneg\hfillneg \let\normalvfillneg\vfillneg %D Visualization is not always wanted. Instead of turning this %D option off in those (unpredictable) situations, we just %D redefine a few \PLAIN\ macros. % \ifx\tlap\undefined % % \def\rlap#1{\normalhbox to \zeropoint{#1\normalhss}} % \def\llap#1{\normalhbox to \zeropoint{\normalhss#1}} % \def\blap#1{\normalvbox to \zeropoint{#1\normalvss}} % \def\tlap#1{\normalvbox to \zeropoint{\normalvss#1}} % % \fi %D \macros %D {makeruledbox} %D %D Ruled boxes can be typeset is many ways. Here we present %D just one alternative. This implementation may be a little %D complicated, but it supports all three kind of boxes. The %D next command expects a \BOX\ specification, like: %D %D \starttyping %D \makeruledbox0 %D \stoptyping %D \macros %D {baselinerule,baselinefill} %D %D We can make the baseline of a box visible, both dashed and %D as a rule. The line is drawn on top of the baseline. All %D we have to say is: %D %D \starttyping %D \baselineruletrue %D \baselinefilltrue %D \stoptyping %D %D At the cost of some overhead these alternatives are %D implemented using \type{\if}'s: \newif\ifbaselinerule\baselineruletrue \newif\ifbaselinefill\baselinefillfalse %D \macros %D {iftoprule,ifbottomrule,ifleftrule,ifrightrule} %D %D Rules can be turned on and off, but by default we have: %D %D \starttyping %D \topruletrue %D \bottomruletrue %D \leftruletrue %D \rightruletrue %D \stoptyping %D %D As we see below: \newif\iftoprule \topruletrue \newif\ifbottomrule\bottomruletrue \newif\ifleftrule \leftruletrue \newif\ifrightrule \rightruletrue %D \macros %D {boxrulewidth} %D %D The width in the surrounding rules can be specified by %D assigning an apropriate value to the dimension used. This %D module defaults the width to: %D %D \starttyping %D \boxrulewidth=.2pt %D \stoptyping \newdimen \boxrulewidth \boxrulewidth=.2pt \newdimen \boxruleht \newdimen \boxruledp \newdimen \boxrulewd \newbox \boxrulescratchbox %D The core macro \type{\makeruledbox} looks a bit hefty. The %D manipulation at the end is needed because we want to %D preserve both the mode and the baseline. This means that %D \type{\vtop}'s and \type{\vbox}'es behave the way we expect %D them to do. %D %D \startlinecorrection %D \hbox %D {\ruledhbox to 5em{\strut test\normalhss}\hskip1em %D \ruledvbox{\hsize 5em\strut test \par test\strut}\hskip1em %D \ruledvtop{\hsize 5em\strut test \par test\strut}} %D \stoplinecorrection %D %D The \type{\cleaders} part of the macro is responsible for %D the visual baseline. The \type{\normalhfill} belongs to this %D primitive too. By storing and restoring the height and depth %D of box \type{#1}, we preserve the mode. \let\dowithruledbox\relax % hook \unexpanded\def\makeruledbox#1% {\boxruleht\ht#1% \boxruledp\dp#1% \boxrulewd\wd#1% \setbox\boxrulescratchbox\normalvbox {\dontcomplain \normaloffinterlineskip \visualhrule \s!height\boxrulewidth \iftoprule\else\s!width\zeropoint\fi \normalvskip-\boxrulewidth \normalhbox to \boxrulewd {\visualvrule \s!height\boxruleht \s!depth \boxruledp \s!width \ifleftrule\boxrulewidth\else\zeropoint\fi \ifdim\boxruleht>\zeropoint \else \baselinerulefalse \fi \ifdim\boxruledp>\zeropoint \else \baselinerulefalse \fi \ifbaselinerule \ifdim\boxrulewd<20\boxrulewidth \baselinefilltrue \fi \cleaders \ifbaselinefill \visualhrule \s!height\boxrulewidth \else \normalhbox {\normalhskip2.5\boxrulewidth \visualvrule \s!height\boxrulewidth \s!width5\boxrulewidth \normalhskip2.5\boxrulewidth}% \fi \fi \normalhfill \visualvrule \s!width\ifrightrule\boxrulewidth\else\zeropoint\fi}% \normalvskip-\boxrulewidth \visualhrule \s!height\boxrulewidth \ifbottomrule\else\s!width\zeropoint\fi}% \wd#1\zeropoint \setbox#1=\ifhbox#1\normalhbox\else\normalvbox\fi {\normalhbox {\box#1% \lower\boxruledp\normalhbox{\dowithruledbox{\box\boxrulescratchbox}}}}% \ht#1\boxruleht \wd#1\boxrulewd \dp#1\boxruledp} %D Just in case one didn't notice: the rules are in fact layed %D over the box. This way the contents of a box cannot %D visually interfere with the rules around (upon) it. A more %D advanced version of ruled boxes can be found in one of the %D core modules of \CONTEXT. There we take offsets, color, %D rounded corners, backgrounds and alignment into account too. %D \macros %D {ruledhbox, %D ruledvbox,ruledvtop, %D ruledvcenter} %D %D These macro's can be used instead of \type{\hbox}, %D \type{\vbox}, \type{\vtop} and, when in math mode, %D \type{\vcenter}. They just do what their names state. Using %D an auxiliary macro would save us a few words of memory, but %D it would make their appearance even more obscure. %D %D \startbuffer %D \hbox %D {\strut %D one %D two %D \hbox{three} %D four %D five} %D \stopbuffer %D %D \ShowBufferedExampleBox \unexpanded\def\ruledhbox {\normalhbox\bgroup \dowithnextboxcs\supp_visualizers_hbox_finish\normalhbox} \def\supp_visualizers_hbox_finish {\makeruledbox\nextbox \box\nextbox \egroup} %D \startbuffer %D \vbox %D {\strut %D first line \par %D second line \par %D third line \par %D fourth line \par %D fifth line %D \strut } %D \stopbuffer %D %D \ShowBufferedExampleBox \unexpanded\def\ruledvbox {\normalvbox\bgroup \dowithnextboxcs\supp_visualizers_vbox_finish\normalvbox} \def\supp_visualizers_vbox_finish {\makeruledbox\nextbox \box\nextbox \egroup} %D \startbuffer %D \vtop %D {\strut %D first line \par %D second line \par %D third line \par %D fourth line \par %D fifth line %D \strut } %D \stopbuffer %D %D \ShowBufferedExampleBox \unexpanded\def\ruledvtop {\normalvtop\bgroup \dowithnextboxcs\supp_visualizers_vtop_finish\normalvtop} \def\supp_visualizers_vtop_finish {\makeruledbox\nextbox \box\nextbox \egroup} %D \startbuffer %D \hbox %D {$\vcenter{\hsize.2\hsize %D alfa \par beta}$ %D $\vcenter to 3cm{\hsize.2\hsize %D alfa \par beta \par gamma}$ %D $\vcenter{\hsize.2\hsize %D alfa \par beta}$} %D \stopbuffer %D %D \ShowBufferedExampleBox \unexpanded\def\ruledvcenter {\normalvbox\bgroup \dontinterfere \dowithnextboxcs\supp_visualizers_vcenter_finish\normalvbox} \def\supp_visualizers_vcenter_finish {\scratchdimen.5\dimexpr\ht\nextbox+\dp\nextbox\relax \ht\nextbox\scratchdimen \dp\nextbox\scratchdimen %\ruledhbox{\box\nextbox}% \makeruledbox\nextbox \box\nextbox \egroup} %D \macros %D {ruledbox, %D setruledbox} %D %D Of the next two macros the first can be used to precede a %D box of ones own choice. One can for instance prefix boxes %D with \type{\ruledbox} and afterwards --- when the macro %D satisfy the needs --- let it to \type{\relax}. %D %D \starttyping %D \ruledbox\hbox{What rules do you mean?} %D \stoptyping %D %D The macro \type{\setruledbox} can be used to directly %D rule a box. %D %D \starttyping %D \setruledbox12=\hbox{Who's talking about rules here?} %D \stoptyping %D %D At the cost of some extra macros we can implement a %D variant that does not need the~\type{=}, but we stick to: \unexpanded\def\ruledbox {\dowithnextboxcs\supp_visualizers_box_finish} \def\supp_visualizers_box_finish {\makeruledbox\nextbox\box\nextbox} % \def\setruledbox#1=% % {\dowithnextbox{\makeruledbox\nextbox\setbox#1\nextbox}} \def\setruledbox#1=% not nice, better {\afterassignment\supp_visualizers_setruledbox_indeed\scratchcounter} \def\supp_visualizers_setruledbox_indeed {\dowithnextboxcs\supp_visualizers_setruledbox_finish} \def\supp_visualizers_setruledbox_finish {\makeruledbox\nextbox \setbox\scratchcounter\nextbox} %D \macros %D {investigateskip, %D investigatecount, %D investigatemuskip} %D %D Before we meet the visualizing macro's, we first implement %D ourselves some handy utility ones. Just for the sake of %D efficiency and readability, we introduce some status %D variables, that tell us a bit more about the registers we %D use: %D %D \starttyping %D \ifflexible %D \ifzero %D \ifnegative %D \ifpositive %D \stoptyping %D %D These status variables are set when we call for one of the %D investigation macros, e.g. %D %D \starttyping %D \investigateskip\scratchskip %D \stoptyping %D %D We use some dirty trick to check stretchability of \SKIPS. %D Users of these macros are invited to study their exact %D behavior first. The positive and negative states both %D include zero and are in fact non-negative ($\geq0$) and %D non-positive ($\leq0$). Well, no dirty trick is needed %D any longer as we have \ETEX\ functionality. \newif\ifflexible \newif\ifzero \newif\ifnegative \newif\ifpositive \def\investigateskip#1% {\relax \ifdim#1=\zeropoint \ifdim\gluestretch#1=\zeropoint \ifdim\glueshrink#1=\zeropoint \flexiblefalse \else \flexibletrue \fi \else \flexibletrue \fi \else \flexibletrue \fi \ifdim#1=\zeropoint\relax \zerotrue \else \zerofalse \fi \ifdim#1<\zeropoint\relax \positivefalse \else \positivetrue \fi \ifdim#1>\zeropoint\relax \negativefalse \else \negativetrue \fi} \def\investigatecount#1% {\relax \flexiblefalse \ifnum#1=\zerocount \zerotrue \else \zerofalse \fi \ifnum#1<\zerocount \positivefalse \else \positivetrue \fi \ifnum#1>\zerocount \negativefalse \else \negativetrue \fi} \def\investigatemuskip#1% etex ? {\relax \edef\!!stringa{\the#1}% \edef\!!stringb{0mu}% \def\!!stringc##1##2\\{##1}% \expandafter\edef\expandafter\!!stringc\expandafter {\expandafter\!!stringc\!!stringa\\}% \edef\!!stringd{-}% \flexiblefalse \ifx\!!stringa\!!stringb \zerotrue \negativefalse \positivefalse \else \zerofalse \ifx\!!stringc\!!stringd \positivefalse \negativetrue \else \positivetrue \negativefalse \fi \fi} %D Now the neccessary utility macros are defined, we can make a %D start with the visualizing ones. The implementation of these %D macros is a compromise between readability, efficiency of %D coding and processing speed. Sometimes we do in steps what %D could have been done in combination, sometimes we use a few %D boxes more or less then actually needed, and more than once %D one can find the same piece of rule drawing code twice. %D \macros %D {ifcenteredvcue,normalvcue} %D %D Depending on the context, one can force visual vertical cues %D being centered along \type{\hsize} or being put at the %D current position. Although centering often looks better, %D we've chosen the second alternative as default. The main %D reason for doing so is that often when we don't set the %D \type{\hsize} ourselves, \TEX\ takes the value of the %D surrounding box. As a result the visual cues can migrate %D outside the current context. %D %D This behavior is accomplished by a small but effective %D auxiliary macro, which behavior can be influenced by the %D boolean \type{\centeredvcue}. By saying %D %D \starttyping %D \centeredvcuetrue %D \stoptyping %D %D one turns centering on. As said, we turn it off. \newif\ifcenteredvcue \centeredvcuefalse \def\normalvcue#1% {\normalhbox \ifcenteredvcue to \hsize \fi {\normalhss#1\normalhss}} %D We could have used the more robust version %D %D \starttyping %D \def\normalvcue% %D {\normalhbox \ifcenteredvcue to \hsize \fi %D \bgroup\bgroup\normalhss %D \aftergroup\normalhss\aftergroup\egroup %D \let\next=} %D \stoptyping %D %D or the probably best one: %D %D \starttyping %D \def\normalvcue% %D {\hbox \ifcenteredvcue to \hsize %D \bgroup\bgroup\normalhss %D \aftergroup\normalhss\aftergroup\egroup %D \else %D \bgroup %D \fi %D \let\next=} %D \stoptyping %D %D Because we don't have to preserve \CATCODES\ and only use %D small arguments, we stick to the first alternative. %D \macros %D {testrulewidth} %D %D We build our visual cues out of rules. At the cost of a much %D bigger \DVI\ file, this is to be prefered over using %D characters (1)~because we cannot be sure of their %D availability and (2)~because their dimensions are fixed. %D %D As with ruled boxes, we use a \DIMENSION\ to specify the %D width of the ruled elements. This dimension defaults to: %D %D \starttyping %D \testrulewidth=\boxrulewidth %D \stoptyping %D %D Because we prefer whole numbers for specifying the %D dimensions, we often use even multiples of %D \type{\testrulewidth}. %D \macros %D {visiblestretch} %D %D A second variable is introduced because of the stretch %D components of \SKIPS. At the cost of some accuracy we can %D make this stretch visible. %D %D \starttyping %D \visiblestretchtrue %D \stoptyping \newdimen\testrulewidth \testrulewidth=\boxrulewidth \newif\ifvisiblestretch \visiblestretchfalse %D \macros %D {ruledhss, %D ruledhfil,ruledhfilneg, %D ruledhfill,ruledhfillneg} %D %D We start with the easiest part, the fills. The scheme we %D follow is {\em visual filling -- going back -- normal %D filling}. Visualizing is implemented using \type{\cleaders}. %D Because the \BOX\ that follows this command is constructed %D only once, the \type{\copy} is not really a prerequisite. We %D prefer using a \type{\normalhbox} here instead of a %D \type{\hbox}. \def\setvisiblehfilbox#1\to#2#3#4% {\setbox#1\normalhbox {\visualvrule \s!width #2\testrulewidth \s!height#3\testrulewidth \s!depth #4\testrulewidth}% \smashbox#1} \def\doruledhfiller#1#2#3#4% {#1#2% \bgroup \dontinterfere \dontcomplain \setvisiblehfilbox0\to{4}{#3}{#4}% \setvisiblehfilbox2\to422% \copy0\copy2 \bgroup \setvisiblehfilbox0\to422% \cleaders \normalhbox to 12\testrulewidth {\normalhss\copy0\normalhss}% #1% \egroup \setbox0\normalhbox {\normalhskip-4\testrulewidth\copy0\copy2}% \smashbox0% \box0 \egroup} %D The horizontal fillers differ in their boundary %D visualization. Watch the small dots. Fillers can be %D combined within reasonable margins. %D %D \startlinecorrection %D \baselinerulefalse %D \ruledhbox to \hsize %D {\strut\type{\hss}\ruledhss test} %D \stoplinecorrection %D %D \startlinecorrection %D \baselinerulefalse %D \ruledhbox to \hsize %D {\strut\type{\hfil}\ruledhfil test} %D \stoplinecorrection %D %D \startlinecorrection %D \baselinerulefalse %D \ruledhbox to \hsize %D {\strut\type{\hfill}\ruledhfill test} %D \stoplinecorrection %D %D \startlinecorrection %D \baselinerulefalse %D \ruledhbox to \hsize %D {\strut %D \type{\hfil}\type{\hfil}\ruledhfil\ruledhfil %D test% %D \ruledhfil\type{\hfil}} %D \stoplinecorrection %D %D The negative counterparts are visualizes, but seldom %D become visible, apart from their boundaries. %D %D \startlinecorrection %D \baselinerulefalse %D \ruledhbox to \hsize %D {\strut\type{\hfilneg}\ruledhfilneg test} %D \stoplinecorrection %D %D \startlinecorrection %D \baselinerulefalse %D \ruledhbox to \hsize %D {\strut\type{\hfillneg}\ruledhfillneg test} %D \stoplinecorrection %D %D Although leaders are used for visualizing, they are %D visualized themselves correctly as the next example shows. %D %D \startlinecorrection %D \baselinerulefalse %D \ruledhbox to \hsize %D {\strut\cleaders\normalhbox to 2em{\normalhss$\circ$\normalhss}\ruledhfill} %D \stoplinecorrection %D %D All five substitutions use the same auxiliary macro. Watch %D the positive first -- negative next approach. \unexpanded\def\ruledhss {\doruledhfiller\normalhss \normalhfilneg {0}{0}} \unexpanded\def\ruledhfil {\doruledhfiller\normalhfil \normalhfilneg {10}{-6}} \unexpanded\def\ruledhfill {\doruledhfiller\normalhfill \normalhfillneg{18}{-14}} \unexpanded\def\ruledhfilneg {\doruledhfiller\normalhfilneg \normalhfil {-6}{10}} \unexpanded\def\ruledhfillneg{\doruledhfiller\normalhfillneg\normalhfill {-14}{18}} %D \macros %D {ruledvss, %D ruledvfil,ruledvfilneg, %D ruledvfill,ruledvfillneg} %D %D The vertical mode commands adopt the same visualization %D scheme, but are implemented in a slightly different way. \def\setvisiblevfilbox#1\to#2#3#4% {\setbox#1\normalhbox {\visualvrule \s!width #2\testrulewidth \s!height#3\testrulewidth \s!depth #4\testrulewidth}% \smashbox#1}% \def\doruledvfiller#1#2#3% {#1#2% \bgroup \dontinterfere \dontcomplain \normaloffinterlineskip \setvisiblevfilbox0\to422% \setbox2\normalvcue {\normalhskip -#3\testrulewidth\copy0}% \smashbox2% \copy2 \bgroup \setbox2\normalvcue {\normalhskip -2\testrulewidth\copy0}% \smashbox2% \copy2 \cleaders \normalvbox to 12\testrulewidth {\normalvss\copy2\normalvss}% #1% \setbox2\normalvbox {\normalvskip-2\testrulewidth\copy2}% \smashbox2% \box2 \egroup \box2 \egroup} %D Because they act the same as their horizontal counterparts %D we only show a few examples. %D %D \startlinecorrection %D \hbox to \hsize %D {\dontinterfere %D \baselinerulefalse %D \centeredvcuetrue %D \ruledvbox to 10ex %D {\hsize.18\hsize %D \type{\vss}\ruledvss last line}\normalhss %D \ruledvbox to 10ex %D {\hsize.18\hsize %D \type{\vfil}\ruledvfil last line}\normalhss %D \ruledvbox to 10ex %D {\hsize.18\hsize %D \type{\vfill}\ruledvfill last line}\normalhss %D \ruledvbox to 10ex %D {\hsize.18\hsize %D \type{\vfilneg}\ruledvfilneg last line}\normalhss %D \ruledvbox to 10ex %D {\hsize.18\hsize %D \type{\vfillneg}\ruledvfillneg last line}} %D \stoplinecorrection %D %D Keep in mind that \type{\vfillneg} is not part of \PLAIN\ %D \TEX, but are mimmicked by a macro. \unexpanded\def\ruledvss {\doruledvfiller\normalvss \normalvfilneg {2}} \unexpanded\def\ruledvfil {\doruledvfiller\normalvfil \normalvfilneg {-4}} \unexpanded\def\ruledvfill {\doruledvfiller\normalvfill \normalvfillneg{-12}} \unexpanded\def\ruledvfilneg {\doruledvfiller\normalvfilneg \normalvfil {8}} \unexpanded\def\ruledvfillneg{\doruledvfiller\normalvfillneg\normalvfill {16}} %D \macros %D {ruledhskip} %D %D Skips differ from kerns in two important aspects: %D %D \startitemize[packed] %D \item line and pagebreaks are allowed at a skip %D \item skips can have a positive and/or negative %D stretchcomponent %D \stopitemize %D %D Stated a bit different: kerns are fixed skips at which no %D line or pagebreak can occur. Because skips have a more open %D character, they are visualized in a open way. %D %D \startbuffer %D one %D \hskip +30pt plus 5pt %D two %D \hskip +30pt %D \hskip -10pt plus 5pt %D three %D \hskip 0pt %D four %D \hskip +30pt %D five %D \stopbuffer %D %D \ShowBufferedExample %D %D When skips have a stretch component, this is visualized by %D means of a dashed line. Positive skips are on top of the %D baseline, negative ones are below it. This way we can show %D the combined results. An alternative visualization of %D stretch could be drawing the mid line over a length of the %D stretch, in positive or negative direction. \def\supp_visualizers_hskip_indeed {\relax \dontinterfere \dontcomplain \investigateskip\scratchskip \ifzero \setbox0\normalhbox {\normalhskip-\testrulewidth \visualvrule \s!width4\testrulewidth \s!height16\testrulewidth \s!depth16\testrulewidth}% \else \setbox0\normalhbox to \ifnegative-\fi\scratchskip {\visualvrule \s!width2\testrulewidth \ifnegative\s!depth\else\s!height\fi16\testrulewidth \cleaders \visualhrule \ifnegative \s!depth2\testrulewidth \s!height\zeropoint \else \s!height2\testrulewidth \s!depth\zeropoint \fi \normalhfill \ifflexible \normalhskip\ifnegative\else-\fi\scratchskip \normalhskip2\testrulewidth \cleaders \normalhbox {\normalhskip 2\testrulewidth \visualvrule \s!width2\testrulewidth \s!height\ifnegative-7\else9\fi\testrulewidth \s!depth\ifnegative9\else-7\fi\testrulewidth \normalhskip 2\testrulewidth}% \normalhfill \fi \visualvrule \s!width2\testrulewidth \ifnegative\s!depth\else\s!height\fi16\testrulewidth}% \setbox0\normalhbox {\ifnegative\else\normalhskip-\scratchskip\fi \box0}% \fi \smashbox0% \ifvisiblestretch \else \flexiblefalse \fi \ifflexible % breaks ok but small displacements can occur \skip2\scratchskip \advance\skip2 -1\scratchskip \divide\skip2 2 \advance\scratchskip -\skip2 \normalhskip\scratchskip \normalpenalty\plustenthousand \box0 \normalhskip\skip2 \else \normalhskip\scratchskip \box0 \fi \egroup} \unexpanded\def\ruledhskip {\bgroup \afterassignment\supp_visualizers_hskip_indeed \scratchskip=} %D The visual skip is located at a feasible point. Normally %D this does not interfere with the normaltypesetting process. %D The next examples show (1)~the default behavior, (2)~the %D (not entirely correct) distributed stretch and (3)~the way %D the text is typeset without cues. %D %D \startbuffer %D \dorecurse %D {15} %D {test\hskip1em plus .5em minus .5em %D test\hskip2em %D test} %D \stopbuffer %D %D \startlinecorrection %D \showmakeup %D \getbuffer %D \stoplinecorrection %D %D \startlinecorrection %D \showmakeup %D \visiblestretchtrue %D \getbuffer %D \stoplinecorrection %D %D \startlinecorrection %D \getbuffer %D \stoplinecorrection %D \macros %D {ruledvskip} %D %D We are less fortunate when implementing the vertical skips. %D This is a direct result of interference between the boxes that %D visualize the skip and skip removal at a pagebreak. Normally %D skips disappear at the top of a page, but not of course when %D visualized in a \type{\vbox}. A quite perfect simulation %D could have been built if we would have had available two %D more primitives: \type{\hnop} and \type{\vnop}. These new %D primitives could stand for boxes that are visible but are %D not taken into account in any way. They are there for us, %D but not for \TEX. %D %D \startbuffer %D first line %D \vskip +30pt plus 5pt %D second line %D \vskip +30pt %D \vskip -10pt plus 5pt %D third line %D \par %D fourth line %D \vskip +30pt %D fifth line %D \vskip 0pt %D sixth line %D \stopbuffer %D %D \ShowBufferedExample %D %D We have to postpone \type{\prevdepth}. Although this %D precaution probably is not completely waterproof, it works %D quite well. \def\dodoruledvskip {\nextdepth\prevdepth \dontinterfere \dontcomplain \normaloffinterlineskip \investigateskip\scratchskip \ifzero \setbox0\normalvcue {\visualvrule \s!width32\testrulewidth \s!height2\testrulewidth \s!depth2\testrulewidth}% \else \setbox0\normalvbox to \ifnegative-\fi\scratchskip {\visualhrule \s!width16\testrulewidth \s!height2\testrulewidth \ifflexible \cleaders \normalhbox to 16\testrulewidth {\normalhss \normalvbox {\normalvskip 2\testrulewidth \visualhrule \s!width2\testrulewidth \s!height2\testrulewidth \normalvskip 2\testrulewidth}% \normalhss}% \normalvfill \else \normalvfill \fi \visualhrule \s!width16\testrulewidth \s!height2\testrulewidth}% \setbox2\normalvbox to \ht0 {\visualhrule \s!width2\testrulewidth \s!height\ht0}% \ifnegative \ht0\zeropoint \setbox0\normalhbox {\normalhskip2\testrulewidth % will be improved \normalhskip-\wd0\box0}% \fi \smashbox0% \smashbox2% \setbox0\normalvcue {\box2\box0}% \setbox0\normalvbox {\ifnegative\normalvskip\scratchskip\fi\box0}% \smashbox0% \fi \ifvisiblestretch \ifflexible \skip2\scratchskip \advance\skip2 -1\scratchskip \divide\skip2 2 \advance\scratchskip -\skip2 \normalvskip\skip2 \fi \fi \normalpenalty\plustenthousand \box0 \prevdepth\nextdepth % not \dp0=\nextdepth \normalvskip\scratchskip} %D We try to avoid interfering at the top of a page. Of course %D we only do so when we are in the main vertical list. \def\doruledvskip {\endgraf % \par \ifdim\pagegoal=\maxdimen \ifinner \dodoruledvskip \fi \else \dodoruledvskip \fi \egroup} \unexpanded\def\ruledvskip {\bgroup \afterassignment\doruledvskip \scratchskip=} %D \macros %D {ruledkern} %D %D The macros that implement the kerns are a bit more %D complicated than needed, because they also serve the %D visualization of glue, our \PLAIN\ defined kerns with %D stretch or shrink. We've implemented both horizontal and %D vertical kerns as ruled boxes. %D %D \startbuffer %D one %D \kern +30pt %D two %D \kern +30pt %D \kern -10pt %D three %D \kern 0pt %D four %D \kern +30pt %D five %D \stopbuffer %D %D \ShowBufferedExample %D %D Positive and negative kerns are placed on top or below the %D baseline, so we are able to track their added result. We %D didn't mention spacings of 0~pt yet. Zero values are %D visualized a bit different, because we want to see them %D anyhow. \def\supp_visualizers_hkern_indeed {\dontinterfere \dontcomplain \baselinerulefalse \investigateskip\scratchskip \boxrulewidth2\testrulewidth \ifzero \setbox0\ruledhbox to 8\testrulewidth {\visualvrule \s!width\zeropoint \s!height16\testrulewidth \s!depth16\testrulewidth}% \setbox0\normalhbox {\normalhskip-4\testrulewidth\box0}% \else \setbox0\ruledhbox to \ifnegative-\fi\scratchskip {\visualvrule \s!width\zeropoint \ifnegative\s!depth\else\s!height\fi16\testrulewidth \ifflexible \normalhskip2\testrulewidth \cleaders \normalhbox {\normalhskip 2\testrulewidth \visualvrule \s!width2\testrulewidth \s!height\ifnegative-7\else9\fi\testrulewidth \s!depth\ifnegative9\else-7\fi\testrulewidth \normalhskip 2\testrulewidth}% \normalhfill \else \normalhfill \fi}% \testrulewidth2\testrulewidth \setbox0\ruledhbox{\box0}% \make... \fi \smashbox0% \normalpenalty\plustenthousand \normalhbox to \zeropoint {\ifnegative\normalhskip1\scratchskip\fi \box0}% \afterwards\scratchskip \egroup} \unexpanded\def\ruledhkern#1% {\bgroup \let\afterwards#1% \afterassignment\supp_visualizers_hkern_indeed \scratchskip=} %D After having seen the horizontal ones, the vertical kerns %D will not surprise us. In this example we use \type{\par} to %D switch to vertical mode. %D %D \startbuffer %D first line %D \par \kern +30pt %D second line %D \par \kern +30pt %D \par \kern -10pt %D third line %D \par %D fourth line %D \par \kern +30pt %D fifth line %D \par \kern 0pt %D sixth line %D \stopbuffer %D %D \ShowBufferedExample %D %D Like before, we have to postpone \type{\prevdepth}. If we %D leave out this trick, we got ourselves some wrong spacing. \def\supp_visualizers_vkern_finish {\nextdepth\prevdepth \dontinterfere \dontcomplain \baselinerulefalse \normaloffinterlineskip \investigateskip\scratchskip \boxrulewidth2\testrulewidth \ifzero \setbox0\ruledhbox to 32\testrulewidth {\visualvrule \s!width\zeropoint \s!height4\testrulewidth \s!depth4\testrulewidth}% \else \setbox0\ruledvbox to \ifnegative-\fi\scratchskip {\hsize16\testrulewidth \ifflexible \cleaders \normalhbox to 16\testrulewidth {\normalhss \normalvbox {\normalvskip 2\testrulewidth \visualhrule \s!width2\testrulewidth \s!height2\testrulewidth \normalvskip 2\testrulewidth}% \normalhss}% \normalvfill \else \visualvrule \s!width\zeropoint \s!height\ifnegative-\fi\scratchskip \normalhfill \fi} \fi \testrulewidth2\testrulewidth \setbox0\ruledvbox{\box0}% \make... \smashbox0% \setbox0\normalvbox {\ifnegative\normalvskip\scratchskip\fi \normalvcue {\ifnegative\normalhskip-16\testrulewidth\fi\box0}}% \smashbox0% \normalpenalty\plustenthousand \box0 \prevdepth\nextdepth} % not \dp0=\nextdepth \def\supp_visualizers_vkern_indeed {\ifdim\pagegoal=\maxdimen \ifinner \supp_visualizers_vkern_finish \fi \else \supp_visualizers_vkern_finish \fi \afterwards\scratchskip \egroup} \unexpanded\def\ruledvkern#1% {\bgroup \let\afterwards#1\relax \afterassignment\supp_visualizers_vkern_indeed \scratchskip=} \unexpanded\def\ruledkern {\ifvmode \expandafter\ruledvkern \else \expandafter\ruledhkern \fi \normalkern} %D A a bit more \TEX nice solution is: %D %D \starttyping %D \unexpanded\def\ruledkern% %D {\csname ruled\ifvmode v\else h\fi kern\endcsname\normalkern} %D \stoptyping %D \macros %D {ruledhglue,ruledvglue} %D %D The non-primitive glue commands are treated as kerns with %D stretch. This stretch is presented as a dashed line. I %D have to admit that until now, I've never used these glue %D commands. %D %D \startbuffer %D one %D \hglue +30pt plus 5pt %D two %D \hglue +30pt %D \hglue -10pt plus 5pt %D three %D \hglue 0pt %D four %D \hglue +30pt %D five %D \stopbuffer %D %D \ShowBufferedExample \def\supp_visualizers_hglue_indeed {\leavevmode % plain tex uses this \scratchcounter\spacefactor \visualvrule\s!width\zeropoint \normalpenalty\plustenthousand \ruledhkern\normalhskip\scratchskip \spacefactor\scratchcounter \egroup} \unexpanded\def\ruledhglue {\bgroup \afterassignment\supp_visualizers_hglue_indeed\scratchskip=} %D \startbuffer %D first line %D \vglue +30pt plus 5pt %D second line %D \vglue +30pt %D \vglue -10pt plus 5pt %D third line %D \par %D fourth line %D \vglue +30pt %D fifth line %D \vglue 0pt %D sixth line %D \stopbuffer %D %D \ShowBufferedExample \def\supp_visualizers_vglue_indeed {\endgraf % \par \nextdepth\prevdepth \visualhrule\s!height\zeropoint \normalpenalty\plustenthousand \ruledvkern\normalvskip\scratchskip \prevdepth\nextdepth \egroup} \unexpanded\def\ruledvglue {\bgroup \afterassignment\supp_visualizers_vglue_indeed\scratchskip=} %D \macros %D {ruledmkern,ruledmskip} %D %D Mathematical kerns and skips are specified in mu. This %D font related unit is incompatible with those of \DIMENSIONS\ %D and \SKIPS. Because in math mode spacing is often a very %D subtle matter, we've used a very simple, not overloaded way %D to show them. \def\supp_visualizers_mkern_finish#1% {\dontinterfere \dontcomplain \setbox\boxrulescratchbox\normalhbox {\normalstartimath \normalmkern\ifnegative-\fi\scratchskip \normalstopimath}% \setbox\boxrulescratchbox\normalhbox to \wd\boxrulescratchbox {\visualvrule \s!height16\testrulewidth \s!depth 16\testrulewidth \s!width \testrulewidth \leaders \visualhrule \s!height\ifpositive 16\else-14\fi\testrulewidth \s!depth \ifpositive-14\else 16\fi\testrulewidth \normalhfill \ifflexible \normalhskip-\wd\boxrulescratchbox \leaders \visualhrule \s!height\testrulewidth \s!depth \testrulewidth \normalhfill \fi \visualvrule \s!height16\testrulewidth \s!depth 16\testrulewidth \s!width \testrulewidth}% \smashbox0% \ifnegative #1\scratchskip \box\boxrulescratchbox \else \box\boxrulescratchbox #1\scratchskip \fi \egroup} %D \startbuffer %D $a \mkern3mu = \mkern3mu %D b \quad %D \mkern-2mu + \mkern-2mu %D \quad c$ %D \stopbuffer %D %D \ShowBufferedExample \unexpanded\def\ruledmkern {\bgroup \afterassignment\supp_visualizers_mkern_indeed \scratchmuskip=} \def\supp_visualizers_mkern_indeed {\investigatemuskip\scratchmuskip \flexiblefalse \supp_visualizers_mkern_finish\normalmkern} %D \startbuffer %D $a \mskip3mu = \mskip3mu %D b \quad %D \mskip-2mu + \mskip-2mu %D \quad c$ %D \stopbuffer %D %D \ShowBufferedExample \def\supp_visualizers_mskip_indeed {\investigatemuskip\scratchmuskip \flexibletrue \supp_visualizers_mkern_finish\normalmskip} \unexpanded\def\ruledmskip {\bgroup \afterassignment\supp_visualizers_mskip_indeed \scratchmuskip=} %D \macros %D {penalty} %D %D After presenting fills, skip, kerns and glue we've come to %D see penalties. In the first implementation --- most of the %D time needed to develop this set of macros went into testing %D different types of visualization --- penalties were mere %D small blocks with one black half, depending on the sign. %D This most recent version also gives an indication of the %D amount of penalty. Penalties can go from less than $-10000$ %D to over $+10000$, and their behavior is somewhat %D non-lineair, with some values having special meanings. We %D therefore decided not to use its value for a lineair %D indicator. %D %D \startbuffer %D one %D \penalty +100 %D two %D \penalty +100 %D \penalty -100 %D three %D \penalty 0 %D four %D \penalty +100 %D five %D \stopbuffer %D %D \ShowBufferedExample %D %D The small sticks at the side of the penalty indicate it %D size. The next example shows the positive and negative %D penalties of 0, 1, 10, 100, 1000 and 10000. %D %D \startlinecorrection %D \hbox %D {test \ruledhpenalty0 %D test \ruledhpenalty1 %D test \ruledhpenalty10 %D test \ruledhpenalty100 %D test \ruledhpenalty1000 %D test \ruledhpenalty10000 %D test} %D \stoplinecorrection %D %D \blank %D %D \startlinecorrection %D \hbox %D {test \ruledhpenalty0 %D test \ruledhpenalty-1 %D test \ruledhpenalty-10 %D test \ruledhpenalty-100 %D test \ruledhpenalty-1000 %D test \ruledhpenalty-10000 %D test} %D \stoplinecorrection %D %D \blank %D %D This way stacked penalties of different severance can be %D shown in combination. %D %D test \ruledhpenalty10 \ruledhpenalty100 %D test %D test \ruledhpenalty1000 \ruledhpenalty-1000 %D test \def\supp_visualizers_penalty_box#1#2#3#4#5#6% {\setbox#1\normalhbox {\ifnum#2=\zerocount \else \edef\sign{\ifnum#2>\zerocount +\else-\fi}% \scratchdimen \ifnum\sign#2>9999 28\else \ifnum\sign#2>999 22\else \ifnum\sign#2>99 16\else \ifnum\sign#2>9 10\else 4\fi\fi\fi\fi \testrulewidth \ifnum#2<\zerocount \normalhskip-\scratchdimen \normalhskip-2\testrulewidth \visualvrule \s!width 2\testrulewidth \s!height#3\testrulewidth \s!depth #4\testrulewidth \fi \visualvrule \s!width \scratchdimen \s!height#5\testrulewidth \s!depth #6\testrulewidth \ifnum#2>\zerocount \visualvrule \s!width 2\testrulewidth \s!height#3\testrulewidth \s!depth #4\testrulewidth \fi \fi}% \smashbox#1} \unexpanded\def\ruledhpenalty {\bgroup \afterassignment\supp_visualizers_hpenalty_indeed \scratchcounter=} \def\supp_visualizers_hpenalty_indeed {\dontinterfere \dontcomplain \investigatecount\scratchcounter \testrulewidth2\testrulewidth \boxrulewidth\testrulewidth \setbox0\ruledhbox to 8\testrulewidth {\ifnegative\else\normalhss\fi \visualvrule \s!depth8\testrulewidth \s!width\ifzero\zeropoint\else4\testrulewidth\fi \ifpositive\else\normalhss\fi}% \supp_visualizers_penalty_box{2}{\scratchcounter}{0}{8}{-3.5}{4.5}% \normalpenalty\plustenthousand \setbox0\normalhbox {\normalhskip-4\testrulewidth \ifnegative \box2\box0 \else \box0\box2 \fi}% \smashbox0% \box0 \normalpenalty\scratchcounter \egroup} %D The size of a vertical penalty is also shown on the %D horizontal axis. This way there is less interference with %D the often preceding or following skips and kerns. %D %D \startbuffer %D first line %D \par \penalty +100 %D second line %D \par \penalty +100 %D \par \penalty -100 %D third line %D \par \penalty 0 %D fourth line %D \par \penalty +100 %D fifth line %D \stopbuffer %D %D \ShowBufferedExample \unexpanded\def\ruledvpenalty {\bgroup \afterassignment\supp_visualizers_vpenalty_indeed \scratchcounter=} \def\supp_visualizers_vpenalty_indeed {\ifdim\pagegoal=\maxdimen \else \nextdepth\prevdepth \dontinterfere \dontcomplain \investigatecount\scratchcounter \testrulewidth2\testrulewidth \boxrulewidth\testrulewidth \setbox0\ruledhbox {\visualvrule \s!height4\testrulewidth \s!depth 4\testrulewidth \s!width \zeropoint \visualvrule \s!height\ifnegative.5\else4\fi\testrulewidth \!!dept \ifpositive.5\else4\fi\testrulewidth \s!width 8\testrulewidth}% \supp_visualizers_penalty_box{2}{\scratchcounter}{4}{4}{.5}{.5}% \setbox0\normalhbox {\normalhskip-4\testrulewidth \ifnegative \box2\box0 \else \box0\box2 \fi \normalhss}% \smashbox0% \normalpenalty\plustenthousand \nointerlineskip \dp0\nextdepth % not \prevdepth=\nextdepth \normalvbox {\normalvcue{\box0}}% \fi \normalpenalty\scratchcounter \egroup} %D This comes together in: \unexpanded\def\ruledpenalty {\ifvmode \expandafter\ruledvpenalty \else \expandafter\ruledhpenalty \fi} %D \macros %D {showfils,dontshowfils, %D showboxes,dontshowboxes, %D showskips,dontshowskips, %D showpenalties,dontshowpenalties} %D %D For those who want to manipulate the visual cues in detail, %D we have grouped them. \unexpanded\def\showfils {\showingcompositiontrue \let\hss \ruledhss \let\hfil \ruledhfil \let\hfill \ruledhfill \let\hfilneg \ruledhfilneg \let\hfillneg \ruledhfillneg \let\vss \ruledvss \let\vfil \ruledvfil \let\vfill \ruledvfill \let\vfilneg \ruledvfilneg \let\vfillneg \ruledvfillneg} \unexpanded\def\dontshowfils {\let\hss \normalhss \let\hfil \normalhfil \let\hfill \normalhfill \let\hfilneg \normalhfilneg \let\hfillneg \normalhfillneg \let\vss \normalvss \let\vfil \normalvfil \let\vfill \normalvfill \let\vfilneg \normalvfilneg \let\vfillneg \normalvfillneg} \unexpanded\def\showboxes {\showingcompositiontrue \baselineruletrue \let\hbox \ruledhbox \let\vbox \ruledvbox \let\vtop \ruledvtop \let\vcenter \ruledvcenter} \unexpanded\def\dontshowboxes {\let\hbox \normalhbox \let\vbox \normalvbox \let\vtop \normalvtop \let\vcenter \normalvcenter} \unexpanded\def\showskips {\showingcompositiontrue \let\hskip \ruledhskip \let\vskip \ruledvskip \let\kern \ruledkern \let\mskip \ruledmskip \let\mkern \ruledmkern \let\hglue \ruledhglue \let\vglue \ruledvglue} \unexpanded\def\dontshowskips {\let\hskip \normalhskip \let\vskip \normalvskip \let\kern \normalkern \let\mskip \normalmskip \let\mkern \normalmkern \let\hglue \normalhglue \let\vglue \normalvglue} \unexpanded\def\showpenalties {\showingcompositiontrue \let\penalty \ruledpenalty} \unexpanded\def\dontshowpenalties {\let\penalty \normalpenalty} %D \macros %D {showcomposition,dontshowcomposition, %D showingcomposition} %D %D All these nice options come together in three macros. One %D for turning the options on, one for turning them off, and a %D boolean for enabling the mechanism outside the scope of the %D user. The first two macros only do their job when we are %D actually showing the composition. %D %D \starttyping %D \showingcompositiontrue %D \showcomposition %D \stoptyping %D %D Because the output routine can do tricky things, like %D multiple column typesetting and manipulation of the %D pagebody, shifting things around and so on, the macro %D \type{\dontshowcomposition} best can be called when we enter %D this routine. Too much visual cues just don't make sense. In %D \CONTEXT\ this has been taken care of. \newif\ifshowingcomposition \unexpanded\def\showcomposition {\ifshowingcomposition \showfils \showboxes \showskips \showpenalties \fi} \unexpanded\def\dontshowcomposition {\ifshowingcomposition \dontshowfils \dontshowboxes \dontshowskips \dontshowpenalties \fi} %D \macros %D {showmakeup, %D defaulttestrulewidth} %D %D Just to make things even more easy, we have defined: %D %D \starttyping %D \showmakeup %D \stoptyping %D %D For the sake of those who don't (yet) use \CONTEXT\ we %D preset \type{\defaulttestrulewidth} to the already set %D value. Otherwise we default to a bodyfontsize related value. %D %D \starttyping %D \def\defaulttestrulewidth{.2pt} %D \stoptyping %D %D Beware, it's a macro not a \DIMENSION. \ifx\bodyfontsize\undefined \edef\defaulttestrulewidth{\the\testrulewidth} \else \def\defaulttestrulewidth{.02\bodyfontsize} \fi \unexpanded\def\showmakeup {\testrulewidth\defaulttestrulewidth \showingcompositiontrue \showcomposition} \protect %D Lets end with some more advanced examples. %D Definitions and enumerations come in many flavors. The %D next one for instance is defined as: %D %D \starttyping %D \definedescription[test][place=left,hang=3,width=6em] %D \stoptyping %D %D When applied to some text, this would look like: %D %D \bgroup %D \showmakeup %D \definedescription[test][location=left,hang=3,width=6em] %D %D \test{visual\\debugger} I would be very pleased if \TEX\ %D had two more primitives: \type{\vnop} and \type{\hnop}. Both %D should act and show up as normal boxes, but stay invisible %D for \TEX\ when it's doing calculations. The \type{\vnop} %D for instance should not interact with the internal mechanism %D responsible for the disappearing skips, kerns and penalties %D at a pagebreak. As long as we don't have these two boxtypes, %D visual debugging will never be perfect. %D %D \egroup %D %D The index to this section looks like: %D %D {\setupreferencing[prefixprefix=dummy]\showmakeup\placeindex[criterium=local]} %D %D Although not impressive examples or typesetting, both %D show us how and where things happen. When somehow the last %D lines in this two column index don't allign, then this is %D due to some still unknown interference. \endinput