pack-com.mkxl /size: 33 Kb    last modification: 2021-10-28 13:51
1
%D \module
2
%D [ file=pack-com, % used to be in core-mis,
3
%D version=20120111,
4
%D title=\CONTEXT\ Packing Macros,
5
%D subtitle=Combinations,
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
Packaging
Macros
/
Combinations
}
15 16
\unprotect
17 18
% \startfloatcombination will be redone ... we can decouple the floatcontent
19
% and caption and pass them to combinations so that we get better fit when the
20
% caption is wider than the float, testcase:
21
%
22
% \startfloatcombination [2*2]
23
% \placefigure[local]{alpha}{\externalfigure[cow.pdf][width=1cm]}%
24
% \placefigure[local]{beta} {\externalfigure[cow.pdf][width=2cm]}%
25
% \placefigure[local]{gamma}{\externalfigure[cow.pdf][width=3cm]}
26
% \placefigure[local]{delta}{\externalfigure[cow.pdf][width=4cm]}
27
% \stopfloatcombination
28 29
%D We could of course map combinations onto one of the table mechanisms but as it
30
%D has served us well for ages we keep this one. The code has been cleaned up a bit
31
%D and mkiv'd.
32
%D
33
%D Okay ... I might luafy this one eventually.
34 35
% \startcombination {alpha} {a} {beta} {b} \stopcombination
36
% \startcombination[2*1] {alpha} {a} {beta} {b} \stopcombination
37
% \startcombination[1*2] {alpha} {a} {beta} {b} \stopcombination
38
% \startcombination[2] {alpha} {a} {beta} {b} \stopcombination
39
% \startcombination[2] \combination {alpha} {a} \combination{beta} {b} \stopcombination
40 41
%D We do support some structure but the order matters and currently it's only window
42
%D dressing:
43 44
%D \starttyping
45
%D \let\startcontent\bgroup
46
%D \let\stopcontent \egroup
47
%D \let\startcaption\bgroup
48
%D \let\stopcaption \egroup
49
%D \stoptyping
50
%D
51
%D Of course we should have started with more structure as it would simply the code.
52
%D
53
%D \starttyping
54
%D \startcombination
55
%D \startcontent
56
%D \externalfigure[cow]
57
%D \stopcontent
58
%D \startcaption
59
%D Some cow.
60
%D \stopcaption
61
%D \startcontent
62
%D \externalfigure[cow]
63
%D \stopcontent
64
%D \startcaption
65
%D The same cow.
66
%D \stopcaption
67
%D \stopcombination
68
%D \stoptyping
69 70
\ifdefined
\dotagcombination
\else
\aliased
\let
\dotagcombination
\relax
\fi
71 72
\newsystemmode
{
combination
}
73 74
\appendtoks
75
\globalresetsystemmode
{
combination
}
%
76
\to
\everyinsidefloat
77 78
\newcount
\c_pack_combinations_nesting
% local
79 80
\newcount
\c_pack_combinations_x
% global
81
\newcount
\c_pack_combinations_y
% global
82
\newcount
\c_pack_combinations_max
% global
83 84
\newdimen
\d_pack_combinations_ht
% global
85 86
\newbox
\b_pack_combinations_captions
% global % can go
87
\newbox
\b_pack_combinations_temp
% global % can go
88
\newbox
\b_pack_combinations_content
% local
89
\newbox
\b_pack_combinations_caption
% local
90 91
\installcorenamespace
{
combination
}
92 93
\installcommandhandler
\??combination
{
combination
}
\??combination
94 95
\initializeboxstack
{
\??combination
captions
}
96
\initializeboxstack
{
\??combination
temp
}
97 98
\newcount
\c_pack_combinations_x_saved
99
\newcount
\c_pack_combinations_y_saved
100
\newcount
\c_pack_combinations_max_saved
101 102
\newdimen
\d_pack_combinations_ht_saved
103 104
\newbox
\b_pack_combinations_captions_saved
105
\newbox
\b_pack_combinations_temp_saved
106
\newbox
\b_pack_combinations_content_saved
107
\newbox
\b_pack_combinations_caption_saved
108 109
\setfalse
\c_strc_constructions_define_commands
110 111
\def
\pack_combinations_push
112
{
\advance
\c_pack_combinations_nesting
\plusone
113
\ifnum
\c_pack_combinations_nesting
>
\plusone
114
\c_pack_combinations_x_saved
\c_pack_combinations_x
115
\c_pack_combinations_y_saved
\c_pack_combinations_y
116
\c_pack_combinations_max_saved
\c_pack_combinations_max
117
\d_pack_combinations_ht_saved
\d_pack_combinations_ht
118
\setbox
\b_pack_combinations_captions_saved
\box
\b_pack_combinations_captions
119
\setbox
\b_pack_combinations_temp_saved
\box
\b_pack_combinations_temp
120
\setbox
\b_pack_combinations_content_saved
\box
\b_pack_combinations_content
121
\setbox
\b_pack_combinations_caption_saved
\box
\b_pack_combinations_caption
122
\else
123
\globalsetsystemmode
{
combination
}
% why global
124
\fi
}
125 126
\def
\pack_combinations_pop
127
{
\ifnum
\c_pack_combinations_nesting
>
\plusone
128
\global
\c_pack_combinations_x
\c_pack_combinations_x_saved
129
\global
\c_pack_combinations_y
\c_pack_combinations_y_saved
130
\global
\c_pack_combinations_max
\c_pack_combinations_max_saved
131
\global
\d_pack_combinations_ht
\d_pack_combinations_ht_saved
132
\global
\setbox
\b_pack_combinations_captions
\box
\b_pack_combinations_captions_saved
133
\global
\setbox
\b_pack_combinations_temp
\box
\b_pack_combinations_temp_saved
134
\setbox
\b_pack_combinations_content
\box
\b_pack_combinations_content_saved
135
\setbox
\b_pack_combinations_caption
\box
\b_pack_combinations_caption_saved
136
\else
137
\globalresetsystemmode
{
combination
}
% why global
138
\fi
139
\advance
\c_pack_combinations_nesting
\minusone
}
140 141
\definelabel
142
[
\v!combination
]
% handy for configuring
143
[
\c!numberconversion
=
\v!character
,
144
\c!text
=
]
145 146
\settrue
\c_strc_constructions_define_commands
147 148
\setupcombination
149
[
\c!width
=
\v!fit
,
150
\c!height
=
\v!fit
,
151
\c!distance
=
\emwidth
,
152
\c!location
=
\v!bottom
,
% can be something {top,left}
153
\c!before
=
\blank
,
154
\c!after
=
,
155
\c!inbetween
=
{
\blank
[
\v!medium
]
}
,
156
%\c!style=,
157
%\c!color=,
158
\c!nx
=
2
,
% new
159
\c!ny
=
1
,
% new
160
\c!align
=
\v!middle
]
161 162
\let
\setupcombinations
\setupcombination
% for the moment (we might distinguish)
163 164
\installcorenamespace
{
combinationlocation
}
165
\installcorenamespace
{
combinationalternative
}
166 167
\appendtoks
168
\setfalse
\c_strc_constructions_define_commands
169
\normalexpanded
170
{
\definelabel
171
[
\v!combination
:
\currentcombination
]
%
172
[
\v!combination
\ifempty
\currentcombinationparent
\else
:
\currentcombinationparent
\fi
]
}
%
173
[
\s!counter
=
\currentcombination
,
\c!levels
=
1
]
%
174
\settrue
\c_strc_constructions_define_commands
175
\to
\everydefinecombination
176 177
\setvalue
{
\??combinationlocation
\v!left
}
{
\let
\m_pack_combinations_leftfiller
\relax
}
178
\setvalue
{
\??combinationlocation
\v!right
}
{
\let
\m_pack_combinations_rightfiller
\relax
}
179
\setvalue
{
\??combinationlocation
\v!top
}
{
\let
\m_pack_combinations_valigner
\depthonlybox
}
180
\setvalue
{
\??combinationlocation
\v!middle
}
{
\let
\m_pack_combinations_valigner
\halfwaybox
}
181 182
\def
\pack_combinations_location_reset
183
{
\let
\m_pack_combinations_rightfiller
\hfil
184
\let
\m_pack_combinations_leftfiller
\hfil
185
\let
\m_pack_combinations_valigner
\firstofoneargument
}
186 187
\pack_combinations_location_reset
188 189
\def
\pack_combinations_location_step
#
1
%
190
{
\csname
\??combinationlocation
#
1
\endcsname
}
191 192
% formally ok:
193
%
194
% \protected\def\stopcombination
195
% {\egroup
196
% \egroup}
197
%
198
% more robust:
199
%
200
% \protected\def\stopcombination
201
% {{}{}{}{}{}{}{}{}% catches (at most 4) missing entries
202
% \egroup
203
% \egroup}
204
%
205
% even better:
206
%
207
% \protected\def\stopcombination
208
% {\bgroup
209
% \scratchtoks{{}}%
210
% \dorecurse\c_pack_combinations_y
211
% {\toksapp{{}{}}}%
212
% \expandafter\egroup\the\scratchtoks
213
% \egroup
214
% \dostoptagged
215
% \egroup}
216
%
217
% faster
218 219
\ifdefined
\startcontent
\else
\aliased
\let
\startcontent
\relax
\fi
220
\ifdefined
\stopcontent
\else
\aliased
\let
\stopcontent
\relax
\fi
221
\ifdefined
\startcaption
\else
\aliased
\let
\startcaption
\relax
\fi
222
\ifdefined
\stopcaption
\else
\aliased
\let
\stopcaption
\relax
\fi
223 224
\protected
\def
\pack_common_content_start
{
\bgroup
\ignorespaces
}
225
\protected
\def
\pack_common_content_stop
{
\removeunwantedspaces
\egroup
}
226
\protected
\def
\pack_common_caption_start
{
\bgroup
\ignorespaces
}
227
\protected
\def
\pack_common_caption_stop
{
\removeunwantedspaces
\egroup
}
228 229
\newtoks
\everycombination
230 231
\aliased
\let
\combination
\empty
232 233
\let
\p_nx_ny
\empty
234 235
\permanent
\protected
\def
\stopcombination
236
{
\bgroup
\normalexpanded
{
\egroup
{
}
\ntimes
{
{
}
{
}
}
\c_pack_combinations_y
}
% brr
237
\dostoptagged
238
\egroup
239
\pack_combinations_pop
240
\egroup
}
241 242
\permanent
\tolerant
\protected
\def
\startcombination
[
#
1
]
#
*
[
#
2
]
% can be simplified
243
{
\bgroup
% so we can grab a group
244
\pack_combinations_push
245
\edef
\currentcombination
{
#
1
}
%
246
\edef
\p_nx_ny
{
#
2
}
%
247
%
248
\ifempty
\p_nx_ny
249
\ifcondition
\validassignment
{
#
1
}
%
250
\let
\currentcombination
\empty
251
\setupcurrentcombination
[
#
1
]
%
252
\edef
\p_nx_ny
{
\combinationparameter
\c!nx
*
\combinationparameter
\c!ny
*
}
%
253
\else
254
\doifelseinstring
{
*
}
\currentcombination
255
{
\edef
\p_nx_ny
{
\currentcombination
*
\plusone
*
}
%
256
\let
\currentcombination
\empty
}
257
{
\doifelsenumber
\currentcombination
258
{
\edef
\p_nx_ny
{
\currentcombination
*
\plusone
*
}
%
259
\let
\currentcombination
\empty
}
260
{
\edef
\p_nx_ny
{
\combinationparameter
\c!nx
*
\combinationparameter
\c!ny
*
}
}
}
%
261
\fi
262
\else
263
\ifcondition
\validassignment
{
#
2
}
%
264
\setupcurrentcombination
[
#
2
]
%
265
\edef
\p_nx_ny
{
\combinationparameter
\c!nx
*
\combinationparameter
\c!ny
*
}
%
266
\else
267
\edef
\p_nx_ny
{
\p_nx_ny
*
\plusone
*
}
%
268
\fi
269
\fi
270
%
271
% test first:
272
%
273
% \ifempty\p_nx_ny
274
% \ifhastok={#1}%
275
% \let\currentcombination\empty
276
% \setupcurrentcombination[#1]%
277
% \edef\p_nx_ny{\combinationparameter\c!nx*\combinationparameter\c!ny*}%
278
% \orelse\ifhastok*{\currentcombination}%
279
% \edef\p_nx_ny{\currentcombination*\plusone*}%
280
% \let\currentcombination\empty
281
% \orelse\ifchknum\currentcombination\or
282
% \edef\p_nx_ny{\currentcombination*\plusone*}%
283
% \let\currentcombination\empty
284
% \else
285
% \edef\p_nx_ny{\combinationparameter\c!nx*\combinationparameter\c!ny*}%
286
% \fi
287
% \orelse\ifhastok={#2}%
288
% \setupcurrentcombination[#2]%
289
% \edef\p_nx_ny{\combinationparameter\c!nx*\combinationparameter\c!ny*}%
290
% \else
291
% \edef\p_nx_ny{\p_nx_ny*\plusone*}%
292
% \fi
293
%
294
\forgetall
295
%
296
\the
\everycombination
297
%
298
\enforced
\let
\startcontent
\pack_common_content_start
299
\enforced
\let
\stopcontent
\pack_common_content_stop
300
\enforced
\let
\startcaption
\pack_common_caption_start
301
\enforced
\let
\stopcaption
\pack_common_caption_stop
302
%
303
\edef
\p_height
{
\combinationparameter
\c!height
}
%
304
\edef
\p_width
{
\combinationparameter
\c!width
}
%
305
\edef
\p_location
{
\combinationparameter
\c!location
}
%
306
\edef
\p_distance
{
\combinationparameter
\c!distance
}
%
307
%
308
\pack_combinations_location_reset
309
\rawprocesscommacommand
[
\p_location
]
\pack_combinations_location_step
310
%
311
\dostarttaggedchained
\t!combination
\currentcombination
\??combination
312
\vbox
\ifx
\p_height
\v!fit
\else
to
\p_height
\fi
\bgroup
313
\enforced
\let
\combination
\empty
% permits \combination{}{} handy for cld
314
\normalexpanded
{
\pack_combinations_start_indeed
[
\p_nx_ny
]
}
}
315 316
\let
\pack_combinations_check_x_y
\relax
317 318
\protected
\def
\pack_combinations_start_indeed
[
#
1
*
#
2
*
#
3
]
%
319
{
\global
\c_pack_combinations_x
#
1
\relax
320
\global
\c_pack_combinations_y
#
2
\relax
321
\setexpandedcombinationparameter
\c!nx
{
\the
\c_pack_combinations_x
}
% in case we access it
322
\setexpandedcombinationparameter
\c!ny
{
\the
\c_pack_combinations_y
}
% in case we access it
323
\pack_combinations_check_x_y
324
\dotagcombination
325
\global
\setbox
\b_pack_combinations_captions
\emptybox
326
\global
\c_pack_combinations_max
\c_pack_combinations_x
327
\multiply
\c_pack_combinations_y
\c_pack_combinations_x
328
\tabskip
\zeropoint
329
\halign
\ifx
\p_width
\v!fit
\else
to
\p_width
\fi
\bgroup
% repetitive preamble
330
% \halign noskips \ifx\p_width\v!fit\else to \p_width \fi \bgroup % repetitive preamble
331
\aligntab
332
\m_pack_combinations_leftfiller
333
\aligncontent
334
\m_pack_combinations_rightfiller
335
\aligntab
336
\tabskip
\zeropoint
\s!plus
1
fill
% \fillskip
337
\aligncontent
338
\cr
339
\pack_combinations_pickup
}
340 341
%D I've first considered using a constructor directly but it's more overhead and
342
%D some settings conflict with already used combination settings so instead we plug
343
%D in labels. This also permits extensions later on.
344 345
\appendtoks
346
\edef
\p_pack_combinations_alternative
{
\combinationparameter
\c!alternative
}
%
347
\to
\everydefinecombination
348 349
\def
\pack_combinations_pickup
350
{
\dostarttagged
\t!combinationpair
\empty
% better make this text
351
\dostarttagged
\t!combinationcontent
\empty
352
\expandafterpars
\pack_combinations_pickup_content_indeed
}
353 354
\def
\pack_combinations_pickup_content_indeed
355
{
\dowithnextboxcs
\pack_combinations_pickup_content
\hbox
}
356 357
\def
\pack_combinations_pickup_content
% we want to add struts but still ignore an empty box
358
{
\dostoptagged
359
\setbox
\b_pack_combinations_content
\box
\nextbox
360
\dostarttagged
\t!combinationcaption
\empty
361
\expandnamespacemacro
\??combinationalternative
\p_pack_combinations_alternative
\v!text
}
362 363
\setvalue
{
\??combinationalternative
\v!text
}
%
364
{
\expandafterpars
\pack_combinations_alternative_text_indeed
}
365 366
\setvalue
{
\??combinationalternative
\v!label
}
%
367
{
\expandafterpars
\pack_combinations_alternative_label_indeed
}
368 369
\def
\pack_combinations_alternative_text_indeed
370
{
\dowithnextboxcs
\pack_combinations_pickup_caption
\vtop
\bgroup
371
\afterassignment
\pack_combinations_caption_first
372
\let
\nexttoken
=
}
373 374
\def
\pack_combinations_alternative_label_indeed
375
{
\dowithnextboxcs
\pack_combinations_pickup_caption
\vtop
\bgroup
376
\hsize
\wd
\b_pack_combinations_content
377
\usealignparameter
\combinationparameter
378
\usecombinationstyleandcolor
\c!style
\c!color
379
\begstrut
380
\normalexpanded
{
\strc_labels_command
[
\v!combination
\ifempty
\currentcombination
\else
:
\currentcombination
\fi
]
}
%
381
\endstrut
382
\egroup
}
383 384
\appendtoks
385
\edef
\p_pack_combinations_alternative
{
\combinationparameter
\c!alternative
}
%
386
\ifx
\p_pack_combinations_alternative
\v!label
387
\edef
\p_continue
{
\combinationparameter
\c!continue
}
%
388
\ifx
\p_continue
\v!yes
\else
389
\normalexpanded
{
\strc_labels_reset
{
\v!combination
\ifempty
\currentcombination
\else
:
\currentcombination
\fi
}
{
1
}
}
%
390
\fi
391
\fi
392
\to
\everycombination
393 394
\def
\pack_combinations_pickup_caption
395
{
\dostoptagged
396
\dostoptagged
397
\setbox
\b_pack_combinations_caption
\box
\nextbox
398
\pack_combinations_pickup_package_pair
}
399 400
\def
\pack_combinations_caption_first
401
{
\futurelet
\nexttoken
\pack_combinations_caption_second
}
402 403
\def
\pack_combinations_caption_second
404
{
\ifx
\nexttoken
\egroup
405
% the caption is empty
406
\orelse
\ifx
\nexttoken
\stopcaption
407
% the caption is empty (new per 2014-05-24)
408
\else
409
% todo: \p_pack_combinations_alternative\v!none: no style, strut etc
410
\hsize
\wd
\b_pack_combinations_content
411
\usealignparameter
\combinationparameter
412
\usecombinationstyleandcolor
\c!style
\c!color
413
\bgroup
414
\aftergroup
\endstrut
415
\aftergroup
\egroup
416
\begstrut
417
\fi
}
418 419
\def
\pack_combinations_pickup_package_pair
% we need to store the caption row
420
{
\vbox
421
{
\forgetall
422
\m_pack_combinations_valigner
{
\box
\b_pack_combinations_content
}
%
423
% we need to save the caption for a next alignment line
424
\pack_combinations_save_caption
}
%
425
\ifnum
\c_pack_combinations_y
>
\plusone
426
\global
\advance
\c_pack_combinations_y
\minusone
427
\global
\advance
\c_pack_combinations_x
\minusone
428
\ifcase
\c_pack_combinations_x
429
\doubleexpandafter
\pack_combinations_pickup_package_pair_a
430
\else
431
\doubleexpandafter
\pack_combinations_pickup_package_pair_b
432
\fi
433
\else
434
\singleexpandafter
\pack_combinations_pickup_package_pair_c
435
\fi
}
436 437
\def
\pack_combinations_pickup_package_pair_a
438
{
\cr
439
\pack_combinations_flush_captions
440
\noalign
441
{
\forgetall
442
\global
\setbox
\b_pack_combinations_captions
\emptybox
443
\nointerlineskip
444
\combinationparameter
\c!after
445
\combinationparameter
\c!before
446
\vss
447
\nointerlineskip
}
%
448
\global
\c_pack_combinations_x
\c_pack_combinations_max
449
\pack_combinations_pickup
}
450 451
\def
\pack_combinations_pickup_package_pair_b
452
{
\aligntab
453
\aligntab
454
\aligntab
455
\kern
\p_distance
456
\aligntab
457
\pack_combinations_pickup
}
458 459
\def
\pack_combinations_pickup_package_pair_c
460
{
\cr
461
\pack_combinations_flush_captions
462
\egroup
}
463 464
\installcorenamespace
{
combinationcaption
}
465 466
\def
\pack_combinations_save_caption
467
{
\ifdim
\htdp
\b_pack_combinations_caption
>
\d_pack_combinations_ht
468
\global
\d_pack_combinations_ht
\htdp
\b_pack_combinations_caption
469
\fi
470
\savebox
{
\??combinationcaption
:
\number
\c_pack_combinations_nesting
}
{
\number
\c_pack_combinations_x
}
{
\box
\b_pack_combinations_caption
}
}
471 472
\let
\pack_combinations_flush_captions_indeed
\relax
473 474
\def
\pack_combinations_flush_captions
475
{
\noalign
476
{
\ifdim
\d_pack_combinations_ht
>
\zeropoint
477
\nointerlineskip
% indeed
478
\combinationparameter
\c!inbetween
479
\global
\c_pack_combinations_x
\c_pack_combinations_max
480
\glet
\pack_combinations_flush_captions_indeed
\pack_combinations_flush_captions_yes
481
\else
482
\glet
\pack_combinations_flush_captions_indeed
\pack_combinations_flush_captions_nop
483
\fi
}
%
484
\pack_combinations_flush_captions_indeed
485
\crcr
}
486 487
\def
\pack_combinations_flush_captions_yes
488
{
\vpack
to
\d_pack_combinations_ht
\bgroup
489
\foundbox
{
\??combinationcaption
:
\number
\c_pack_combinations_nesting
}
{
\number
\c_pack_combinations_x
}
%
490
\vss
491
\egroup
492
\global
\advance
\c_pack_combinations_x
\minusone
493
\ifnum
\c_pack_combinations_x
>
\zerocount
% \c_pack_combinations_max
494
\expandafter
\pack_combinations_flush_captions_yes_followup
495
\else
496
\global
\d_pack_combinations_ht
\zeropoint
497
\initializeboxstack
{
\??combinationcaption
:
\number
-
\c_pack_combinations_nesting
}
%
498
\fi
}
499 500
\let
\pack_combinations_flush_captions_nop
\donothing
501 502
\def
\pack_combinations_flush_captions_yes_followup
503
{
\aligntab
504
\aligntab
505
\aligntab
506
\aligntab
507
\pack_combinations_flush_captions_indeed
}
508 509
%D \macros
510
%D {startfloatcombination}
511
%D
512
%D \setupexternalfigures[directory={../sample}]
513
%D \startbuffer
514
%D \placefigure
515
%D [left,none]
516
%D {}
517
%D {\startfloatcombination[2*2]
518
%D \placefigure{alpha}{\externalfigure[cow.pdf][width=1cm]}
519
%D \placefigure{beta} {\externalfigure[cow.pdf][width=2cm]}
520
%D \placefigure{gamma}{\externalfigure[cow.pdf][width=3cm]}
521
%D \placefigure{delta}{\externalfigure[cow.pdf][width=4cm]}
522
%D \stopfloatcombination}
523
%D
524
%D \input tufte
525
%D \stopbuffer
526
%D
527
%D \typebuffer \getbuffer
528 529
\protected
\def
\pack_combinations_float_hack_a
#
1
%
530
{
\strc_floats_build_box_separate_split
{
#
1
}
%
531
\box
\b_strc_floats_separate_content
}
532 533
\protected
\def
\pack_combinations_float_hack_b
#
1
%
534
{
\box
\b_strc_floats_separate_caption
}
535 536
\permanent
\tolerant
\protected
\def
\startfloatcombination
[
#
1
]
#
*
[
#
2
]
%
537
{
\ifinsidefloat
\else
\dontleavehmode
\fi
% tricky, floatcombinations fail to align well otherwise
538
\vbox
\bgroup
539
\strc_floats_build_box_separate_set
540
%\insidecolumnstrue % trick, forces no centering, todo: proper switch/feature
541
\postcenterfloatmethod
\zerocount
542
\forcelocalfloats
543
\enforced
\permanent
\protected
\def
\stopfloatcombination
{
\pack_combinations_stop_float
{
#
1
}
}
}
544 545
\aliased
\let
\stopfloatcombination
\relax
546 547
\def
\pack_combinations_float_check_x_y
548
{
\ifnum
\numexpr
\c_pack_combinations_x
*
\c_pack_combinations_y
\relax
<
\noflocalfloats
\relax
549
\global
\c_pack_combinations_x
\noflocalfloats
550
\global
\c_pack_combinations_y
\plusone
551
\fi
552
\let
\pack_combinations_check_x_y
\relax
}
%
553 554
\def
\pack_combinations_stop_float
#
1
%
555
{
\scratchtoks
\emptytoks
556
\dorecurse
\noflocalfloats
557
{
\appendetoks
558
{
\pack_combinations_float_hack_a
{
\recurselevel
}
}
%
559
{
\pack_combinations_float_hack_b
{
\recurselevel
}
}
%
560
\to
\scratchtoks
}
% brrr
561
\let
\pack_combinations_check_x_y
\pack_combinations_float_check_x_y
562
\expanded
{
\startcombination
[
#
1
]
\the
\scratchtoks
}
\stopcombination
563
\resetlocalfloats
564
\egroup
}
565 566
%D \macros
567
%D {definepairedbox, setuppairedbox, placepairedbox}
568
%D
569
%D Paired boxes, formally called legends, but from now on a legend is just an
570
%D instance, are primarily meant for typesetting some text alongside an
571
%D illustration. Although there is quite some variation possible, the functionality
572
%D is kept simple, if only because in most cases such pairs are typeset sober.
573
%D
574
%D The location specification accepts a pair, where the first keyword specifies the
575
%D arrangement, and the second one the alignment. The first key of the location pair
576
%D is one of \type {left}, \type {right}, \type {top} or \type {bottom}, while the
577
%D second key can also be \type {middle}.
578
%D
579
%D The first box is just collected in an horizontal box, but the second one is a
580
%D vertical box that gets passed the bodyfont and alignment settings.
581
%D
582
%D In many cases the table builders can be used instead, but as this mechanism is a
583
%D traditional \CONTEXT\ one we keep it around.
584 585
%D \macros
586
%D {setuplegend, placelegend}
587
%D
588
%D It makes sense to typeset a legend to a figure in \TEX\ and not in a drawing
589
%D package. The macro \type {\placelegend} combines a figure (or something else) and
590
%D its legend. This command is just a paired box.
591
%D
592
%D The legend is placed according to \type {location}, being \type {bottom} or \type
593
%D {right}. The macro macro is used as follows.
594
%D
595
%D \starttyping
596
%D \placefigure
597
%D {whow}
598
%D {\placelegend
599
%D {\externalfigure[cow]}
600
%D {\starttabulate
601
%D \NC 1 \NC head \NC \NR
602
%D \NC 2 \NC legs \NC \NR
603
%D \NC 3 \NC tail \NC \NR
604
%D \stoptabulate}}
605
%D
606
%D \placefigure
607
%D {whow}
608
%D {\placelegend
609
%D {\externalfigure[cow]}
610
%D {\starttabulate[|l|l|l|l|]
611
%D \NC 1 \NC head \NC 3 \NC tail \NC \NR
612
%D \NC 2 \NC legs \NC \NC \NC \NR
613
%D \stoptabulate}}
614
%D
615
%D \placefigure
616
%D {whow}
617
%D {\placelegend[n=2]
618
%D {\externalfigure[cow]}
619
%D {\starttabulate
620
%D \NC 1 \NC head \NC \NR
621
%D \NC 2 \NC legs \NC \NR
622
%D \NC 3 \NC tail \NC \NR
623
%D \stoptabulate}}
624
%D
625
%D \placefigure
626
%D {whow}
627
%D {\placelegend[n=2]
628
%D {\externalfigure[cow]}
629
%D {head \par legs \par tail}}
630
%D
631
%D \placefigure
632
%D {whow}
633
%D {\placelegend[n=2]
634
%D {\externalfigure[cow]}
635
%D {\startitemize[packed]
636
%D \item head \item legs \item tail \item belly \item horns
637
%D \stopitemize}}
638
%D
639
%D \placefigure
640
%D {whow}
641
%D {\placelegend[n=2,width=.8\hsize]
642
%D {\externalfigure[cow]}
643
%D {\startitemize[packed]
644
%D \item head \item legs \item tail \item belly \item horns
645
%D \stopitemize}}
646
%D
647
%D \def\MytTestTwo#1#2%
648
%D {\placefigure
649
%D {whow}
650
%D {\placelegend[location={#1,#2}]
651
%D {\externalfigure[cow]}
652
%D {\starttabulate
653
%D \NC 1 \NC head \NC \NR
654
%D \NC 2 \NC legs \NC \NR
655
%D \NC 3 \NC tail \NC \NR
656
%D \stoptabulate}}}
657
%D
658
%D \def\MytTestOne#1{\processcommalist[left,right,top,bottom]{\MytTestTwo{#1}}}
659
%D
660
%D \processcommalist[left,right,top,bottom,middle]\MytTestOne
661
%D \stoptyping
662
%D
663
%D More structure is also possible (the order matters!):
664
%D
665
%D \starttyping
666
%D \startplacefigure[title=whow]
667
%D \startplacelegend[location={bottom,middle},color=red]
668
%D \startcontent
669
%D \externalfigure[cow]
670
%D \stopcontent
671
%D \startcaption
672
%D \starttabulate[|l|l|]
673
%D \NC 1 \NC head \NC \NR
674
%D \NC 2 \NC legs \NC \NR
675
%D \NC 3 \NC tail \NC \NR
676
%D \stoptabulate
677
%D \stopcaption
678
%D \stopplacelegend
679
%D \stopplacefigure
680
%D \stoptyping
681 682
% todo: natural size
683 684
\newsystemmode
{
pairedbox
}
685 686
\appendtoks
687
\globalresetsystemmode
{
pairedbox
}
%
688
\to
\everyinsidefloat
689 690
\installcorenamespace
{
pairedbox
}
691 692
\installcommandhandler
\??pairedbox
{
pairedbox
}
\??pairedbox
693 694
\setuppairedbox
695
[
\c!n
=
1
,
696
\c!distance
=
\bodyfontsize
,
697
%\c!before=,
698
%\c!after=,
699
%\c!color=,
700
%\c!style=,
701
\c!inbetween
=
{
\blank
[
\v!medium
]
}
,
702
\c!width
=
\hsize
,
703
\c!height
=
\vsize
,
704
\c!maxwidth
=
\textwidth
,
% \makeupwidth,
705
\c!maxheight
=
\textheight
,
% \makeupheight,
706
%\c!bodyfont=,
707
%\c!align=,
708
\c!location
=
\v!bottom
]
709 710
% watch the hsize/vsize tricks
711 712
\newbox
\b_pack_pairedboxes_first
713
\newbox
\b_pack_pairedboxes_second
714
\newdimen
\s_pack_pairedboxes_size
715 716
\appendtoks
717
\frozen
\instance
\setuevalue
{
\e!setup
\currentpairedbox
\e!endsetup
}
{
\setuppairedbox
[
\currentpairedbox
]
}
%
718
\frozen
\instance
\setuevalue
{
\e!place
\currentpairedbox
}
{
\placepairedbox
[
\currentpairedbox
]
}
% one argument is mandate anyway
719
\frozen
\instance
\setuevalue
{
\e!start
\e!place
\currentpairedbox
}
{
\startplacepairedbox
[
\currentpairedbox
]
}
% one argument is mandate anyway
720
\frozen
\instance
\setuevalue
{
\e!stop
\e!place
\currentpairedbox
}
{
\stopplacepairedbox
}
%
721
\to
\everydefinepairedbox
722 723
\permanent
\tolerant
\protected
\def
\startplacepairedbox
[
#
1
]
#
*
[
#
2
]
%
724
{
\bgroup
725
\edef
\currentpairedbox
{
#
1
}
%
726
\setupcurrentpairedbox
[
#
2
]
%
727
\pairedboxparameter
\c!before
728
\bgroup
729
\edef
\p_location
{
\pairedboxparameter
\c!location
}
%
730
\edef
\p_n
{
\pairedboxparameter
\c!n
}
%
731
%
732
\enforced
\let
\startcontent
\pack_common_content_start
733
\enforced
\let
\stopcontent
\pack_common_content_stop
734
\enforced
\let
\startcaption
\pack_common_caption_start
735
\enforced
\let
\stopcaption
\pack_common_caption_stop
736
%
737
\globalsetsystemmode
{
pairedbox
}
%
738
\pack_pairedboxes_before
739
\expandafterpars
\pack_pairedboxes_first_pickup
}
740 741
\permanent
\protected
\def
\stopplacepairedbox
{
}
% we just pick up two boxes
742 743
\aliased
\let
\placepairedbox
\startplacepairedbox
% we just pick up two boxes
744 745
\def
\pack_pairedboxes_first_pickup
746
{
\dowithnextboxcs
\pack_pairedboxes_first
\hbox
747
\bgroup
748
\let
\next
=
}
749 750
\def
\pack_pairedboxes_first
751
{
\pack_pairedboxes_between
752
\expandafterpars
\pack_pairedboxes_second_pickup
}
753 754
\def
\pack_pairedboxes_second_pickup
755
{
\dowithnextboxcs
\pack_pairedboxes_second
\vbox
756
\bgroup
757
\pack_pairedboxes_inside_second
758
\let
\next
=
}
759 760
\def
\pack_pairedboxes_second
761
{
\pack_pairedboxes_after
762
\egroup
763
\pairedboxparameter
\c!after
764
\egroup
}
765 766
\newconditional
\c_pack_pairedboxes_horizontal
\settrue
\c_pack_pairedboxes_horizontal
767 768
\installcorenamespace
{
pairedboxnature
}
769
\installcorenamespace
{
pairedboxalign
}
770 771
\let
\pack_pairedboxes_flush
\relax
772
\let
\pack_pairedboxes_fill_top
\relax
773
\let
\pack_pairedboxes_fill_bottom
\relax
774 775
\defcsname
\??pairedboxnature
\v!left
\endcsname
776
{
\settrue
\c_pack_pairedboxes_horizontal
777
\let
\pack_pairedboxes_flush
\pack_pairedboxes_flush_left
}
778 779
\defcsname
\??pairedboxnature
\v!right
\endcsname
780
{
\settrue
\c_pack_pairedboxes_horizontal
781
\let
\pack_pairedboxes_flush
\pack_pairedboxes_flush_right
}
782 783
\defcsname
\??pairedboxnature
\v!top
\endcsname
784
{
\setfalse
\c_pack_pairedboxes_horizontal
785
\let
\pack_pairedboxes_fill_top
\relax
786
\let
\pack_pairedboxes_fill_bottom
\vss
787
\let
\pack_pairedboxes_flush
\pack_pairedboxes_flush_top
}
788 789
\defcsname
\??pairedboxnature
\v!bottom
\endcsname
790
{
\setfalse
\c_pack_pairedboxes_horizontal
791
\let
\pack_pairedboxes_fill_top
\vss
792
\let
\pack_pairedboxes_fill_bottom
\relax
793
\let
\pack_pairedboxes_flush
\pack_pairedboxes_flush_bottom
}
794 795
\def
\pack_pairedboxes_flush_left
796
{
\box
\b_pack_pairedboxes_second
797
\kern
\pairedboxparameter
\c!distance
798
\box
\b_pack_pairedboxes_first
}
799 800
\def
\pack_pairedboxes_flush_right
801
{
\box
\b_pack_pairedboxes_first
802
\kern
\pairedboxparameter
\c!distance
803
\box
\b_pack_pairedboxes_second
}
804 805
\def
\pack_pairedboxes_flush_top
806
{
\box
\b_pack_pairedboxes_second
807
\endgraf
808
\nointerlineskip
809
\pairedboxparameter
\c!inbetween
810
\box
\b_pack_pairedboxes_first
}
811 812
\def
\pack_pairedboxes_flush_bottom
813
{
\box
\b_pack_pairedboxes_first
814
\endgraf
815
\nointerlineskip
816
\pairedboxparameter
\c!inbetween
817
\box
\b_pack_pairedboxes_second
}
818 819
\let
\pack_pairedboxes_align_l
\relax
820
\let
\pack_pairedboxes_align_r
\relax
821
\let
\pack_pairedboxes_align_t
\relax
822
\let
\pack_pairedboxes_align_b
\relax
823 824
\defcsname
\??pairedboxalign
\v!left
\endcsname
% 0
825
{
\let
\pack_pairedboxes_align_l
\relax
826
\let
\pack_pairedboxes_align_r
\hss
827
\let
\pack_pairedboxes_align_t
\relax
828
\let
\pack_pairedboxes_align_b
\relax
}
829 830
\defcsname
\??pairedboxalign
\v!right
\endcsname
% 1
831
{
\let
\pack_pairedboxes_align_l
\hss
832
\let
\pack_pairedboxes_align_r
\relax
833
\let
\pack_pairedboxes_align_t
\relax
834
\let
\pack_pairedboxes_align_b
\relax
}
835 836
\defcsname
\??pairedboxalign
\v!high
\endcsname
% 2
837
{
\let
\pack_pairedboxes_align_l
\relax
838
\let
\pack_pairedboxes_align_r
\relax
839
\let
\pack_pairedboxes_align_t
\relax
840
\let
\pack_pairedboxes_align_b
\vss
}
841 842
\defcsname
\??pairedboxalign
\v!low
\endcsname
% 3
843
{
\let
\pack_pairedboxes_align_l
\relax
844
\let
\pack_pairedboxes_align_r
\relax
845
\let
\pack_pairedboxes_align_t
\vss
846
\let
\pack_pairedboxes_align_b
\relax
}
847 848
\defcsname
\??pairedboxalign
\v!middle
\endcsname
% 4
849
{
\let
\pack_pairedboxes_align_l
\hss
850
\let
\pack_pairedboxes_align_r
\hss
851
\let
\pack_pairedboxes_align_t
\vss
852
\let
\pack_pairedboxes_align_b
\vss
}
853 854
\defcsname
\??pairedboxalign
\v!bottom
\endcsname
{
\csname
\??pairedboxalign
\v!low
\endcsname
}
855
\defcsname
\??pairedboxalign
\v!top
\endcsname
{
\csname
\??pairedboxalign
\v!high
\endcsname
}
856 857
\def
\pack_pairedbox_valign
#
1
{
\setbox
#
1
\vpack
to
\s_pack_pairedboxes_size
{
\pack_pairedboxes_align_t
\box
#
1
\pack_pairedboxes_align_b
}
}
858
\def
\pack_pairedbox_halign
#
1
{
\setbox
#
1
\hpack
to
\s_pack_pairedboxes_size
{
\pack_pairedboxes_align_l
\box
#
1
\pack_pairedboxes_align_r
}
}
859 860
\def
\pack_pairedboxes_before
861
{
\ifempty
\p_location
862
\csname
\??pairedboxnature
\v!left
\endcsname
863
\csname
\??pairedboxalign
\v!middle
\endcsname
864
\else
865
\getfromcommacommand
[
\p_location
]
[
1
]
%
866
\csname
\??pairedboxnature
867
\ifcsname
\??pairedboxnature
\commalistelement
\endcsname
\commalistelement
\else
\v!left
\fi
868
\endcsname
869
\getfromcommacommand
[
\p_location
]
[
2
]
%
870
\csname
\??pairedboxalign
871
\ifcsname
\??pairedboxalign
\commalistelement
\endcsname
\commalistelement
\else
\v!middle
\fi
872
\endcsname
873
\fi
}
874 875
\def
\pack_pairedboxes_between
876
{
\usebodyfontparameter
\pairedboxparameter
877
\setbox
\b_pack_pairedboxes_first
\box
\nextbox
878
\ifconditional
\c_pack_pairedboxes_horizontal
879
\pack_pairedboxes_between_horizontal
880
\else
881
\pack_pairedboxes_between_vertical
882
\fi
883
\ifnum
\p_n
>
\plusone
884
\setrigidcolumnhsize
\hsize
{
\pairedboxparameter
\c!distance
}
\p_n
885
\fi
}
886 887
\def
\pack_pairedboxes_between_horizontal
888
{
\scratchdistance
\pairedboxparameter
\c!distance
889
\scratchwidth
\pairedboxparameter
\c!maxwidth
\relax
890
\setlocalhsize
891
\hsize
\dimexpr
\availablehsize
-
\wd
\b_pack_pairedboxes_first
-
\scratchdistance
\relax
892
\hsize
\pairedboxparameter
\c!width
\relax
% can be \hsize
893
\scratchdimen
\dimexpr
\wd
\b_pack_pairedboxes_first
+
\scratchdistance
\relax
894
\ifdim
\dimexpr
\hsize
+
\scratchdimen
\relax
>
\scratchwidth
895
\hsize
\dimexpr
\scratchwidth
-
\scratchdimen
\relax
896
\fi
}
897 898
\def
\pack_pairedboxes_between_vertical
899
{
\scratchwidth
\pairedboxparameter
\c!maxwidth
\relax
900
\hsize
\wd
\b_pack_pairedboxes_first
901
\hsize
\pairedboxparameter
\c!width
\relax
% can be \hsize
902
\ifdim
\hsize
>
\scratchwidth
\relax
903
\hsize
\scratchwidth
904
\fi
}
905 906
\def
\pack_pairedboxes_after
907
{
\setbox
\b_pack_pairedboxes_second
\vpack
908
{
\ifnum
\p_n
>
\plusone
909
\rigidcolumnbalance
\nextbox
910
\else
911
\box
\nextbox
912
\fi
}
%
913
\ifconditional
\c_pack_pairedboxes_horizontal
914
\pack_pairedboxes_pack_horizontal
915
\else
916
\pack_pairedboxes_pack_vertical
917
\fi
}
918 919
\def
\pack_pairedboxes_pack_horizontal
920
{
\dontleavehmode
\hbox
\bgroup
921
\forgetall
922
\s_pack_pairedboxes_size
\ht
923
\ifdim
\ht
\b_pack_pairedboxes_first
>
\ht
\b_pack_pairedboxes_second
924
\b_pack_pairedboxes_first
925
\else
926
\b_pack_pairedboxes_second
927
\fi
928
\vsize
\s_pack_pairedboxes_size
929
\ifdim
\s_pack_pairedboxes_size
<
\pairedboxparameter
\c!height
\relax
% can be \vsize
930
\s_pack_pairedboxes_size
\pairedboxparameter
\c!height
931
\fi
932
\ifdim
\s_pack_pairedboxes_size
>
\pairedboxparameter
\c!maxheight
\relax
933
\s_pack_pairedboxes_size
\pairedboxparameter
\c!maxheight
934
\fi
935
\pack_pairedbox_valign
\b_pack_pairedboxes_first
936
\pack_pairedbox_valign
\b_pack_pairedboxes_second
937
\pack_pairedboxes_flush
938
\egroup
}
939 940
\def
\pack_pairedboxes_pack_vertical
941
{
\dontleavehmode
\vpack
\bgroup
942
\forgetall
943
\s_pack_pairedboxes_size
\wd
944
\ifdim
\wd
\b_pack_pairedboxes_first
>
\wd
\b_pack_pairedboxes_second
945
\b_pack_pairedboxes_first
946
\else
947
\b_pack_pairedboxes_second
948
\fi
949
\pack_pairedbox_halign
\b_pack_pairedboxes_first
950
\pack_pairedbox_halign
\b_pack_pairedboxes_second
951
\s_pack_pairedboxes_size
\ht
\b_pack_pairedboxes_second
952
\vsize
\s_pack_pairedboxes_size
953
\ifdim
\ht
\b_pack_pairedboxes_second
<
\pairedboxparameter
\c!height
\relax
% can be \vsize
954
\s_pack_pairedboxes_size
\pairedboxparameter
\c!height
\relax
% \relax needed
955
\fi
956
\ifdim
\s_pack_pairedboxes_size
>
\pairedboxparameter
\c!maxheight
\relax
% todo: totale hoogte
957
\s_pack_pairedboxes_size
\pairedboxparameter
\c!maxheight
\relax
% \relax needed
958
\fi
959
\ifdim
\s_pack_pairedboxes_size
>
\ht
\b_pack_pairedboxes_second
960
\setbox
\b_pack_pairedboxes_second
\vpack
to
\s_pack_pairedboxes_size
961
{
\pack_pairedboxes_fill_top
962
\box
\b_pack_pairedboxes_second
963
\pack_pairedboxes_fill_bottom
}
% \kern\zeropoint
964
\fi
965
\pack_pairedboxes_flush
966
\egroup
}
967 968
\def
\pack_pairedboxes_inside_second
969
{
\forgetall
970
\setupalign
[
\pairedboxparameter
\c!align
]
%
971
\usepairedboxstyleandcolor
\c!style
\c!color
972
\tolerantTABLEbreaktrue
% hm.
973
\blank
[
\v!disable
]
% use fast one
974
\everypar
{
\begstrut
}
}
% also flushers here (see bTABLE)
975 976
\definepairedbox
[
\v!legend
]
977 978
\permanent
\protected
\def
\placeontopofeachother
{
\bgroup
\dowithnextboxcs
\pack_topofeachother_one
\hbox
}
979
\permanent
\protected
\def
\placesidebyside
{
\bgroup
\dowithnextboxcs
\pack_sidebyside_one
\hbox
}
980 981
\def
\pack_topofeachother_one
{
\bgroup
\setbox
\scratchboxone
\box
\nextbox
\dowithnextboxcs
\pack_topofeachother_two
\hbox
}
982
\def
\pack_sidebyside_one
{
\bgroup
\setbox
\scratchboxone
\box
\nextbox
\dowithnextboxcs
\pack_sidebyside_two
\hbox
}
983 984
\def
\pack_topofeachother_two
{
\setbox
\scratchboxtwo
\box
\nextbox
985
\halign
{
\hss
\aligncontent
\hss
\cr
\box
\scratchboxone
\cr
\box
\scratchboxtwo
\cr
}
%
986
\egroup
\egroup
}
987
\def
\pack_sidebyside_two
{
\setbox
\scratchboxtwo
\box
\nextbox
988
\valign
{
\vss
\aligncontent
\vss
\cr
\box
\scratchboxone
\cr
\box
\scratchboxtwo
\cr
}
%
989
\egroup
\egroup
}
990 991
\protect
\endinput
992