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