supp-box.mkxl /size: 85 Kb    last modification: 2020-07-01 14:35
1
%D \module
2
%D [ file=supp-box,
3
%D version=1995.10.10,
4
%D title=\CONTEXT\ Support Macros,
5
%D subtitle=Boxes,
6
%D author=Hans Hagen,
7
%D date=\currentdate,
8
%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
9
%C
10
%C This module is part of the \CONTEXT\ macro||package and is
11
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
12
%C details.
13 14
\writestatus
{
loading
}{
ConTeXt
Support
Macros
/
Boxes
}
15 16
\unprotect
17 18
\registerctxluafile
{
supp
-
box
}{
optimize
}
19 20
% This file is partially cleaned up.
21 22
%D First some defaults:
23 24
\fixupboxesmode
\plusone
25 26
%D And some dimensions:
27 28
\newdimen\givenwidth
29
\newdimen\givenheight
30
\newdimen\givendepth
31 32
%D \macros
33
%D {dontcomplain}
34
%D
35
%D The next macro suppresses over- and underfull messages which often makes sense
36
%D when we deal with boxes.
37 38
\unexpanded
\def
\dontcomplain
39
{
\hbadness
\plustenthousand
40
\vbadness
\plustenthousand
41
\hfuzz
\maxdimen
42
\vfuzz
\maxdimen
}
43 44
%D This module implements some box manipulation macros. Some are quite simple, some
45
%D are more advanced and when understood well, all can be of use.
46
%D
47
%D \macros
48
%D {strutdp,strutht,strutwd}
49
%D
50
%D The next shortcuts save memory and keying. The width is normally zero points (if
51
%D not, you're in trouble). These shortcuts can be used like a dimension, opposite
52
%D to the core macros \type {\strutdepth} and alike, which are values.
53 54
\def
\strutdp
{
\dp
\strutbox
}
55
\def
\strutht
{
\ht
\strutbox
}
56
\def
\strutwd
{
\wd
\strutbox
}
57
\def
\struthtdp
{
\htdp\strutbox
}
58
\def
\strutgap
{
\dimexpr\ht
\strutbox
-
\dp
\strutbox
\relax
}
59 60
%D \macros
61
%D {voidbox,nextbox}
62
%D
63
%D Let's start with an easy one. The next macro hides the ugly \type {@} in \type
64
%D {\voidb@x}.
65 66
\ifdefined
\voidbox
\else
\newbox
\voidbox
\fi
67
\ifdefined
\nextbox
\else
\newbox\nextbox
\fi
68 69
%D \macros
70
%D {nextdepth}
71
%D
72
%D Let's start with a rather simple declaration. Sometimes we need to save the \TEX\
73
%D \DIMENSION\ \type{\prevdepth} and append it later on. The name \type {\nextdepth}
74
%D suits this purpose well.
75 76
\newdimen
\nextdepth
77 78
%D \macros
79
%D {smashbox, smashedbox}
80
%D
81
%D Smashing is introduced in \PLAIN\ \TEX, and stands for reducing the dimensions of
82
%D a box to zero. The most resolute one is presented first.
83 84
\unexpanded
\def
\smashbox
#
1
%
85
{
\wd
#
1
\zeropoint
86
\ht
#
1
\zeropoint
87
\dp
#
1
\zeropoint
}
88 89
\unexpanded
\def
\smashboxed
#
1
%
90
{
\wd
#
1
\zeropoint
91
\ht
#
1
\zeropoint
92
\dp
#
1
\zeropoint
93
\box
#
1
\relax
}
94 95
%D \macros
96
%D {hsmashbox,vsmashbox}
97
%D
98
%D Smashing can be used for overlaying boxes. Depending on the mode, horizontal or
99
%D vertical, one can use:
100 101
\unexpanded
\def
\hsmashbox
#
1
%
102
{
\wd
#
1
\zeropoint
}
103 104
\unexpanded
\def
\vsmashbox
#
1
%
105
{
\ht
#
1
\zeropoint
106
\dp
#
1
\zeropoint
}
107 108
%D The next implementation is less sensitive for spurious spaces.
109 110
\newcount
\c_boxes_register
111 112
\unexpanded
\def
\smashbox
113
{
\afterassignment
\syst_boxes_smash_boxes_register
\c_boxes_register
}
114 115
\def
\syst_boxes_smash_boxes_register
116
{
\wd
\c_boxes_register
\zeropoint
117
\ht
\c_boxes_register
\zeropoint
118
\dp
\c_boxes_register
\zeropoint
}
119 120
\unexpanded
\def
\hsmashbox
121
{
\afterassignment
\syst_boxes_hsmashed_boxes_register
\c_boxes_register
}
122 123
\def
\syst_boxes_hsmashed_boxes_register
124
{
\wd
\c_boxes_register
\zeropoint
}
125 126
\unexpanded
\def
\vsmashbox
127
{
\afterassignment
\syst_boxes_vsmashed_boxes_register
\c_boxes_register
}
128 129
\def
\syst_boxes_vsmashed_boxes_register
130
{
\ht
\c_boxes_register
\zeropoint
131
\dp
\c_boxes_register
\zeropoint
}
132 133
\unexpanded
\def
\smashedbox
134
{
\afterassignment
\syst_boxes_smashed_boxes_register
\c_boxes_register
}
135 136
\unexpanded
\def
\syst_boxes_smashed_boxes_register
137
{
\wd
\c_boxes_register
\zeropoint
138
\ht
\c_boxes_register
\zeropoint
139
\dp
\c_boxes_register
\zeropoint
140
\box
\c_boxes_register
}
141 142
%D \macros
143
%D {hsmash,vsmash,
144
%D hsmashed,vsmashed}
145
%D
146
%D While the previous macros expected a \BOX, the next act on a content. They are
147
%D some subtle differences betreen the smash and smashed alternatives. The later
148
%D ones reduce all dimensions to zero.
149 150
\unexpanded
\def
\hsmash
{
\bgroup
\dowithnextboxcs
\syst_boxes_hsmashed_nextbox
\hbox
}
151
\unexpanded
\def
\vsmash
{
\bgroup
\dowithnextboxcs
\syst_boxes_vsmashed_nextbox
\vbox
}
152
\unexpanded
\def
\hsmashed
{
\bgroup
\dowithnextboxcs
\syst_boxes_smashed_nextbox
\hbox
}
153
\unexpanded
\def
\vsmashed
{
\bgroup
\dowithnextboxcs
\syst_boxes_smashed_nextbox
\vbox
}
154 155
\unexpanded
\def
\syst_boxes_hsmashed_nextbox
156
{
\wd
\nextbox
\zeropoint
157
\box
\nextbox
158
\egroup
}
159 160
\unexpanded
\def
\syst_boxes_vsmashed_nextbox
161
{
\ht
\nextbox
\zeropoint
162
\dp
\nextbox
\zeropoint
163
\box
\nextbox
164
\egroup
}
165 166
\unexpanded
\def
\syst_boxes_smashed_nextbox
167
{
\ht
\nextbox
\zeropoint
168
\dp
\nextbox
\zeropoint
169
\wd
\nextbox
\zeropoint
170
\box
\nextbox
171
\egroup
}
172 173
%D \macros
174
%D {smashedhbox,smashedvbox}
175
%D
176
%D Also handy (all dimensions zeroed):
177
%D
178
%D \starttyping
179
%D \smashedhbox to ... {...}
180
%D \smashedvbox to ... {...}
181
%D \stoptyping
182 183
\unexpanded
\def
\smashedhbox
{
\hpack
\bgroup
\dowithnextboxcs
\syst_boxes_smashed_nextbox
\hbox
}
184
\unexpanded
\def
\smashedvbox
{
\vpack
\bgroup
\dowithnextboxcs
\syst_boxes_smashed_nextbox
\vbox
}
185 186
%D First we define a helper. We use a \LUATEX\ feature in order to avoid
187
%D mathpalettes.
188 189
\newcount
\c_boxes_math_style
190 191
\unexpanded
\def
\syst_boxes_math_set_nextbox
#
1
%
192
{
\c_boxes_math_style
\normalmathstyle
193
\setbox
\nextbox
\hbox
{
\normalstartimath
\mathsurround
\zeropoint
\triggermathstyle
\c_boxes_math_style
{
#
1
}
\normalstopimath
}}
194 195
%D \macros
196
%D {smash}
197
%D
198
%D This smash alternative takes an optional arg [whdtb] as well as is potentially
199
%D catcode safer. It is needed by the math module (although the \type {\leavevmode}
200
%D is not added here).
201 202
\unexpanded
\def
\smash
203
{
\begingroup
204
\futureexpandis
[
\syst_boxes_smash_yes
\syst_boxes_smash_nop
}
205 206
\def
\syst_boxes_smash_nop
207
{
\edef
\m_boxes_smash_options
{
hd
}
%
208
\futurelet
\nexttoken
\syst_boxes_smash_indeed
}
209 210
\def
\syst_boxes_smash_yes
[#
1
]
%
211
{
\edef
\m_boxes_smash_options
{
#
1
}
%
212
\futurelet
\nexttoken
\syst_boxes_smash_indeed
}
213 214
\def
\syst_boxes_smash_indeed
215
{
\ifmmode
216
\expandafter
\syst_boxes_smash_math
217
\orelse\ifx
\nexttoken
\bgroup
218
\expandafter
\syst_boxes_smash_hbox
219
\else
220
\expandafter
\syst_boxes_smash_text
221
\fi
}
222 223
\def
\syst_boxes_smash_math
#
1
%
224
{
\syst_boxes_math_set_nextbox
{
#
1
}
%
225
\syst_boxes_smash_process
}
226 227
\def
\syst_boxes_smash_hbox
228
{
\dowithnextboxcs
\syst_boxes_smash_process
\hbox
}
229 230
\def
\syst_boxes_smash_text
#
1
%
231
{
\setbox
\nextbox
\hbox
{
#
1
}
%
232
\syst_boxes_smash_process
}
233 234
\def
\syst_boxes_smash_process
235
{
\expandafter
\syst_boxes_smash_process_option
\m_boxes_smash_options
\relax
236
\box
\nextbox
237
\endgroup
}
238 239
\installcorenamespace
{
smashoptions
}
240 241
\setvalue
{
\??smashoptions
w
}{
\wd
\nextbox
\zeropoint
}
242
\setvalue
{
\??smashoptions
h
}{
\ht
\nextbox
\zeropoint
}
243
\setvalue
{
\??smashoptions
d
}{
\dp
\nextbox
\zeropoint
}
244
\setvalue
{
\??smashoptions
t
}{
\ht
\nextbox
\zeropoint
}
245
\setvalue
{
\??smashoptions
b
}{
\dp
\nextbox
\zeropoint
}
246 247
\def
\syst_boxes_smash_process_option
#
1
%
248
{
\ifx
#
1
\relax\else
249
\begincsname
\??smashoptions
#
1
\endcsname
250
\expandafter
\syst_boxes_smash_process_option
251
\fi
}
252 253
\def
\syst_boxes_lower_nextbox_dp
254
{
\setbox
\nextbox
\hpack
{
\lower\dp
\nextbox
\box
\nextbox
}}
255 256
%D \starttabulate[|l|l|]
257
%D \NC w \NC \ruledhbox{\smash [w]{This is some great smashing, isn't it?}} \NC \NR
258
%D \NC h \NC \ruledhbox{\smash [h]{This is some great smashing, isn't it?}} \NC \NR
259
%D \NC d \NC \ruledhbox{\smash [d]{This is some great smashing, isn't it?}} \NC \NR
260
%D \NC tb \NC \ruledhbox{\smash [tb]{This is some great smashing, isn't it?}} \NC \NR
261
%D \NC whd \NC \ruledhbox{\smash[whd]{This is some great smashing, isn't it?}} \NC \NR
262
%D \stoptabulate
263 264
%D \macros
265
%D {phantom, hphantom, vphantom, mathstrut}
266
%D
267
%D The next implementation of \type {\phantom} cum suis does not grab an argument in
268
%D the non||math case, which is better.
269
%D
270
%D Due to a complicated call to \type {\mathpallete} and thereby \type
271
%D {\mathchoice}, the next macro looks ugly. We also take care of non||braced
272
%D arguments.
273 274
\unexpanded
\def
\phantom
{
\begingroup\futurelet
\nexttoken
\syst_boxes_phantom_indeed
}
275
\unexpanded
\def
\vphantom
{
\begingroup\futurelet
\nexttoken
\syst_boxes_phantom_indeed_v
}
276
\unexpanded
\def
\hphantom
{
\begingroup\futurelet
\nexttoken
\syst_boxes_phantom_indeed_h
}
277 278
\def
\syst_boxes_phantom_math
#
1
{
\syst_boxes_math_set_nextbox
{
#
1
}
\syst_boxes_phantom_make
}
279
\def
\syst_boxes_phantom_math_v
#
1
{
\syst_boxes_math_set_nextbox
{
#
1
}
\syst_boxes_phantom_make_v
}
280
\def
\syst_boxes_phantom_math_h
#
1
{
\syst_boxes_math_set_nextbox
{
#
1
}
\syst_boxes_phantom_make_h
}
281 282
\def
\syst_boxes_phantom_hbox
{
\dowithnextboxcs
\syst_boxes_phantom_make
\hbox
}
% always hbox
283
\def
\syst_boxes_phantom_hbox_v
{
\dowithnextboxcs
\syst_boxes_phantom_make_v
\hbox
}
% always hbox
284
\def
\syst_boxes_phantom_hbox_h
{
\dowithnextboxcs
\syst_boxes_phantom_make_h
\hbox
}
% always hbox
285 286
\def
\syst_boxes_phantom_text
#
1
{
\setbox
\nextbox
\hbox
{
#
1
}
\syst_boxes_phantom_make
}
% always hbox
287
\def
\syst_boxes_phantom_text_v
#
1
{
\setbox
\nextbox
\hbox
{
#
1
}
\syst_boxes_phantom_make_v
}
% always hbox
288
\def
\syst_boxes_phantom_text_h
#
1
{
\setbox
\nextbox
\hbox
{
#
1
}
\syst_boxes_phantom_make_h
}
% always hbox
289 290
\def
\syst_boxes_phantom_indeed
291
{
\ifmmode
292
\expandafter
\syst_boxes_phantom_math
293
\orelse\ifx
\nexttoken
\bgroup
294
\expandafter
\syst_boxes_phantom_hbox
295
\else
296
\expandafter
\syst_boxes_phantom_text
297
\fi
}
298 299
\def
\syst_boxes_phantom_indeed_v
300
{
\ifmmode
301
\expandafter
\syst_boxes_phantom_math_v
302
\orelse\ifx
\nexttoken
\bgroup
303
\expandafter
\syst_boxes_phantom_hbox_v
304
\else
305
\expandafter
\syst_boxes_phantom_text_v
306
\fi
}
307 308
\def
\syst_boxes_phantom_indeed_h
309
{
\ifmmode
310
\expandafter
\syst_boxes_phantom_math_h
311
\orelse\ifx
\nexttoken
\bgroup
312
\expandafter
\syst_boxes_phantom_hbox_h
313
\else
314
\expandafter
\syst_boxes_phantom_text_h
315
\fi
}
316 317
\def
\syst_boxes_phantom_make
318
{
\setbox
\scratchbox
\emptyhbox
319
\ht
\scratchbox
\ht
\nextbox
320
\dp
\scratchbox
\dp
\nextbox
321
\wd
\scratchbox
\wd
\nextbox
322
\box
\scratchbox
323
\endgroup
}
324 325
\def
\syst_boxes_phantom_make_v
326
{
\setbox
\scratchbox
\emptyhbox
327
\ht
\scratchbox
\ht
\nextbox
328
\dp
\scratchbox
\dp
\nextbox
329
\box
\scratchbox
330
\endgroup
}
331 332
\def
\syst_boxes_phantom_make_h
333
{
\setbox
\scratchbox
\emptyhbox
334
\wd
\scratchbox
\wd
\nextbox
335
\box
\scratchbox
336
\endgroup
}
337 338
%D We also define plain's \type {\mathstrut}.
339 340
\unexpanded
\def
\mathstrut
{
\vphantom
(
}
% can be made faster by inlining
341 342
%D \macros
343
%D {getboxheight}
344
%D
345
%D Although often needed, \TEX\ does not support arithmics like:
346
%D
347
%D \starttyping
348
%D \dimen0 = \ht0 + \dp0
349
%D \stoptyping
350
%D
351
%D so we implemented:
352
%D
353
%D \starttyping
354
%D \getboxheight ... \of \box...
355
%D \stoptyping
356
%D
357
%D For instance,
358
%D
359
%D \starttyping
360
%D \getboxheight \dimen0 \of \box0
361
%D \getboxheight \someheight \of \box \tempbox
362
%D \stoptyping
363
%D
364
%D The implementation is rather stupid:
365
%D
366
%D \starttyping
367
%D \def\getboxheight#1\of#2\box#3%
368
%D {#1\ht#3\advance#1\dp#3\relax}
369
%D \stoptyping
370
%D
371
%D The next alternative is slightly more clever, since it accepts \type {{12}} as
372
%D well as \type {12} as box number.
373 374
\unexpanded
\def
\getboxheight
#
1
\of
#
2
\box
#
3
%
375
{
\def
\next
{
#
1
\htdp
\c_boxes_register
}
%
376
\afterassignment
\next
\c_boxes_register
=#
3
}
377 378
%D For a long time the following three macros were part of the grid snapping core
379
%D module, but it makes more sense to have them here so that users can see them.
380
%D
381
%D \macros
382
%D {getnoflines, getroundednoflines, getrawnoflines}
383
%D
384
%D Het commando \type {\getnoflines} converteert een hoogte (dimensie) in een aantal
385
%D regels en kent dit toe aan \type {\noflines}.
386
%D
387
%D \starttyping
388
%D \getnoflines{dimensie}
389
%D \stoptyping
390
%D
391
%D Er wordt gedeeld door \type {\openlineheight} en een hoogte van~0pt komt overeen
392
%D met 0~regels. The raw alternative does not round.
393
%D
394
%D For a long time we had:
395
%D
396
%D \starttyping
397
%D \newcount\noflines
398
%D \newdimen\noflinesheight
399
%D
400
%D \def\dogetnoflines#1#2%
401
%D {\noflinesheight#2\relax
402
%D \ifzeropt\noflinesheight
403
%D \noflines\zerocount
404
%D \else
405
%D \divide\noflinesheight \openlineheight
406
%D \noflines\noflinesheight
407
%D #1\ifdim\noflines\openlineheight=#2\relax \else
408
%D \advance\noflines\ifdim#2>\zeropoint\plusone\else\minusone\fi
409
%D \fi\fi
410
%D \fi}
411
%D
412
%D \def\getnoflines {\dogetnoflines\iftrue } % compensated
413
%D \def\getrawnoflines{\dogetnoflines\iffalse} % no compensation
414
%D \stoptyping
415
%D
416
%D A more recent variant is:
417 418
\ifx
\roundingeps
\undefined
\newdimen
\roundingeps
\roundingeps
=
1
0
sp
\fi
419 420
\newcount
\noflines
421
\newdimen
\noflinesheight
422 423
\unexpanded
\def
\getnoflines
#
1
%
424
{
\noflinesheight
#
1
\relax
425
\ifzeropt
\noflinesheight
426
\noflines
\zerocount
427
\orelse\ifdim
\noflinesheight
>
\zeropoint
428
\advance
\noflinesheight
-
\roundingeps
429
\divide
\noflinesheight
\openlineheight
430
\noflines
\noflinesheight
431
\advance
\noflines
\plusone
432
\else
433
\advance
\noflinesheight
\roundingeps
434
\divide
\noflinesheight
\openlineheight
435
\noflines
\noflinesheight
436
\advance
\noflines
\minusone
437
\fi
}
438 439
\unexpanded
\def
\getroundednoflines
#
1
%
440
{
\noflinesheight
#
1
\relax
441
\ifzeropt
\noflinesheight
442
\noflines
\zerocount
443
\orelse\ifdim
\noflinesheight
>
\zeropoint
444
\advance
\noflinesheight
\roundingeps
445
\divide
\noflinesheight
\openlineheight
446
\noflines
\noflinesheight
447
\else
448
\advance
\noflinesheight
-
\roundingeps
449
\divide
\noflinesheight
\openlineheight
450
\noflines
\noflinesheight
451
\fi
}
452 453
\unexpanded
\def
\getrawnoflines
#
1
%
454
{
\noflinesheight
#
1
\relax
455
\ifzeropt
\noflinesheight
456
\noflines
\zerocount
457
\orelse\ifdim
\noflinesheight
>
\zeropoint
458
\advance
\noflinesheight
\roundingeps
459
\advance
\noflinesheight
.
5
\openlineheight
460
\divide
\noflinesheight
\openlineheight
461
\noflines
\noflinesheight
462
\else
463
\advance
\noflinesheight
-
\roundingeps
464
\advance
\noflinesheight
-
.
5
\openlineheight
465
\divide
\noflinesheight
\openlineheight
466
\noflines
\noflinesheight
467
\fi
}
468 469
%D Let's proof that it works:
470
%D
471
%D \startbuffer
472
%D \scratchdimen\dimexpr(3pt) \getnoflines\scratchdimen 1=\the\noflines \endgraf
473
%D \scratchdimen\dimexpr(10\lineheight) \getnoflines\scratchdimen 10=\the\noflines \endgraf
474
%D \scratchdimen\dimexpr(10.1\lineheight) \getnoflines\scratchdimen 11=\the\noflines \endgraf
475
%D \scratchdimen\dimexpr(10.5\lineheight) \getnoflines\scratchdimen 11=\the\noflines \endgraf
476
%D \scratchdimen\dimexpr(10.9\lineheight) \getnoflines\scratchdimen 11=\the\noflines \endgraf
477
%D \scratchdimen\dimexpr(10\lineheight+3pt) \getnoflines\scratchdimen 11=\the\noflines \endgraf
478
%D \scratchdimen\dimexpr(10\lineheight+3sp) \getnoflines\scratchdimen 10=\the\noflines \endgraf
479
%D \scratchdimen\dimexpr(10\lineheight-3sp) \getnoflines\scratchdimen 10=\the\noflines \endgraf
480
%D
481
%D \scratchdimen\dimexpr(3pt) \getrawnoflines\scratchdimen 0=\the\noflines \endgraf
482
%D \scratchdimen\dimexpr(10\lineheight) \getrawnoflines\scratchdimen 10=\the\noflines \endgraf
483
%D \scratchdimen\dimexpr(10.1\lineheight) \getrawnoflines\scratchdimen 10=\the\noflines \endgraf
484
%D \scratchdimen\dimexpr(10.5\lineheight) \getrawnoflines\scratchdimen 11=\the\noflines \endgraf
485
%D \scratchdimen\dimexpr(10.9\lineheight) \getrawnoflines\scratchdimen 11=\the\noflines \endgraf
486
%D \scratchdimen\dimexpr(10\lineheight+3pt) \getrawnoflines\scratchdimen 10=\the\noflines \endgraf
487
%D \scratchdimen\dimexpr(10\lineheight+3sp) \getrawnoflines\scratchdimen 10=\the\noflines \endgraf
488
%D \scratchdimen\dimexpr(10\lineheight-3sp) \getrawnoflines\scratchdimen 10=\the\noflines \endgraf
489
%D \stopbuffer
490
%D
491
%D \typebuffer \getbuffer
492 493
%D \macros
494
%D {determinenoflines}
495
%D
496
%D The next macro determines the number of lines and returns it it \type
497
%D {\noflines}. The macro works reasonable well as long as the content can be
498
%D unboxed.
499
%D
500
%D \starttyping
501
%D \determinenoflines{test\\test}
502
%D \determinenoflines{\bfd test\\test}
503
%D \determinenoflines{\definedfont[Sans at 40pt]test\\test}
504
%D \stoptyping
505 506
% \def\syst_boxes_determine_noflines % can be mkiv'd
507
% {\beginofshapebox
508
% \unvbox\nextbox
509
% \endofshapebox
510
% \globalscratchcounter\zerocount
511
% \reshapebox{\global\advance\globalscratchcounter\plusone}%
512
% \expandafter\egroup\expandafter\noflines\the\globalscratchcounter\relax}
513 514
\def
\syst_boxes_determine_noflines
515
{
\expandafter
\egroup
\expandafter
\noflines
\noflinesinbox
\nextbox
\relax
}
516 517
\unexpanded
\def
\determinenoflines
518
{
\bgroup
519
\forgetall
520
\let
\crlf\endgraf
521
\let
\\
\endgraf
522
\dowithnextboxcs
\syst_boxes_determine_noflines
\vbox
}
523 524
%D \macros
525
%D {doiftextelse, doiftext}
526
%D
527
%D When \type {\doifelse} cum suis hopelessly fail, for instance because we pass
528
%D data, we can fall back on the next macro:
529
%D
530
%D \starttyping
531
%D \doiftextelse {data} {then branch} {else branch}
532
%D \doiftext {data} {then branch}
533
%D \stoptyping
534 535
\unexpanded
\def
\doifelsetext
#
1
%
536
{
\begingroup
537
\setbox
\scratchbox
\hbox
% no \hpack because we can have fallbacks
538
{
\settrialtypesetting
539
\ignorespaces
#
1
\removeunwantedspaces
}
%
540
\ifzeropt
\wd
\scratchbox
541
\endgroup\expandafter
\secondoftwoarguments
542
\else
543
\endgroup\expandafter
\firstoftwoarguments
544
\fi
}
545 546
\unexpanded
\def
\doiftext
#
1
%
547
{
\begingroup
548
\setbox
\scratchbox
\hbox
% no \hpack because we can have fallbacks
549
{
\settrialtypesetting
550
\ignorespaces
#
1
\removeunwantedspaces
}
%
551
\ifzeropt
\wd
\scratchbox
552
\endgroup\expandafter
\gobbleoneargument
553
\else
554
\endgroup\expandafter
\firstofoneargument
555
\fi
}
556 557
% more efficient but maybe fragile:
558
%
559
% \nospacing#1}%
560 561
\let
\doiftextelse\doifelsetext
562 563
%D \macros
564
%D {dowithnextbox,nextbox}
565
%D
566
%D Sometimes we want a macro to grab a box and do something on the content. One
567
%D could pass an argument to a box, but this can violate the specific \CATCODES\ of
568
%D its content and leads to unexpected results. The next macro treats the following
569
%D braced text as the content of a box and manipulates it afterwards in a predefined
570
%D way.
571
%D
572
%D The first argument specifies what to do with the content. This content is
573
%D available in \type {\nextbox}. The second argument is one of \type {\hbox}, \type
574
%D {\vbox} or \type {\vtop}. The third argument must be grouped with \type {\bgroup}
575
%D and \type {\egroup}, \type {{...}} or can be a \type {\box} specification.
576
%D
577
%D In \CONTEXT\ this macro is used for picking up a box and treating it according to
578
%D earlier specifications. We use for instance something like:
579
%D
580
%D \starttyping
581
%D \def\getfloat%
582
%D {\def\handlefloat{...\box\nextbox...}
583
%D \dowithnextboxcs\handlefloat\vbox}
584
%D \stoptyping
585
%D
586
%D instead of:
587
%D
588
%D \starttyping
589
%D \def\getfloat#1%
590
%D {...#1...}
591
%D \stoptyping
592
%D
593
%D In this implementation the \type {\aftergroup} construction is needed because
594
%D \type {\afterassignment} is executed inside the box.
595 596
\unexpanded
\def
\dowithnextbox
#
1
%
597
{
\def
\syst_boxes_with_next_box
{
#
1
}
%
598
\afterassignment
\syst_boxes_with_next_box_indeed
599
\setbox
\nextbox
}
600 601
\def
\syst_boxes_with_next_box_indeed
602
{
\aftergroup
\syst_boxes_with_next_box
}
603 604
\unexpanded
\def
\dowithnextboxcs
#
1
%
605
{
\let
\syst_boxes_with_next_box
#
1
%
606
\afterassignment
\syst_boxes_with_next_box_indeed
607
\setbox
\nextbox
}
608 609
%D So in fact we get:
610
%D
611
%D \starttyping
612
%D \setbox\nextbox { \aftergroup\syst_boxes_with_next_box ... }
613
%D \stoptyping
614
%D
615
%D or
616
%D
617
%D \starttyping
618
%D \setbox\nextbox { ... } \syst_boxes_with_next_box
619
%D \stoptyping
620
%D
621
%D A slower but more versatile implementation is:
622
%D
623
%D \starttyping
624
%D \unexpanded\def\dowithnextbox#1#2%
625
%D {\def\syst_boxes_with_next_box{#1}%
626
%D \ifx#2\hbox
627
%D \afterassignment\syst_boxes_with_next_box_indeed
628
%D \else\ifx#2\vbox
629
%D \afterassignment\syst_boxes_with_next_box_indeed
630
%D \else\ifx#2\vtop
631
%D \afterassignment\syst_boxes_with_next_box_indeed
632
%D \else\ifx#2\normalvcenter
633
%D \afterassignment\syst_boxes_with_next_box_indeed
634
%D \else
635
%D \afterassignment\syst_boxes_with_next_box
636
%D \fi\fi\fi\fi
637
%D \setbox\nextbox#2}
638
%D \stoptyping
639
%D
640
%D This alternative also accepts \type {\box0} and alike, but we don't really need
641
%D this functionality now.
642 643
%D \macros
644
%D {nextboxht,nextboxwd,nextboxdp,flushnextbox}
645
%D
646
%D The next couple of shortcuts saves us memory as well as \type {{}}'s in passing
647
%D parameters.
648 649
\def
\nextboxht
{
\ht
\nextbox
}
650
\def
\nextboxwd
{
\wd
\nextbox
}
651
\def
\nextboxdp
{
\dp
\nextbox
}
652
\def
\nextboxhtdp
{
\htdp\nextbox
}
653 654
\unexpanded
\def
\flushnextbox
{
\box
\nextbox
}
655 656
%D \macros
657
%D {dowithnextboxcontent}
658
%D
659
%D But, occasionally we do need to pass some local settings without wanting to use
660
%D additional grouping. Therefore we provide:
661
%D
662
%D \starttyping
663
%D \dowithnextboxcontent{inside}{after}{box content}
664
%D \stoptyping
665
%D
666
%D {\em todo: Search source for potential usage!}
667 668
\unexpanded
\def
\dowithnextboxcontent
#
1
#
2
% inside, after
669
{
\def
\syst_boxes_with_next_box_one
{
#
2
}
%
670
\def
\syst_boxes_with_next_box_two
{
#
1
}
%
671
\afterassignment
\syst_boxes_with_next_box_content_indeed
672
\setbox
\nextbox
}
673 674
\unexpanded
\def
\dowithnextboxcontentcs
#
1
#
2
% inside, after
675
{
\let
\syst_boxes_with_next_box_one
#
2
%
676
\let
\syst_boxes_with_next_box_two
#
1
%
677
\afterassignment
\syst_boxes_with_next_box_content_indeed
678
\setbox
\nextbox
}
679 680
\def
\syst_boxes_with_next_box_content_indeed
681
{
\syst_boxes_with_next_box_two
\aftergroup
\syst_boxes_with_next_box_one
}
682 683
%D \macros
684
%D {llap, rlap, tlap, blap, clap}
685
%D
686
%D Some well known friends, but we implement them our own way. We want the macros to
687
%D work in both math and text mode.
688 689
\def
\dodorlap
{
\hpack
to
\zeropoint
{
\box
\nextbox
\hss
}
\endgroup
}
690
\def
\dodollap
{
\hpack
to
\zeropoint
{
\hss\box
\nextbox
}
\endgroup
}
691
\def
\dodoclap
{
\hpack
to
\zeropoint
{
\hss\box
\nextbox
\hss
}
\endgroup
}
692 693
\def
\dorlap
{
\begingroup
\dowithnextboxcs
\dodorlap
\hbox
}
694
\def
\dollap
{
\begingroup
\dowithnextboxcs
\dodollap
\hbox
}
695
\def
\doclap
{
\begingroup
\dowithnextboxcs
\dodoclap
\hbox
}
696 697
\def
\domathclap
{
\mathpalette
\dodomathclap
}
\def
\dodomathclap
#
1
#
2
{
\doclap
{
\normalstartimath
\mathsurround
\zeropoint
#
1
#
2
\normalstopimath
}}
698
\def
\domathllap
{
\mathpalette
\dodomathllap
}
\def
\dodomathllap
#
1
#
2
{
\dollap
{
\normalstartimath
\mathsurround
\zeropoint
#
1
#
2
\normalstopimath
}}
699
\def
\domathrlap
{
\mathpalette
\dodomathrlap
}
\def
\dodomathrlap
#
1
#
2
{
\dorlap
{
\normalstartimath
\mathsurround
\zeropoint
#
1
#
2
\normalstopimath
}}
700 701
\unexpanded
\def
\rlap
{
\mathortext
\domathrlap
\dorlap
}
702
\unexpanded
\def
\llap
{
\mathortext
\domathllap
\dollap
}
703
\unexpanded
\def
\clap
{
\mathortext
\domathclap
\doclap
}
704 705
\def
\dodotlap
{
\vpack
to
\zeropoint
{
\vss\box
\nextbox
}
\endgroup
}
706
\def
\dodoblap
{
\vpack
to
\zeropoint
{
\box
\nextbox
\vss
}
\endgroup
}
707 708
\unexpanded
\def
\tlap
{
\begingroup
\dowithnextboxcs
\dodotlap
\vbox
}
709
\unexpanded
\def
\blap
{
\begingroup
\dowithnextboxcs
\dodoblap
\vbox
}
710 711
%D \macros
712
%D {beginofshapebox,
713
%D reshapebox, doreshapebox,
714
%D flushshapebox,
715
%D innerflushshapebox,
716
%D shapebox,
717
%D ifreshapingbox}
718
%D
719
%D The next utility macro originates from some linenumbering mechanism. Due to
720
%D \TEX's advanced way of typesetting paragraphs, it's not easy to do things on a
721
%D line||by||line basis. This macro is able to reprocess a given box and can act
722
%D upon its vertical boxed components, such as lines. The unwinding sequence in this
723
%D macro is inspired by a \NTG\ workshop of David Salomon in June 1992.
724
%D
725
%D First we have to grab the piece of text we want to act upon. This is done by
726
%D means of the duo macros:
727
%D
728
%D \starttyping
729
%D \beginofshapebox
730
%D a piece of text
731
%D \endofshapebox
732
%D \stoptyping
733
%D
734
%D When all texts is collected, we can call \type {\reshapebox} and do something
735
%D with it's vertical components. We can make as much passes as needed. When we're
736
%D done, the box can be unloaded with \type {\flushshapebox}. The only condition in
737
%D this scheme is that \type {\reshapebox} must somehow unload the \BOX\ \type
738
%D {\shapebox}.
739
%D
740
%D An important aspect is that the content is unrolled bottom||up. The next example
741
%D illustrates this maybe unexpected characteristic.
742
%D
743
%D \startbuffer
744
%D \beginofshapebox
745
%D \em \input tufte
746
%D \endofshapebox
747
%D
748
%D \newcounter\LineNumber
749
%D
750
%D \reshapebox
751
%D {\doglobal\increment\LineNumber
752
%D \hbox{\llap{\LineNumber\hskip2em}\box\shapebox}}
753
%D
754
%D \flushshapebox
755
%D \stopbuffer
756
%D
757
%D \typebuffer
758
%D
759
%D \getbuffer
760
%D
761
%D As we can see, when some kind of numbering is done, we have to add a second pass.
762
%D
763
%D \startbuffer
764
%D \newcounter\LineNumber
765
%D \newcounter\NumberOfLines
766
%D
767
%D \reshapebox
768
%D {\doglobal\increment\NumberOfLines
769
%D \box\shapebox}
770
%D
771
%D \reshapebox
772
%D {\doglobal\increment\LineNumber
773
%D \hbox
774
%D {\llap{\LineNumber\ (\NumberOfLines)\hskip2em}%
775
%D \box\shapebox}%
776
%D \doglobal\decrement\NumberOfLines}
777
%D
778
%D \flushshapebox
779
%D \stopbuffer
780
%D
781
%D \typebuffer
782
%D
783
%D \getbuffer
784
%D
785
%D This example shows that the content of the box is still available after flushing.
786
%D Another feature is that only the last reshaping counts. Multiple reshaping can be
787
%D done by:
788
%D
789
%D \startbuffer
790
%D \beginofshapebox
791
%D \flushshapebox
792
%D \endofshapebox
793
%D
794
%D \reshapebox
795
%D {\doglobal\increment\LineNumber
796
%D \hbox{\llap{$\star$\hskip1em}\box\shapebox}%
797
%D \doglobal\decrement\NumberOfLines}
798
%D
799
%D \flushshapebox
800
%D \stopbuffer
801
%D
802
%D \typebuffer
803
%D
804
%D \getbuffer
805
%D
806
%D The macros are surprisingly easy to follow and in fact introduce no new concepts.
807
%D Nearly all books on \TEX\ show similar solutions for unwinding \BOXES.
808
%D
809
%D Some macros, like footnote ones, can be sensitive for reshaping, which can result
810
%D in an endless loop. We therefore offer:
811
%D
812
%D \starttyping
813
%D \ifreshapingbox
814
%D \stoptyping
815
%D
816
%D Some \CONTEXT\ commands are protected this way. Anyhow, reshaping is aborted
817
%D after 100 dead cycles.
818
%D
819
%D By the way, changing the height and depth of \BOX\ \type {\shapebox} results in
820
%D bad spacing. This means that for instance linenumbers etc. should be given zero
821
%D height and depth before being lapped into the margin. The previous examples
822
%D ignore this side effect, but beware!
823 824
\newif
\ifsomeshapeleft
825
\newif
\ifreshapingbox
826
\newif
\ifreshapingfailed
% may save redundant runs
827 828
\newbox
\shapebox
829
\newcount
\shapepenalty
830
\newdimen
\shapekern
831
\newskip
\shapeskip
832 833
\newbox
\newshapebox
834
\newbox
\oldshapebox
835
\newbox
\tmpshapebox
836 837
\newcount
\shapecounter
838 839
\newevery
\everyshapebox
\relax
840 841
\def
\shapesignal
{
.
1
2
3
4
5
6
7
8
pt
}
% or 12345sp
842 843
\unexpanded
\def
\reshapebox
#
1
%
844
{
\doreshapebox
845
{
#
1
}
%
846
{
\penalty
\shapepenalty
}
%
847
{
\kern
\shapekern
}
%
848
{
\vskip
\shapeskip
}}
849 850
\def
\doreshapebox
#
1
#
2
#
3
#
4
% \shapebox, \shapepenalty, \shapekern, \shapeskip
851
{
\global
\reshapingfailedfalse
852
\ifzeropt
\ht
\oldshapebox
853
\setbox
\newshapebox
\emptyvbox
854
\else
855
\setbox
\newshapebox
\vbox
% can be \vpack
856
{
\unvcopy
\oldshapebox
857
\setbox
\newshapebox
\emptybox
858
\shapecounter
\zerocount
859
\doloop
{
\dodoreshapebox
{
#
1
}{
#
2
}{
#
3
}{
#
4
}}}
%
860
\setbox
\newshapebox
\box
\tmpshapebox
861
\fi
}
862 863
\ifx
\originalshapebox
\undefined
\let
\originalshapebox
\oldshapebox
\fi
864 865
% We will turn this into a \MKIV\ variant (we can use \type {\vpack} too).
866 867
\unexpanded
\def
\insertshapesignal
868
{
\hpack
to
\shapesignal
{
\strut
\hss
}
% plus \strut
869
\prevdepth
\strutdp
}
% never \nointerlineskip
870 871
\unexpanded
\def
\restoreshapebox
% compensates for the signal
872
{
\global\setbox
\tmpshapebox
\vbox
{
\vskip
-
\lineheight
\unvcopy
\oldshapebox
}}
873 874
\def
\dodoreshapebox
#
1
#
2
#
3
#
4
% \shapebox, \shapepenalty, \shapekern, \shapeskip
875
{
\ifnum
\lastnodetype
=
\gluenodecode
876
\shapeskip
\lastskip
877
\global\setbox
\tmpshapebox
\vbox
{
#
4
\unvbox
\tmpshapebox
}
%
878
\unskip
879
\orelse\ifnum\lastnodetype
=
\kernnodecode
880
\shapekern
\lastkern
881
\global\setbox
\tmpshapebox
\vbox
{
#
3
\unvbox
\tmpshapebox
}
%
882
\unkern
883
\orelse\ifnum\lastnodetype
=
\penaltynodecode
884
\shapepenalty
\lastpenalty
885
\global\setbox
\tmpshapebox
\vbox
{
#
2
\unvbox
\tmpshapebox
}
%
886
\unpenalty
887
\orelse\ifnum\lastnodetype
<
\zeropoint
888
\exitloop
889
\else
890
\setbox
\shapebox
\lastbox
891
\ifvoid
\shapebox
892
\orelse\ifdim\wd
\shapebox
=
\shapesignal
\relax
893
\exitloop
894
\else
895
\shapecounter
\zerocount
896
\global\setbox
\tmpshapebox
\vbox
{
#
1
\unvbox
\tmpshapebox
}
%
897
\fi
898
\fi
899
\ifnum
\shapecounter
>
1
0
0
% can be less
900
\global
\reshapingfailedtrue
901
\message
{
!
!
forced
exit
from
shapebox
\the\lastnodetype
!
!
}
%
902
\restoreshapebox
903
\exitloop
904
\else
905
\advance
\shapecounter
\plusone
906
\fi
}
907 908
\unexpanded
\def
\beginofshapebox
909
{
\setbox
\oldshapebox
\vbox
910
\bgroup
911
\reshapingboxtrue
912
\the
\everyshapebox
913
\insertshapesignal
}
914 915
\unexpanded
\def
\endofshapebox
916
{
\endgraf
917
\egroup
}
918 919
\let
\beginshapebox
\beginofshapebox
920
\let
\endshapebox
\endofshapebox
921 922
\unexpanded
\def
\flushshapebox
923
{
\bgroup
924
\ifzeropt
\ht
\newshapebox
925
\else
926
% make \prevdepth legal
927
% \par before the next \vskip gives far worse results
928
\ifdim
\parskip
>
\zeropoint
\vskip\parskip\else\par\fi
929
% and take a look
930
\ifdim
\prevdepth
=
-
\thousandpoint
931
\prevdepth
\zeropoint
932
\fi
933
\ifdim
\prevdepth
<
\zeropoint
\relax
934
% something like a line or a signal or ...
935
\donetrue
936
\orelse\ifinner
937
% not watertight and not ok
938
\donefalse
939
\orelse\ifdim\pagegoal
=
\maxdimen
940
\donetrue
941
\else
942
% give the previous line a normal depth
943
\donetrue
944
{
\forgeteverypar
\verticalstrut
}
\nobreak
945
\kern
-
\struttotal
% geen \vskip
946
\kern
-
\parskip
947
% \vskip-\strutdp
948
\fi
949
\scratchdimen
\dp
\newshapebox
950
\unvbox
\newshapebox
951
% \prevdepth=0pt and \dp\newshapebox depend on last line
952
\kern
-
\scratchdimen
% ??
953
% now \prevdepth=0pt
954
\ifdone
955
\kern
\strutdp
956
\prevdepth
\strutdp
957
\fi
958
\fi
959
\egroup
}
960 961
%D In real inner situations we can use:
962
%D
963
%D \starttyping
964
%D \flushinnershapebox
965
%D \stoptyping
966
%D
967
%D This one is used in \type{\framed}.
968 969
% The kern fails on for instance:
970
%
971
% \omlijnd[offset=0pt,hoogte=8mm,uitlijnen={rechts,laho}]{\bfa test}
972 973
\unexpanded
\def
\innerflushshapebox
974
{
\ifzeropt
\ht
\newshapebox
\else
975
\unvcopy
\newshapebox
\relax
% unvcopy ! else spacing problem
976
% \kern-\dp\newshapebox\relax
977
\fi
}
978 979
%D For absolute control, one can use \type {\doreshapebox} directly. This macro
980
%D takes four arguments, that take care of:
981
%D
982
%D \startitemize[n,packed]
983
%D \item \type{\shapebox}
984
%D \item \type{\shapepenalty}
985
%D \item \type{\shapekern}
986
%D \item \type{\shapeskip}
987
%D \stopitemize
988 989
%D \macros
990
%D {shapedhbox}
991
%D
992
%D When constructing a new box, using the content of \type {\shapebox}, one can best
993
%D use \type {\shapedhbox} instead of \type {\hbox}, since it manages the height and
994
%D depth of the line.
995 996
\unexpanded
\def
\shapedhbox
% lines with non strutted dimensions have
997
{
\expanded
{
\dowithnextbox
% interlineskip so if we want the original
998
{
\ht
\nextbox
\the\ht
\shapebox
% spacing, we need to preserve the original
999
\dp
\nextbox
\the\dp
\shapebox
% height and depth which is definitely
1000
\box
\nextbox
}}
% needed if we apply struts to the 'new'
1001
\hbox
}
% box or do something that changed ist size
1002 1003
%D \macros
1004
%D {hyphenatedword,
1005
%D hyphenatedpar,
1006
%D hyphenatedfile,
1007
%D dohyphenateword}
1008
%D
1009
%D We no longer use the pure \TEX\ variant. In due time we will report some more
1010
%D advanced statistics.
1011
%D
1012
%D \starttyping
1013
%D \showhyphens{dohyphenatedword}
1014
%D \stoptyping
1015 1016
\unexpanded
\def
\doshowhyphenatednextbox
1017
{
\clf_showhyphenatedinlist
\nextbox
}
1018 1019
\unexpanded
\def
\showhyphens
% hpack: so no processing (we hyphenate in lua)
1020
{
\dowithnextboxcs
\doshowhyphenatednextbox
\hpack
}
1021 1022
%D The following macros are seldom used but handy for tracing.
1023
%D
1024
%D \starttyping
1025
%D \hyphenatedword{dohyphenatedword}
1026
%D \hyphenatedpar {\dorecurse{10}{dohyphenatedword }}
1027
%D \hyphenatedfile{tufte}
1028
%D \stoptyping
1029 1030
\unexpanded
\def
\dohyphenatednextbox
1031
{
\clf_hyphenatedlist
\nextbox
false
\relax
1032
\unhbox
\nextbox
}
1033 1034
\unexpanded
\def
\hyphenatedword
{
\dowithnextboxcs
\dohyphenatednextbox
\hbox
}
1035
\unexpanded
\def
\hyphenatedpar
{
\dowithnextboxcs
\dohyphenatednextbox
\hbox
}
1036
\unexpanded
\def
\hyphenatedfile
#
1
{
\dowithnextboxcs
\dohyphenatednextbox
\hbox
{
\readfile
{
#
1
}
\donothing\donothing
}}
1037 1038
\unexpanded
\def
\dohyphenatednextboxcolor
1039
{
\clf_hyphenatedlist
\nextbox
true
\relax
1040
\unhbox
\nextbox
}
1041 1042
\unexpanded
\def
\hyphenatedcoloredword
{
\dowithnextboxcs
\dohyphenatednextboxcolor
\hbox
}
1043 1044
%D \macros
1045
%D {processtokens}
1046
%D
1047
%D We fully agree with (most) typographers that inter||letter spacing is only
1048
%D permitted in fancy titles, we provide a macro that can be used to do so. Because
1049
%D this is (definitely and fortunately) no feature of \TEX, we have to step through
1050
%D the token list ourselves.
1051
%D
1052
%D \starttyping
1053
%D \processtokens {before} {between} {after} {space} {tokens}
1054
%D \stoptyping
1055
%D
1056
%D An example of a call is:
1057
%D
1058
%D \startbuffer
1059
%D \processtokens {[} {+} {]} {\space} {hello world}
1060
%D \stopbuffer
1061
%D
1062
%D \typebuffer
1063
%D
1064
%D This results in:
1065
%D
1066
%D \getbuffer
1067
%D
1068
%D The list of tokens may contain spaces, while \type {\\}, \type {{}} and \type {\
1069
%D } are handled as space too.
1070 1071
\unexpanded
\def
\processtokens
#
1
#
2
#
3
#
4
#
5
%
1072
{
\begingroup
1073
\def
\lastcharacter
{
\lastcharacter
}
% hm, recursive ?
1074
\def
\space
{
}
%
1075
\let
\\
=
\space
1076
\def
\before
{
#
1
}
%
1077
\def
\between
{
#
2
}
%
1078
\def
\after
{
#
3
}
%
1079
\def
\white
{
#
4
}
%
1080
\let
\savedbefore
\before
1081
\doprocesstokens
#
5
\lastcharacter
1082
\endgroup
}
1083 1084
\def
\doprocesstokens
% the space after = is essential
1085
{
\afterassignment
\dodoprocesstokens
\let
\nextprocessedtoken
=
}
1086 1087
\def
\redoprocessedtoken
1088
{
\dowithnextbox
1089
{
\before
{
\copy
\nextbox
}
% \before can use nextbox several times
1090
\let
\before
\between
1091
\doprocesstokens
}
1092
\hbox
\bgroup
}
1093 1094
\def
\dodoprocesstokens
1095
{
\ifx
\nextprocessedtoken
\lastcharacter
1096
\after
1097
\orelse\ifx
\nextprocessedtoken
\bgroup
1098
\expandafter
\redoprocessedtoken
1099
\else
1100
\expandafter\if
\space
\nextprocessedtoken
1101
\after
\white
1102
\let
\before
\savedbefore
1103
\else
1104
\before
\nextprocessedtoken
1105
\let
\before
\between
1106
\fi
1107
\expandafter
\doprocesstokens
1108
\fi
}
1109 1110
%D \macros
1111
%D {doboundtext}
1112
%D
1113
%D Sometimes there is not enough room to show the complete (line of) text. In such a
1114
%D situation we can strip of some characters by using \type {\doboundtext}. When the
1115
%D text is wider than the given width, it's split and the third argument is
1116
%D appended. When the text to be checked is packed in a command, we'll have to use
1117
%D \type {\expandafter}.
1118
%D
1119
%D \starttyping
1120
%D \doboundtext{a very, probably to long, text}{3cm}{...}
1121
%D \stoptyping
1122
%D
1123
%D When calculating the room needed, we take the width of the third argument into
1124
%D account, which leads to a bit more complex macro than needed at first sight.
1125 1126
\def
\dodoboundtext
#
1
%
1127
{
\setbox
\scratchboxone
\hbox
{
#
1
}
%
1128
\advance
\scratchdimen
-
\wd
\scratchboxone
1129
\ifdim
\scratchdimen
>
\zeropoint
\relax
#
1
\fi
}
1130 1131
\def
\doboundtext
#
1
#
2
#
3
% still used?
1132
{
\hbox
1133
{
\setbox
\scratchbox
\hbox
{
#
1
}
%
1134
\scratchdimen
#
2
\relax
1135
\ifdim
\wd
\scratchbox
>
\scratchdimen
1136
\setbox
\scratchbox
\hbox
{
#
3
}
%
1137
\advance
\scratchdimen
-
\wd
\scratchbox
1138
\handletokens
#
1
\with
\dodoboundtext
1139
\fi
1140
\box
\scratchbox
}}
1141 1142
%D \macros
1143
%D {limitatetext}
1144
%D
1145
%D A bit more beautiful alternative for the previous command is the next one. This
1146
%D command is more robust because we let \TEX\ do most of the job. The previous
1147
%D command works better on text that cannot be hyphenated.
1148
%D
1149
%D \starttyping
1150
%D \limitatetext {text} {width} {sentinel}
1151
%D \limitatetext {text} {-width} {prelude}
1152
%D \stoptyping
1153
%D
1154
%D When no width is given, the whole text comes available. The sentinel is optional.
1155
%D This is about the third version.
1156 1157
\ifdefined
\fakecompoundhyphen
\else
\let
\fakecompoundhyphen
\relax
\fi
1158
\ifdefined
\veryraggedright
\else
\def
\veryraggedright
{
\raggedright
}
\fi
1159 1160
% \unexpanded\def\limitatetext
1161
% {\bgroup % evt \setstrut
1162
% \forgetall % otherwise indentation and so
1163
% \let\limitatetext\firstofthreearguments
1164
% \fakecompoundhyphen % dangerous ! ! ! ! ! ! ! ! !
1165
% \dowithnextboxcs\syst_boxes_limitate_text\hbox}
1166
%
1167
% \def\syst_boxes_limitate_text#1% #2
1168
% {\doifelsenothing{#1}\syst_boxes_limitate_text_nop\syst_boxes_limitate_text_yes{#1}} % {#2}
1169
%
1170
% \def\syst_boxes_limitate_text_nop#1#2%
1171
% {\unhbox\nextbox
1172
% \egroup}
1173
%
1174
% \def\syst_boxes_limitate_text_yes#1#2%
1175
% {\nopenalties
1176
% \scratchdimen#1\relax
1177
% \ifdim\scratchdimen<\zeropoint\relax % we'll take the last line
1178
% \donefalse
1179
% \scratchdimen-\scratchdimen
1180
% \else
1181
% \donetrue
1182
% \fi
1183
% \ifdim\wd\nextbox>\scratchdimen
1184
% \setbox\scratchbox\hbox{\ifdone\space#2\else#2\space\fi}%
1185
% \advance\scratchdimen -\wd\scratchbox
1186
% \setbox\scratchboxone\box\nextbox
1187
% \setbox\nextbox\vbox
1188
% {\hsize\scratchdimen
1189
% \hfuzz\maxdimen
1190
% \veryraggedright
1191
% \strut
1192
% \ifdone \else
1193
% \parfillskip\zeropoint
1194
% \rightskip\zeropoint
1195
% \hskip\zeropoint \s!plus 1\s!fill % \hsize
1196
% \fi
1197
% \unhcopy\scratchboxone}%
1198
% \ifdim\ht\nextbox>\strutht
1199
% \setbox\nextbox\vbox % if omitted: missing brace reported
1200
% {\splittopskip\openstrutheight
1201
% \ifdone
1202
% \setbox\nextbox\vsplit\nextbox to \strutht
1203
% \else
1204
% \doloop
1205
% {\setbox\scratchboxone\vsplit\nextbox to \strutht
1206
% \ifdim\ht\nextbox>\strutht \else \exitloop \fi}%
1207
% \fi
1208
% \unvbox\nextbox
1209
% \setbox\nextbox\lastbox
1210
% \global\setbox1\hpack
1211
% {\ifdone
1212
% \unhbox\nextbox\unskip\kern\zeropoint\box\scratchbox
1213
% \else
1214
% \box\scratchbox\unhbox\nextbox
1215
% \fi
1216
% \unskip}}%
1217
% \unhbox1
1218
% \else
1219
% \unhbox0%
1220
% \fi
1221
% \else
1222
% \unhbox\nextbox
1223
% \fi
1224
% \egroup}
1225
%
1226
% %D We can also limit a text with more control:
1227
% %D
1228
% %D \startbuffer
1229
% %D \limitatetext {\input tufte } {2cm,5mm} {\unknown}
1230
% %D \limitatetext {ton en hans} {2cm,5mm} {\unknown}
1231
% %D \limitatetext {ton en hans zijn eikels} {2cm,5mm} {\unknown}
1232
% %D \limitatetext {ton} {2cm,5mm} {\unknown}
1233
% %D \stopbuffer
1234
% %D
1235
% %D \typebuffer \getbuffer
1236
% %D
1237
% %D We build this feature on top of the previous macro.
1238
%
1239
% % we could move the text argument to the end
1240
%
1241
% \let\normallimitatetext\limitatetext
1242
%
1243
% \def\speciallimitatetext#1#2#3#4% text left right placeholder
1244
% {%\dontleavehmode
1245
% \bgroup
1246
% \let\speciallimitatetext\firstoffourarguments
1247
% \setbox\scratchboxone\hbox
1248
% {\nohyphens
1249
% \normallimitatetext{#1}{+#2}{}#4%
1250
% \normallimitatetext{#1}{-#3}{}}%
1251
% \setbox\scratchboxtwo\hbox
1252
% {#1}%
1253
% \ifdim\wd\scratchboxtwo<\wd\scratchboxone #1\else\unhbox\scratchboxone\fi
1254
% \egroup}
1255
%
1256
% \unexpanded\def\limitatetext#1#2#3% \expanded added 2003/01/16
1257
% {\splitatcomma{#2}\leftlimit\rightlimit
1258
% \ifempty\rightlimit
1259
% \normallimitatetext {#1}\leftlimit {#3}%
1260
% \else
1261
% \speciallimitatetext{#1}\leftlimit\rightlimit{#3}%
1262
% \fi}
1263 1264
\unexpanded
\def
\limitatetext
#
1
#
2
#
3
% \expanded added 2003/01/16
1265
{
\splitatcomma
{
#
2
}
\leftlimit
\rightlimit
1266
\limitated
1267
left
\leftlimit
1268
\ifempty
\rightlimit
\else
1269
right
\rightlimit
1270
\fi
1271
strip
true
1272
sentinel
{
#
3
}
1273
text
{
#
1
}
1274
\relax
}
1275 1276
%D Undocumented bonus (see wiki):
1277
%D
1278
%D \starttyping
1279
%D \limitatefirstline{\input tufte\relax}{10cm}{\unknown}
1280
%D \stoptyping
1281 1282
\unexpanded
\def
\limitatefirstline
#
1
#
2
#
3
%
1283
{
\hbox
\bgroup
\strut
% \hpack
1284
\setbox
\scratchbox
\hbox
{
\begstrut
#
1
\endstrut
}
%
1285
\ifdim
\wd
\scratchbox
>#
2
\relax
1286
\setbox
\scratchbox
\hbox
{
#
3
}
%
1287
\hsize
#
2
\relax
1288
\advance\hsize
-
\wd
\scratchbox
1289
\setbox
\scratchbox
\vbox
{
\forgetall
\veryraggedright
#
1
}
%
1290
\setbox
\scratchbox
\vsplit
\scratchbox
to
\lineheight
1291
\vbox
1292
{
\unvbox
\scratchbox
1293
\global\setbox
\plusone
\lastbox
1294
\global\setbox
\plusone
\hbox
{
\strut
\unhbox
\plusone
}
%
1295
\hbox
% to #2 % \hpack
1296
{
\ifx
\clip
\undefined
1297
\box
\plusone
1298
\orelse\ifdim\wd
\plusone
>
\hsize
1299
\lower
\strutdepth
\hpack
{
\clip
[
\c!width
=
\hsize
,
\c!height
=
\lineheight
]
{
\hpack
{
\raise
\strutdepth
\box
\plusone
}}}
%
1300
\else
1301
\box
\plusone
1302
\fi
1303
\removeunwantedspaces
#
3
}}
% \removeunwantedspaces\hss#3}}%
1304
\else
1305
#
1
%
1306
\fi
1307
\egroup
}
1308 1309
%D \macros
1310
%D {processisolatedwords,processisolatedchars}
1311
%D
1312
%D \startbuffer
1313
%D \processisolatedchars{some more words} \ruledhbox \par
1314
%D \processisolatedchars{and some $x + y = z$ math} \ruledhbox \par
1315
%D \processisolatedchars{and a \hbox{$x + y = z$}} \ruledhbox \par
1316
%D \processisolatedwords{some more words} \ruledhbox \par
1317
%D \processisolatedwords{and some $x + y = z$ math} \ruledhbox \par
1318
%D \processisolatedwords{and a \hbox{$x + y = z$}} \ruledhbox \par
1319
%D \stopbuffer
1320
%D
1321
%D \typebuffer \blank \getbuffer \blank
1322 1323
% todo: provide variant with #1 picked up as box
1324 1325
\unexpanded
\def
\processisolatedchars
#
1
#
2
%
1326
{
\dontleavehmode
1327
\begingroup
1328
\setbox
\scratchbox
\hbox
{
\settrialtypesetting
#
2
{
\savecurrentattributes
{
pic
}}}
%
1329
\setbox
\scratchbox
\hbox
{
\restorecurrentattributes
{
pic
}
#
1
}
%
1330
\clf_applytobox
1331
method
{
char
}
%
1332
box
\scratchbox
1333
command
{
\csstring
#
2
}
%
1334
nested
true
%
1335
\relax
1336
\endgroup
}
1337 1338
\unexpanded
\def
\processisolatedwords
#
1
#
2
%
1339
{
\dontleavehmode
1340
\begingroup
1341
\setbox
\scratchbox
\hbox
{
\settrialtypesetting
#
2
{
\savecurrentattributes
{
pic
}}}
%
1342
\setbox
\scratchbox
\hbox
{
\restorecurrentattributes
{
pic
}
#
1
}
%
1343
\clf_applytobox
1344
method
{
word
}
%
1345
box
\scratchbox
1346
command
{
\csstring
#
2
}
%
1347
nested
true
%
1348
\relax
1349
\endgroup
}
1350 1351
%D A variant:
1352 1353
\unexpanded
\def
\applytocharacters
#
1
%
1354
{
\dontleavehmode
1355
\dowithnextbox
{
\clf_applytobox
1356
method
{
char
}
%
1357
box
\nextbox
1358
command
{
\csstring
#
1
}
%
1359
nested
true
%
1360
\relax
}
%
1361
\hbox
}
1362 1363
\unexpanded
\def
\applytowords
#
1
%
1364
{
\dontleavehmode
1365
\dowithnextbox
{
\clf_applytobox
1366
method
{
word
}
%
1367
box
\nextbox
1368
command
{
\csstring
#
1
}
%
1369
nested
true
%
1370
\relax
}
%
1371
\hbox
}
1372 1373
%D The old call:
1374 1375
\unexpanded
\def
\processwords
#
1
%
1376
{
\processisolatedwords
{
#
1
}
\processword
}
1377 1378
\let
\processword
\relax
1379 1380
\unexpanded
\def
\applytosplitstringchar
#
1
#
2
%
1381
{
\dontleavehmode
\clf_processsplit
1382
data
{
#
2
}
%
1383
command
{
\csstring
#
1
}
%
1384
method
{
char
}
%
1385
\relax
}
1386 1387
\unexpanded
\def
\applytosplitstringword
#
1
#
2
%
1388
{
\dontleavehmode
\clf_processsplit
1389
data
{
#
2
}
%
1390
command
{
\csstring
#
1
}
%
1391
method
{
word
}
%
1392
\relax
}
1393 1394
\unexpanded
\def
\applytosplitstringline
#
1
#
2
%
1395
{
\dontleavehmode
\clf_processsplit
1396
data
{
#
2
}
%
1397
command
{
\csstring
#
1
}
%
1398
method
{
line
}
%
1399
\relax
}
1400 1401
\unexpanded
\def
\applytosplitstringcharspaced
#
1
#
2
%
1402
{
\dontleavehmode
\clf_processsplit
1403
data
{
#
2
}
%
1404
command
{
\csstring
#
1
}
%
1405
method
{
char
}
%
1406
spaced
true
%
1407
\relax
}
1408 1409
\unexpanded
\def
\applytosplitstringwordspaced
#
1
#
2
%
1410
{
\dontleavehmode
\clf_processsplit
1411
data
{
#
2
}
%
1412
command
{
\csstring
#
1
}
%
1413
method
{
word
}
%
1414
spaced
true
%
1415
\relax
}
1416 1417
\unexpanded
\def
\applytosplitstringlinespaced
#
1
#
2
%
1418
{
\dontleavehmode
\clf_processsplit
1419
data
{
#
2
}
%
1420
command
{
\csstring
#
1
}
%
1421
method
{
line
}
%
1422
spaced
true
%
1423
\relax
}
1424 1425
%D \macros
1426
%D {sbox}
1427
%D
1428
%D This is a rather strange command. It grabs some box content and and limits the
1429
%D size to the height and depth of a \type {\strut}. The resulting bottom||alligned
1430
%D box can be used aside other ones, without disturbing the normal baseline
1431
%D distance.
1432
%D
1433
%D \startbuffer
1434
%D \ruledhbox to .5\hsize{\sbox{eerste\par tweede \par derde}}
1435
%D \stopbuffer
1436
%D
1437
%D \typebuffer
1438
%D
1439
%D Shows up as:
1440
%D
1441
%D \startexample
1442
%D \vskip3\baselineskip
1443
%D \getbuffer
1444
%D \stopexample
1445
%D
1446
%D Before displaying the result we added some skip, otherwise the first two lines
1447
%D would have ended up in the text. This macro can be useful when building
1448
%D complicated menus, headers and footers and|/|or margin material.
1449 1450
\unexpanded
\def
\sbox
1451
{
\vpack
\bgroup
1452
\dowithnextboxcs
\syst_boxes_sbox_finish
\vbox
}
1453 1454
\unexpanded
\def
\syst_boxes_sbox_finish
1455
{
\boxyoffset
\nextbox
-
\strutdp
1456
\dp
\nextbox\strutdp
1457
\ht
\nextbox\strutht
1458
\box
\nextbox
1459
\egroup
}
1460 1461
%D A variant on this:
1462
%D
1463
%D \starttyping
1464
%D xx \ruledhbox{\inlinedbox{\tfd test}} xx
1465
%D \stoptyping
1466 1467
\unexpanded
\def
\inlinedbox
1468
{
\bgroup
1469
\dowithnextboxcs
\syst_boxes_inlined_finish
\hbox
}
1470 1471
\unexpanded
\def
\syst_boxes_inlined_finish
1472
{
\boxyoffset
\nextbox
-
\dimexpr
(
\htdp\nextbox
-
\lineheight
)
/
\plustwo
+
\strutdp
\relax
1473
\ht
\nextbox\strutht
1474
\dp
\nextbox\strutdp
1475
\box
\nextbox
1476
\egroup
}
1477 1478
%D \macros
1479
%D {struttedbox}
1480
%D
1481
%D This boxing macro limits the height and depth to those of a strut.
1482 1483
\unexpanded
\def
\struttedbox
1484
{
\hpack
\bgroup
1485
\dowithnextboxcs
\syst_boxes_struttedbox_finish
\hbox
}
1486 1487
\def
\syst_boxes_struttedbox_finish
1488
{
\dp
\nextbox
\strutdepth
1489
\ht
\nextbox
\strutheight
1490
\box
\nextbox
1491
\egroup
}
1492 1493
%D \macros
1494
%D {topskippedbox}
1495
%D
1496
%D This macro compensates the difference between the topskip and strutheight. Watch
1497
%D how we preserve the depth when it equals strutdepth.
1498 1499
\unexpanded
\def
\topskippedbox
1500
{
\hpack
\bgroup
\dowithnextboxcs
\syst_boxes_topskippedbox_finish
\hbox
}
1501 1502
\def
\syst_boxes_topskippedbox_finish
1503
{
\edef
\m_boxes_tmp
{
\ifdim
\strutdepth
=
\dp
\nextbox
\dp
\nextbox
\the\dp
\nextbox
\fi
}
%
1504
\lower\topskip\hpack
{
\raise
\strutheight
\box
\nextbox
}
%
1505
\m_boxes_tmp
1506
\egroup
}
1507 1508
%D \macros
1509
%D {centeredbox, centerednextbox}
1510
%D
1511
%D Here is another strange one. This one offers a sort of overlay with positive or
1512
%D negative offsets. This command can be used in well defined areas where no offset
1513
%D options are available. We first used it when building a button inside the margin
1514
%D footer, where the button should have a horizontal offset and should be centered
1515
%D with respect to the surrounding box. The last of the three examples we show below
1516
%D says:
1517
%D
1518
%D \starttyping
1519
%D \vsize=3cm
1520
%D \hsize=3cm
1521
%D \ruledvbox to \vsize
1522
%D {\centeredbox height .5cm width -1cm
1523
%D {\vrule width \hsize height \vsize}}}
1524
%D \stoptyping
1525
%D
1526
%D Here the \type {\ruledvbox} just shows the surrounding box and \type {\vrule} is
1527
%D used to show the centered box.
1528
%D
1529
%D \def\AnExample#1#2%
1530
%D {\vsize=3cm
1531
%D \hsize=3cm
1532
%D \ruledvbox to \vsize
1533
%D {\centeredbox height #1 width #2
1534
%D {\color[green]{\vrule width \hsize height \vsize}}}}
1535
%D
1536
%D \startlinecorrection
1537
%D \startcombination[3*1]
1538
%D {\AnExample {-1cm} {.5cm}} {}
1539
%D {\AnExample {.5cm} {-1cm}} {}
1540
%D {\AnExample {-1cm} {-.5cm}} {}
1541
%D \stopcombination
1542
%D \stoplinecorrection
1543
%D
1544
%D This command takes two optional arguments: \type {width} and \type {height}.
1545
%D Observing readers can see that we use \TEX's own scanner for grabbing these
1546
%D arguments: \type {#1#} reads everyting till the next brace and passes it to both
1547
%D rules. The setting of the box dimensions at the end is needed for special cases.
1548
%D The dimensions of the surrounding box are kept intact. This commands handles
1549
%D positive and negative dimensions (which is why we need two boxes with rules).
1550 1551
\unexpanded
\def
\centeredbox
#
1
#
% height +/-dimen width +/-dimen
1552
{
\bgroup
1553
\dontcomplain
1554
\forgetall
1555
\scangivendimensions
#
1
\relax
1556
\advance\vsize
\givenheight
1557
\advance\hsize
\givenwidth
1558
\dowithnextboxcs
\syst_boxes_centered_finish
1559
\hbox
}
1560 1561
\def
\syst_boxes_centered_finish
1562
{
\boxxoffset
\nextbox
.
5
\dimexpr
1563
\hsize
1564
-
\wd
\nextbox
1565
-
\givenwidth
1566
\relax
1567
\boxyoffset
\nextbox
.
5
\dimexpr
1568
\vsize
1569
-
\ht
\nextbox
1570
+
\dp
\nextbox
1571
-
\givenheight
1572
\relax
1573
\wd
\nextbox
\dimexpr\hsize
-
\givenwidth
\relax
1574
\ht
\nextbox
\dimexpr\vsize
-
\givenheight
\relax
1575
\dp
\nextbox
\zeropoint
1576
\box
\nextbox
1577
\egroup
}
1578 1579
%D For those who don't want to deal with \type {\hsize} and \type {\vsize}, we have:
1580
%D
1581
%D \starttyping
1582
%D \centerednextbox width 2bp height 2bp
1583
%D {\framed[width=100bp,height=100bp]{}}
1584
%D \stoptyping
1585
%D
1586
%D Do you see why we call this one \type {next}?
1587 1588
\unexpanded
\def
\centerednextbox
#
1
#
%
1589
{
\bgroup
1590
\dowithnextbox
1591
{
\hsize\wd
\nextbox
1592
\vsize\ht
\nextbox
1593
\centeredbox
#
1
{
\box
\nextbox
}
%
1594
\egroup
}
1595
\hbox
}
1596 1597
%D \macros
1598
%D {centerbox}
1599
%D
1600
%D Centering on the available space is done by:
1601
%D
1602
%D \starttyping
1603
%D \centerbox <optional specs> {content}
1604
%D \stoptyping
1605
%D
1606
%D When omitted, the current \type {\hsize} and \type {\vsize} are used. Local
1607
%D dimensions are supported.
1608 1609
\unexpanded
\def
\centerbox
#
1
#
% optional height +/-dimen width +/-dimen
1610
{
\bgroup
1611
\dowithnextbox
1612
{
\setlocalhsize
1613
\setbox
\scratchbox
\hpack
{
\vrule
\s!width
\zeropoint
#
1
}
%
1614
\ifzeropt
\wd
\scratchbox
\else\hsize\wd
\scratchbox
\fi
1615
\setbox
\scratchbox
\vpack
{
\hrule
\s!height
\zeropoint
#
1
}
%
1616
\ifzeropt
\ht
\scratchbox
\else\vsize\ht
\scratchbox
\fi
1617
\vpack
to
\vsize
{
\vss\hpack
to
\hsize
{
\hss\box
\nextbox
\hss
}
\vss
}
%
1618
\egroup
}
%
1619
\hbox
}
1620 1621
%D \macros
1622
%D {setrigidcolumnhsize,rigidcolumnbalance,rigidcolumnlines}
1623
%D
1624
%D These macros are copied from the \TEX book, page~397, and extended by a macro
1625
%D that sets the \type {\hsize}.
1626
%D
1627
%D \starttyping
1628
%D \setrigidcolumnhsize {total width} {distance} {n}
1629
%D \rigidcolumnbalance {box}
1630
%D \stoptyping
1631
%D
1632
%D Both these macros are for instance used in typesetting footnotes. The following
1633
%D flags influence the process.
1634 1635
\newif
\ifalignrigidcolumns
1636
\newif
\ifstretchrigidcolumns
1637
\newif
\iftightrigidcolumns
% if true: just a vbox, no depth/noflines/gridsnap corrrections
1638 1639
\unexpanded
\def
\setrigidcolumnhsize
#
1
#
2
#
3
% todo: \dimexpr
1640
{
\xdef
\savedrigidhsize
{
\the\hsize
}
%
1641
\hsize
#
1
\relax
1642
\global\chardef
\rigidcolumns
#
3
\relax
1643
\scratchdimen
-
#
2
\relax
1644
\multiply
\scratchdimen
#
3
\relax
1645
\advance
\scratchdimen
#
2
\relax
1646
\advance\hsize
\scratchdimen
1647
\divide\hsize
#
3
\relax
}
1648 1649
% ==
1650
%
1651
% \def\setrigidcolumnhsize#1#2#3%
1652
% {\xdef\savedrigidhsize{\the\hsize}%
1653
% \global\chardef\rigidcolumns#3\relax
1654
% \hsize=\dimexpr(#1-\numexpr#3-1\relax\dimexpr#2\relax)/#3\relax}
1655 1656
\newbox
\rigidcolumnbox
1657 1658
\let
\rigidcolumnlines
\!!zerocount
1659 1660
\unexpanded
\def
\rigidcolumnbalance
#
1
%
1661
{
\ifnum
\rigidcolumns
=
1
% tzt ook h/d correctie
1662
\ifinner\ifhmode
\box\else\unvbox\fi\else\unvbox\fi
#
1
\relax
1663
\else
1664
\vbox
% \vpack
1665
{
\forgetall
1666
\nopenalties
1667
\dontcomplain
1668
\setbox
\rigidcolumnbox
\vbox
1669
{
\line
{}
\goodbreak
\unvbox
#
1
\removebottomthings
}
%
1670
\splittopskip
\openstrutheight
1671
\setbox
\scratchbox
\vsplit
\rigidcolumnbox
to
\zeropoint
1672
\ifcase
\rigidcolumnlines
\relax
1673
% \iffalse
1674
% % maybe some day an option
1675
% \scratchskip\ht\rigidcolumnbox
1676
% \advance\scratchskip\dp\rigidcolumnbox
1677
% \getnoflines\scratchskip
1678
% \ifodd\noflines
1679
% \advance\noflines\plusone
1680
% \fi
1681
% \divide\noflines\rigidcolumns
1682
%\else
1683
\scratchdimen
\ht
\rigidcolumnbox
1684
\divide
\scratchdimen
\rigidcolumns
1685
\getnoflines
\scratchdimen
1686
%\fi
1687
\else
1688
\noflines
\rigidcolumnlines
% to be sure
1689
\fi
1690
\scratchdimen
\noflines
\lineheight
1691
% new: we now loop so that we don't loose content
1692
% since in practice we also use this macro for
1693
% funny lineheights and border cases
1694
\setbox
0
=
\box
\rigidcolumnbox
1695
\doloop
1696
{
\setbox
\rigidcolumnbox
=
\copy
0
1697
\setbox
\scratchbox
\hpack
to
\savedrigidhsize
1698
{
\dorecurse
\rigidcolumns
1699
{
\setbox
\scratchbox
\vsplit
\rigidcolumnbox
to
\scratchdimen
1700
\dp
\scratchbox
\openstrutdepth
1701
\setbox
\scratchbox
\vtop
1702
\ifalignrigidcolumns
to
1703
\ifstretchrigidcolumns
\vsize\else
\scratchdimen
\fi
1704
\fi
1705
{
\unvbox
\scratchbox
}
%
1706
\wd
\scratchbox
\hsize
1707
\box
\scratchbox
1708
\hfill
}
%
1709
\hfillneg
}
%
1710
\ifvoid
\rigidcolumnbox
\exitloop
\else\advance
\scratchdimen\lineheight
\fi
}
%
1711
\iftightrigidcolumns
1712
\setbox
\scratchbox
\hpack
{
\raise\dp
\scratchbox
\box
\scratchbox
}
%
1713
\else
1714
\advance
\scratchdimen
-
\openstrutdepth
1715
\setbox
\scratchbox
\hpack
{
\raise
\scratchdimen
\box
\scratchbox
}
%
1716
\dp
\scratchbox
\openstrutdepth
1717
\ht
\scratchbox\scratchdimen
1718
\fi
1719
\box
\scratchbox
}
%
1720
\fi
}
1721 1722
%D \macros
1723
%D {startvboxtohbox,stopvboxtohbox,convertvboxtohbox}
1724
%D
1725
%D Here is another of Knuth's dirty tricks, as presented on pages 398 and 399 of the
1726
%D \TEX book. These macros can be used like:
1727
%D
1728
%D \starttyping
1729
%D \vbox
1730
%D \bgroup
1731
%D \startvboxtohbox ... \stopvboxtohbox
1732
%D \startvboxtohbox ... \stopvboxtohbox
1733
%D \startvboxtohbox ... \stopvboxtohbox
1734
%D \egroup
1735
%D
1736
%D \vbox
1737
%D \bgroup
1738
%D \convertvboxtohbox
1739
%D \egroup
1740
%D \stoptyping
1741
%D
1742
%D These macros are used in reformatting footnotes, so they do what they're meant
1743
%D for.
1744 1745
\newdimen
\vboxtohboxslack
1746
\newdimen
\hboxestohboxslack
1747 1748
%D Create line and fake height of paragraph by messign with heights: a nice hack by
1749
%D DEK himself.
1750 1751
%\unexpanded\def\setvboxtohbox
1752
% {\bgroup
1753
% \ifdim\baselineskip<16pt \relax
1754
% \scratchdimen\baselineskip
1755
% \multiply\scratchdimen 1024
1756
% \else
1757
% \message{cropping \baselineskip to 16pt}%
1758
% \scratchdimen\maxdimen
1759
% \fi
1760
% \divide\scratchdimen \hsize
1761
% \multiply\scratchdimen 64
1762
% \xdef\vboxtohboxfactor{\withoutpt\the\scratchdimen}%
1763
% \egroup}
1764
%
1765
% \unexpanded\def\startvboxtohbox
1766
% {\bgroup
1767
% \setvboxtohbox
1768
% \setbox\scratchbox\hbox\bgroup}
1769
%
1770
% \unexpanded\def\stopvboxtohbox
1771
% {\ifcase\vboxtohboxslack\else\hskip\zeropoint\!!minus\vboxtohboxslack\fi
1772
% \egroup
1773
% \dp\scratchbox\zeropoint
1774
% \ht\scratchbox\vboxtohboxfactor\wd\scratchbox
1775
% \box\scratchbox
1776
% \egroup}
1777 1778
% More modern:
1779 1780
% \definesystemattribute[vboxtohboxseparator][public]
1781 1782
%newbox\d_syst_boxes_vboxtohbox
1783
\newbox
\d_syst_boxes_separator
1784 1785
\unexpanded
\def
\startvboxtohboxseparator
1786
{
\setbox
\d_syst_boxes_separator
\hbox
attr
\vboxtohboxseparatorattribute
\plusone\bgroup
}
1787 1788
\unexpanded
\def
\stopvboxtohboxseparator
1789
{
\egroup
}
1790 1791
\unexpanded
\def
\startvboxtohbox
1792
{
\begingroup
1793
\setbox
\scratchbox
\hbox
\bgroup
}
1794 1795
\unexpanded
\def
\stopvboxtohbox
1796
{
\ifvoid
\d_syst_boxes_separator
1797
\hskip
\zeropoint
\ifcase
\vboxtohboxslack
\else
\s!minus
\vboxtohboxslack
\fi
% we really need a skip
1798
\else
1799
\box
\d_syst_boxes_separator
1800
\fi
1801
\egroup
1802
\clf_hboxtovbox
\scratchbox
1803
\box
\scratchbox
1804
\endgroup
}
1805 1806
% A possible reconstruction:
1807 1808
\unexpanded
\def
\convertvboxtohbox
1809
{
\makehboxofhboxes
1810
\setbox
\scratchboxone
\hpack
{
\unhbox
\scratchboxone
\removehboxes
}
% \hpack
1811
\noindent\unhbox
\scratchboxone
\par
}
1812 1813
\unexpanded
\def
\makehboxofhboxes
1814
{
\setbox
\scratchboxone
\emptyhbox
1815
\loop
% \doloop { .. \exitloop .. }
1816
\setbox
\scratchboxtwo
\lastbox
1817
\ifhbox
\scratchboxtwo
1818
\setbox
\scratchboxone
\hpack
{
\box
\scratchboxtwo
\unhbox
\scratchboxone
}
%
1819
\repeat
}
1820 1821
\unexpanded
\def
\removehboxes
1822
{
\setbox
\scratchboxone
\lastbox
1823
\ifhbox
\scratchboxone
1824
{
\removehboxes
}
\unhbox
\scratchboxone
1825
\fi
}
1826 1827
% And one special for notes:
1828 1829
\unexpanded
\def
\starthboxestohbox
1830
{
\bgroup
1831
\setbox
\scratchbox
\vbox
\bgroup
}
1832 1833
\unexpanded
\def
\stophboxestohbox
1834
{
\egroup
1835
\clf_vboxlisttohbox
\scratchbox\nextbox
\dimexpr
\hboxestohboxslack
\relax
1836
\dontleavehmode
1837
\unhbox
\nextbox
1838
\removeunwantedspaces
1839
\par
1840
\egroup
}
1841 1842
%D \macros
1843
%D {unhhbox}
1844
%D
1845
%D The next macro is used in typesetting inline headings. Let's first look at the
1846
%D macro and then show an example.
1847 1848
\newbox
\unhhedbox
1849
\newbox
\hhbox
1850
\newdimen
\lasthhboxwidth
1851
\newskip
\hhboxindent
1852 1853
\unexpanded
\def
\unhhbox
#
1
\with
#
2
%
1854
{
\bgroup
1855
\nopenalties
1856
\dontcomplain
1857
\forgetall
1858
\setbox
\unhhedbox
\vbox
{
\hskip
\hhboxindent
\strut
\unhbox
#
1
}
% => \hsize
1859
\doloop
1860
{
\setbox
\hhbox
\vsplit
\unhhedbox
to
\lineheight
1861
\ifvoid
\unhhedbox
1862
\setbox
\hhbox
\hbox
{
\strut
\hboxofvbox
\hhbox
}
% \hpack
1863
\fi
1864
\ht
\hhbox
\strutht
1865
\dp
\hhbox
\strutdp
1866
\ifzeropt
\hhboxindent
\else
1867
\setbox
\hhbox
\hpack
{
\kern
-
\hhboxindent
\box
\hhbox
}
%
1868
\hhboxindent
\zeropoint
1869
\fi
1870
\global
\lasthhboxwidth
\wd
\hhbox
1871
#
2
\relax
1872
\ifvoid
\unhhedbox
1873
\exitloop
1874
\else
1875
\hskip
\zeropoint
\s!plus
\zeropoint
1876
\fi
}
%
1877
\egroup
}
1878 1879
\def
\dohboxofvbox
1880
{
\setbox
0
\vpack
{
\unvbox
\scratchcounter
\global\setbox
1
\lastbox
}
%
1881
\unhbox
1
1882
\egroup
}
1883 1884
\unexpanded
\def
\hboxofvbox
1885
{
\bgroup
1886
\afterassignment
\dohboxofvbox
1887
\scratchcounter
=
}
1888 1889
%D This macro can be used to break a paragraph apart and treat each line seperately,
1890
%D for instance, making it clickable. The main complication is that we want to be
1891
%D able to continue the paragraph, something that's needed in the in line section
1892
%D headers.
1893
%D
1894
%D \startbuffer
1895
%D \setbox0=\hbox{\input tufte \relax}
1896
%D \setbox2=\hbox{\input knuth \relax}
1897
%D \unhhbox0\with{\ruledhbox{\box\hhbox}}
1898
%D \hskip1em plus 1em minus 1em
1899
%D \hhboxindent=\lasthhboxwidth
1900
%D \advance\hhboxindent by \lastskip
1901
%D \unhhbox2\with{\ruledhbox{\box\hhbox}}
1902
%D \stopbuffer
1903
%D
1904
%D \getbuffer
1905
%D
1906
%D This piece of text was typeset by saying:
1907
%D
1908
%D \typebuffer
1909
%D
1910
%D Not that nice a definition, but effective. Note the stretch we've build in the
1911
%D line that connects the two paragraphs.
1912 1913
%D \macros
1914
%D {doifcontent}
1915
%D
1916
%D When processing depends on the availability of content, one can give the next
1917
%D macro a try.
1918
%D
1919
%D \starttyping
1920
%D \doifcontent{pre content}{post content}{no content}\somebox
1921
%D \stoptyping
1922
%D
1923
%D Where \type {\somebox} is either a \type {\hbox} or \type {\vbox}. If the
1924
%D dimension of this box suggest some content, the resulting box is unboxed and
1925
%D surrounded by the first two arguments, else the third arguments is executed.
1926 1927
\unexpanded
\def
\doifcontent
#
1
#
2
#
3
%
1928
{
\dowithnextbox
1929
{
\ifhbox
\nextbox
1930
\ifdim
\wd
\nextbox
>
\zeropoint
1931
#
1
\unhbox
\nextbox
#
2
\relax
1932
\else
1933
#
3
\relax
1934
\fi
1935
\else
1936
\ifdim
\ht
\nextbox
>
\zeropoint
1937
#
1
\unvbox
\nextbox
#
2
\relax
1938
\else
1939
#
3
\relax
1940
\fi
1941
\fi
}}
1942 1943
%D So when we say:
1944
%D
1945
%D \startbuffer
1946
%D \doifcontent{[}{]}{}\hbox{content sensitive typesetting}
1947
%D
1948
%D \doifcontent{}{\page}{}\vbox{content sensitive typesetting}
1949
%D
1950
%D \doifcontent{}{}{\message{Didn't you forget something?}}\hbox{}
1951
%D \stopbuffer
1952
%D
1953
%D \typebuffer
1954
%D
1955
%D We get:
1956
%D
1957
%D \getbuffer
1958
%D
1959
%D Where the last call of course does not show up in this document, but definitely
1960
%D generates a confusing message.
1961 1962
%D \macros
1963
%D {processboxes}
1964
%D
1965
%D The next macro gobble boxes and is for instance used for overlays. First we show
1966
%D the general handler.
1967 1968
\newbox
\processbox
% public : this is the one where \nextbox's end up in
1969 1970
\unexpanded
\def
\processboxes
#
1
%
1971
{
\bgroup
1972
\def
\syst_boxes_process_indeed
{
#
1
}
% #1 can be redefined halfway
1973
\setbox
\processbox
\emptybox
1974
\doifelsenextbgroup
\syst_boxes_process_yes
\syst_boxes_process_nop
}
1975 1976
\def
\syst_boxes_process_yes
1977
{
\dowithnextboxcs
\syst_boxes_process_content
\hbox
}
1978 1979
\def
\syst_boxes_process_content
1980
{
\removeunwantedspaces
1981
\syst_boxes_process_indeed
% takes \nextbox makes \processbox
1982
\doifelsenextbgroup
\syst_boxes_process_yes
\syst_boxes_process_nop
}
1983 1984
\unexpanded
\def
\syst_boxes_process_nop
1985
{
\removeunwantedspaces
1986
\box
\processbox
1987
\egroup
}
1988 1989
%D \macros
1990
%D {startoverlay}
1991
%D
1992
%D We can overlay boxes by saying:
1993
%D
1994
%D \startbuffer
1995
%D \startoverlay
1996
%D {\framed{hans}}
1997
%D {\framed[width=3cm]{ton}}
1998
%D {\framed[height=2cm]{oeps}}
1999
%D \stopoverlay
2000
%D \stopbuffer
2001
%D
2002
%D \typebuffer
2003
%D
2004
%D shows up as:
2005
%D
2006
%D \leavevmode\getbuffer
2007 2008
\def
\boxisempty
#
1
%
2009
{
\ifdim
\wd
#
1
=
\zeropoint
2010
\ifdim
\ht
#
1
=
\zeropoint
2011
\ifdim
\dp
#
1
=
\zeropoint
2012
\zerocount
2013
\else
2014
\plusone
2015
\fi
2016
\else
2017
\plusone
2018
\fi
2019
\else
2020
\plusone
2021
\fi
}
2022 2023
\def
\syst_boxes_overlay_process
2024
{
\ifcase
\boxisempty\nextbox
\else
2025
\syst_boxes_overlay_process_indeed
2026
\fi
}
2027 2028
\def
\syst_boxes_overlay_process_indeed
2029
{
%\removeunwantedspaces % already done
2030
\scratchdepth
\dp\ifdim\dp
\nextbox
>
\dp
\processbox
\nextbox
\else
\processbox
\fi
2031
\ifdim
\ht
\nextbox
>
\ht
\processbox
2032
\setbox
\processbox
\vpack
to
\ht
\nextbox
{
\dp
\processbox
\zeropoint
\vss\box
\processbox
\vss
}
%
2033
\else
2034
\setbox
\nextbox
\vpack
to
\ht
\processbox
{
\dp
\nextbox
\zeropoint
\vss\box
\nextbox
\vss
}
%
2035
\fi
2036
\dp
\nextbox
\scratchdepth
2037
\dp
\processbox
\scratchdepth
2038
\scratchwidth
\wd\ifdim\wd
\nextbox
>
\wd
\processbox
\nextbox
\else
\processbox
\fi
2039
\setbox
\processbox
\hpack
to
\scratchwidth
2040
{
\hpack
to
\scratchwidth
{
\hss\box
\processbox
\hss
}
%
2041
\kern
-
\scratchwidth
2042
\hpack
to
\scratchwidth
{
\hss\box
\nextbox
\hss
}}}
2043 2044
\unexpanded
\def
\startoverlay
2045
{
\bgroup
2046
\let
\stopoverlay
\egroup
2047
\processboxes
\syst_boxes_overlay_process
}
2048 2049
\let
\stopoverlay
\relax
2050 2051
%D \macros
2052
%D {fakebox}
2053
%D
2054
%D The next macro is a rather silly one, but saves space.
2055
%D
2056
%D \starttyping
2057
%D \hbox{\fakebox0}
2058
%D \stoptyping
2059
%D
2060
%D returns an empty box with the dimensions of the box specified, here being zero.
2061 2062
\unexpanded
\def
\fakebox
2063
{
\bgroup
2064
\afterassignment
\syst_boxes_fakebox_finish
\scratchcounter
}
2065 2066
\def
\syst_boxes_fakebox_finish
2067
{
\setbox
\scratchbox
\ifhbox
\scratchcounter
\emptyhbox
\else
\emptyvbox
\fi
2068
\wd
\scratchbox
\wd
\scratchcounter
2069
\ht
\scratchbox
\ht
\scratchcounter
2070
\dp
\scratchbox
\dp
\scratchcounter
2071
\box
\scratchbox
2072
\egroup
}
2073 2074
%D \macros
2075
%D {lbox,rbox,cbox,tbox,bbox}
2076
%D
2077
%D Here are some convenient alternative box types:
2078
%D
2079
%D \starttyping
2080
%D \lbox{text ...}
2081
%D \cbox{text ...}
2082
%D \rbox{text ...}
2083
%D \stoptyping
2084
%D
2085
%D Are similar to \type {\vbox}, which means that they also accept something like
2086
%D \type {to 3cm}, but align to the left, middle and right. These box types can be
2087
%D used to typeset paragraphs.
2088 2089
\def
\syst_boxes_lrc_process
#
1
{
\bgroup
\forgetall
\let
\\
\endgraf
#
1
\let
\next
}
2090 2091
\unexpanded
\def
\lbox
#
1
#
{
\vbox
#
1
\syst_boxes_lrc_process
\raggedleft
}
2092
\unexpanded
\def
\cbox
#
1
#
{
\vbox
#
1
\syst_boxes_lrc_process
\raggedcenter
}
2093
\unexpanded
\def
\rbox
#
1
#
{
\vbox
#
1
\syst_boxes_lrc_process
\raggedright
}
2094 2095
\unexpanded
\def
\ltop
#
1
#
{
\vtop
#
1
\syst_boxes_lrc_process
\raggedleft
}
2096
\unexpanded
\def
\ctop
#
1
#
{
\vtop
#
1
\syst_boxes_lrc_process
\raggedcenter
}
2097
\unexpanded
\def
\rtop
#
1
#
{
\vtop
#
1
\syst_boxes_lrc_process
\raggedright
}
2098 2099
%D The alternatives \type {\tbox} and \type {\bbox} can be used to properly align
2100
%D boxes, like in:
2101
%D
2102
%D \setupexternalfigures[directory={../sample}]
2103
%D \startbuffer
2104
%D \starttable[|||]
2105
%D \HL
2106
%D \VL \tbox{\externalfigure[cow][height=3cm,frame=on]} \VL top aligned \VL\SR
2107
%D \HL
2108
%D \VL \bbox{\externalfigure[cow][height=3cm,frame=on]} \VL bottom aligned \VL\SR
2109
%D \HL
2110
%D \stoptable
2111
%D \stopbuffer
2112
%D
2113
%D \typebuffer
2114
%D
2115
%D The positioning depends on the strut settings:
2116
%D
2117
%D \getbuffer
2118 2119
\unexpanded
\def
\tbox
{
\hpack
\bgroup
\dowithnextboxcs
\syst_boxes_tbox_finish
\hbox
}
2120
\unexpanded
\def
\bbox
{
\hpack
\bgroup
\dowithnextboxcs
\syst_boxes_bbox_finish
\hbox
}
2121 2122
\def
\syst_boxes_tbox_finish
2123
{
\scratchheight
\ht
\strutbox
2124
\scratchdepth
\dimexpr
\htdp\nextbox
-
\scratchheight
\relax
2125
\ht
\nextbox\scratchheight
2126
\dp
\nextbox\scratchdepth
2127
\boxyoffset
\nextbox
-
\scratchdepth
2128
\box
\nextbox
2129
\egroup
}
2130 2131
\def
\syst_boxes_bbox_finish
2132
{
\scratchdepth
\dp
\strutbox
2133
\scratchheight
\dimexpr
\htdp\nextbox
-
\scratchdepth
\relax
2134
\dp
\nextbox\scratchdepth
2135
\ht
\nextbox\scratchheight
2136
\boxyoffset
\nextbox
-
\scratchdepth
2137
\box
\nextbox
2138
\egroup
}
2139 2140
%D \macros
2141
%D {lhbox,mhbox,rhbox}
2142
%D
2143
%D A few more boxes.
2144 2145
\def
\dodolhbox
{
\hpack
to
\hsize
{
\box
\nextbox
\hss
}}
2146
\def
\dodomhbox
{
\hpack
to
\hsize
{
\hss\box
\nextbox
\hss
}}
2147
\def
\dodorhbox
{
\hpack
to
\hsize
{
\hss\box
\nextbox
}}
2148 2149
\unexpanded
\def
\lhbox
{
\dowithnextboxcs
\dodolhbox
\hbox
}
2150
\unexpanded
\def
\mhbox
{
\dowithnextboxcs
\dodomhbox
\hbox
}
2151
\unexpanded
\def
\rhbox
{
\dowithnextboxcs
\dodorhbox
\hbox
}
2152 2153
\let
\lefthbox
\lhbox
2154
\let
\midhbox
\mhbox
2155
\let
\righthbox\rhbox
2156 2157
%D \macros
2158
%D {boxofsize}
2159
%D
2160
%D Sometimes we need to construct a box with a height or width made up of several
2161
%D dimensions. Instead of cumbersome additions, we can use:
2162
%D
2163
%D \starttyping
2164
%D \boxofsize \vbox 10cm 3cm -5cm {the text to be typeset}
2165
%D \stoptyping
2166
%D
2167
%D This example demonstrates that one can use positive and negative values.
2168
%D Dimension registers are also accepted.
2169 2170
\newdimen
\sizeofbox
2171 2172
\unexpanded
\def
\boxofsize
#
1
%
2173
{
\bgroup
2174
\sizeofbox
\zeropoint
2175
\scratchdimen
\zeropoint
2176
\def
\docommand
2177
{
\advance
\sizeofbox
\scratchdimen
2178
\futurelet
\next
\dodocommand
}
%
2179
\def
\dodocommand
2180
{
\ifx
\next
\bgroup
2181
\expanded
{
\egroup
#
1
to
\the
\sizeofbox
}
%
2182
\else
2183
\expandafter\afterassignment\expandafter
\docommand
\expandafter
\scratchdimen
2184
\fi
}
%
2185
\docommand
}
2186 2187
%D Some new, still undocumented features:
2188 2189
% limitatetext -> beter {text} als laatste !!
2190
%
2191
% \limitvbox
2192
% \limithbox
2193 2194
\unexpanded
\def
\limitatelines
#
1
#
2
% size sentinel
2195
{
\dowithnextbox
2196
{
\scratchdimen
#
1
\hsize
2197
\ifdim
\wd
\nextbox
>
\scratchdimen
2198
\setbox
\nextbox
\hbox
2199
{
\advance
\scratchdimen
-
.
1
\hsize
2200
\limitatetext
{
\unhbox
\nextbox
}{
\scratchdimen
}{
\nobreak
#
2
}}
%
2201
\fi
2202
\unhbox
\nextbox
}
2203
\hbox
}
2204 2205
\unexpanded
\def
\fittoptobaselinegrid
% weg hier
2206
{
\dowithnextbox
2207
{
\bgroup
2208
\par
2209
\scratchdimen
\ht
\nextbox
2210
\ht
\nextbox\strutht
2211
\dp
\nextbox\strutdp
2212
\hpack
{
\box
\nextbox
}
2213
\prevdepth
\strutdp
2214
\doloop
2215
{
\advance
\scratchdimen
-
\lineheight
2216
\ifdim
\scratchdimen
<
\zeropoint
2217
\exitloop
2218
\else
2219
\nobreak
2220
\hpack
{
\strut
}
2221
\fi
}
2222
\egroup
}
2223
\vbox
}
2224 2225
%D Some more undocumented macros (used in m-chart).
2226 2227
\newif
\iftraceboxplacement
% \traceboxplacementtrue
2228 2229
\newbox
\fakedboxcursor
2230 2231
\setbox
\fakedboxcursor
\hpack
2232
{
\vrule
\s!width
\zeropoint
\s!height
\zeropoint
\s!depth
\zeropoint
}
2233 2234
\unexpanded
\def
\boxcursor
% overloaded in core-vis
2235
{
\iftraceboxplacement
2236
\bgroup
2237
\scratchdimen
2
\onepoint
2238
\setbox
\scratchbox
\hpack
to
\zeropoint
2239
{
\hss
2240
\vrule
2241
\s!width
\scratchdimen
2242
\s!height
\scratchdimen
2243
\s!depth
\scratchdimen
2244
\hss
}
%
2245
\smashedbox
\scratchbox
2246
\egroup
2247
\else
2248
\copy
\fakedboxcursor
2249
\fi
}
2250 2251
\unexpanded
\def
\placedbox
2252
{
\iftraceboxplacement
\ruledhbox
\else\hbox\fi
}
2253 2254
\newdimen
\boxoffset
2255
\newdimen
\boxhdisplacement
2256
\newdimen
\boxvdisplacement
2257 2258
\unexpanded
\def
\rightbox
{
\hpack
\bgroup
\dowithnextboxcs
\syst_boxes_rightbox_finish
\placedbox
}
2259
\unexpanded
\def
\leftbox
{
\hpack
\bgroup
\dowithnextboxcs
\syst_boxes_leftbox_finish
\placedbox
}
2260
\unexpanded
\def
\topbox
{
\hpack
\bgroup
\dowithnextboxcs
\syst_boxes_topbox_finish
\placedbox
}
2261
\unexpanded
\def
\bottombox
{
\hpack
\bgroup
\dowithnextboxcs
\syst_boxes_bottombox_finish
\placedbox
}
2262
\unexpanded
\def
\lefttopbox
{
\hpack
\bgroup
\dowithnextboxcs
\syst_boxes_lefttopbox_finish
\placedbox
}
2263
\unexpanded
\def
\righttopbox
{
\hpack
\bgroup
\dowithnextboxcs
\syst_boxes_righttopbox_finish
\placedbox
}
2264
\unexpanded
\def
\leftbottombox
{
\hpack
\bgroup
\dowithnextboxcs
\syst_boxes_leftbottombox_finish
\placedbox
}
2265
\unexpanded
\def
\rightbottombox
{
\hpack
\bgroup
\dowithnextboxcs
\syst_boxes_rightbottombox_finish
\placedbox
}
2266 2267
\let
\topleftbox
\lefttopbox
2268
\let
\toprightbox
\righttopbox
2269
\let
\bottomleftbox
\leftbottombox
2270
\let
\bottomrightbox\rightbottombox
2271 2272
\def
\syst_boxes_rightbox_finish
2273
{
\global
\boxhdisplacement
\boxoffset
2274
\global
\boxvdisplacement
.
5
\dimexpr\ht
\nextbox
-
\dp
\nextbox
\relax
2275
\boxcursor
2276
\boxxmove
\nextbox
\boxhdisplacement
2277
\boxymove
\nextbox
-
\boxvdisplacement
2278
\box
\nextbox
2279
\egroup
}
2280 2281
\def
\syst_boxes_leftbox_finish
2282
{
\global
\boxhdisplacement
\dimexpr
-
\wd
\nextbox
-
\boxoffset
\relax
2283
\global
\boxvdisplacement
.
5
\dimexpr\ht
\nextbox
-
\dp
\nextbox
\relax
2284
\boxcursor
2285
\boxxmove
\nextbox
\boxhdisplacement
2286
\boxymove
\nextbox
-
\boxvdisplacement
2287
\box
\nextbox
2288
\egroup
}
2289 2290
\def
\syst_boxes_topbox_finish
2291
{
\global
\boxhdisplacement
-
.
5
\wd
\nextbox
2292
\global
\boxvdisplacement
\dimexpr
-
\dp
\nextbox
-
\boxoffset
\relax
2293
\boxcursor
2294
\boxxmove
\nextbox
\boxhdisplacement
2295
\boxymove
\nextbox
-
\boxvdisplacement
2296
\box
\nextbox
2297
\egroup
}
2298 2299
\def
\syst_boxes_bottombox_finish
2300
{
\global
\boxhdisplacement
-
.
5
\wd
\nextbox
2301
\global
\boxvdisplacement
\dimexpr\ht
\nextbox
+
\boxoffset
\relax
2302
\boxcursor
2303
\boxxmove
\nextbox
\boxhdisplacement
2304
\boxymove
\nextbox
-
\boxvdisplacement
2305
\box
\nextbox
2306
\egroup
}
2307 2308
\def
\syst_boxes_lefttopbox_finish
2309
{
\global
\boxhdisplacement
\dimexpr
-
\wd
\nextbox
-
\boxoffset
\relax
2310
\global
\boxvdisplacement
\dimexpr
-
\dp
\nextbox
-
\boxoffset
\relax
2311
\boxcursor
2312
\boxxmove
\nextbox
\boxhdisplacement
2313
\boxymove
\nextbox
-
\boxvdisplacement
2314
\box
\nextbox
2315
\egroup
}
2316 2317
\def
\syst_boxes_righttopbox_finish
2318
{
\global
\boxhdisplacement
\boxoffset
2319
\global
\boxvdisplacement
\dimexpr
-
\dp
\nextbox
-
\boxoffset
\relax
2320
\boxcursor
2321
\boxxmove
\nextbox
\boxhdisplacement
2322
\boxymove
\nextbox
-
\boxvdisplacement
2323
\box
\nextbox
2324
\egroup
}
2325 2326
\def
\syst_boxes_leftbottombox_finish
2327
{
\global
\boxhdisplacement
\dimexpr
-
\wd
\nextbox
-
\boxoffset
\relax
2328
\global
\boxvdisplacement
\dimexpr\ht
\nextbox
+
\boxoffset
\relax
2329
\boxcursor
2330
\boxxmove
\nextbox
\boxhdisplacement
2331
\boxymove
\nextbox
-
\boxvdisplacement
2332
\box
\nextbox
2333
\egroup
}
2334 2335
\def
\syst_boxes_rightbottombox_finish
2336
{
\global
\boxhdisplacement
\boxoffset
2337
\global
\boxvdisplacement
\dimexpr\ht
\nextbox
+
\boxoffset
\relax
2338
\boxcursor
2339
\boxxmove
\nextbox
\boxhdisplacement
2340
\boxymove
\nextbox
-
\boxvdisplacement
2341
\box
\nextbox
2342
\egroup
}
2343 2344
\unexpanded
\def
\middlebox
{
\hpack
\bgroup
\dowithnextboxcs
\syst_boxes_middlebox_finish
\placedbox
}
2345
\unexpanded
\def
\baselinemiddlebox
{
\hpack
\bgroup
\dowithnextboxcs
\syst_boxes_baselinemiddlebox_finish
\placedbox
}
2346
\unexpanded
\def
\baselineleftbox
{
\hpack
\bgroup
\dowithnextboxcs
\syst_boxes_baselineleftbox_finish
\placedbox
}
2347
\unexpanded
\def
\baselinerightbox
{
\hpack
\bgroup
\dowithnextboxcs
\syst_boxes_baselinerightbox_finish
\placedbox
}
2348 2349
\def
\syst_boxes_middlebox_finish
2350
{
\global
\boxhdisplacement
-
.
5
\wd
\nextbox
2351
\global
\boxvdisplacement
.
5
\dimexpr\ht
\nextbox
-
\dp
\nextbox
\relax
2352
\boxcursor
2353
\boxxmove
\nextbox
\boxhdisplacement
2354
\boxymove
\nextbox
-
\boxvdisplacement
2355
\box
\nextbox
2356
\egroup
}
2357 2358
\def
\syst_boxes_baselinemiddlebox_finish
2359
{
\global
\boxhdisplacement
\dimexpr
-
.
5
\wd
\nextbox
-
\boxoffset
\relax
2360
\global
\boxvdisplacement
-
\boxoffset
2361
\boxcursor
2362
\boxxmove
\nextbox
\boxhdisplacement
2363
\boxymove
\nextbox
-
\boxvdisplacement
2364
\box
\nextbox
2365
\egroup
}
2366 2367
\def
\syst_boxes_baselineleftbox_finish
2368
{
\global
\boxhdisplacement
\dimexpr
-
\wd
\nextbox
-
\boxoffset
\relax
2369
\global
\boxvdisplacement
-
\boxoffset
2370
\boxcursor
2371
\boxxmove
\nextbox
\boxhdisplacement
2372
\boxymove
\nextbox
-
\boxvdisplacement
2373
\box
\nextbox
2374
\egroup
}
2375 2376
\def
\syst_boxes_baselinerightbox_finish
2377
{
\global
\boxhdisplacement
\boxoffset
2378
\global
\boxvdisplacement
-
\boxoffset
2379
\boxcursor
2380
\boxxmove
\nextbox
\boxhdisplacement
2381
\boxymove
\nextbox
-
\boxvdisplacement
2382
\box
\nextbox
2383
\egroup
}
2384 2385
%D \macros
2386
%D {obox}
2387
%D
2388
%D Experimental, not yet frozen:
2389 2390
\unexpanded
\def
\lrtbbox
#
1
#
2
#
3
#
4
% l r t b
2391
{
\bgroup
2392
\dowithnextboxcontent
2393
{
\advance\hsize
-
#
1
\advance\hsize
-
#
2
\relax
2394
\advance\vsize
-
#
3
\advance\vsize
-
#
4
\relax
}
2395
{
\forgetall
\vpack
to
\vsize
{
\vskip
#
3
\hpack
to
\hsize
{
\hskip
#
1
\box
\nextbox
\hss
}
\vss
}
\egroup
}
2396
\vbox
}
2397 2398
%D \macros
2399
%D {toplinebox}
2400
%D
2401
%D See core-tbl.tex for an example of its usage:
2402 2403
\unexpanded
\def
\toplinebox
2404
{
\dowithnextboxcs
\syst_boxes_toplinebox_finish
\tbox
}
2405 2406
\def
\syst_boxes_toplinebox_finish
2407
{
\ifdim
\dp
\nextbox
>
\strutdepth
2408
\scratchdimen
\dp
\nextbox
2409
\advance
\scratchdimen
-
\strutdepth
2410
\getnoflines
\scratchdimen
2411
\struttedbox
{
\box
\nextbox
}
%
2412
\dorecurse
\noflines
\verticalstrut
2413
\else
2414
\box
\nextbox
2415
\fi
}
2416 2417
%D \macros
2418
%D {initializeboxstack,savebox,foundbox}
2419
%D
2420
%D At the cost of some memory, but saving box registers, we have implemented a box
2421
%D repository.
2422
%D
2423
%D \starttyping
2424
%D \initializeboxstack{one}
2425
%D
2426
%D \savebox{one}{a}{test a}
2427
%D \savebox{one}{p}{test p}
2428
%D \savebox{one}{q}{test q}
2429
%D
2430
%D \hbox{a:\foundbox{one}{a}} \par
2431
%D \hbox{q:\foundbox{one}{q}} \par
2432
%D \hbox{p:\foundbox{one}{p}} \par
2433
%D \hbox{x:\foundbox{one}{x}} \par
2434
%D \hbox{y:\foundbox{two}{a}} \par
2435
%D \stoptyping
2436 2437
%D Kind of obsolete:
2438 2439
\installcorenamespace
{
stackbox
}
2440
\installcorenamespace
{
stacklst
}
2441 2442
\unexpanded
\def
\setstackbox
#
1
#
2
%
2443
{
\ifcsname
\??stackbox
#
1
:
#
2
\endcsname\else
2444
\expandafter
\newbox
\csname
\??stackbox
#
1
:
#
2
\endcsname
2445
\fi
2446
\global\setbox\csname
\??stackbox
#
1
:
#
2
\endcsname\vbox
}
2447 2448
\unexpanded
\def
\initializeboxstack
#
1
%
2449
{
\def
\docommand
##
1
{
\setstackbox
{
#
1
}{
##
1
}{}}
%
2450
\ifcsname
\??stacklst
#
1
\endcsname
2451
\expandafter
\processcommacommand
\expandafter
[
\lastnamedcs
]
\docommand
2452
\fi
2453
\letgvalueempty
{
\??stacklst
#
1
}}
2454 2455
\unexpanded
\def
\savebox
#
1
#
2
% stack name
2456
{
% beware, \setxvalue defines the cs beforehand so we cannot use the
2457
% test inside the { }
2458
\ifcsname
\??stacklst
#
1
\endcsname
2459
%\setxvalue{\??stacklst#1}{\csname\??stacklst#1\endcsname,#2}%
2460
\expandafter\xdef\csname
\??stacklst
#
1
\expandafter\endcsname\expandafter
{
\lastnamedcs
,
#
2
}
%
2461
\else
2462
\expandafter\xdef\csname
\??stacklst
#
1
\endcsname
{
#
2
}
%
2463
\fi
2464
\setstackbox
{
#
1
}{
#
2
}}
2465 2466
\unexpanded
\def
\flushbox
#
1
#
2
% unwrapped
2467
{
\ifcsname
\??stackbox
#
1
:
#
2
\endcsname
2468
\box\lastnamedcs
2469
\else
2470
\emptybox
2471
\fi
}
2472 2473
\unexpanded
\def
\restorebox
#
1
#
2
% unwrapped
2474
{
\ifcsname
\??stackbox
#
1
:
#
2
\endcsname
2475
\copy\lastnamedcs
2476
\else
2477
\emptybox
2478
\fi
}
2479 2480
\unexpanded
\def
\foundbox
#
1
#
2
% wrapped
2481
{
\vpack
2482
{
\ifcsname
\??stackbox
#
1
:
#
2
\endcsname
2483
\copy\lastnamedcs
2484
\fi
}}
2485 2486
\unexpanded
\def
\doifelsebox
#
1
#
2
%
2487
{
\ifcsname
\??stackbox
#
1
:
#
2
\endcsname
2488
\ifvoid
\lastnamedcs
2489
\doubleexpandafter\secondoftwoarguments
2490
\else
2491
\doubleexpandafter\firstoftwoarguments
2492
\fi
2493
\else
2494
\expandafter
\secondoftwoarguments
2495
\fi
}
2496 2497
\let
\doifboxelse\doifelsebox
2498 2499
%D This one is cheaper (the above is no longer used that much):
2500 2501
\installcorenamespace
{
boxstack
}
2502 2503
\newcount
\c_syst_boxes_stack
2504
\let
\b_syst_boxes_stack
\relax
2505 2506
\unexpanded
\def
\syst_boxes_stack_allocate
2507
{
\newbox
\b_syst_boxes_stack
2508
\expandafter\let\csname
\??boxstack
\number
\c_syst_boxes_stack
\endcsname
\b_syst_boxes_stack
}
2509 2510
\unexpanded
\def
\syst_boxes_push
#
1
#
2
%
2511
{
\global\advance
\c_syst_boxes_stack
\plusone
2512
\expandafter\let\expandafter
\b_syst_boxes_stack
\csname
\??boxstack
\number
\c_syst_boxes_stack
\endcsname
2513
\ifx
\b_syst_boxes_stack
\relax
% cheaper then csname check as in most cases it's defined
2514
\syst_boxes_stack_allocate
2515
\fi
2516
#
1
\setbox
\b_syst_boxes_stack
\box
#
2
\relax
}
2517 2518
\unexpanded
\def
\syst_boxes_pop
#
1
#
2
%
2519
{
#
1
\setbox
#
2
\box\csname
\??boxstack
\number
\c_syst_boxes_stack
\endcsname
2520
\global\advance
\c_syst_boxes_stack
\minusone
}
2521 2522
\unexpanded
\def
\localpushbox
{
\syst_boxes_push
\relax
}
2523
\unexpanded
\def
\localpopbox
{
\syst_boxes_pop
\relax
}
2524 2525
\unexpanded
\def
\globalpushbox
{
\syst_boxes_push
\global
}
2526
\unexpanded
\def
\globalpopbox
{
\syst_boxes_pop
\global
}
2527 2528
%D And here is a more modern one (not yet in i-*):
2529
%D
2530
%D \starttyping
2531
%D \dorecurse {100} {
2532
%D \setbox\zerocount\hbox{test \recurselevel}
2533
%D \putboxincache{foo}{\recurselevel}\zerocount
2534
%D \copyboxfromcache{foo}{\recurselevel}\zerocount
2535
%D \iftrue
2536
%D \setbox\zerocount\hbox{\directboxfromcache{foo}{\recurselevel}}%
2537
%D \else
2538
%D \getboxfromcache{foo}{\recurselevel}\zerocount
2539
%D \fi
2540
%D }
2541
%D \resetboxesincache{foo}
2542
%D \stoptyping
2543 2544
\unexpanded
\def
\putboxincache
#
1
#
2
#
3
{
\clf_putboxincache
{
#
1
}{
#
2
}
#
3
\relax
}
2545
\unexpanded
\def
\getboxfromcache
#
1
#
2
#
3
{
\clf_getboxfromcache
{
#
1
}{
#
2
}
#
3
\relax
}
2546
\unexpanded
\def
\doifelseboxincache
#
1
#
2
{
\clf_doifelseboxincache
{
#
1
}{
#
2
}}
2547
\unexpanded
\def
\copyboxfromcache
#
1
#
2
#
3
{
\clf_copyboxfromcache
{
#
1
}{
#
2
}
#
3
\relax
}
2548
\unexpanded
\def
\directboxfromcache
#
1
#
2
{
\clf_directboxfromcache
{
#
1
}{
#
2
}}
2549
\unexpanded
\def
\directcopyboxfromcache
#
1
#
2
{
\clf_directcopyboxfromcache
{
#
1
}{
#
2
}}
2550
\unexpanded
\def
\resetboxesincache
#
1
{
\clf_resetboxesincache
{
#
1
}}
2551 2552
\unexpanded
\def
\putnextboxincache
#
1
#
2
%
2553
{
\dowithnextbox
{
\putboxincache
{
#
1
}{
#
2
}
\nextbox
}}
2554 2555
%D \macros
2556
%D {removedepth, obeydepth}
2557
%D
2558
%D While \type {\removedepth} removes the preceding depth, \type {\obeydepth} makes
2559
%D sure we have depth. Both macros leave the \type {\prevdepth} untouched.
2560 2561
\unexpanded
\def
\removedepth
2562
{
\ifvmode
2563
\ifdim
\prevdepth
>
\zeropoint
2564
\kern
-
\prevdepth
2565
\fi
2566
\fi
}
2567 2568
\unexpanded
\def
\obeydepth
2569
{
\par
% watch out for changes in math formulas
2570
\ifvmode\ifdim
\prevdepth
<
\zeropoint
\orelse\ifdim\prevdepth
<
\strutdp
2571
\kern\dimexpr
\strutdp
-
\prevdepth\relax
2572
\prevdepth
\strutdp
2573
\fi\fi
}
2574 2575
\unexpanded
\def
\undepthed
2576
{
\dowithnextbox
{
\dp
\nextbox
\zeropoint
\box
\nextbox
}
\hbox
}
2577 2578
%D \macros
2579
%D {removebottomthings, removelastskip}
2580
%D
2581
%D A funny (but rather stupid) one, plus a redefinition.
2582 2583
\unexpanded
\def
\removebottomthings
2584
{
\dorecurse
\plusfive
{
\unskip\unkern\unpenalty
}}
2585 2586
\unexpanded
\def
\removelastskip
% \ifvmode the plain tex one \fi
2587
{
\ifvmode\ifzeropt
\lastskip\else\vskip
-
\lastskip\fi\fi
}
2588 2589
%D \macros
2590
%D {makestrutofbox}
2591
%D
2592
%D This macro sets the dimensions of a box to those of a strut. Sort of obsolete so
2593
%D it will go away.
2594 2595
\unexpanded
\def
\makestrutofbox
% not used
2596
{
\afterassignment
\syst_boxes_makestrutofbox
\c_boxes_register
}
2597 2598
\def
\syst_boxes_makestrutofbox
2599
{
\ht
\c_boxes_register
\strutht
2600
\dp
\c_boxes_register
\strutdp
2601
\wd
\c_boxes_register
\zeropoint
}
2602 2603
%D \macros
2604
%D {raisebox,lowerbox}
2605
%D
2606
%D Some more box stuff, related to positioning (under construction). Nice stuff for
2607
%D a tips and tricks maps article.
2608
%D
2609
%D \starttyping
2610
%D \raisebox{100pt}\hbox{test}
2611
%D \hsmash{\raisebox{100pt}\hbox{test}}
2612
%D \stoptyping
2613 2614
\unexpanded
\def
\raisebox
#
1
{
\bgroup
\afterassignment
\syst_boxes_raise_indeed
\scratchdimen
#
1
}
% so both 10pt and {10pt} is accepted
2615
\unexpanded
\def
\lowerbox
#
1
{
\bgroup
\afterassignment
\syst_boxes_lower_indeed
\scratchdimen
#
1
}
% so both 10pt and {10pt} is accepted
2616 2617
\def
\syst_boxes_raise_indeed
{
\dowithnextboxcs
\syst_boxes_raise_finish
}
2618
\def
\syst_boxes_lower_indeed
{
\dowithnextboxcs
\syst_boxes_lower_finish
}
2619 2620
\def
\syst_boxes_raise_finish
2621
{
\boxyoffset
\nextbox\scratchdimen
2622
\ht
\nextbox\strutht
2623
\dp
\nextbox\strutdp
2624
\box
\nextbox
2625
\egroup
}
2626 2627
\def
\syst_boxes_lower_finish
2628
{
\boxyoffset
\nextbox
-
\scratchdimen
2629
\ht
\nextbox\strutht
2630
\dp
\nextbox\strutdp
2631
\box
\nextbox
2632
\egroup
}
2633 2634
% vcenter in text, we kunnen vcenter overloaden
2635 2636
\unexpanded
\def
\halfwaybox
2637
{
\hpack
\bgroup
2638
\dowithnextboxcs
\syst_boxes_halfwaybox_finish
\hbox
}
2639 2640
\def
\syst_boxes_halfwaybox_finish
2641
{
\dp
\nextbox
\zeropoint
2642
\lower
.
5
\ht
\nextbox
\box
\nextbox
2643
\egroup
}
2644 2645
\unexpanded
\def
\depthonlybox
2646
{
\tpack
\bgroup
2647
\dowithnextboxcs
\syst_boxes_depthonlybox_finish
\vbox
}
2648 2649
\def
\syst_boxes_depthonlybox_finish
2650
{
\hsize\wd
\nextbox
2651
\kern
\zeropoint
\box
\nextbox
2652
\egroup
}
2653 2654
%D New:
2655 2656
\def
\setdimentoatleast
#
1
#
2
{
\ifdim
#
1
>
\zeropoint
\else
#
1
=#
2
\fi
}
2657
\def
\setdimentoatmost
#
1
#
2
{
\ifdim
#
1
>#
2
\relax
\else
#
1
=#
2
\fi
}
2658 2659
%D And even rawer:
2660 2661
\let
\naturalvcenter
\normalvtop
% will go away
2662 2663
% \appendtoks \let\vcenter\normalvcenter \to \everymathematics
2664 2665
%D \macros
2666
%D {frozenhbox}
2667
%D
2668
%D A not so well unhboxable box can be made with:
2669 2670
\unexpanded
\def
\frozenhbox
2671
{
\hpack
\bgroup
2672
\dowithnextboxcs
\syst_boxes_frozenhbox_finish
\hbox
}
2673 2674
\def
\syst_boxes_frozenhbox_finish
2675
{
\hpack
{
\hpack
{
\box
\nextbox
}}
%
2676
\egroup
}
2677 2678
%D \macros
2679
%D {setboxllx,setboxlly,gsetboxllx,gsetboxlly,getboxllx,getboxlly}
2680
%D
2681
%D A prelude to an extended \TEX\ feature:
2682 2683
\installcorenamespace
{
box
_
x
}
2684
\installcorenamespace
{
box
_
y
}
2685 2686
\unexpanded
\def
\setboxllx
#
1
#
2
{
\expandafter\edef\csname
\??box_x
\number
#
1
\endcsname
{
\the\dimexpr
#
2
\relax
}}
2687
\unexpanded
\def
\setboxlly
#
1
#
2
{
\expandafter\edef\csname
\??box_y
\number
#
1
\endcsname
{
\the\dimexpr
#
2
\relax
}}
2688 2689
\unexpanded
\def
\gsetboxllx
#
1
#
2
{
\expandafter\xdef\csname
\??box_x
\number
#
1
\endcsname
{
\the\dimexpr
#
2
\relax
}}
2690
\unexpanded
\def
\gsetboxlly
#
1
#
2
{
\expandafter\xdef\csname
\??box_y
\number
#
1
\endcsname
{
\the\dimexpr
#
2
\relax
}}
2691 2692
%def\getboxllx#1{\ifcsname\??box_x\number#1\endcsname\csname\??box_x\number#1\endcsname\else\zeropoint\fi}
2693
%def\getboxlly#1{\ifcsname\??box_y\number#1\endcsname\csname\??box_y\number#1\endcsname\else\zeropoint\fi}
2694
\def
\getboxllx
#
1
{
\ifcsname
\??box_x
\number
#
1
\endcsname\lastnamedcs\else
\zeropoint
\fi
}
2695
\def
\getboxlly
#
1
{
\ifcsname
\??box_y
\number
#
1
\endcsname\lastnamedcs\else
\zeropoint
\fi
}
2696 2697
\def
\directgetboxllx
#
1
{
\csname
\??box_x
\number
#
1
\endcsname
}
% use when sure existence
2698
\def
\directgetboxlly
#
1
{
\csname
\??box_y
\number
#
1
\endcsname
}
% use when sure existence
2699 2700
%D \macros
2701
%D {shownextbox}
2702
%D
2703
%D Handy for tracing
2704
%D
2705
%D \starttyping
2706
%D \shownextbox\vbox{test}
2707
%D \shownextbox\vbox{test\endgraf}
2708
%D \shownextbox\vbox{test\endgraf\strut\endgraf}
2709
%D \shownextbox\vbox{test\endgraf\thinrule}
2710
%D \shownextbox\vbox{\setupwhitespace[big]test\endgraf\thinrule}
2711
%D \stoptyping
2712 2713
\unexpanded
\def
\shownextbox
% seldom used
2714
{
\dowithnextbox
2715
{
\bgroup
2716
\showboxbreadth
\maxdimen
2717
\showboxdepth
\maxdimen
2718
\scratchcounter
\interactionmode
2719
\batchmode
2720
\showbox
\nextbox
2721
\box
\nextbox
2722
\interactionmode
\scratchcounter
2723
\egroup
}}
2724 2725
\unexpanded
\def
\spreadhbox
#
1
% rebuilds \hbox{<box><hss><box><hss><box>}
2726
{
\bgroup
2727
\ifhbox
#
1
\relax
2728
\setbox
\scratchboxtwo
\emptybox
2729
\unhbox
#
1
%
2730
\doloop
2731
{
\unpenalty\unskip\unpenalty\unskip\unpenalty\unskip
2732
\setbox
\scratchboxone
\lastbox
2733
\ifvoid
\scratchboxone
2734
\exitloop
2735
\else
2736
\setbox
\scratchboxtwo
\hbox
2737
{
\ifhbox
\scratchboxone
\spreadhbox
\scratchboxone
\else\box
\scratchboxone
\fi
2738
\ifvoid
\scratchboxtwo
\else\hss\unhbox
\scratchboxtwo
\fi
}
%
2739
\fi
}
%
2740
\ifvoid
\scratchboxtwo
\else\unhbox
\scratchboxtwo
\fi
2741
\else
2742
\box
#
1
%
2743
\fi
2744
\egroup
}
2745 2746
% makes sense but too much log for overfull boxes:
2747
%
2748
% \showboxbreadth\maxdimen
2749
% \showboxdepth \maxdimen
2750 2751
%D Moved from cont-new:
2752
%D
2753
%D \starttyping
2754
%D \minimalhbox 100pt {test}
2755
%D \stoptyping
2756 2757
\unexpanded
\def
\minimalhbox
#
1
#
%
2758
{
\dowithnextbox
2759
{
\bgroup
2760
\setbox
\scratchbox
\hpack
#
1
{
\hss
}
%
2761
\ifdim
\wd
\nextbox
<
\wd
\scratchbox
\wd
\nextbox
\wd
\scratchbox
\fi
2762
\box
\nextbox
2763
\egroup
}
2764
\hbox
}
2765 2766
%D A bit dirty:
2767 2768
\unexpanded
\def
\nodestostring
#
1
#
2
% more tolerant for #2=\cs
2769
{
\begingroup
2770
\setbox
\nextbox
\hbox
{
#
2
}
%
2771
\normalexpanded
{
\endgroup\edef\noexpand
#
1
{
\clf_boxtostring
\nextbox
}}}
2772 2773
%D Even more dirty:
2774 2775
\let
\hyphenatedhbox
\hbox
2776 2777
%D We can do this:
2778
%D
2779
%D \starttyping
2780
%D \setbox0\hbox to 10cm{foo} \setbox2\hbox{\unhbox0} \the\wd2
2781
%D \stoptyping
2782
%D
2783
%D But this saves a copy (and hpack pass):
2784
%D
2785
%D \starttyping
2786
%D \setbox0\hbox to 10cm{foo} \the\naturalwd0
2787
%D \stoptyping
2788 2789
\newdimen
\lastnaturalboxwd
2790
\newdimen
\lastnaturalboxht
2791
\newdimen
\lastnaturalboxdp
2792 2793
\let
\getnaturaldimensions
\clf_getnaturaldimensions
% sets three dimensions
2794
\let
\naturalwd
\clf_naturalwd
% calculates and returns wd
2795 2796
\let
\getnaturalwd
\clf_getnaturalwd
% no intermediate
2797
\let
\setnaturalwd
\clf_setnaturalwd
% no intermediate
2798 2799
\unexpanded
\def
\doifelserighttoleftinbox
{
\clf_doifelserighttoleftinbox
}
2800 2801
\let
\doifrighttoleftinboxelse\doifelserighttoleftinbox
2802 2803
%D New, used in high/low:
2804 2805
\definesystemattribute
[
runningtext
]
[
public
]
2806 2807
%unexpanded\def\runninghbox{\hbox attr \runningtextattribute \plusone} % not yet in i-*
2808
\unexpanded
\def
\runninghbox
{
\hbox
attr
\runningtextattribute
\fontid\font
}
% not yet in i-*
2809 2810
%D To complement lua (yet undocumented):
2811 2812
\unexpanded
\def
\beginhbox
{
\hbox
\bgroup
}
\let
\endhbox
\egroup
2813
\unexpanded
\def
\beginvbox
{
\vbox
\bgroup
}
\let
\endvbox
\egroup
2814
\unexpanded
\def
\beginvtop
{
\vtop
\bgroup
}
\let
\endvtop
\egroup
2815 2816
\unexpanded
\def
\sethboxregister
#
1
{
\setbox
#
1
\hbox
}
2817
\unexpanded
\def
\setvboxregister
#
1
{
\setbox
#
1
\vbox
}
2818
\unexpanded
\def
\setvtopregister
#
1
{
\setbox
#
1
\vtop
}
2819 2820
\unexpanded
\def
\flushboxregister
#
1
{
\box\numexpr
#
1
\relax
}
2821 2822
\unexpanded
\def
\starthboxregister
#
1
{
\setbox
#
1
\hbox
\bgroup
}
\let
\stophboxregister
\egroup
2823
\unexpanded
\def
\startvboxregister
#
1
{
\setbox
#
1
\vbox
\bgroup
}
\let
\stopvboxregister
\egroup
2824
\unexpanded
\def
\startvtopregister
#
1
{
\setbox
#
1
\vtop
\bgroup
}
\let
\stopvtopregister
\egroup
2825 2826
%D For whatever third party package needs it:
2827
%D
2828
%D \starttyping
2829
%D \newlocalbox\BoxOne
2830
%D \newlocalbox\BoxTwo
2831
%D
2832
%D \setbox\BoxOne\hbox{Box One}
2833
%D \setbox\BoxTwo\hbox{Box Two}
2834
%D
2835
%D [\box\BoxTwo] [\box\BoxOne]
2836
%D \stoptyping
2837 2838
\installcorenamespace
{
localbox
}
2839 2840
\unexpanded
\def
\newlocalbox
#
1
%
2841
{
\expandafter\let\expandafter
#
1
\csname
\??localbox
\string
#
1
\endcsname
2842
\ifx
#
1
\relax
2843
\syst_aux_new_localbox
#
1
%
2844
\fi
}
2845 2846
\def
\syst_aux_new_localbox
#
1
%
2847
{
\expandafter
\newbox
\csname
\??localbox
\string
#
1
\endcsname
2848
\newlocalbox
#
1
}
2849 2850
%D Who knows when this comes in handy:
2851 2852
\unexpanded
\def
\lastlinewidth
{
\dimexpr
\clf_lastlinewidth
\scaledpoint
\relax
}
2853 2854
%D Keep as reference:
2855 2856
% \unexpanded\def\tightvbox{\dowithnextbox{\dp\nextbox\zeropoint\box\nextbox}\vbox}
2857
% \unexpanded\def\tightvtop{\dowithnextbox{\ht\nextbox\zeropoint\box\nextbox}\vtop}
2858 2859
%D This one keeps dimensions and sets the shift field (and so it's more for testing
2860
%D than for real usage):
2861 2862
\unexpanded
\def
\shiftbox
{
\clf_shiftbox
}
2863
\unexpanded
\def
\vpackbox
{
\clf_vpackbox
}
2864
\unexpanded
\def
\hpackbox
{
\clf_hpackbox
}
2865
\unexpanded
\def
\vpackedbox
{
\clf_vpackedbox
}
2866
\unexpanded
\def
\hpackedbox
{
\clf_hpackedbox
}
2867 2868
%D This one has been moved from a 2 decade old file. It makes something boxed
2869
%D sit on the baseline.
2870 2871
\unexpanded
\def
\linebox
2872
{
\hpack
\bgroup
\dowithnextbox
2873
{
\scratchdimen
\dimexpr\dimexpr
\htdp\nextbox
-
\lineheight
\relax
/
2
+
\dp
\strutbox
\relax
2874
\setbox
\nextbox
\hpack
{
\lower
\scratchdimen
\box
\nextbox
}
%
2875
\ht
\nextbox
\ht
\strutbox
2876
\dp
\nextbox
\dp
\strutbox
2877
\box
\nextbox
2878
\egroup
}
2879
\hbox
}
2880 2881 2882
%D \macros
2883
%D {widthuptohere}
2884
%D
2885
%D Implemented at the \LUA\ end:
2886
%D
2887
%D \startbuffer
2888
%D widthuptohere:\the\widthuptohere\crlf
2889
%D widthuptohere : \the\widthuptohere (space without stretch or shrink!)
2890
%D \stopbuffer
2891
%D
2892
%D \typebuffer \blank \getbuffer \blank
2893 2894
\protect
\endinput
2895 2896
% a bit of test code:
2897 2898
% \hbox \bgroup
2899
% \ruledvbox {\hbox{\strut gans}}
2900
% \ruledvbox to \lineheight {\hbox{\strut gans}}
2901
% \ruledvbox to \lineheight {\hbox {gans}}
2902
% \ruledvbox to \strutheight{\hbox {gans}}
2903
% \ruledvbox to \strutheight{\hbox{\strut gans}}
2904
% \ruledvbox to \strutheight{\vss\hbox{gans}}
2905
% \egroup
2906 2907
% to be considered
2908 2909
% \startluacode
2910
%
2911
% local spacer = lpeg.patterns.spacer
2912
%
2913
% function commands.withwords(command,str)
2914
% if str then
2915
% command = command or "ruledhbox"
2916
% local done = false
2917
% local function apply(s)
2918
% if done then
2919
% context.space()
2920
% done = true
2921
% else
2922
% context.dontleavehmode()
2923
% end
2924
% context[command](s)
2925
% end
2926
% lpeg.match(lpeg.splitter(spacer,apply),str)
2927
% end
2928
%
2929
% end
2930
%
2931
% \stopluacode
2932
%
2933
% \unprotect
2934
%
2935
% \unexpanded\def\withwordsinstring#1#2% command str
2936
% {\ctxcommand{withwords(\!!bs#1\!!es,\!!bs#2\!!es)}}
2937
%
2938
% \unexpanded\def\withwordsinfile#1#2% command name
2939
% {\ctxcommand{withwords(\!!bs#1\!!es,io.loaddata(resolvers.findfile("#2")))}}
2940
%
2941
% \protect
2942
%
2943
% \starttext
2944
%
2945
% \defineframed[colored][foregroundcolor=red,foregroundstyle=\bfc\underbar,location=low]
2946
%
2947
% \withwordsinstring{colored}{bla bla}
2948
% \withwordsinfile{colored}{ward.tex}
2949
%
2950
% \stoptext
2951