diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkxl/supp-box.mkxl')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkxl/supp-box.mkxl | 2926 |
1 files changed, 2926 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkxl/supp-box.mkxl b/Master/texmf-dist/tex/context/base/mkxl/supp-box.mkxl new file mode 100644 index 00000000000..e52ea90b81c --- /dev/null +++ b/Master/texmf-dist/tex/context/base/mkxl/supp-box.mkxl @@ -0,0 +1,2926 @@ +%D \module +%D [ file=supp-box, +%D version=1995.10.10, +%D title=\CONTEXT\ Support Macros, +%D subtitle=Boxes, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Support Macros / Boxes} + +\unprotect + +\registerctxluafile{supp-box}{autosuffix,optimize} + +%D And some dimensions: + +\newdimen\givenwidth +\newdimen\givenheight +\newdimen\givendepth + +% \fixupboxesmode\plusone % gone: is now the default + +%D This module implements some box manipulation macros. Some are quite simple, some +%D are more advanced and when understood well, all can be of use. +%D +%D \macros +%D {strutdp,strutht,strutwd} +%D +%D The next shortcuts save memory and keying. The width is normally zero points (if +%D not, you're in trouble). These shortcuts can be used like a dimension, opposite +%D to the core macros \type {\strutdepth} and alike, which are values. + + \def\strutdp {\dp\strutbox} % overloaded in spac-ver + \def\strutht {\ht\strutbox} % overloaded in spac-ver +\permanent\protected\def\strutwd {\wd\strutbox} +\permanent\protected\def\struthtdp{\dimexpr\strutht+\strutdp\relax} +\permanent\protected\def\strutgap {\dimexpr\strutht-\strutdp\relax} + +%D \macros +%D {voidbox,nextbox} +%D +%D Let's start with an easy one. The next macro hides the ugly \type {@} in \type +%D {\voidb@x}. + +\ifdefined\voidbox \else \newbox\voidbox \fi +\ifdefined\nextbox \else \newbox\nextbox \fi + +%D \macros +%D {nextdepth} +%D +%D Let's start with a rather simple declaration. Sometimes we need to save the \TEX\ +%D \DIMENSION\ \type{\prevdepth} and append it later on. The name \type {\nextdepth} +%D suits this purpose well. + +\newdimen\nextdepth + +%D \macros +%D {smashbox, smashboxed, smashedbox} +%D +%D Smashing is introduced in \PLAIN\ \TEX, and stands for reducing the dimensions of +%D a box to zero. The most resolute one is presented first. + +% \permanent\protected\def\smashbox#1% +% {\wd#1\zeropoint +% \ht#1\zeropoint +% \dp#1\zeropoint} +% +% \permanent\protected\def\smashboxed#1% +% {\wd#1\zeropoint +% \ht#1\zeropoint +% \dp#1\zeropoint +% \box#1\relax} + +%D \macros +%D {hsmashbox,vsmashbox} +%D +%D Smashing can be used for overlaying boxes. Depending on the mode, horizontal or +%D vertical, one can use: + +% \permanent\protected\def\hsmashbox#1% +% {\wd#1\zeropoint} +% +% \permanent\protected\def\vsmashbox#1% +% {\ht#1\zeropoint +% \dp#1\zeropoint} + +%D The next implementation is less sensitive for spurious spaces. + +\newcount\c_boxes_register + +\permanent\protected\def\smashbox + {\afterassignment\syst_boxes_smash_boxes_register\c_boxes_register} + +\def\syst_boxes_smash_boxes_register + {\wd\c_boxes_register\zeropoint + \ht\c_boxes_register\zeropoint + \dp\c_boxes_register\zeropoint} + +\permanent\protected\def\hsmashbox + {\afterassignment\syst_boxes_hsmashed_boxes_register\c_boxes_register} + +\def\syst_boxes_hsmashed_boxes_register + {\wd\c_boxes_register\zeropoint} + +\permanent\protected\def\vsmashbox + {\afterassignment\syst_boxes_vsmashed_boxes_register\c_boxes_register} + +\def\syst_boxes_vsmashed_boxes_register + {\ht\c_boxes_register\zeropoint + \dp\c_boxes_register\zeropoint} + +\permanent\protected\def\smashedbox + {\afterassignment\syst_boxes_smashed_boxes_register\c_boxes_register} + +\protected\def\syst_boxes_smashed_boxes_register + {\wd\c_boxes_register\zeropoint + \ht\c_boxes_register\zeropoint + \dp\c_boxes_register\zeropoint + \box\c_boxes_register} + +\aliased\let\smashboxed\smashedbox + +%D \macros +%D {hsmash,vsmash, +%D hsmashed,vsmashed} +%D +%D While the previous macros expected a \BOX, the next act on a content. They are +%D some subtle differences betreen the smash and smashed alternatives. The later +%D ones reduce all dimensions to zero. + +\permanent\protected\def\hsmash {\bgroup\dowithnextboxcs\syst_boxes_hsmashed_nextbox\hbox} +\permanent\protected\def\vsmash {\bgroup\dowithnextboxcs\syst_boxes_vsmashed_nextbox\vbox} +\permanent\protected\def\hsmashed{\bgroup\dowithnextboxcs\syst_boxes_smashed_nextbox \hbox} +\permanent\protected\def\vsmashed{\bgroup\dowithnextboxcs\syst_boxes_smashed_nextbox \vbox} + +\protected\def\syst_boxes_hsmashed_nextbox + {\wd\nextbox\zeropoint + \box\nextbox + \egroup} + +\protected\def\syst_boxes_vsmashed_nextbox + {\ht\nextbox\zeropoint + \dp\nextbox\zeropoint + \box\nextbox + \egroup} + +\protected\def\syst_boxes_smashed_nextbox + {\ht\nextbox\zeropoint + \dp\nextbox\zeropoint + \wd\nextbox\zeropoint + \box\nextbox + \egroup} + +%D \macros +%D {smashedhbox,smashedvbox} +%D +%D Also handy (all dimensions zeroed): +%D +%D \starttyping +%D \smashedhbox to ... {...} +%D \smashedvbox to ... {...} +%D \stoptyping + +\permanent\protected\def\smashedhbox{\hpack\bgroup\dowithnextboxcs\syst_boxes_smashed_nextbox\hbox} +\permanent\protected\def\smashedvbox{\vpack\bgroup\dowithnextboxcs\syst_boxes_smashed_nextbox\vbox} + +%D First we define a helper. We use a \LUATEX\ feature in order to avoid +%D mathpalettes. + +\newcount\c_boxes_math_style + +\protected\def\syst_boxes_math_set_nextbox#1% + {\c_boxes_math_style\normalmathstyle + \setbox\nextbox\hbox{\normalstartimath\mathsurround\zeropoint\triggermathstyle\c_boxes_math_style{#1}\normalstopimath}} + +%D \macros +%D {smash} +%D +%D This smash alternative takes an optional arg [whdtb] as well as is potentially +%D catcode safer. It is needed by the math module (although the \type {\leavevmode} +%D is not added here). + +\permanent\protected\def\smash + {\begingroup + \futureexpandis[\syst_boxes_smash_yes\syst_boxes_smash_nop} + +\def\syst_boxes_smash_nop + {\edef\m_boxes_smash_options{hd}% + \futurelet\nexttoken\syst_boxes_smash_indeed} + +\def\syst_boxes_smash_yes[#1]% + {\edef\m_boxes_smash_options{#1}% + \futurelet\nexttoken\syst_boxes_smash_indeed} + +\def\syst_boxes_smash_indeed + {\ifmmode + \expandafter\syst_boxes_smash_math + \orelse\ifx\nexttoken\bgroup + \expandafter\syst_boxes_smash_hbox + \else + \expandafter\syst_boxes_smash_text + \fi} + +\def\syst_boxes_smash_math#1% + {\syst_boxes_math_set_nextbox{#1}% + \syst_boxes_smash_process} + +\def\syst_boxes_smash_hbox + {\dowithnextboxcs\syst_boxes_smash_process\hbox} + +\def\syst_boxes_smash_text#1% + {\setbox\nextbox\hbox{#1}% + \syst_boxes_smash_process} + +\def\syst_boxes_smash_process + {\expandafter\syst_boxes_smash_process_option\m_boxes_smash_options\relax + \box\nextbox + \endgroup} + +\installcorenamespace {smashoptions} + +\setvalue{\??smashoptions w}{\wd\nextbox\zeropoint} +\setvalue{\??smashoptions h}{\ht\nextbox\zeropoint} +\setvalue{\??smashoptions d}{\dp\nextbox\zeropoint} +\setvalue{\??smashoptions t}{\ht\nextbox\zeropoint} +\setvalue{\??smashoptions b}{\dp\nextbox\zeropoint} + +\def\syst_boxes_smash_process_option#1% + {\ifx#1\relax\else + \begincsname\??smashoptions#1\endcsname + \expandafter\syst_boxes_smash_process_option + \fi} + +\def\syst_boxes_lower_nextbox_dp + {\setbox\nextbox\hpack{\lower\dp\nextbox\box\nextbox}} + +%D \starttabulate[|l|l|] +%D \NC w \NC \ruledhbox{\smash [w]{This is some great smashing, isn't it?}} \NC \NR +%D \NC h \NC \ruledhbox{\smash [h]{This is some great smashing, isn't it?}} \NC \NR +%D \NC d \NC \ruledhbox{\smash [d]{This is some great smashing, isn't it?}} \NC \NR +%D \NC tb \NC \ruledhbox{\smash [tb]{This is some great smashing, isn't it?}} \NC \NR +%D \NC whd \NC \ruledhbox{\smash[whd]{This is some great smashing, isn't it?}} \NC \NR +%D \stoptabulate + +%D \macros +%D {phantom, hphantom, vphantom, mathstrut} +%D +%D The next implementation of \type {\phantom} cum suis does not grab an argument in +%D the non||math case, which is better. +%D +%D Due to a complicated call to \type {\mathpallete} and thereby \type +%D {\mathchoice}, the next macro looks ugly. We also take care of non||braced +%D arguments. + +\permanent\protected\def\phantom {\begingroup\futurelet\nexttoken\syst_boxes_phantom_indeed } +\permanent\protected\def\vphantom{\begingroup\futurelet\nexttoken\syst_boxes_phantom_indeed_v} +\permanent\protected\def\hphantom{\begingroup\futurelet\nexttoken\syst_boxes_phantom_indeed_h} + +\def\syst_boxes_phantom_math #1{\syst_boxes_math_set_nextbox{#1}\syst_boxes_phantom_make } +\def\syst_boxes_phantom_math_v#1{\syst_boxes_math_set_nextbox{#1}\syst_boxes_phantom_make_v} +\def\syst_boxes_phantom_math_h#1{\syst_boxes_math_set_nextbox{#1}\syst_boxes_phantom_make_h} + +\def\syst_boxes_phantom_hbox {\dowithnextboxcs\syst_boxes_phantom_make \hbox} % always hbox +\def\syst_boxes_phantom_hbox_v{\dowithnextboxcs\syst_boxes_phantom_make_v\hbox} % always hbox +\def\syst_boxes_phantom_hbox_h{\dowithnextboxcs\syst_boxes_phantom_make_h\hbox} % always hbox + +\def\syst_boxes_phantom_text #1{\setbox\nextbox\hbox{#1}\syst_boxes_phantom_make } % always hbox +\def\syst_boxes_phantom_text_v#1{\setbox\nextbox\hbox{#1}\syst_boxes_phantom_make_v} % always hbox +\def\syst_boxes_phantom_text_h#1{\setbox\nextbox\hbox{#1}\syst_boxes_phantom_make_h} % always hbox + +\def\syst_boxes_phantom_indeed + {\ifmmode + \expandafter\syst_boxes_phantom_math + \orelse\ifx\nexttoken\bgroup + \expandafter\syst_boxes_phantom_hbox + \else + \expandafter\syst_boxes_phantom_text + \fi} + +\def\syst_boxes_phantom_indeed_v + {\ifmmode + \expandafter\syst_boxes_phantom_math_v + \orelse\ifx\nexttoken\bgroup + \expandafter\syst_boxes_phantom_hbox_v + \else + \expandafter\syst_boxes_phantom_text_v + \fi} + +\def\syst_boxes_phantom_indeed_h + {\ifmmode + \expandafter\syst_boxes_phantom_math_h + \orelse\ifx\nexttoken\bgroup + \expandafter\syst_boxes_phantom_hbox_h + \else + \expandafter\syst_boxes_phantom_text_h + \fi} + +\def\syst_boxes_phantom_make + {\setbox\scratchbox\emptyhbox + \ht\scratchbox\ht\nextbox + \dp\scratchbox\dp\nextbox + \wd\scratchbox\wd\nextbox + \box\scratchbox + \endgroup} + +\def\syst_boxes_phantom_make_v + {\setbox\scratchbox\emptyhbox + \ht\scratchbox\ht\nextbox + \dp\scratchbox\dp\nextbox + \box\scratchbox + \endgroup} + +\def\syst_boxes_phantom_make_h + {\setbox\scratchbox\emptyhbox + \wd\scratchbox\wd\nextbox + \box\scratchbox + \endgroup} + +%D We also define plain's \type {\mathstrut}. + +\permanent\protected\def\mathstrut{\vphantom(} % can be made faster by inlining + +%D \macros +%D {getboxheight} +%D +%D Although often needed, \TEX\ does not support arithmics like: +%D +%D \starttyping +%D \dimen0 = \ht0 + \dp0 +%D \stoptyping +%D +%D so we implemented: +%D +%D \starttyping +%D \getboxheight ... \of \box... +%D \stoptyping +%D +%D For instance, +%D +%D \starttyping +%D \getboxheight \dimen0 \of \box0 +%D \getboxheight \someheight \of \box \tempbox +%D \stoptyping +%D +%D The implementation is rather stupid: +%D +%D \starttyping +%D \def\getboxheight#1\of#2\box#3% +%D {#1\ht#3\advance#1\dp#3\relax} +%D \stoptyping +%D +%D The next alternative is slightly more clever, since it accepts \type {{12}} as +%D well as \type {12} as box number. + +\permanent\protected\def\getboxheight#1\of#2\box#3% + {\def\next{#1\htdp\c_boxes_register}% + \afterassignment\next\c_boxes_register=#3} + +%D For a long time the following three macros were part of the grid snapping core +%D module, but it makes more sense to have them here so that users can see them. +%D +%D \macros +%D {getnoflines, getroundednoflines, getrawnoflines} +%D +%D Het commando \type {\getnoflines} converteert een hoogte (dimensie) in een aantal +%D regels en kent dit toe aan \type {\noflines}. +%D +%D \starttyping +%D \getnoflines{dimensie} +%D \stoptyping +%D +%D Er wordt gedeeld door \type {\openlineheight} en een hoogte van~0pt komt overeen +%D met 0~regels. The raw alternative does not round. See the \MKII\ and \MKIV\ files +%D for historic variants. + +\ifdefined\roundingeps \else \newdimen\roundingeps \roundingeps=10sp \fi + +\newcount\noflines +\newdimen\noflinesheight + +\permanent\protected\def\getnoflines#1% + {\noflinesheight#1\relax + \ifzeropt\noflinesheight + \noflines\zerocount + \orelse\ifdim\noflinesheight>\zeropoint + \advance\noflinesheight-\roundingeps + \divide\noflinesheight\openlineheight + \noflines\noflinesheight + \advance\noflines\plusone + \else + \advance\noflinesheight\roundingeps + \divide\noflinesheight\openlineheight + \noflines\noflinesheight + \advance\noflines\minusone + \fi} + +\permanent\protected\def\getroundednoflines#1% + {\noflinesheight#1\relax + \ifzeropt\noflinesheight + \noflines\zerocount + \orelse\ifdim\noflinesheight>\zeropoint + \advance\noflinesheight\roundingeps + \divide\noflinesheight\openlineheight + \noflines\noflinesheight + \else + \advance\noflinesheight-\roundingeps + \divide\noflinesheight\openlineheight + \noflines\noflinesheight + \fi} + +\permanent\protected\def\getrawnoflines#1% + {\noflinesheight#1\relax + \ifzeropt\noflinesheight + \noflines\zerocount + \orelse\ifdim\noflinesheight>\zeropoint + \advance\noflinesheight\roundingeps + \advance\noflinesheight.5\openlineheight + \divide\noflinesheight\openlineheight + \noflines\noflinesheight + \else + \advance\noflinesheight-\roundingeps + \advance\noflinesheight-.5\openlineheight + \divide\noflinesheight\openlineheight + \noflines\noflinesheight + \fi} + +%D Let's proof that it works: +%D +%D \startbuffer +%D \scratchdimen\dimexpr(3pt) \getnoflines\scratchdimen 1=\the\noflines \endgraf +%D \scratchdimen\dimexpr(10\lineheight) \getnoflines\scratchdimen 10=\the\noflines \endgraf +%D \scratchdimen\dimexpr(10.1\lineheight) \getnoflines\scratchdimen 11=\the\noflines \endgraf +%D \scratchdimen\dimexpr(10.5\lineheight) \getnoflines\scratchdimen 11=\the\noflines \endgraf +%D \scratchdimen\dimexpr(10.9\lineheight) \getnoflines\scratchdimen 11=\the\noflines \endgraf +%D \scratchdimen\dimexpr(10\lineheight+3pt) \getnoflines\scratchdimen 11=\the\noflines \endgraf +%D \scratchdimen\dimexpr(10\lineheight+3sp) \getnoflines\scratchdimen 10=\the\noflines \endgraf +%D \scratchdimen\dimexpr(10\lineheight-3sp) \getnoflines\scratchdimen 10=\the\noflines \endgraf +%D +%D \scratchdimen\dimexpr(3pt) \getrawnoflines\scratchdimen 0=\the\noflines \endgraf +%D \scratchdimen\dimexpr(10\lineheight) \getrawnoflines\scratchdimen 10=\the\noflines \endgraf +%D \scratchdimen\dimexpr(10.1\lineheight) \getrawnoflines\scratchdimen 10=\the\noflines \endgraf +%D \scratchdimen\dimexpr(10.5\lineheight) \getrawnoflines\scratchdimen 11=\the\noflines \endgraf +%D \scratchdimen\dimexpr(10.9\lineheight) \getrawnoflines\scratchdimen 11=\the\noflines \endgraf +%D \scratchdimen\dimexpr(10\lineheight+3pt) \getrawnoflines\scratchdimen 10=\the\noflines \endgraf +%D \scratchdimen\dimexpr(10\lineheight+3sp) \getrawnoflines\scratchdimen 10=\the\noflines \endgraf +%D \scratchdimen\dimexpr(10\lineheight-3sp) \getrawnoflines\scratchdimen 10=\the\noflines \endgraf +%D \stopbuffer +%D +%D \typebuffer \getbuffer + +%D \macros +%D {determinenoflines} +%D +%D The next macro determines the number of lines and returns it it \type +%D {\noflines}. The macro works reasonable well as long as the content can be +%D unboxed. +%D +%D \starttyping +%D \determinenoflines{test\\test} +%D \determinenoflines{\bfd test\\test} +%D \determinenoflines{\definedfont[Sans at 40pt]test\\test} +%D \stoptyping + +% \def\syst_boxes_determine_noflines % can be mkiv'd +% {\beginofshapebox +% \unvbox\nextbox +% \endofshapebox +% \globalscratchcounter\zerocount +% \reshapebox{\global\advance\globalscratchcounter\plusone}% +% \expandafter\egroup\expandafter\noflines\the\globalscratchcounter\relax} + +\def\syst_boxes_determine_noflines + {\expandafter\egroup\expandafter\noflines\noflinesinbox\nextbox\relax} + +\permanent\protected\def\determinenoflines + {\bgroup + \forgetall + \enforced\let\crlf\endgraf + \enforced\let\\\endgraf + \dowithnextboxcs\syst_boxes_determine_noflines\vbox} + +%D \macros +%D {doiftextelse, doiftext} +%D +%D When \type {\doifelse} cum suis hopelessly fail, for instance because we pass +%D data, we can fall back on the next macro: +%D +%D \starttyping +%D \doiftextelse {data} {then branch} {else branch} +%D \doiftext {data} {then branch} +%D \stoptyping + +\permanent\protected\def\doifelsetext#1% + {\begingroup + \setbox\scratchbox\hbox % no \hpack because we can have fallbacks + {\settrialtypesetting + \ignorespaces#1\removeunwantedspaces}% + \ifzeropt\wd\scratchbox + \endgroup\expandafter\secondoftwoarguments + \else + \endgroup\expandafter\firstoftwoarguments + \fi} + +\permanent\protected\def\doiftext#1% + {\begingroup + \setbox\scratchbox\hbox % no \hpack because we can have fallbacks + {\settrialtypesetting + \ignorespaces#1\removeunwantedspaces}% + \ifzeropt\wd\scratchbox + \endgroup\expandafter\gobbleoneargument + \else + \endgroup\expandafter\firstofoneargument + \fi} + +% more efficient but maybe fragile: +% +% \nospacing#1}% + +\aliased\let\doiftextelse\doifelsetext + +%D \macros +%D {dowithnextbox,nextbox} +%D +%D Sometimes we want a macro to grab a box and do something on the content. One +%D could pass an argument to a box, but this can violate the specific \CATCODES\ of +%D its content and leads to unexpected results. The next macro treats the following +%D braced text as the content of a box and manipulates it afterwards in a predefined +%D way. +%D +%D The first argument specifies what to do with the content. This content is +%D available in \type {\nextbox}. The second argument is one of \type {\hbox}, \type +%D {\vbox} or \type {\vtop}. The third argument must be grouped with \type {\bgroup} +%D and \type {\egroup}, \type {{...}} or can be a \type {\box} specification. +%D +%D In \CONTEXT\ this macro is used for picking up a box and treating it according to +%D earlier specifications. We use for instance something like: +%D +%D \starttyping +%D \def\getfloat% +%D {\def\handlefloat{...\box\nextbox...} +%D \dowithnextboxcs\handlefloat\vbox} +%D \stoptyping +%D +%D instead of: +%D +%D \starttyping +%D \def\getfloat#1% +%D {...#1...} +%D \stoptyping +%D +%D In this implementation the \type {\aftergroup} construction is needed because +%D \type {\afterassignment} is executed inside the box. + +\let\syst_boxes_with_next_box\relax + +\permanent\protected\def\dowithnextbox#1% + {\def\syst_boxes_with_next_box{#1}% + \afterassignment\syst_boxes_with_next_box_indeed + \setbox\nextbox} + +\def\syst_boxes_with_next_box_indeed + {\aftergroup\syst_boxes_with_next_box} + +\permanent\protected\def\dowithnextboxcs#1% + {\let\syst_boxes_with_next_box#1% + \afterassignment\syst_boxes_with_next_box_indeed + \setbox\nextbox} + +%D So in fact we get: +%D +%D \starttyping +%D \setbox\nextbox { \aftergroup\syst_boxes_with_next_box ... } +%D \stoptyping +%D +%D or +%D +%D \starttyping +%D \setbox\nextbox { ... } \syst_boxes_with_next_box +%D \stoptyping +%D +%D A slower but more versatile implementation is: +%D +%D \starttyping +%D \protected\def\dowithnextbox#1#2% +%D {\def\syst_boxes_with_next_box{#1}% +%D \ifx#2\hbox +%D \afterassignment\syst_boxes_with_next_box_indeed +%D \orelse\ifx#2\vbox +%D \afterassignment\syst_boxes_with_next_box_indeed +%D \orelse\ifx#2\vtop +%D \afterassignment\syst_boxes_with_next_box_indeed +%D \orelse\ifx#2\normalvcenter +%D \afterassignment\syst_boxes_with_next_box_indeed +%D \else +%D \afterassignment\syst_boxes_with_next_box +%D \fi +%D \setbox\nextbox#2} +%D \stoptyping +%D +%D This alternative also accepts \type {\box0} and alike, but we don't really need +%D this functionality now. + +%D \macros +%D {nextboxht,nextboxwd,nextboxdp,flushnextbox} +%D +%D The next couple of shortcuts saves us memory as well as \type {{}}'s in passing +%D parameters. + +\permanent\def\nextboxht {\ht\nextbox} +\permanent\def\nextboxwd {\wd\nextbox} +\permanent\def\nextboxdp {\dp\nextbox} +\permanent\def\nextboxhtdp{\htdp\nextbox} + +\permanent\protected\def\flushnextbox{\box\nextbox} + +%D \macros +%D {dowithnextboxcontent} +%D +%D But, occasionally we do need to pass some local settings without wanting to use +%D additional grouping. Therefore we provide: +%D +%D \starttyping +%D \dowithnextboxcontent{inside}{after}{box content} +%D \stoptyping +%D +%D {\em todo: Search source for potential usage!} + +% \protected\def\dowithnextboxcontent#1#2% inside, after +% {\def\syst_boxes_with_next_box_one{#2}% +% \def\syst_boxes_with_next_box_two{#1}% +% \afterassignment\syst_boxes_with_next_box_content_indeed +% \setbox\nextbox} +% +% \protected\def\dowithnextboxcontentcs#1#2% inside, after +% {\let\syst_boxes_with_next_box_one#2% +% \let\syst_boxes_with_next_box_two#1% +% \afterassignment\syst_boxes_with_next_box_content_indeed +% \setbox\nextbox} +% +% \def\syst_boxes_with_next_box_content_indeed +% {\syst_boxes_with_next_box_two\aftergroup\syst_boxes_with_next_box_one} + +\permanent\protected\def\dowithnextboxcontent#1#2% inside, after + {\afterassigned{#1\aftergrouped{#2}}% + \setbox\nextbox} + +\permanent\protected\def\dowithnextboxcontentcs#1#2% inside, after + {\afterassigned{#1\aftergroup#2}% + \setbox\nextbox} + +%D \macros +%D {llap, rlap, tlap, blap, clap} +%D +%D Some well known friends, but we implement them our own way. We want the macros to +%D work in both math and text mode. + +\def\syst_boxes_do_rlap{\hpack to \zeropoint{\box\nextbox\hss}\endgroup} +\def\syst_boxes_do_llap{\hpack to \zeropoint{\hss\box\nextbox}\endgroup} +\def\syst_boxes_do_clap{\hpack to \zeropoint{\hss\box\nextbox\hss}\endgroup} +\def\syst_boxes_do_tlap{\vpack to \zeropoint{\vss\box\nextbox}\endgroup} +\def\syst_boxes_do_blap{\vpack to \zeropoint{\box\nextbox\vss}\endgroup} + +\def\syst_boxes_rlap {\begingroup\dowithnextboxcs\syst_boxes_do_rlap\hbox} +\def\syst_boxes_llap {\begingroup\dowithnextboxcs\syst_boxes_do_llap\hbox} +\def\syst_boxes_clap {\begingroup\dowithnextboxcs\syst_boxes_do_clap\hbox} +\def\syst_boxes_math_clap{\mathpalette\syst_boxes_do_math_clap} +\def\syst_boxes_math_llap{\mathpalette\syst_boxes_do_math_llap} +\def\syst_boxes_math_rlap{\mathpalette\syst_boxes_do_math_rlap} + +\def\syst_boxes_do_math_clap#1#2{\syst_boxes_clap{\normalstartimath\mathsurround\zeropoint#1#2\normalstopimath}} +\def\syst_boxes_do_math_llap#1#2{\syst_boxes_llap{\normalstartimath\mathsurround\zeropoint#1#2\normalstopimath}} +\def\syst_boxes_do_math_rlap#1#2{\syst_boxes_rlap{\normalstartimath\mathsurround\zeropoint#1#2\normalstopimath}} + +\permanent\protected\def\rlap{\mathortext\syst_boxes_math_rlap\syst_boxes_rlap} +\permanent\protected\def\llap{\mathortext\syst_boxes_math_llap\syst_boxes_llap} +\permanent\protected\def\clap{\mathortext\syst_boxes_math_clap\syst_boxes_clap} +\permanent\protected\def\tlap{\begingroup\dowithnextboxcs\syst_boxes_do_tlap\vbox} +\permanent\protected\def\blap{\begingroup\dowithnextboxcs\syst_boxes_do_blap\vbox} + +%D in \LMTX\ this mechanism is obsolete! Use boxlines instead! + +%D \macros +%D {beginofshapebox, +%D reshapebox, doreshapebox, +%D flushshapebox, +%D innerflushshapebox, +%D shapebox, +%D ifreshapingbox} +%D +%D The next utility macro originates from some linenumbering mechanism. Due to +%D \TEX's advanced way of typesetting paragraphs, it's not easy to do things on a +%D line||by||line basis. This macro is able to reprocess a given box and can act +%D upon its vertical boxed components, such as lines. The unwinding sequence in this +%D macro is inspired by a \NTG\ workshop of David Salomon in June 1992. +%D +%D First we have to grab the piece of text we want to act upon. This is done by +%D means of the duo macros: +%D +%D \starttyping +%D \beginofshapebox +%D a piece of text +%D \endofshapebox +%D \stoptyping +%D +%D When all texts is collected, we can call \type {\reshapebox} and do something +%D with it's vertical components. We can make as much passes as needed. When we're +%D done, the box can be unloaded with \type {\flushshapebox}. The only condition in +%D this scheme is that \type {\reshapebox} must somehow unload the \BOX\ \type +%D {\shapebox}. +%D +%D An important aspect is that the content is unrolled bottom||up. The next example +%D illustrates this maybe unexpected characteristic. +%D +%D \startbuffer +%D \beginofshapebox +%D \em \input tufte +%D \endofshapebox +%D +%D \newcounter\LineNumber +%D +%D \reshapebox +%D {\doglobal\increment\LineNumber +%D \hbox{\llap{\LineNumber\hskip2em}\box\shapebox}} +%D +%D \flushshapebox +%D \stopbuffer +%D +%D \typebuffer +%D +%D \getbuffer +%D +%D As we can see, when some kind of numbering is done, we have to add a second pass. +%D +%D \startbuffer +%D \newcounter\LineNumber +%D \newcounter\NumberOfLines +%D +%D \reshapebox +%D {\doglobal\increment\NumberOfLines +%D \box\shapebox} +%D +%D \reshapebox +%D {\doglobal\increment\LineNumber +%D \hbox +%D {\llap{\LineNumber\ (\NumberOfLines)\hskip2em}% +%D \box\shapebox}% +%D \doglobal\decrement\NumberOfLines} +%D +%D \flushshapebox +%D \stopbuffer +%D +%D \typebuffer +%D +%D \getbuffer +%D +%D This example shows that the content of the box is still available after flushing. +%D Another feature is that only the last reshaping counts. Multiple reshaping can be +%D done by: +%D +%D \startbuffer +%D \beginofshapebox +%D \flushshapebox +%D \endofshapebox +%D +%D \reshapebox +%D {\doglobal\increment\LineNumber +%D \hbox{\llap{$\star$\hskip1em}\box\shapebox}% +%D \doglobal\decrement\NumberOfLines} +%D +%D \flushshapebox +%D \stopbuffer +%D +%D \typebuffer +%D +%D \getbuffer +%D +%D The macros are surprisingly easy to follow and in fact introduce no new concepts. +%D Nearly all books on \TEX\ show similar solutions for unwinding \BOXES. +%D +%D Some macros, like footnote ones, can be sensitive for reshaping, which can result +%D in an endless loop. We therefore offer: +%D +%D \starttyping +%D \ifreshapingbox +%D \stoptyping +%D +%D Some \CONTEXT\ commands are protected this way. Anyhow, reshaping is aborted +%D after 100 dead cycles. +%D +%D By the way, changing the height and depth of \BOX\ \type {\shapebox} results in +%D bad spacing. This means that for instance linenumbers etc. should be given zero +%D height and depth before being lapped into the margin. The previous examples +%D ignore this side effect, but beware! +%D +%D This is ancient stuff and proably not used any more but we keep it around or +%D maybe turn it into a module some day. It shows the kind of struggling that we +%D needed before \LUATEX\ came around. + +\newif \ifsomeshapeleft +\newif \ifreshapingbox +\newif \ifreshapingfailed % may save redundant runs + +\newbox \shapebox +\newcount \shapepenalty +\newdimen \shapekern +\newskip \shapeskip + +\newbox \newshapebox +\newbox \oldshapebox +\newbox \tmpshapebox + +\newcount \shapecounter + +\newevery \everyshapebox \relax + +\permanent\dimensiondef\shapesignal.12345678pt % or 12345sp + +\permanent\protected\def\reshapebox#1% + {\doreshapebox + {#1}% + {\penalty\shapepenalty}% + {\kern \shapekern }% + {\vskip \shapeskip }} + +\permanent\protected\def\doreshapebox#1#2#3#4% \shapebox, \shapepenalty, \shapekern, \shapeskip + {\global\reshapingfailedfalse + \ifzeropt\ht\oldshapebox + \setbox\newshapebox\emptyvbox + \else + \setbox\newshapebox\vbox % can be \vpack + {\unvcopy\oldshapebox + \setbox\newshapebox\emptybox + \shapecounter\zerocount + \doloop{\dodoreshapebox{#1}{#2}{#3}{#4}}}% + \setbox\newshapebox\box\tmpshapebox + \fi} + +% We will turn this into a \MKIV\ variant (we can use \type {\vpack} too). + +\permanent\protected\def\insertshapesignal + {\hpack to \shapesignal{\strut\hss}% plus \strut + \prevdepth\strutdp} % never \nointerlineskip + +\permanent\protected\def\restoreshapebox % compensates for the signal + {\global\setbox\tmpshapebox\vbox{\vskip-\lineheight\unvcopy\oldshapebox}} + +\permanent\def\dodoreshapebox#1#2#3#4% \shapebox, \shapepenalty, \shapekern, \shapeskip + {\ifnum\lastnodetype=\gluenodecode + \shapeskip\lastskip + \global\setbox\tmpshapebox\vbox{#4\unvbox\tmpshapebox}% + \unskip + \orelse\ifnum\lastnodetype=\kernnodecode + \shapekern\lastkern + \global\setbox\tmpshapebox\vbox{#3\unvbox\tmpshapebox}% + \unkern + \orelse\ifnum\lastnodetype=\penaltynodecode + \shapepenalty\lastpenalty + \global\setbox\tmpshapebox\vbox{#2\unvbox\tmpshapebox}% + \unpenalty + \orelse\ifnum\lastnodetype<\zeropoint + \exitloop + \else + \setbox\shapebox\lastbox + \ifvoid\shapebox + \orelse\ifdim\wd\shapebox=\shapesignal\relax + \exitloop + \else + \shapecounter\zerocount + \global\setbox\tmpshapebox\vbox{#1\unvbox\tmpshapebox}% + \fi + \fi + \ifnum\shapecounter>100 % can be less + \global\reshapingfailedtrue + \message{!!forced exit from shapebox \the\lastnodetype !!}% + \restoreshapebox + \exitloop + \else + \advance\shapecounter \plusone + \fi} + +\permanent\protected\def\beginofshapebox + {\setbox\oldshapebox\vbox + \bgroup + \reshapingboxtrue + \the\everyshapebox + \insertshapesignal} + +\permanent\protected\def\endofshapebox + {\endgraf + \egroup} + +\aliased\let\beginshapebox\beginofshapebox +\aliased\let\endshapebox \endofshapebox + +\permanent\protected\def\flushshapebox + {\bgroup + \ifzeropt\ht\newshapebox + \else + % make \prevdepth legal + % \par before the next \vskip gives far worse results + \ifdim\parskip>\zeropoint\vskip\parskip\else\par\fi + % and take a look + \ifdim\prevdepth=-\thousandpoint + \prevdepth\zeropoint + \fi + \ifdim\prevdepth<\zeropoint\relax + % something like a line or a signal or ... + \donetrue + \orelse\ifinner + % not watertight and not ok + \donefalse + \orelse\ifdim\pagegoal=\maxdimen + \donetrue + \else + % give the previous line a normal depth + \donetrue + {\forgeteverypar\verticalstrut}\nobreak + \kern-\struttotal % geen \vskip + \kern-\parskip + % \vskip-\strutdp + \fi + \scratchdimen\dp\newshapebox + \unvbox\newshapebox + % \prevdepth=0pt and \dp\newshapebox depend on last line + \kern-\scratchdimen % ?? + % now \prevdepth=0pt + \ifdone + \kern\strutdp + \prevdepth\strutdp + \fi + \fi + \egroup} + +%D In real inner situations we can use: +%D +%D \starttyping +%D \flushinnershapebox +%D \stoptyping +%D +%D This one is used in \type{\framed}. + +% The kern fails on for instance: +% +% \omlijnd[offset=0pt,hoogte=8mm,uitlijnen={rechts,laho}]{\bfa test} + +\permanent\protected\def\innerflushshapebox + {\ifzeropt\ht\newshapebox \else + \unvcopy\newshapebox\relax % unvcopy ! else spacing problem + % \kern-\dp\newshapebox\relax + \fi} + +%D For absolute control, one can use \type {\doreshapebox} directly. This macro +%D takes four arguments, that take care of: +%D +%D \startitemize[n,packed] +%D \item \type{\shapebox} +%D \item \type{\shapepenalty} +%D \item \type{\shapekern} +%D \item \type{\shapeskip} +%D \stopitemize + +%D \macros +%D {shapedhbox} +%D +%D When constructing a new box, using the content of \type {\shapebox}, one can best +%D use \type {\shapedhbox} instead of \type {\hbox}, since it manages the height and +%D depth of the line. + +\permanent\protected\def\shapedhbox % lines with non strutted dimensions have + {\expanded{\dowithnextbox % interlineskip so if we want the original + {\ht\nextbox\the\ht\shapebox % spacing, we need to preserve the original + \dp\nextbox\the\dp\shapebox % height and depth which is definitely + \box\nextbox}} % needed if we apply struts to the 'new' + \hbox} % box or do something that changed ist size + +%D Till here obsolete. + +%D \macros +%D {hyphenatedword, +%D hyphenatedpar, +%D hyphenatedfile, +%D dohyphenateword} +%D +%D We no longer use the pure \TEX\ variant. In due time we will report some more +%D advanced statistics. +%D +%D \starttyping +%D \showhyphens{dohyphenatedword} +%D \stoptyping + +\permanent\protected\def\doshowhyphenatednextbox + {\clf_showhyphenatedinlist\nextbox} + +\permanent\protected\def\showhyphens % hpack: so no processing (we hyphenate in lua) + {\dowithnextboxcs\doshowhyphenatednextbox\hpack} + +%D The following macros are seldom used but handy for tracing. +%D +%D \starttyping +%D \hyphenatedword{dohyphenatedword} +%D \hyphenatedpar {\dorecurse{10}{dohyphenatedword }} +%D \hyphenatedfile{tufte} +%D \stoptyping + +\def\syst_boxes_hyphenatednextbox {\clf_hyphenatedlist\nextbox false\relax\unhbox\nextbox} +\def\syst_boxes_hyphenatednextboxcolor{\clf_hyphenatedlist\nextbox true \relax\unhbox\nextbox} + +\permanent\protected\def\hyphenatedword {\dowithnextboxcs\syst_boxes_hyphenatednextbox\hbox} +\permanent\protected\def\hyphenatedpar {\dowithnextboxcs\syst_boxes_hyphenatednextbox\hbox} +\permanent\protected\def\hyphenatedfile #1{\dowithnextboxcs\syst_boxes_hyphenatednextbox\hbox{\readfile{#1}\donothing\donothing}} +\permanent\protected\def\hyphenatedcoloredword{\dowithnextboxcs\syst_boxes_hyphenatednextboxcolor\hbox} + +%D \macros +%D {processtokens} +%D +%D We fully agree with (most) typographers that inter||letter spacing is only +%D permitted in fancy titles, we provide a macro that can be used to do so. Because +%D this is (definitely and fortunately) no feature of \TEX, we have to step through +%D the token list ourselves. +%D +%D \starttyping +%D \processtokens {before} {between} {after} {space} {tokens} +%D \stoptyping +%D +%D An example of a call is: +%D +%D \startbuffer +%D \processtokens {[} {+} {]} {\space} {hello world} +%D \stopbuffer +%D +%D \typebuffer +%D +%D This results in: +%D +%D \getbuffer +%D +%D The list of tokens may contain spaces, while \type {\\}, \type {{}} and \type {\ +%D } are handled as space too. + +%D This can be done in a more modern way but for nostalgic reasons we keep it. + +\mutable\let\nextprocessedtoken\empty + +\mutable\let\before \relax % for now mutable +%mutable\let\between\relax % is a math character +\mutable\let\after \relax % for now mutable +\mutable\let\white \relax % for now mutable + +\permanent\protected\def\processtokens#1#2#3#4#5% + {\begingroup + \enforced\permanent\def\space{ }% + \enforced\let\\\space + \enforced\def\before {#1}% + \enforced\def\between{#2}% + \enforced\def\after {#3}% + \enforced\def\white {#4}% + \enforced\let\m_syst_boxes_before\before + \syst_boxes_processtokens#5\s!e_o_t_token + \endgroup} + +\def\syst_boxes_processtokens% the space after = is essential + {\afterassignment\syst_boxes_do_processtokens\let\nextprocessedtoken= } + +\def\syst_boxes_redo_processedtoken + {\dowithnextbox + {\before{\copy\nextbox}% \before can use nextbox several times + \enforced\let\before\between + \syst_boxes_processtokens} + \hbox\bgroup} + +\def\syst_boxes_do_processtokens + {\ifx\nextprocessedtoken\s!e_o_t_token + \after + \orelse\ifx\nextprocessedtoken\bgroup + \expandafter\syst_boxes_redo_processedtoken + \else + \expandafter\if\space\nextprocessedtoken + \after\white + \enforced\let\before\m_syst_boxes_before + \else + \before\nextprocessedtoken + \enforced\let\before\between + \fi + \expandafter\syst_boxes_processtokens + \fi} + +%D \macros +%D {doboundtext} +%D +%D Sometimes there is not enough room to show the complete (line of) text. In such a +%D situation we can strip of some characters by using \type {\doboundtext}. When the +%D text is wider than the given width, it's split and the third argument is +%D appended. When the text to be checked is packed in a command, we'll have to use +%D \type {\expandafter}. +%D +%D \starttyping +%D \doboundtext{a very, probably to long, text}{3cm}{...} +%D \stoptyping +%D +%D When calculating the room needed, we take the width of the third argument into +%D account, which leads to a bit more complex macro than needed at first sight. +%D +%D Sort of obsolete I guess: + +\def\syst_boxes_boundtext#1% + {\setbox\scratchboxone\hbox{#1}% + \advance\scratchdimen -\wd\scratchboxone + \ifdim\scratchdimen>\zeropoint\relax#1\fi} + +\permanent\protected\def\doboundtext#1#2#3% still used? + {\hbox + {\setbox\scratchbox\hbox{#1}% + \scratchdimen#2\relax + \ifdim\wd\scratchbox>\scratchdimen + \setbox\scratchbox\hbox{#3}% + \advance\scratchdimen -\wd\scratchbox + \handletokens#1\with\syst_boxes_boundtext + \fi + \box\scratchbox}} + +%D \macros +%D {limitatetext} +%D +%D A bit more beautiful alternative for the previous command is the next one. This +%D command is more robust because we let \TEX\ do most of the job. The previous +%D command works better on text that cannot be hyphenated. +%D +%D \starttyping +%D \limitatetext {text} {width} {sentinel} +%D \limitatetext {text} {-width} {prelude} +%D \stoptyping +%D +%D When no width is given, the whole text comes available. The sentinel is optional. +%D This is about the third version. + +\ifdefined\fakecompoundhyphen\else \let\fakecompoundhyphen\relax \fi +\ifdefined\veryraggedright \else \def\veryraggedright{\raggedright} \fi + +%D See \MKIV\ file for the older implementation. + +\let\m_syst_boxes_left \empty +\let\m_syst_boxes_right\empty + +\permanent\protected\def\limitatetext#1#2#3% + {% we could also split in \LUA + \splitatcomma{#2}\m_syst_boxes_left\m_syst_boxes_right + \limitated + \ifempty\m_syst_boxes_left\else + left \m_syst_boxes_left + \fi + \ifempty\m_syst_boxes_right\else + right \m_syst_boxes_right + \fi + strip true + sentinel {#3} + text {#1} + \relax} + +%D Undocumented bonus (see wiki): +%D +%D \starttyping +%D \limitatefirstline{\input tufte\relax}{10cm}{\unknown} +%D \stoptyping + +\permanent\protected\def\limitatefirstline#1#2#3% + {\hbox\bgroup\strut % \hpack + \setbox\scratchbox\hbox{\begstrut#1\endstrut}% + \ifdim\wd\scratchbox>#2\relax + \setbox\scratchbox\hbox{#3}% + \hsize#2\relax + \advance\hsize-\wd\scratchbox + \setbox\scratchbox\vbox{\forgetall\veryraggedright#1}% + \setbox\scratchbox\vsplit\scratchbox to \lineheight + \vbox + {\unvbox\scratchbox + \global\setbox\plusone\lastbox + \global\setbox\plusone\hbox{\strut\unhbox\plusone}% + \hbox % to #2 % \hpack + {\unless\ifdefined\clip + \box\plusone + \orelse\ifdim\wd\plusone>\hsize + \lower\strutdepth\hpack{\clip[\c!width=\hsize,\c!height=\lineheight]{\hpack{\raise\strutdepth\box\plusone}}}% + \else + \box\plusone + \fi + \removeunwantedspaces#3}}% \removeunwantedspaces\hss#3}}% + \else + #1% + \fi + \egroup} + +%D \macros +%D {processisolatedwords,processisolatedchars} +%D +%D \startbuffer +%D \processisolatedchars{some more words} \ruledhbox \par +%D \processisolatedchars{and some $x + y = z$ math} \ruledhbox \par +%D \processisolatedchars{and a \hbox{$x + y = z$}} \ruledhbox \par +%D \processisolatedwords{some more words} \ruledhbox \par +%D \processisolatedwords{and some $x + y = z$ math} \ruledhbox \par +%D \processisolatedwords{and a \hbox{$x + y = z$}} \ruledhbox \par +%D \stopbuffer +%D +%D \typebuffer \blank \getbuffer \blank + +% todo: provide variant with #1 picked up as box + +\permanent\protected\def\processisolatedchars#1#2% + {\dontleavehmode + \begingroup + \setbox\scratchbox\hbox{\settrialtypesetting#2{\savecurrentattributes{pic}}}% + \setbox\scratchbox\hbox{\restorecurrentattributes{pic}#1}% + \clf_applytobox + method {char}% + box \scratchbox + command {\csstring#2}% + nested true% + \relax + \endgroup} + +\permanent\protected\def\processisolatedwords#1#2% + {\dontleavehmode + \begingroup + \setbox\scratchbox\hbox{\settrialtypesetting#2{\savecurrentattributes{pic}}}% + \setbox\scratchbox\hbox{\restorecurrentattributes{pic}#1}% + \clf_applytobox + method {word}% + box \scratchbox + command {\csstring#2}% + nested true% + \relax + \endgroup} + +%D A variant: + +\permanent\protected\def\applytocharacters#1% + {\dontleavehmode + \dowithnextbox{\clf_applytobox + method {char}% + box \nextbox + command {\csstring#1}% + nested true% + \relax}% + \hbox} + +\permanent\protected\def\applytowords#1% + {\dontleavehmode + \dowithnextbox{\clf_applytobox + method {word}% + box \nextbox + command {\csstring#1}% + nested true% + \relax}% + \hbox} + +%D The old call: + +\permanent\protected\def\processwords#1% + {\processisolatedwords{#1}\processword} + +\mutable\let\processword\relax + +\permanent\protected\def\applytosplitstringchar#1#2% + {\dontleavehmode\clf_processsplit + data {#2}% + command {\csstring#1}% + method {char}% + \relax} + +\permanent\protected\def\applytosplitstringword#1#2% + {\dontleavehmode\clf_processsplit + data {#2}% + command {\csstring#1}% + method {word}% + \relax} + +\permanent\protected\def\applytosplitstringline#1#2% + {\dontleavehmode\clf_processsplit + data {#2}% + command {\csstring#1}% + method {line}% + \relax} + +\permanent\protected\def\applytosplitstringcharspaced#1#2% + {\dontleavehmode\clf_processsplit + data {#2}% + command {\csstring#1}% + method {char}% + spaced true% + \relax} + +\permanent\protected\def\applytosplitstringwordspaced#1#2% + {\dontleavehmode\clf_processsplit + data {#2}% + command {\csstring#1}% + method {word}% + spaced true% + \relax} + +\permanent\protected\def\applytosplitstringlinespaced#1#2% + {\dontleavehmode\clf_processsplit + data {#2}% + command {\csstring#1}% + method {line}% + spaced true% + \relax} + +%D \macros +%D {sbox} +%D +%D This is a rather strange command. It grabs some box content and and limits the +%D size to the height and depth of a \type {\strut}. The resulting bottom||alligned +%D box can be used aside other ones, without disturbing the normal baseline +%D distance. +%D +%D \startbuffer +%D \ruledhbox to .5\hsize{\sbox{eerste\par tweede \par derde}} +%D \stopbuffer +%D +%D \typebuffer +%D +%D Shows up as: +%D +%D \startexample +%D \vskip3\baselineskip +%D \getbuffer +%D \stopexample +%D +%D Before displaying the result we added some skip, otherwise the first two lines +%D would have ended up in the text. This macro can be useful when building +%D complicated menus, headers and footers and|/|or margin material. + +\permanent\protected\def\sbox + {\vpack\bgroup + \dowithnextboxcs\syst_boxes_sbox_finish\vbox} + +\def\syst_boxes_sbox_finish + {\boxyoffset\nextbox-\strutdp + \dp\nextbox\strutdp + \ht\nextbox\strutht + \box\nextbox + \egroup} + +%D A variant on this: +%D +%D \starttyping +%D xx \ruledhbox{\inlinedbox{\tfd test}} xx +%D \stoptyping + +\permanent\protected\def\inlinedbox + {\bgroup + \dowithnextboxcs\syst_boxes_inlined_finish\hbox} + +\def\syst_boxes_inlined_finish + {\boxyoffset\nextbox-\dimexpr(\htdp\nextbox-\lineheight)/\plustwo+\strutdp\relax + \ht\nextbox\strutht + \dp\nextbox\strutdp + \box\nextbox + \egroup} + +%D \macros +%D {struttedbox} +%D +%D This boxing macro limits the height and depth to those of a strut. + +\permanent\protected\def\struttedbox + {\hpack\bgroup + \dowithnextboxcs\syst_boxes_struttedbox_finish\hbox} + +\def\syst_boxes_struttedbox_finish + {\dp\nextbox\strutdepth + \ht\nextbox\strutheight + \box\nextbox + \egroup} + +%D \macros +%D {topskippedbox} +%D +%D This macro compensates the difference between the topskip and strutheight. Watch +%D how we preserve the depth when it equals strutdepth. + +\permanent\protected\def\topskippedbox + {\hpack\bgroup\dowithnextboxcs\syst_boxes_topskippedbox_finish\hbox} + +\def\syst_boxes_topskippedbox_finish + {\edef\m_boxes_tmp{\ifdim\strutdepth=\dp\nextbox\dp\nextbox\the\dp\nextbox\fi}% + \lower\topskip\hpack{\raise\strutheight\box\nextbox}% + \m_boxes_tmp + \egroup} + +%D \macros +%D {centeredbox, centerednextbox} +%D +%D Here is another strange one. This one offers a sort of overlay with positive or +%D negative offsets. This command can be used in well defined areas where no offset +%D options are available. We first used it when building a button inside the margin +%D footer, where the button should have a horizontal offset and should be centered +%D with respect to the surrounding box. The last of the three examples we show below +%D says: +%D +%D \starttyping +%D \vsize=3cm +%D \hsize=3cm +%D \ruledvbox to \vsize +%D {\centeredbox height .5cm width -1cm +%D {\vrule width \hsize height \vsize}}} +%D \stoptyping +%D +%D Here the \type {\ruledvbox} just shows the surrounding box and \type {\vrule} is +%D used to show the centered box. +%D +%D \def\AnExample#1#2% +%D {\vsize=3cm +%D \hsize=3cm +%D \ruledvbox to \vsize +%D {\centeredbox height #1 width #2 +%D {\color[green]{\vrule width \hsize height \vsize}}}} +%D +%D \startlinecorrection +%D \startcombination[3*1] +%D {\AnExample {-1cm} {.5cm}} {} +%D {\AnExample {.5cm} {-1cm}} {} +%D {\AnExample {-1cm} {-.5cm}} {} +%D \stopcombination +%D \stoplinecorrection +%D +%D This command takes two optional arguments: \type {width} and \type {height}. +%D Observing readers can see that we use \TEX's own scanner for grabbing these +%D arguments: \type {#1#} reads everyting till the next brace and passes it to both +%D rules. The setting of the box dimensions at the end is needed for special cases. +%D The dimensions of the surrounding box are kept intact. This commands handles +%D positive and negative dimensions (which is why we need two boxes with rules). + +\permanent\protected\def\centeredbox#1#% height +/-dimen width +/-dimen + {\bgroup + \dontcomplain + \forgetall + \scangivendimensions#1\relax + \advance\vsize\givenheight + \advance\hsize\givenwidth + \dowithnextboxcs\syst_boxes_centered_finish + \hbox} + +\def\syst_boxes_centered_finish + {\boxxoffset\nextbox.5\dimexpr + \hsize + -\wd\nextbox + -\givenwidth + \relax + \boxyoffset\nextbox.5\dimexpr + \vsize + -\ht\nextbox + +\dp\nextbox + -\givenheight + \relax + \wd\nextbox\dimexpr\hsize-\givenwidth \relax + \ht\nextbox\dimexpr\vsize-\givenheight\relax + \dp\nextbox\zeropoint + \box\nextbox + \egroup} + +%D For those who don't want to deal with \type {\hsize} and \type {\vsize}, we have: +%D +%D \starttyping +%D \centerednextbox width 2bp height 2bp +%D {\framed[width=100bp,height=100bp]{}} +%D \stoptyping +%D +%D Do you see why we call this one \type {next}? + +\permanent\protected\def\centerednextbox#1#% + {\bgroup + \dowithnextbox + {\hsize\wd\nextbox + \vsize\ht\nextbox + \centeredbox#1{\box\nextbox}% + \egroup} + \hbox} + +%D \macros +%D {centerbox} +%D +%D Centering on the available space is done by: +%D +%D \starttyping +%D \centerbox <optional specs> {content} +%D \stoptyping +%D +%D When omitted, the current \type {\hsize} and \type {\vsize} are used. Local +%D dimensions are supported. + +\permanent\protected\def\centerbox#1#% optional height +/-dimen width +/-dimen + {\bgroup + \dowithnextbox + {\setlocalhsize + \setbox\scratchbox\hpack{\vrule\s!width \zeropoint#1}% + \ifzeropt\wd\scratchbox\else\hsize\wd\scratchbox\fi + \setbox\scratchbox\vpack{\hrule\s!height\zeropoint#1}% + \ifzeropt\ht\scratchbox\else\vsize\ht\scratchbox\fi + \vpack to \vsize{\vss\hpack to \hsize{\hss\box\nextbox\hss}\vss}% + \egroup}% + \hbox} + +%D \macros +%D {setrigidcolumnhsize,rigidcolumnbalance,rigidcolumnlines} +%D +%D These macros are copied from the \TEX book, page~397, and extended by a macro +%D that sets the \type {\hsize}. +%D +%D \starttyping +%D \setrigidcolumnhsize {total width} {distance} {n} +%D \rigidcolumnbalance {box} +%D \stoptyping +%D +%D Both these macros are for instance used in typesetting footnotes. The following +%D flags influence the process. + +\newif\ifalignrigidcolumns +\newif\ifstretchrigidcolumns +\newif\iftightrigidcolumns % if true: just a vbox, no depth/noflines/gridsnap corrrections + +\mutable\let\rigidcolumnlines\!!zerocount + +\newbox \rigidcolumnbox +\newdimen\rigidhsize +\newcount\rigidcolumns + +\permanent\protected\def\setrigidcolumnhsize#1#2#3% todo: \dimexpr + {\global\rigidhsize\hsize + \global\rigidcolumns#3\relax + \hsize#1\relax + \scratchdimen -#2\relax + \multiply\scratchdimen #3\relax + \advance\scratchdimen #2\relax + \advance\hsize \scratchdimen + \divide\hsize #3\relax} + +% == +% +% \def\setrigidcolumnhsize#1#2#3% +% {\global\rigidhsize\hsize +% \rigidcolumns#3\relax +% \hsize\dimexpr(#1-\numexpr#3-1\relax\dimexpr#2\relax)/#3\relax} + +\permanent\protected\def\rigidcolumnbalance#1% + {\ifnum\rigidcolumns=1 % tzt ook h/d correctie + \ifinner\ifhmode\box\else\unvbox\fi\else\unvbox\fi#1\relax + \else + \vbox % \vpack + {\forgetall + \nopenalties + \dontcomplain + \setbox\rigidcolumnbox\vbox + {\line{}\goodbreak\unvbox#1\removebottomthings}% + \splittopskip\openstrutheight + \setbox\scratchbox\vsplit\rigidcolumnbox to \zeropoint + \ifcase\rigidcolumnlines\relax + % \iffalse + % % maybe some day an option + % \scratchskip\ht\rigidcolumnbox + % \advance\scratchskip\dp\rigidcolumnbox + % \getnoflines\scratchskip + % \ifodd\noflines + % \advance\noflines\plusone + % \fi + % \divide\noflines\rigidcolumns + %\else + \scratchdimen\ht\rigidcolumnbox + \divide\scratchdimen \rigidcolumns + \getnoflines\scratchdimen + %\fi + \else + \noflines\rigidcolumnlines % to be sure + \fi + \scratchdimen\noflines\lineheight + % new: we now loop so that we don't loose content + % since in practice we also use this macro for + % funny lineheights and border cases + \setbox0=\box\rigidcolumnbox + \doloop + {\setbox\rigidcolumnbox=\copy0 + \setbox\scratchbox\hpack to \rigidhsize + {\dorecurse\rigidcolumns + {\setbox\scratchbox\vsplit\rigidcolumnbox to \scratchdimen + \dp\scratchbox\openstrutdepth + \setbox\scratchbox\vtop + \ifalignrigidcolumns to + \ifstretchrigidcolumns\vsize\else\scratchdimen\fi + \fi + {\unvbox\scratchbox}% + \wd\scratchbox\hsize + \box\scratchbox + \hfill}% + \hfillneg}% + \ifvoid\rigidcolumnbox\exitloop\else\advance\scratchdimen\lineheight\fi}% + \iftightrigidcolumns + \setbox\scratchbox\hpack{\raise\dp\scratchbox\box\scratchbox}% + \else + \advance\scratchdimen -\openstrutdepth + \setbox\scratchbox\hpack{\raise\scratchdimen\box\scratchbox}% + \dp\scratchbox\openstrutdepth + \ht\scratchbox\scratchdimen + \fi + \box\scratchbox}% + \fi} + +%D \macros +%D {startvboxtohbox,stopvboxtohbox,convertvboxtohbox} +%D +%D Here is another of Knuth's dirty tricks, as presented on pages 398 and 399 of the +%D \TEX book. These macros can be used like: +%D +%D \starttyping +%D \vbox +%D \bgroup +%D \startvboxtohbox ... \stopvboxtohbox +%D \startvboxtohbox ... \stopvboxtohbox +%D \startvboxtohbox ... \stopvboxtohbox +%D \egroup +%D +%D \vbox +%D \bgroup +%D \convertvboxtohbox +%D \egroup +%D \stoptyping +%D +%D These macros are used in reformatting footnotes, so they do what they're meant +%D for. + +\newdimen\vboxtohboxslack +\newdimen\hboxestohboxslack + +%D Create line and fake height of paragraph by messign with heights: a nice hack by +%D DEK himself. + +%\protected\def\setvboxtohbox +% {\bgroup +% \ifdim\baselineskip<16pt \relax +% \scratchdimen\baselineskip +% \multiply\scratchdimen 1024 +% \else +% \message{cropping \baselineskip to 16pt}% +% \scratchdimen\maxdimen +% \fi +% \divide\scratchdimen \hsize +% \multiply\scratchdimen 64 +% \xdef\vboxtohboxfactor{\withoutpt\the\scratchdimen}% +% \egroup} +% +% \protected\def\startvboxtohbox +% {\bgroup +% \setvboxtohbox +% \setbox\scratchbox\hbox\bgroup} +% +% \protected\def\stopvboxtohbox +% {\ifcase\vboxtohboxslack\else\hskip\zeropoint\s!minus\vboxtohboxslack\fi +% \egroup +% \dp\scratchbox\zeropoint +% \ht\scratchbox\vboxtohboxfactor\wd\scratchbox +% \box\scratchbox +% \egroup} + +% More modern: + +% \definesystemattribute[vboxtohboxseparator][public] + +%newbox\d_syst_boxes_vboxtohbox +\newbox\d_syst_boxes_separator + +\permanent\protected\def\startvboxtohboxseparator + {\setbox\d_syst_boxes_separator\hbox attr \vboxtohboxseparatorattribute\plusone\bgroup} + +\permanent\protected\def\stopvboxtohboxseparator + {\egroup} + +\permanent\protected\def\startvboxtohbox + {\begingroup + \setbox\scratchbox\hbox\bgroup} + +\permanent\protected\def\stopvboxtohbox + {\ifvoid\d_syst_boxes_separator + \hskip\zeropoint\ifcase\vboxtohboxslack\else\s!minus\vboxtohboxslack\fi % we really need a skip + \else + \box\d_syst_boxes_separator + \fi + \egroup + \clf_hboxtovbox\scratchbox + \box\scratchbox + \endgroup} + +% A possible reconstruction: + +\permanent\protected\def\convertvboxtohbox + {\makehboxofhboxes + \setbox\scratchboxone\hpack{\unhbox\scratchboxone\removehboxes}% \hpack + \noindent\unhbox\scratchboxone\par} + +\permanent\protected\def\makehboxofhboxes + {\setbox\scratchboxone\emptyhbox + \loop % \doloop { .. \exitloop .. } + \setbox\scratchboxtwo\lastbox + \ifhbox\scratchboxtwo + \setbox\scratchboxone\hpack{\box\scratchboxtwo\unhbox\scratchboxone}% + \repeat} + +\permanent\protected\def\removehboxes + {\setbox\scratchboxone\lastbox + \ifhbox\scratchboxone + {\removehboxes}\unhbox\scratchboxone + \fi} + +% And one special for notes: + +\permanent\protected\def\starthboxestohbox + {\bgroup + \setbox\scratchbox\vbox\bgroup} + +\permanent\protected\def\stophboxestohbox + {\egroup + \clf_vboxlisttohbox\scratchbox\nextbox\dimexpr\hboxestohboxslack\relax + \dontleavehmode + \unhbox\nextbox + \removeunwantedspaces + \par + \egroup} + +%D \macros +%D {unhhbox} +%D +%D The next macro is used in typesetting inline headings. Let's first look at the +%D macro and then show an example. + +\newbox \unhhedbox +\newbox \hhbox +\newdimen \lasthhboxwidth +\newskip \hhboxindent + +\permanent\protected\def\unhhbox#1\with#2% + {\bgroup + \nopenalties + \dontcomplain + \forgetall + \setbox\unhhedbox\vbox{\hskip\hhboxindent\strut\unhbox#1}% => \hsize + \doloop + {\setbox\hhbox\vsplit\unhhedbox to \lineheight + \ifvoid\unhhedbox + \setbox\hhbox\hbox{\strut\hboxofvbox\hhbox}% \hpack + \fi + \ht\hhbox\strutht + \dp\hhbox\strutdp + \ifzeropt\hhboxindent\else + \setbox\hhbox\hpack{\kern-\hhboxindent\box\hhbox}% + \hhboxindent\zeropoint + \fi + \global\lasthhboxwidth\wd\hhbox + #2\relax + \ifvoid\unhhedbox + \exitloop + \else + \hskip\zeropoint \s!plus \zeropoint + \fi}% + \egroup} + +\def\syst_boxes_hboxofvbox + {\setbox0\vpack{\unvbox\scratchcounter\global\setbox1\lastbox}% + \unhbox1 + \egroup} + +\permanent\protected\def\hboxofvbox + {\bgroup + \afterassignment\syst_boxes_hboxofvbox + \scratchcounter=} + +%D This macro can be used to break a paragraph apart and treat each line seperately, +%D for instance, making it clickable. The main complication is that we want to be +%D able to continue the paragraph, something that's needed in the in line section +%D headers. +%D +%D \startbuffer +%D \setbox0=\hbox{\input tufte \relax} +%D \setbox2=\hbox{\input knuth \relax} +%D \unhhbox0\with{\ruledhbox{\box\hhbox}} +%D \hskip1em plus 1em minus 1em +%D \hhboxindent=\lasthhboxwidth +%D \advance\hhboxindent by \lastskip +%D \unhhbox2\with{\ruledhbox{\box\hhbox}} +%D \stopbuffer +%D +%D \getbuffer +%D +%D This piece of text was typeset by saying: +%D +%D \typebuffer +%D +%D Not that nice a definition, but effective. Note the stretch we've build in the +%D line that connects the two paragraphs. + +%D \macros +%D {doifcontent} +%D +%D When processing depends on the availability of content, one can give the next +%D macro a try. +%D +%D \starttyping +%D \doifcontent{pre content}{post content}{no content}\somebox +%D \stoptyping +%D +%D Where \type {\somebox} is either a \type {\hbox} or \type {\vbox}. If the +%D dimension of this box suggest some content, the resulting box is unboxed and +%D surrounded by the first two arguments, else the third arguments is executed. + +\permanent\protected\def\doifcontent#1#2#3% + {\dowithnextbox + {\ifhbox\nextbox + \ifdim\wd\nextbox>\zeropoint + #1\unhbox\nextbox#2\relax + \else + #3\relax + \fi + \else + \ifdim\ht\nextbox>\zeropoint + #1\unvbox\nextbox#2\relax + \else + #3\relax + \fi + \fi}} + +%D So when we say: +%D +%D \startbuffer +%D \doifcontent{[}{]}{}\hbox{content sensitive typesetting} +%D +%D \doifcontent{}{\page}{}\vbox{content sensitive typesetting} +%D +%D \doifcontent{}{}{\message{Didn't you forget something?}}\hbox{} +%D \stopbuffer +%D +%D \typebuffer +%D +%D We get: +%D +%D \getbuffer +%D +%D Where the last call of course does not show up in this document, but definitely +%D generates a confusing message. + +%D \macros +%D {processboxes} +%D +%D The next macro gobble boxes and is for instance used for overlays. First we show +%D the general handler. + +\newbox\processbox % public : this is the one where \nextbox's end up in + +\let\syst_boxes_process_indeed\relax + +\permanent\protected\def\processboxes#1% + {\bgroup + \def\syst_boxes_process_indeed{#1}% #1 can be redefined halfway + \setbox\processbox\emptybox + \doifelsenextbgroup\syst_boxes_process_yes\syst_boxes_process_nop} + +\def\syst_boxes_process_yes + {\dowithnextboxcs\syst_boxes_process_content\hbox} + +\def\syst_boxes_process_content + {\removeunwantedspaces + \syst_boxes_process_indeed % takes \nextbox makes \processbox + \doifelsenextbgroup\syst_boxes_process_yes\syst_boxes_process_nop} + +\protected\def\syst_boxes_process_nop + {\removeunwantedspaces + \box\processbox + \egroup} + +%D \macros +%D {startoverlay} +%D +%D We can overlay boxes by saying: +%D +%D \startbuffer +%D \startoverlay +%D {\framed{hans}} +%D {\framed[width=3cm]{ton}} +%D {\framed[height=2cm]{oeps}} +%D \stopoverlay +%D \stopbuffer +%D +%D \typebuffer +%D +%D shows up as: +%D +%D \leavevmode\getbuffer + +\permanent\def\boxisempty#1% + {\ifdim\wd#1=\zeropoint + \ifdim\ht#1=\zeropoint + \ifdim\dp#1=\zeropoint + \zerocount + \else + \plusone + \fi + \else + \plusone + \fi + \else + \plusone + \fi} + +\def\syst_boxes_overlay_process + {\ifcase\boxisempty\nextbox\else + \syst_boxes_overlay_process_indeed + \fi} + +\def\syst_boxes_overlay_process_indeed + {%\removeunwantedspaces % already done + \scratchdepth\dp\ifdim\dp\nextbox>\dp\processbox\nextbox\else\processbox\fi + \ifdim\ht\nextbox>\ht\processbox + \setbox\processbox\vpack to \ht\nextbox {\dp\processbox\zeropoint\vss\box\processbox\vss}% + \else + \setbox\nextbox \vpack to \ht\processbox{\dp\nextbox \zeropoint\vss\box\nextbox \vss}% + \fi + \dp\nextbox \scratchdepth + \dp\processbox\scratchdepth + \scratchwidth\wd\ifdim\wd\nextbox>\wd\processbox\nextbox\else\processbox\fi + \setbox\processbox\hpack to \scratchwidth + {\hpack to \scratchwidth{\hss\box\processbox\hss}% + \kern-\scratchwidth + \hpack to \scratchwidth{\hss\box\nextbox \hss}}} + +\permanent\protected\def\startoverlay + {\bgroup + \enforced\aliased\let\stopoverlay\egroup + \processboxes\syst_boxes_overlay_process} + +\aliased\let\stopoverlay\relax + +%D \macros +%D {fakebox} +%D +%D The next macro is a rather silly one, but saves space. +%D +%D \starttyping +%D \hbox{\fakebox0} +%D \stoptyping +%D +%D returns an empty box with the dimensions of the box specified, here being zero. + +\permanent\protected\def\fakebox + {\bgroup + \afterassignment\syst_boxes_fakebox_finish\scratchcounter} + +\def\syst_boxes_fakebox_finish + {\setbox\scratchbox\ifhbox\scratchcounter\emptyhbox\else\emptyvbox\fi + \wd\scratchbox\wd\scratchcounter + \ht\scratchbox\ht\scratchcounter + \dp\scratchbox\dp\scratchcounter + \box\scratchbox + \egroup} + +%D \macros +%D {lbox,rbox,cbox,tbox,bbox} +%D +%D Here are some convenient alternative box types: +%D +%D \starttyping +%D \lbox{text ...} +%D \cbox{text ...} +%D \rbox{text ...} +%D \stoptyping +%D +%D Are similar to \type {\vbox}, which means that they also accept something like +%D \type {to 3cm}, but align to the left, middle and right. These box types can be +%D used to typeset paragraphs. + +\def\syst_boxes_lrc_process#1% + {\bgroup + \forgetall + \enforced\let\\\endgraf + #1% + \let\nexttoken} + +\permanent\protected\def\lbox#1#{\vbox#1\syst_boxes_lrc_process\raggedleft } +\permanent\protected\def\cbox#1#{\vbox#1\syst_boxes_lrc_process\raggedcenter} +\permanent\protected\def\rbox#1#{\vbox#1\syst_boxes_lrc_process\raggedright } + +\permanent\protected\def\ltop#1#{\vtop#1\syst_boxes_lrc_process\raggedleft } +\permanent\protected\def\ctop#1#{\vtop#1\syst_boxes_lrc_process\raggedcenter} +\permanent\protected\def\rtop#1#{\vtop#1\syst_boxes_lrc_process\raggedright } + +%D The alternatives \type {\tbox} and \type {\bbox} can be used to properly align +%D boxes, like in: +%D +%D \setupexternalfigures[directory={../sample}] +%D \startbuffer +%D \starttable[|||] +%D \HL +%D \VL \tbox{\externalfigure[cow][height=3cm,frame=on]} \VL top aligned \VL\SR +%D \HL +%D \VL \bbox{\externalfigure[cow][height=3cm,frame=on]} \VL bottom aligned \VL\SR +%D \HL +%D \stoptable +%D \stopbuffer +%D +%D \typebuffer +%D +%D The positioning depends on the strut settings: +%D +%D \getbuffer + +\permanent\protected\def\tbox{\hpack\bgroup\dowithnextboxcs\syst_boxes_tbox_finish\hbox} +\permanent\protected\def\bbox{\hpack\bgroup\dowithnextboxcs\syst_boxes_bbox_finish\hbox} + +\def\syst_boxes_tbox_finish + {\scratchheight\ht\strutbox + \scratchdepth\dimexpr\htdp\nextbox-\scratchheight\relax + \ht\nextbox\scratchheight + \dp\nextbox\scratchdepth + \boxyoffset\nextbox-\scratchdepth + \box\nextbox + \egroup} + +\def\syst_boxes_bbox_finish + {\scratchdepth\dp\strutbox + \scratchheight\dimexpr\htdp\nextbox-\scratchdepth\relax + \dp\nextbox\scratchdepth + \ht\nextbox\scratchheight + \boxyoffset\nextbox-\scratchdepth + \box\nextbox + \egroup} + +%D \macros +%D {lhbox,mhbox,rhbox} +%D +%D A few more boxes. + +\def\syst_boxes_lhbox{\hpack to \hsize{\box\nextbox\hss }} +\def\syst_boxes_mhbox{\hpack to \hsize{\hss\box\nextbox\hss}} +\def\syst_boxes_rhbox{\hpack to \hsize{\hss\box\nextbox }} + +\permanent\protected\def\lhbox{\dowithnextboxcs\syst_boxes_lhbox\hbox} +\permanent\protected\def\mhbox{\dowithnextboxcs\syst_boxes_mhbox\hbox} +\permanent\protected\def\rhbox{\dowithnextboxcs\syst_boxes_rhbox\hbox} + +\aliased\let\lefthbox \lhbox +\aliased\let\midhbox \mhbox +\aliased\let\righthbox\rhbox + +%D \macros +%D {boxofsize} +%D +%D Sometimes we need to construct a box with a height or width made up of several +%D dimensions. Instead of cumbersome additions, we can use: +%D +%D \starttyping +%D \boxofsize \vbox 10cm 3cm -5cm {the text to be typeset} +%D \stoptyping +%D +%D This example demonstrates that one can use positive and negative values. +%D Dimension registers are also accepted. + +\newdimen\sizeofbox + +\permanent\protected\def\boxofsize#1% + {\bgroup + \sizeofbox\zeropoint + \scratchdimen\zeropoint + \def\docommand + {\advance\sizeofbox\scratchdimen + \futurelet\nexttoken\dodocommand}% + \def\dodocommand + {\ifx\nexttoken\bgroup + \expanded{\egroup#1 to \the\sizeofbox}% + \else + \expandafter\afterassignment\expandafter\docommand\expandafter\scratchdimen + \fi}% + \docommand} + +%D Some new, still undocumented features: + +% limitatetext -> beter {text} als laatste !! +% +% \limitvbox +% \limithbox + +\permanent\protected\def\limitatelines#1#2% size sentinel + {\dowithnextbox + {\scratchdimen#1\hsize + \ifdim\wd\nextbox>\scratchdimen + \setbox\nextbox\hbox + {\advance\scratchdimen -.1\hsize + \limitatetext{\unhbox\nextbox}{\scratchdimen}{\nobreak#2}}% + \fi + \unhbox\nextbox} + \hbox} + +\permanent\protected\def\fittoptobaselinegrid % weg hier + {\dowithnextbox + {\bgroup + \par + \scratchdimen\ht\nextbox + \ht\nextbox\strutht + \dp\nextbox\strutdp + \hpack{\box\nextbox} + \prevdepth\strutdp + \doloop + {\advance\scratchdimen -\lineheight + \ifdim\scratchdimen<\zeropoint + \exitloop + \else + \nobreak + \hpack{\strut} + \fi} + \egroup} + \vbox} + +%D Some more undocumented macros (used in m-chart). + +\newif\iftraceboxplacement % \traceboxplacementtrue + +\newbox\fakedboxcursor + +\setbox\fakedboxcursor\hpack + {\vrule\s!width\zeropoint\s!height\zeropoint\s!depth\zeropoint} + +\permanent\protected\def\boxcursor % overloaded in core-vis + {\iftraceboxplacement + \bgroup + \scratchdimen2\onepoint + \setbox\scratchbox\hpack to \zeropoint + {\hss + \vrule + \s!width \scratchdimen + \s!height\scratchdimen + \s!depth \scratchdimen + \hss}% + \smashedbox\scratchbox + \egroup + \else + \copy\fakedboxcursor + \fi} + +\permanent\protected\def\placedbox + {\iftraceboxplacement\ruledhbox\else\hbox\fi} + +\newdimen\boxoffset +\newdimen\boxhdisplacement +\newdimen\boxvdisplacement + +\permanent\protected\def\rightbox {\hpack\bgroup\dowithnextboxcs\syst_boxes_rightbox_finish \placedbox} +\permanent\protected\def\leftbox {\hpack\bgroup\dowithnextboxcs\syst_boxes_leftbox_finish \placedbox} +\permanent\protected\def\topbox {\hpack\bgroup\dowithnextboxcs\syst_boxes_topbox_finish \placedbox} +\permanent\protected\def\bottombox {\hpack\bgroup\dowithnextboxcs\syst_boxes_bottombox_finish \placedbox} +\permanent\protected\def\lefttopbox {\hpack\bgroup\dowithnextboxcs\syst_boxes_lefttopbox_finish \placedbox} +\permanent\protected\def\righttopbox {\hpack\bgroup\dowithnextboxcs\syst_boxes_righttopbox_finish \placedbox} +\permanent\protected\def\leftbottombox {\hpack\bgroup\dowithnextboxcs\syst_boxes_leftbottombox_finish \placedbox} +\permanent\protected\def\rightbottombox{\hpack\bgroup\dowithnextboxcs\syst_boxes_rightbottombox_finish\placedbox} + +\aliased\let\topleftbox \lefttopbox +\aliased\let\toprightbox \righttopbox +\aliased\let\bottomleftbox \leftbottombox +\aliased\let\bottomrightbox\rightbottombox + +\def\syst_boxes_rightbox_finish + {\global\boxhdisplacement\boxoffset + \global\boxvdisplacement.5\dimexpr\ht\nextbox-\dp\nextbox\relax + \boxcursor + \boxxmove\nextbox \boxhdisplacement + \boxymove\nextbox-\boxvdisplacement + \box\nextbox + \egroup} + +\def\syst_boxes_leftbox_finish + {\global\boxhdisplacement\dimexpr-\wd\nextbox-\boxoffset\relax + \global\boxvdisplacement.5\dimexpr\ht\nextbox-\dp\nextbox\relax + \boxcursor + \boxxmove\nextbox \boxhdisplacement + \boxymove\nextbox-\boxvdisplacement + \box\nextbox + \egroup} + +\def\syst_boxes_topbox_finish + {\global\boxhdisplacement-.5\wd\nextbox + \global\boxvdisplacement\dimexpr-\dp\nextbox-\boxoffset\relax + \boxcursor + \boxxmove\nextbox \boxhdisplacement + \boxymove\nextbox-\boxvdisplacement + \box\nextbox + \egroup} + +\def\syst_boxes_bottombox_finish + {\global\boxhdisplacement-.5\wd\nextbox + \global\boxvdisplacement\dimexpr\ht\nextbox+\boxoffset\relax + \boxcursor + \boxxmove\nextbox \boxhdisplacement + \boxymove\nextbox-\boxvdisplacement + \box\nextbox + \egroup} + +\def\syst_boxes_lefttopbox_finish + {\global\boxhdisplacement\dimexpr-\wd\nextbox-\boxoffset\relax + \global\boxvdisplacement\dimexpr-\dp\nextbox-\boxoffset\relax + \boxcursor + \boxxmove\nextbox \boxhdisplacement + \boxymove\nextbox-\boxvdisplacement + \box\nextbox + \egroup} + +\def\syst_boxes_righttopbox_finish + {\global\boxhdisplacement\boxoffset + \global\boxvdisplacement\dimexpr-\dp\nextbox-\boxoffset\relax + \boxcursor + \boxxmove\nextbox \boxhdisplacement + \boxymove\nextbox-\boxvdisplacement + \box\nextbox + \egroup} + +\def\syst_boxes_leftbottombox_finish + {\global\boxhdisplacement\dimexpr-\wd\nextbox-\boxoffset\relax + \global\boxvdisplacement\dimexpr\ht\nextbox+\boxoffset\relax + \boxcursor + \boxxmove\nextbox \boxhdisplacement + \boxymove\nextbox-\boxvdisplacement + \box\nextbox + \egroup} + +\def\syst_boxes_rightbottombox_finish + {\global\boxhdisplacement\boxoffset + \global\boxvdisplacement\dimexpr\ht\nextbox+\boxoffset\relax + \boxcursor + \boxxmove\nextbox \boxhdisplacement + \boxymove\nextbox-\boxvdisplacement + \box\nextbox + \egroup} + +\permanent\protected\def\middlebox {\hpack\bgroup\dowithnextboxcs\syst_boxes_middlebox_finish \placedbox} +\permanent\protected\def\baselinemiddlebox{\hpack\bgroup\dowithnextboxcs\syst_boxes_baselinemiddlebox_finish\placedbox} +\permanent\protected\def\baselineleftbox {\hpack\bgroup\dowithnextboxcs\syst_boxes_baselineleftbox_finish \placedbox} +\permanent\protected\def\baselinerightbox {\hpack\bgroup\dowithnextboxcs\syst_boxes_baselinerightbox_finish \placedbox} + +\def\syst_boxes_middlebox_finish + {\global\boxhdisplacement-.5\wd\nextbox + \global\boxvdisplacement.5\dimexpr\ht\nextbox-\dp\nextbox\relax + \boxcursor + \boxxmove\nextbox \boxhdisplacement + \boxymove\nextbox-\boxvdisplacement + \box\nextbox + \egroup} + +\def\syst_boxes_baselinemiddlebox_finish + {\global\boxhdisplacement\dimexpr-.5\wd\nextbox-\boxoffset\relax + \global\boxvdisplacement-\boxoffset + \boxcursor + \boxxmove\nextbox \boxhdisplacement + \boxymove\nextbox-\boxvdisplacement + \box\nextbox + \egroup} + +\def\syst_boxes_baselineleftbox_finish + {\global\boxhdisplacement\dimexpr-\wd\nextbox-\boxoffset\relax + \global\boxvdisplacement-\boxoffset + \boxcursor + \boxxmove\nextbox \boxhdisplacement + \boxymove\nextbox-\boxvdisplacement + \box\nextbox + \egroup} + +\def\syst_boxes_baselinerightbox_finish + {\global\boxhdisplacement\boxoffset + \global\boxvdisplacement-\boxoffset + \boxcursor + \boxxmove\nextbox \boxhdisplacement + \boxymove\nextbox-\boxvdisplacement + \box\nextbox + \egroup} + +%D \macros +%D {obox} +%D +%D Experimental, not yet frozen: + +\permanent\protected\def\lrtbbox#1#2#3#4% l r t b + {\bgroup + \dowithnextboxcontent + {\advance\hsize-#1\advance\hsize-#2\relax + \advance\vsize-#3\advance\vsize-#4\relax} + {\forgetall\vpack to \vsize{\vskip#3\hpack to \hsize{\hskip#1\box\nextbox\hss}\vss}\egroup} + \vbox} + +%D \macros +%D {toplinebox} +%D +%D See core-tbl.tex for an example of its usage: + +\permanent\protected\def\toplinebox + {\dowithnextboxcs\syst_boxes_toplinebox_finish\tbox} + +\def\syst_boxes_toplinebox_finish + {\ifdim\dp\nextbox>\strutdepth + \scratchdimen\dp\nextbox + \advance\scratchdimen-\strutdepth + \getnoflines\scratchdimen + \struttedbox{\box\nextbox}% + \dorecurse\noflines\verticalstrut + \else + \box\nextbox + \fi} + +%D \macros +%D {initializeboxstack,savebox,foundbox} +%D +%D At the cost of some memory, but saving box registers, we have implemented a box +%D repository. +%D +%D \starttyping +%D \initializeboxstack{one} +%D +%D \savebox{one}{a}{test a} +%D \savebox{one}{p}{test p} +%D \savebox{one}{q}{test q} +%D +%D \hbox{a:\foundbox{one}{a}} \par +%D \hbox{q:\foundbox{one}{q}} \par +%D \hbox{p:\foundbox{one}{p}} \par +%D \hbox{x:\foundbox{one}{x}} \par +%D \hbox{y:\foundbox{two}{a}} \par +%D \stoptyping + +%D Kind of obsolete: + +\installcorenamespace {stackbox} +\installcorenamespace {stacklst} + +\permanent\protected\def\setstackbox#1#2% + {\ifcsname\??stackbox#1:#2\endcsname\else + \expandafter\newbox\csname\??stackbox#1:#2\endcsname + \fi + \global\setbox\csname\??stackbox#1:#2\endcsname\vbox} + +\permanent\protected\def\initializeboxstack#1% + {\def\docommand##1{\setstackbox{#1}{##1}{}}% + \ifcsname\??stacklst#1\endcsname + \expandafter\processcommacommand\expandafter[\lastnamedcs]\docommand + \fi + \gletcsname\??stacklst#1\endcsname\empty} + +\permanent\protected\def\savebox#1#2% stack name + {% beware, \setxvalue defines the cs beforehand so we cannot use the test inside the { } + \ifcsname\??stacklst#1\endcsname + \xdefcsname\??stacklst#1\expandafter\endcsname\expandafter{\lastnamedcs,#2}% + \else + \xdefcsname\??stacklst#1\endcsname{#2}% + \fi + \setstackbox{#1}{#2}} + +\permanent\protected\def\flushbox#1#2% unwrapped + {\ifcsname\??stackbox#1:#2\endcsname + \box\lastnamedcs + \else + \emptybox + \fi} + +\permanent\protected\def\restorebox#1#2% unwrapped + {\ifcsname\??stackbox#1:#2\endcsname + \copy\lastnamedcs + \else + \emptybox + \fi} + +\permanent\protected\def\foundbox#1#2% wrapped + {\vpack + {\ifcsname\??stackbox#1:#2\endcsname + \copy\lastnamedcs + \fi}} + +\permanent\protected\def\doifelsebox#1#2% + {\unless\ifcsname\??stackbox#1:#2\endcsname + \expandafter\secondoftwoarguments + \orelse\ifvoid\lastnamedcs + \expandafter\secondoftwoarguments + \else + \expandafter\firstoftwoarguments + \fi} + +\aliased\let\doifboxelse\doifelsebox + +%D This one is cheaper (the above is no longer used that much): + +\installcorenamespace {boxstack} + +\newcount\c_syst_boxes_stack + +\mutable\let\b_syst_boxes_stack\relax + +\protected\def\syst_boxes_stack_allocate + {\newbox\b_syst_boxes_stack + \letcsname\??boxstack\number\c_syst_boxes_stack\endcsname\b_syst_boxes_stack} + +\protected\def\syst_boxes_push#1#2% + {\global\advance\c_syst_boxes_stack\plusone + \expandafter\let\expandafter\b_syst_boxes_stack\csname\??boxstack\number\c_syst_boxes_stack\endcsname + \ifrelax\b_syst_boxes_stack % cheaper then csname check as in most cases it's defined + \syst_boxes_stack_allocate + \fi + #1\setbox\b_syst_boxes_stack\box#2\relax} + +\protected\def\syst_boxes_pop#1#2% + {#1\setbox#2\box\csname\??boxstack\number\c_syst_boxes_stack\endcsname + \global\advance\c_syst_boxes_stack\minusone} + +\permanent\protected\def\localpushbox {\syst_boxes_push\relax} +\permanent\protected\def\localpopbox {\syst_boxes_pop \relax} + +\permanent\protected\def\globalpushbox{\syst_boxes_push\global} +\permanent\protected\def\globalpopbox {\syst_boxes_pop \global} + +%D And here is a more modern one (not yet in i-*): +%D +%D \starttyping +%D \dorecurse {100} { +%D \setbox\zerocount\hbox{test \recurselevel} +%D \putboxincache{foo}{\recurselevel}\zerocount +%D \copyboxfromcache{foo}{\recurselevel}\zerocount +%D \iftrue +%D \setbox\zerocount\hbox{\directboxfromcache{foo}{\recurselevel}}% +%D \else +%D \getboxfromcache{foo}{\recurselevel}\zerocount +%D \fi +%D } +%D \resetboxesincache{foo} +%D \stoptyping + +% \putboxincache % {category} {name} number +% \getboxfromcache % {category} {name} number +% \doifelseboxincache % {category} {name} +% \copyboxfromcache % {category} {name} number +% \directboxfromcache % {category} {name} +% \directcopyboxfromcache % {category} {name} +% \resetboxesincache % {category} +% \putnextboxincache % {category} {name} box +% \getboxwdfromcache % {category} {name} +% \getboxhtfromcache % {category} {name} +% \getboxdpfromcache % {category} {name} + +%D \macros +%D {removedepth, obeydepth} +%D +%D While \type {\removedepth} removes the preceding depth, \type {\obeydepth} makes +%D sure we have depth. Both macros leave the \type {\prevdepth} untouched. + +\permanent\protected\def\removedepth + {\ifvmode + \ifdim\prevdepth>\zeropoint + \kern-\prevdepth + \fi + \fi} + +\permanent\protected\def\obeydepth + {\par % watch out for changes in math formulas + \ifvmode\ifdim\prevdepth<\zeropoint\orelse\ifdim\prevdepth<\strutdp + \kern\dimexpr\strutdp-\prevdepth\relax + \prevdepth\strutdp + \fi\fi} + +\permanent\protected\def\undepthed + {\dowithnextbox{\dp\nextbox\zeropoint\box\nextbox}\hbox} + +%D \macros +%D {removebottomthings, removelastskip} +%D +%D A funny (but rather stupid) one, plus a redefinition. + +\permanent\protected\def\removebottomthings + {\dorecurse\plusfive{\unskip\unkern\unpenalty}} + +\permanent\protected\def\removelastskip % \ifvmode the plain tex one \fi, overloaded to \permanent in spac-ver + {\ifvmode\ifzeropt\lastskip\else\vskip-\lastskip\fi\fi} + +%D \macros +%D {makestrutofbox} +%D +%D This macro sets the dimensions of a box to those of a strut. Sort of obsolete so +%D it will go away. + +\permanent\protected\def\makestrutofbox % not used + {\afterassignment\syst_boxes_makestrutofbox\c_boxes_register} + +\def\syst_boxes_makestrutofbox + {\ht\c_boxes_register\strutht + \dp\c_boxes_register\strutdp + \wd\c_boxes_register\zeropoint} + +%D \macros +%D {raisebox,lowerbox} +%D +%D Some more box stuff, related to positioning (under construction). Nice stuff for +%D a tips and tricks maps article. +%D +%D \starttyping +%D \raisebox{100pt}\hbox{test} +%D \hsmash{\raisebox{100pt}\hbox{test}} +%D \stoptyping + +\permanent\protected\def\raisebox#1{\bgroup\afterassignment\syst_boxes_raise_indeed\scratchdimen#1} % so both 10pt and {10pt} is accepted +\permanent\protected\def\lowerbox#1{\bgroup\afterassignment\syst_boxes_lower_indeed\scratchdimen#1} % so both 10pt and {10pt} is accepted + +\def\syst_boxes_raise_indeed{\dowithnextboxcs\syst_boxes_raise_finish} +\def\syst_boxes_lower_indeed{\dowithnextboxcs\syst_boxes_lower_finish} + +\def\syst_boxes_raise_finish + {\boxyoffset\nextbox\scratchdimen + \ht\nextbox\strutht + \dp\nextbox\strutdp + \box\nextbox + \egroup} + +\def\syst_boxes_lower_finish + {\boxyoffset\nextbox-\scratchdimen + \ht\nextbox\strutht + \dp\nextbox\strutdp + \box\nextbox + \egroup} + +% vcenter in text, we kunnen vcenter overloaden + +\permanent\protected\def\halfwaybox + {\hpack\bgroup + \dowithnextboxcs\syst_boxes_halfwaybox_finish\hbox} + +\def\syst_boxes_halfwaybox_finish + {\dp\nextbox\zeropoint + \lower.5\ht\nextbox\box\nextbox + \egroup} + +\permanent\protected\def\depthonlybox + {\tpack\bgroup + \dowithnextboxcs\syst_boxes_depthonlybox_finish\vbox} + +\def\syst_boxes_depthonlybox_finish + {\hsize\wd\nextbox + \kern\zeropoint\box\nextbox + \egroup} + +%D New: + +\permanent\def\setdimentoatleast#1#2{\ifdim#1>\zeropoint\else#1=#2\fi} +\permanent\def\setdimentoatmost #1#2{\ifdim#1>#2\relax \else#1=#2\fi} + +%D And even rawer: + +\aliased\let\naturalvcenter\normalvtop % will go away + +% \appendtoks \let\vcenter\normalvcenter \to \everymathematics + +%D \macros +%D {frozenhbox} +%D +%D A not so well unhboxable box can be made with: + +\permanent\protected\def\frozenhbox + {\hpack\bgroup + \dowithnextboxcs\syst_boxes_frozenhbox_finish\hbox} + +\def\syst_boxes_frozenhbox_finish + {\hpack{\hpack{\box\nextbox}}% + \egroup} + +%D \macros +%D {setboxllx,setboxlly,gsetboxllx,gsetboxlly,getboxllx,getboxlly} +%D +%D A prelude to an extended \TEX\ feature: + +\installcorenamespace {box_x} +\installcorenamespace {box_y} + +\permanent\protected\def\setboxllx #1#2{\edefcsname\??box_x\number#1\endcsname{\the\dimexpr#2\relax}} +\permanent\protected\def\setboxlly #1#2{\edefcsname\??box_y\number#1\endcsname{\the\dimexpr#2\relax}} + +\permanent\protected\def\gsetboxllx#1#2{\xdefcsname\??box_x\number#1\endcsname{\the\dimexpr#2\relax}} +\permanent\protected\def\gsetboxlly#1#2{\xdefcsname\??box_y\number#1\endcsname{\the\dimexpr#2\relax}} + +\permanent\def\getboxllx#1{\ifcsname\??box_x\number#1\endcsname\lastnamedcs\else\zeropoint\fi} +\permanent\def\getboxlly#1{\ifcsname\??box_y\number#1\endcsname\lastnamedcs\else\zeropoint\fi} + +\permanent\def\directgetboxllx#1{\csname\??box_x\number#1\endcsname} % use when sure existence +\permanent\def\directgetboxlly#1{\csname\??box_y\number#1\endcsname} % use when sure existence + +%D \macros +%D {shownextbox} +%D +%D Handy for tracing +%D +%D \starttyping +%D \shownextbox\vbox{test} +%D \shownextbox\vbox{test\endgraf} +%D \shownextbox\vbox{test\endgraf\strut\endgraf} +%D \shownextbox\vbox{test\endgraf\thinrule} +%D \shownextbox\vbox{\setupwhitespace[big]test\endgraf\thinrule} +%D \stoptyping + +\permanent\protected\def\shownextbox % seldom used + {\dowithnextbox + {\bgroup + \showboxbreadth\maxdimen + \showboxdepth \maxdimen + \scratchcounter\interactionmode + \batchmode + \showbox\nextbox + \box\nextbox + \interactionmode\scratchcounter + \egroup}} + +\permanent\protected\def\spreadhbox#1% rebuilds \hbox{<box><hss><box><hss><box>} + {\bgroup + \ifhbox#1\relax + \setbox\scratchboxtwo\emptybox + \unhbox#1% + \doloop + {\unpenalty\unskip\unpenalty\unskip\unpenalty\unskip + \setbox\scratchboxone\lastbox + \ifvoid\scratchboxone + \exitloop + \else + \setbox\scratchboxtwo\hbox + {\ifhbox\scratchboxone \spreadhbox\scratchboxone\else\box\scratchboxone\fi + \ifvoid\scratchboxtwo \else\hss\unhbox\scratchboxtwo\fi}% + \fi}% + \ifvoid\scratchboxtwo\else\unhbox\scratchboxtwo\fi + \else + \box#1% + \fi + \egroup} + +% Why not ... + +\showboxbreadth\plusthousand +\showboxdepth \plusthousand + +%D Moved from cont-new: +%D +%D \starttyping +%D \minimalhbox 100pt {test} +%D \stoptyping + +\permanent\protected\def\minimalhbox#1#% + {\dowithnextbox + {\bgroup + \setbox\scratchbox\hpack#1{\hss}% + \ifdim\wd\nextbox<\wd\scratchbox\wd\nextbox\wd\scratchbox\fi + \box\nextbox + \egroup} + \hbox} + +%D A bit dirty: + +% \permanent\protected\def\nodestostring#1#2% more tolerant for #2=\cs +% {\begingroup +% \setbox\nextbox\hbox{#2}% +% \normalexpanded{\endgroup\edef\noexpand#1{\boxtostring\nextbox}}} +% +% \permanent\def\tostring +% {\beginlocalcontrol +% \dowithnextbox{\endlocalcontrol\boxtostring\nextbox}\hbox} +% +% \permanent\def\tostring +% {\beginlocalcontrol\begingroup +% \dowithnextbox{\normalexpanded{\endgroup\endlocalcontrol\boxtostring\nextbox}}\hbox} + +\def\syst_boxes_contenttostring + {\normalexpanded{\endgroup\endlocalcontrol\boxtostring\nextbox}} + +\permanent\def\contenttostring + {\beginlocalcontrol\begingroup + \dowithnextboxcs\syst_boxes_contenttostring\hbox} + +\newtoks\everypreroll + +\let\prerolltostring\firstofoneargument % we need to bypass initializations + +\appendtoks + \permanent\def\prerolltostring + {\beginlocalcontrol\begingroup + \the\everypreroll + \dowithnextboxcs\syst_boxes_contenttostring\hbox} +\to \everydump + +% depricated: + +\permanent\protected\def\nodestostring#1#2% more tolerant for #2=\cs + {\edef#2{\contenttostring{#1}}} + +%D Even more dirty: + +\aliased\let\hyphenatedhbox\hbox % was a macro in mkii + +%D We can do this: +%D +%D \starttyping +%D \setbox0\hbox to 10cm{foo} \setbox2\hbox{\unhbox0} \the\wd2 +%D \stoptyping +%D +%D But this saves a copy (and hpack pass): +%D +%D \starttyping +%D \setbox0\hbox to 10cm{foo} \the\naturalwd0 +%D \stoptyping + +\newdimen\lastnaturalboxwd +\newdimen\lastnaturalboxht +\newdimen\lastnaturalboxdp + +%D We can define these public in lua: + +\aliased\let\getnaturaldimensions\clf_getnaturaldimensions % sets three dimensions +\aliased\let\naturalwd \clf_naturalwd % calculates and returns wd + +\aliased\let\getnaturalwd\clf_getnaturalwd % no intermediate +\aliased\let\setnaturalwd\clf_setnaturalwd % no intermediate + +\permanent\protected\def\doifelserighttoleftinbox{\clf_doifelserighttoleftinbox} + +\aliased\let\doifrighttoleftinboxelse\doifelserighttoleftinbox + +%D New, used in high/low: + +\definesystemattribute [runningtext] [public] + +\permanent\protected\def\runninghbox{\hbox attr \runningtextattribute \fontid\font} % not yet in i-* + +%D To complement lua (yet undocumented): + +\permanent\protected\def\beginhbox{\hbox\bgroup} \aliased\let\endhbox\egroup +\permanent\protected\def\beginvbox{\vbox\bgroup} \aliased\let\endvbox\egroup +\permanent\protected\def\beginvtop{\vtop\bgroup} \aliased\let\endvtop\egroup + +\permanent\protected\def\sethboxregister#1{\setbox#1\hbox} +\permanent\protected\def\setvboxregister#1{\setbox#1\vbox} +\permanent\protected\def\setvtopregister#1{\setbox#1\vtop} + +\permanent\protected\def\flushboxregister#1{\box\numexpr#1\relax} + +\permanent\protected\def\starthboxregister#1{\setbox#1\hbox\bgroup} \aliased\let\stophboxregister\egroup +\permanent\protected\def\startvboxregister#1{\setbox#1\vbox\bgroup} \aliased\let\stopvboxregister\egroup +\permanent\protected\def\startvtopregister#1{\setbox#1\vtop\bgroup} \aliased\let\stopvtopregister\egroup + +% %D For whatever third party package needs it: +% %D +% %D \starttyping +% %D \newlocalbox\BoxOne +% %D \newlocalbox\BoxTwo +% %D +% %D \setbox\BoxOne\hbox{Box One} +% %D \setbox\BoxTwo\hbox{Box Two} +% %D +% %D [\box\BoxTwo] [\box\BoxOne] +% %D \stoptyping +% +% \installcorenamespace{localbox} +% +% \permanent\protected\def\newlocalbox#1% +% {\expandafter\let\expandafter#1\csname\??localbox\string#1\endcsname +% \ifrelax#1% +% \syst_aux_new_localbox#1% +% \fi} +% +% \def\syst_aux_new_localbox#1% +% {\expandafter\newbox\csname\??localbox\string#1\endcsname +% \newlocalbox#1} + +%D Who knows when this comes in handy: + +\permanent\protected\def\lastlinewidth{\dimexpr\clf_lastlinewidth\scaledpoint\relax} + +%D Keep as reference: + +% \protected\def\tightvbox{\dowithnextbox{\dp\nextbox\zeropoint\box\nextbox}\vbox} +% \protected\def\tightvtop{\dowithnextbox{\ht\nextbox\zeropoint\box\nextbox}\vtop} + +%D This one keeps dimensions and sets the shift field (and so it's more for testing +%D than for real usage): + +\permanent\protected\def\shiftbox {\clf_shiftbox} +\permanent\protected\def\vpackbox {\clf_vpackbox} +\permanent\protected\def\hpackbox {\clf_hpackbox} +\permanent\protected\def\vpackedbox{\clf_vpackedbox} +\permanent\protected\def\hpackedbox{\clf_hpackedbox} + +%D This one has been moved from a 2 decade old file. It makes something boxed +%D sit on the baseline. + +\permanent\protected\def\linebox + {\hpack\bgroup\dowithnextbox + {\scratchdimen\dimexpr\dimexpr\htdp\nextbox-\lineheight\relax/2+\dp\strutbox\relax + \setbox\nextbox\hpack{\lower\scratchdimen\box\nextbox}% + \ht\nextbox\ht\strutbox + \dp\nextbox\dp\strutbox + \box\nextbox + \egroup} + \hbox} + +%D \macros +%D {widthuptohere} +%D +%D Implemented at the \LUA\ end: +%D +%D \startbuffer +%D widthuptohere:\the\widthuptohere\crlf +%D widthuptohere : \the\widthuptohere (space without stretch or shrink!) +%D \stopbuffer +%D +%D \typebuffer \blank \getbuffer \blank +%D +%D Implemented elsewhere: +%D +%D \starttyping +%D \boxlines <box> +%D \boxline <box> <line> +%D \copyboxline <box> <line> +%D \setboxline <box> <line> +%D \boxlineht <box> <line> [<dimen>] +%D \boxlinedp <box> <line> [<dimen>] +%D \boxlinewd <box> <line> [<dimen>] +%D \boxlinels <box> <line> +%D \boxliners <box> <line> +%D \boxlinelh <box> <line> +%D \boxlinerh <box> <line> +%D \boxlinelp <box> <line> +%D \boxlinerp <box> <line> +%D \boxlinein <box> <line> +%D \boxrangeht <box> <first line> <last line> +%D \boxrangedp <box> <first line> <last line> +%D \boxrangewd <box> <first line> <last line> +%D \stoptyping + +% To be discussed with ws. +% +% \installcorenamespace{namedboxes} +% +% \protected\def\newnamedbox#1% +% {\ifcsname\??namedboxes#1\endcsname\else +% \expandafter\newbox\csname\??namedboxes#1\endcsname +% \fi} +% +% \protected\def\namedbox#1{\csname\??namedboxes#1\endcsname} + +%D Implemented elsewhere: +%D +%D \startbuffer +%D \setbox0\hbox{test \footnote{test}} (\prelistbox0) (\postlistbox0) +%D \setprelistbox0\hbox{BEFORE} \setpostlistbox0\hbox{AFTER} +%D \box0 +%D \stopbuffer +%D +%D \typebuffer \blank \getbuffer \blank +%D +%D \starttyping +%D \prelistbox <box> +%D \postlistbox <box> +%D \prelistcopy <box> +%D \postlistcopy <box> +%D \setprelistbox <box> <hbox|vbox|vtop|somebox> +%D \setpostlistbox <box> <hbox|vbox|vtop|somebox> +%D \stoptyping + +\protect \endinput + +% a bit of test code: + +% \hbox \bgroup +% \ruledvbox {\hbox{\strut gans}} +% \ruledvbox to \lineheight {\hbox{\strut gans}} +% \ruledvbox to \lineheight {\hbox {gans}} +% \ruledvbox to \strutheight{\hbox {gans}} +% \ruledvbox to \strutheight{\hbox{\strut gans}} +% \ruledvbox to \strutheight{\vss\hbox{gans}} +% \egroup + +% to be considered + +% \startluacode +% +% local spacer = lpeg.patterns.spacer +% +% function commands.withwords(command,str) +% if str then +% command = command or "ruledhbox" +% local done = false +% local function apply(s) +% if done then +% context.space() +% done = true +% else +% context.dontleavehmode() +% end +% context[command](s) +% end +% lpeg.match(lpeg.splitter(spacer,apply),str) +% end +% +% end +% +% \stopluacode +% +% \unprotect +% +% \protected\def\withwordsinstring#1#2% command str +% {\ctxcommand{withwords(\!!bs#1\!!es,\!!bs#2\!!es)}} +% +% \protected\def\withwordsinfile#1#2% command name +% {\ctxcommand{withwords(\!!bs#1\!!es,io.loaddata(resolvers.findfile("#2")))}} +% +% \protect +% +% \starttext +% +% \defineframed[colored][foregroundcolor=red,foregroundstyle=\bfc\underbar,location=low] +% +% \withwordsinstring{colored}{bla bla} +% \withwordsinfile{colored}{ward.tex} +% +% \stoptext |