%D \module %D [ file=trac-vis, % was core-vis, %D version=1996.06.01, %D title=\CONTEXT\ Tracking 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. %D This module adds some more visualization cues to the ones %D supplied in the support module. %D %D %\everypar dual character, \the\everypar and \everypar= %D %\hrule cannot be grabbed in advance, switches mode %D %\vrule cannot be grabbed in advance, switches mode %D % %D %\indent only explicit ones %D %\noindent only explicit ones %D %\par only explicit ones %D %D %\leftskip only if explicit one %D %\rightskip only if explicit one \writestatus{loading}{ConTeXt Tracking Macros / Visualization} \unprotect %D \macros %D {indent, noindent, par} %D %D \TeX\ acts upon paragraphs. In mosts documents paragraphs %D are separated by empty lines, which internally are handled as %D \type{\par}. Paragraphs can be indented or not, depending on %D the setting of \type{\parindent}, the first token of a %D paragraph and/or user suppressed or forced indentation. %D %D Because the actual typesetting is based on both explicit %D user and implicit system actions, visualization is only %D possible for the user supplied \type{\indent}, %D \type{\noindent}, and \type{\par}. Other %D 'clever' tricks will quite certainly lead to more failures %D than successes, so we only support these three explicit %D primitives and one macro: \def\showparagraphcue#1#2#3#4#5% {\bgroup \scratchdimen#1\relax \dontinterfere \dontcomplain \boxrulewidth5\testrulewidth #3#4\relax \setbox\scratchbox\normalhbox to \scratchdimen {#2{\ruledhbox to \scratchdimen {\vrule #5 20\testrulewidth \!!width \zeropoint \normalhss}}}% \smashbox\scratchbox \normalpenalty\!!tenthousand \box\scratchbox \egroup} \def\ruledhanging {\ifdim\hangindent>\zeropoint \ifnum\hangafter<\zerocount \normalhbox {\boxrulewidth5\testrulewidth \setbox\scratchbox\ruledhbox to \hangindent {\scratchdimen\strutht \advance\scratchdimen \strutdp \vrule \!!width \zeropoint \!!height \zeropoint \!!depth -\hangafter\scratchdimen}% \normalhskip-\hangindent \smashbox\scratchbox \raise\strutht\box\scratchbox}% \fi \fi} \def\ruledparagraphcues {\bgroup \dontcomplain \normalhbox to \zeropoint {\ifdim\leftskip>\zeropoint\relax \showparagraphcue\leftskip\llap\relax\relax\!!depth \normalhskip-\leftskip \fi \ruledhanging \normalhskip\hsize \ifdim\rightskip>\zeropoint\relax \normalhskip-\rightskip \showparagraphcue\rightskip\relax\relax\relax\!!depth \fi}% \egroup} \def\ruledpar {\relax \ifhmode \showparagraphcue{40\testrulewidth}\relax\rightrulefalse\relax\!!height \fi \normalpar} \def\rulednoindent {\relax \normalnoindent \ruledparagraphcues \showparagraphcue{40\testrulewidth}\llap\leftrulefalse\relax\!!height} \def\ruledindent {\relax \normalnoindent \ruledparagraphcues \ifdim\parindent>\zeropoint \showparagraphcue\parindent\relax\relax\relax\!!height \else \showparagraphcue{40\testrulewidth}\llap\relax\relax\!!height \fi \normalhskip\parindent} \def\dontshowimplicits {\let\noindent \normalnoindent \let\indent \normalindent \let\par \normalpar} \def\showimplicits {\testrulewidth \defaulttestrulewidth \let\noindent \rulednoindent \let\indent \ruledindent \let\par \ruledpar} %D The next few||line examples show the four cues. Keep in %D mind that we only see them when we explicitly open or close %D a paragraph. %D %D \bgroup %D \def\voorbeeld#1% %D {#1Visualizing some \TeX\ primitives and Plain \TeX\ %D macros can be very instructive, at least it is to me. %D Here we see {\tt\string#1} and {\tt\string\ruledpar} in %D action, while {\tt\string\parindent} equals %D {\tt\the\parindent}.\ruledpar} %D %D \showimplicits %D %D \voorbeeld \indent %D \voorbeeld \noindent %D %D \parindent=60pt %D %D \voorbeeld \indent %D \voorbeeld \noindent %D %D \startnarrower %D \voorbeeld \indent %D \voorbeeld \noindent %D \stopnarrower %D \egroup %D %D These examples also demonstrate the visualization of %D \type {\leftskip} and \type {\rightskip}. The macro %D \type {\nofruledbaselines} determines the number of lines %D shown. \newcounter\ruledbaselines \def\nofruledbaselines{3} \def\debuggertext#1% {\ifx\ttxx\undefined $\scriptscriptstyle#1$% \else {\ttxx#1}% \fi} \def\ruledbaseline {\vrule \!!width \zeropoint \bgroup \dontinterfere \doglobal\increment\ruledbaselines \scratchdimen\nofruledbaselines\baselineskip \setbox\scratchbox\normalvbox to 2\scratchdimen {\leaders \normalhbox {\strut \vrule \!!height \testrulewidth \!!depth \testrulewidth \!!width 120\points} \normalvfill}% \smashbox\scratchbox \advance\scratchdimen \strutheightfactor\baselineskip \setbox\scratchbox\normalhbox {\normalhskip -48\points \normalhbox to 24\points {\normalhss\debuggertext\ruledbaselines\normalhskip6\points}% \raise\scratchdimen\box\scratchbox}% \smashbox\scratchbox \box\scratchbox \egroup} \def\showbaselines {\testrulewidth\defaulttestrulewidth \EveryPar{\ruledbaseline}} %D \macros %D {showpagebuilder} %D %D The next tracing option probaly is only of use to me and a %D few \CONTEXT\ hackers. \def\showpagebuilder {\EveryPar{\doshowpagebuilder}} \def\doshowpagebuilder {\strut\llap {\startcolor[blue]\vl \high{\infofont v:\the\vsize }\vl \high{\infofont g:\the\pagegoal }\vl \high{\infofont t:\the\pagetotal}\vl \stopcolor}} %D \macros %D {makecutbox, cuthbox, cutvbox, cutvtop} %D %D Although mainly used for marking the page, these macros can %D also serve local use. %D %D \startbuffer %D \setbox0=\vbox{a real \crlf vertical box} \makecutbox0 %D \stopbuffer %D %D \typebuffer %D %D This marked \type{\vbox} shows up as: %D %D \startlinecorrection %D \getbuffer %D \stoplinecorrection %D %D The alternative macros are used as: %D %D \startbuffer %D \cuthbox{a made cut box} %D \stopbuffer %D %D \typebuffer %D %D This is typeset as: %D %D \startlinecorrection %D \getbuffer %D \stoplinecorrection %D %D By setting the next macros one can influence the length of %D the marks as well as the horizontal and vertical divisions. \def\cutmarklength {2\bodyfontsize} \chardef\horizontalcutmarks = 2 \chardef\verticalcutmarks = 2 \chardef\cutmarkoffset = 1 \let\cutmarksymbol = \relax \let\cutmarktoptext = \empty \let\cutmarkbottomtext = \empty \def\horizontalcuts {\normalhbox to \ruledwidth {\dorecurse\horizontalcutmarks {\vrule\!!width\boxrulewidth\!!height\cutmarklength\normalhfill}% \unskip}} \def\verticalcuts {\scratchdimen\ruledheight \advance\scratchdimen \ruleddepth \normalvbox to \scratchdimen {\hsize\cutmarklength \dorecurse\verticalcutmarks {\vrule\!!height\boxrulewidth\!!width\hsize\normalvfill}% \unskip}} \def\baselinecuts {\ifdim\ruleddepth>\zeropoint \scratchdimen\ruledheight \advance\scratchdimen \ruleddepth \normalvbox to \scratchdimen {\scratchdimen\cutmarklength \divide\scratchdimen 2 \hsize\scratchdimen \normalvskip\zeropoint\!!plus\ruledheight \vrule\!!height\boxrulewidth\!!width\hsize \normalvskip\zeropoint\!!plus\ruleddepth}% \fi} \def\cutmarksymbols#1% {\normalhbox to \ruledwidth {\setbox\scratchbox\normalhbox to \cutmarklength {\normalhss\infofont\cutmarksymbol\normalhss}% \normalhss \normalvbox to \cutmarklength {\scratchdimen\cutmarklength \divide\scratchdimen \plustwo \normalvss \hbox to \ruledwidth {\llap{\copy\scratchbox\normalhskip\cutmarkoffset\scratchdimen}% \normalhskip\scratchdimen\hss\infofont#1\hss\normalhskip\scratchdimen \rlap{\normalhskip\cutmarkoffset\scratchdimen\copy\scratchbox}}% \normalvss}% \normalhss}} \def\makecutbox#1% simplier with layers, todo {\edef\ruledheight{\the\ht#1}% \edef\ruleddepth {\the\dp#1}% \edef\ruledwidth {\the\wd#1}% \setbox#1\normalhbox {\dontcomplain \forgetall \boxmaxdepth\maxdimen \offinterlineskip \scratchdimen\cutmarklength \divide\scratchdimen \plustwo \hsize\ruledwidth \setbox\scratchbox\normalvbox {\setbox\scratchbox\normalhbox{\horizontalcuts}% \normalvskip-\cutmarkoffset\scratchdimen \normalvskip-2\scratchdimen \copy\scratchbox \normalvskip\cutmarkoffset\scratchdimen \hbox to \ruledwidth {\setbox\scratchbox\normalhbox{\verticalcuts}% \llap{\copy\scratchbox\normalhskip\cutmarkoffset\scratchdimen}% \bgroup \setbox\scratchbox\normalhbox{\baselinecuts}% \llap{\copy\scratchbox\normalhskip\cutmarkoffset\scratchdimen}% \normalhfill \rlap{\normalhskip\cutmarkoffset\scratchdimen\copy\scratchbox}% \egroup \rlap{\normalhskip\cutmarkoffset\scratchdimen\copy\scratchbox}}% \normalvskip\cutmarkoffset\scratchdimen \copy\scratchbox}% \ht\scratchbox\ruledheight \dp\scratchbox\ruleddepth \wd\scratchbox\zeropoint \resetcolorseparation \localstartcolor[\defaulttextcolor]% \box\scratchbox \ifx\cutmarksymbol\relax \else \setbox\scratchbox\normalvbox {\vskip-\cutmarkoffset\scratchdimen \vskip-\cutmarklength \normalhbox{\cutmarksymbols\cutmarktoptext}% \vskip\cutmarkoffset\scratchdimen \vskip\ruledheight \vskip\ruleddepth \vskip\cutmarkoffset\scratchdimen \normalhbox{\cutmarksymbols\cutmarkbottomtext}}% \ht\scratchbox\ruledheight \dp\scratchbox\ruleddepth \wd\scratchbox\zeropoint \box\scratchbox \fi \localstopcolor \box#1}% \wd#1=\ruledwidth \ht#1=\ruledheight \dp#1=\ruleddepth} \def\cuthbox {\normalhbox\bgroup \dowithnextbox{\makecutbox\nextbox\flushnextbox\egroup}\normalhbox} \def\cutvbox {\normalvbox\bgroup \dowithnextbox{\makecutbox\nextbox\flushnextbox\egroup}\normalvbox} \def\cutvtop {\normalvtop\bgroup \dowithnextbox{\makecutbox\nextbox\flushnextbox\egroup}\normalvtop} %D \macros %D {colormarkbox,rastermarkbox} %D %D This macro is used in the pagebody routine. No other use %D is advocated here. %D %D \starttyping %D \colormarkbox0 %D \stoptyping \def\colormarkoffset{\cutmarkoffset} \def\colormarklength{\cutmarklength} \def\colorrangeA#1#2#3#4% {\vbox {\scratchdimen-\colormarklength \multiply\scratchdimen 4 \advance\scratchdimen \ruledheight \advance\scratchdimen \ruleddepth \divide\scratchdimen 21 \def\docommand##1% {\vbox {\hsize3em % \scratchdimen \definecolor [\s!dummy] [\c!c=#2##1\else0\fi, \c!m=#3##1\else0\fi, \c!y=#4##1\else0\fi, \c!k=0]% \localstartcolor[\s!dummy]% \hrule \!!width 3em \!!height \scratchdimen \!!depth \zeropoint \localstopcolor \ifdim\scratchdimen>1ex \vskip-\scratchdimen \vbox to \scratchdimen {\vss \hbox to 3em {\hss \localstartcolor[\s!white]% \ifdim##1\points=\zeropoint#1\else##1\fi \localstopcolor \hss}% \vss}% \fi}}% \offinterlineskip \processcommalist[1.00,0.95,0.75,0.50,0.25,0.05,0.00]\docommand}} \def\colorrangeB {\hbox {\scratchdimen-\colormarklength \multiply\scratchdimen \plustwo \advance\scratchdimen \ruledwidth \divide\scratchdimen 11 \def\docommand ##1 ##2 ##3##4##5##6% {\definecolor [\s!dummy] [\c!c=##3##2\else0\fi, \c!m=##4##2\else0\fi, \c!y=##5##2\else0\fi, \c!k=##6##2\else0\fi]% \localstartcolor[\s!dummy]% \vrule \!!width \scratchdimen \!!height \colormarklength \!!depth \zeropoint \localstopcolor \ifdim\scratchdimen>2em \hskip-\scratchdimen \vbox to \colormarklength {\vss \hbox to \scratchdimen {\hss \localstartcolor[\s!white]% \ifdim##2\points=.5\points##2~\fi##1% \localstopcolor \hss} \vss}% \fi}% \docommand C .5 \iftrue \iffalse\iffalse\iffalse \docommand M .5 \iffalse\iftrue \iffalse\iffalse \docommand Y .5 \iffalse\iffalse\iftrue \iffalse \docommand K .5 \iffalse\iffalse\iffalse\iftrue \docommand C 1 \iftrue \iffalse\iffalse\iffalse \docommand G 1 \iftrue \iffalse\iftrue \iffalse \docommand Y 1 \iffalse\iffalse\iftrue \iffalse \docommand R 1 \iffalse\iftrue \iftrue \iffalse \docommand M 1 \iffalse\iftrue \iffalse\iffalse \docommand B 1 \iftrue \iftrue \iffalse\iffalse \docommand K 1 \iffalse\iffalse\iffalse\iftrue}} \def\colorrangeC {\hbox {\resetcolorseparation \scratchdimen-\colormarklength \multiply\scratchdimen 2 \advance\scratchdimen \ruledwidth \divide\scratchdimen 14 \def\docommand##1% {\definecolor[\s!dummy][\c!s=##1]% \localstartcolor[\s!dummy]% \vrule \!!width \scratchdimen \!!height \colormarklength \!!depth \zeropoint \localstopcolor \ifdim\scratchdimen>2em \hskip-\scratchdimen \vbox to \colormarklength {\vss \localstartcolor[\s!white]% \hbox to \scratchdimen{\hss##1\hss} \localstopcolor \vss}% \fi}% \processcommalist[1,.95,.9,.85,.8,.75,.7,.6,.5,.4,.3,.2,.1,0]\docommand}} \def\docolormarkbox#1#2% {\edef\ruledheight{\the\ht#2}% \edef\ruleddepth {\the\dp#2}% \edef\ruledwidth {\the\wd#2}% \setbox#2\hbox {\scratchdimen\colormarklength \divide\scratchdimen \plustwo \forgetall \ssxx \setbox\scratchbox\vbox {\offinterlineskip \vskip-\colormarkoffset\scratchdimen \vskip-2\scratchdimen\relax % relax needed % beware: no \ifcase, due to nested \iftrue/\iffalse % and lacking \fi's \doifelse{#1}{0}% {\vskip\colormarklength \vskip\colormarkoffset\scratchdimen \vskip\ruledheight} {\hbox to \ruledwidth{\hss\hbox{\colorrangeB}\hss}% \vskip\colormarkoffset\scratchdimen \vbox to \ruledheight {\vss \hbox to \ruledwidth {\llap{\colorrangeA C\iftrue\iffalse\iffalse\hskip\colormarkoffset\scratchdimen}% \hfill \rlap{\hskip\colormarkoffset\scratchdimen\colorrangeA R\iffalse\iftrue\iftrue}}% \vss \hbox to \ruledwidth {\llap{\colorrangeA M\iffalse\iftrue\iffalse\hskip\colormarkoffset\scratchdimen}% \hfill \rlap{\hskip\colormarkoffset\scratchdimen\colorrangeA G\iftrue\iffalse\iftrue}}% \vss \hbox to \ruledwidth {\llap{\colorrangeA Y\iffalse\iffalse\iftrue\hskip\colormarkoffset\scratchdimen}% \hfill \rlap{\hskip\colormarkoffset\scratchdimen\colorrangeA B\iftrue\iftrue\iffalse}}% \vss}}% \vskip\colormarkoffset\scratchdimen \hbox to \ruledwidth {\hss\lower\ruleddepth\hbox{\colorrangeC}\hss}}% \ht\scratchbox\ruledheight \dp\scratchbox\ruleddepth \wd\scratchbox\zeropoint \box\scratchbox \box#2}% \wd#2=\ruledwidth \ht#2=\ruledheight \dp#2=\ruleddepth} \def\colormarkbox % #1 {\ifincolor\@EA\docolormarkbox\else\@EA\gobbletwoarguments\fi1} \def\rastermarkbox % #1 {\ifincolor\@EA\docolormarkbox\else\@EA\gobbletwoarguments\fi0} %D \macros %D {showwhatsits, dontshowwhatsits} %D %D \TEX\ has three so called whatsits: \type {\mark}, \type %D {\write} and \type {\special}. The first one keeps track of %D the current state at page boundaries, the last two are used %D to communicate to the outside world. Due to fact that %D especially \type {\write} is often used in conjunction with %D \type {\edef}, we can only savely support that one in \ETEX. %D %D \bgroup \showwhatsits \setupcolors[state=start] %D %D Whatsits show up \color[blue]{in color} and are %D characterized bij their first character.\footnote [some note] %D {So we may encounter \type {w}, \type {m} and \type{s}.} %D They are \writestatus{dummy}{demo}\color[yellow]{stacked}. %D %D \egroup \newif\ifimmediatewrite \ifx\eTeXversion\undefined \let\showwhatsits \relax \let\dontshowwhatsits\relax \else \let\supernormalmark \normalmark % mark may already been superseded \let\supernormalmarks \normalmarks % mark may already been superseded \def\showwhatsits {\protected\def\normalmark {\visualwhatsit100+m\supernormalmark }% \protected\def\normalmarks{\visualwhatsit100+m\supernormalmarks}% \protected\def\special {\visualwhatsit0100s\normalspecial }% \protected\def\write {\visualwhatsit001-w\normalwrite }% \let\immediate\immediatewhatsit \appendtoks\dontshowwhatsits\to\everystoptext} \def\immediatewhatsit {\bgroup\futurelet\next\doimmediatewhatsit} \def\doimmediatewhatsit {\ifx\next\write \egroup\immediatewritetrue \else \egroup\expandafter\normalimmediate \fi} \def\dontshowwhatsits {\let\immediate \normalimmediate \let\normalmark\supernormalmark \let\special \normalspecial \let\write \normalwrite} \def\visualwhatsit#1#2#3#4#5% {\bgroup \pushwhatsit \dontinterfere \dontcomplain \dontshowcomposition \dontshowwhatsits \ttx \ifvmode\donetrue\else\donefalse\fi \setbox\scratchbox\hbox {\ifdone\dostartgraycolormode0\else\dostartrgbcolormode#1#2#3\fi #5\dostopcolormode}% \setbox\scratchbox\hbox {\ifdone\dostartrgbcolormode#1#2#3\else\dostartgraycolormode0\fi \vrule\!!width\wd\scratchbox\dostopcolormode \hskip-\wd\scratchbox\box\scratchbox}% \scratchdimen1ex \setbox\scratchbox\hbox {\ifdone\hskip\else\raise#4\fi\scratchdimen\box\scratchbox}% \smashbox\scratchbox \ifdone\nointerlineskip\fi \box\scratchbox \ifvmode\nointerlineskip\fi \popwhatsit \egroup \ifimmediatewrite \immediatewritefalse \expandafter\normalimmediate \fi} \def\pushwhatsit {\ifzeropt\lastskip \ifcase\lastpenalty \ifzeropt\lastkern \ifhmode \let\popwhatsit\relax \else \edef\popwhatsit{\prevdepth\the\prevdepth}% \fi \else \ifhmode \edef\popwhatsit{\kern\the\lastkern}\unkern \else \edef\popwhatsit{\kern\the\lastkern\prevdepth\the\prevdepth}% \kern-\lastkern \fi \fi \else \ifhmode \edef\popwhatsit{\the\lastpenalty}% \unpenalty \else \edef\popwhatsit{\penalty\the\lastpenalty\prevdepth\the\prevdepth}% %\nobreak \fi \fi \else \ifhmode \edef\popwhatsit{\hskip\the\lastskip}\unskip \else \edef\popwhatsit{\vskip\the\lastskip\prevdepth\the\prevdepth}% \vskip-\lastskip \fi \fi} \fi %D The next macro can be used to keep track of classes of %D boxes (handy for development cq.\ tracing). \def\dodotagbox#1#2#3% can be reimplemented {\def\next##1##2##3##4% {\vbox to \ht#2{##3\hbox to \wd#2{##1#3##2}##4}}% \processaction [#1] [ l=>\next\relax\hfill\vfill\vfill, r=>\next\hfill\relax\vfill\vfill, t=>\next\hfill\hfill\relax\vfill, b=>\next\hfill\hfill\vfill\relax, lt=>\next\relax\hfill\relax\vfill, lb=>\next\relax\hfill\vfill\relax, rt=>\next\hfill\relax\relax\vfill, rb=>\next\hfill\relax\vfill\relax, tl=>\next\relax\hfill\relax\vfill, bl=>\next\relax\hfill\vfill\relax, tr=>\next\hfill\relax\relax\vfill, br=>\next\hfill\relax\vfill\relax, \s!default=>\next\hfill\hfill\vfill\vfill, \s!unknown=>\next\hfill\hfill\vfill\vfill]} \def\dotagbox[#1]#2% {\bgroup \dowithnextbox {\setbox\scratchbox\flushnextbox \setbox\nextbox\ifhbox\nextbox\hbox\else\vbox\fi \bgroup \startoverlay {\copy\scratchbox} {\dodotagbox{#1}\scratchbox{\framed [\c!background=\v!screen,\c!backgroundscreen=1]{#2}}} \stopoverlay \egroup \nextboxwd\the\wd\scratchbox \nextboxht\the\ht\scratchbox \nextboxdp\the\dp\scratchbox \flushnextbox \egroup}} \def\tagbox {\dosingleempty\dotagbox} %D \macros %D {coloredhbox,coloredvbox,coloredvtop, %D coloredstrut} %D %D The following visualizations are used in some of the manuals: \definecolor[boxcolor:ht][r=.5,g=.75,b=.5] \definecolor[boxcolor:dp][r=.5,g=.5,b=.75] \definecolor[boxcolor:wd][r=.75,g=.5,b=.5] \definecolor[strutcolor] [r=.5,g=.25,b=.25] \def\coloredbox#1% {\dowithnextbox{#1{\hbox {\blackrule[\c!width=\nextboxwd,\c!height=\nextboxht,\c!depth=\zeropoint,\c!color=boxcolor:ht]% \hskip-\nextboxwd \blackrule[\c!width=\nextboxwd,\c!height=\zeropoint,\c!depth=\nextboxdp,\c!color=boxcolor:dp]% \hskip-\nextboxwd \box\nextbox}}}#1} \def\coloredhbox{\coloredbox\hbox} \def\coloredvbox{\coloredbox\vbox} \def\coloredvtop{\coloredbox\vtop} \def\coloredstrut {\color[strutcolor]{\def\strutwidth{2\points}\setstrut\strut}} \protect \endinput