page-sid.mkiv /size: 33 Kb    last modification: 2020-07-01 14:35
1
%D \module
2
%D [ file=page-sid,
3
%D version=2000.10.20,
4
%D title=\CONTEXT\ Page Macros,
5
%D subtitle=Side Floats,
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
Page
Macros
/
Side
Floats
}
15 16
\unprotect
17 18
%D These macro deal with side floats. We started with Daniel Comenetz macros as
19
%D published in TUGBoat Volume 14 (1993), No.\ 1: Anchored Figures at Either Margin.
20
%D I extended and patched the macros to suite our needs which results in a messy
21
%D module.
22
%D
23
%D A complication is that we need to deal with spacing differently before and after
24
%D the float. Also, whitespace can interfere as does the prevdepth. There is no real
25
%D universal solution. So, by now not much is left of that code, if only because we
26
%D need to match \CONTEXT\ spacing module, because we have more placement options
27
%D and control and because the math hackery is not suitable for \CONTEXT\ anyway.
28
%D
29
%D This code had been redone many times because we kept running into spacing issues
30
%D and it's not that much fun (or rewarding). It's probably the module that made
31
%D me go into distraciton mode most often (like watching amusing Walk of The
32
%D Earth, sophisticated Massive Attack video clips, impressive Davie504 movies
33
%D and so on).
34 35
\newdimen
\d_page_sides_margin
36
\newdimen
\d_page_sides_height
% includes the topskip
37
\newdimen
\d_page_sides_width
38
\newdimen
\d_page_sides_hsize
39
\newdimen
\d_page_sides_vsize
40
\newdimen
\d_page_sides_vsize_reset
41
\newdimen
\d_page_sides_progress
42
\newdimen
\d_page_sides_page_total
43 44
\newdimen
\d_page_sides_leftoffset
45
\newdimen
\d_page_sides_rightoffset
46 47
%newbox \b_page_sides_bottom
48 49
\newcount
\c_page_sides_lines_done
50
\newcount
\c_page_sides_checks_done
51
\newcount
\c_page_sides_n_of_lines
52
\newcount
\c_page_sides_n_of_hang
53
\newconstant
\c_page_sides_float_type
54
\newcount
\c_page_sides_hangafter
55 56
\newconditional
\c_page_sides_short
57
\newconditional
\c_page_sides_flag
58 59
\newdimen
\d_page_sides_shift
60
\newdimen
\d_page_sides_extrashift
61
\newdimen
\d_page_sides_leftshift
62
\newdimen
\d_page_sides_rightshift
63
\newdimen
\d_page_sides_leftskip
64
\newdimen
\d_page_sides_rightskip
65
\newdimen
\d_page_sides_maximum
66
\newdimen
\d_page_sides_topskip
67
\newdimen
\d_page_sides_bottomskip
68
\newdimen
\d_page_sides_midskip
69
\newdimen
\d_page_sides_downshift
70
\newdimen
\d_page_sides_pagetotal
71
\newdimen
\d_page_sides_topoffset
72
\newdimen
\d_page_sides_bottomoffset
73
\newdimen
\d_page_sides_toptotal
74
\newdimen
\d_page_sides_bottomtotal
75 76
\newconstant
\c_page_sides_align
77
\newconstant
\c_page_sides_skipmode
78
\newconstant
\c_page_sides_tolerance
79 80
\newconstant
\c_page_sides_method
% sort of obsolete
81 82
\newdimen
\d_page_sides_progression
83 84
\newcount
\c_page_sides_m_of_lines
85
\newconditional
\c_page_sides_delayed
86 87
\newconditional
\c_page_sides_check_same_page
88 89
\newif
\iftracesidefloats
% public (might change)
90 91
%D Defaults:
92 93
\d_page_sides_vsize_reset
-
\onepoint
94
%d_page_sides_vsize_reset \zeropoint % could be an option, needs testing
95 96
%D We have some basic (and colorful) tracing:
97 98
\def
\page_sides_floats_legend
99
{
\showmessage
\m!floatblocks
{
1
6
}
\empty
100
\glet
\page_sides_floats_legend
\relax
}
101 102
\installtextracker
{
floats
.
anchoring
}
103
{
\page_sides_floats_legend
104
\tracesidefloatstrue
}
105
{
\tracesidefloatsfalse
}
106 107
%D The horizontal shifts depend on the location: left or right in the text, margin
108
%D or edge. These shifts are rather stable and don't interfere with the page flow
109
%D as much as the vertical ones do.
110 111
\def
\page_sides_process_float_backspace
{
\global
\c_page_sides_float_type
\plusone
\page_sides_handle_float
}
112
\def
\page_sides_process_float_leftedge
{
\global
\c_page_sides_float_type
\plustwo
\page_sides_handle_float
}
113
\def
\page_sides_process_float_leftmargin
{
\global
\c_page_sides_float_type
\plusthree
\page_sides_handle_float
}
114
\def
\page_sides_process_float_left
{
\global
\c_page_sides_float_type
\plusfour
\page_sides_handle_float
}
115
\def
\page_sides_process_float_right
{
\global
\c_page_sides_float_type
\plusfive
\page_sides_handle_float
}
116
\def
\page_sides_process_float_rightmargin
{
\global
\c_page_sides_float_type
\plussix
\page_sides_handle_float
}
117
\def
\page_sides_process_float_rightedge
{
\global
\c_page_sides_float_type
\plusseven
\page_sides_handle_float
}
118
\def
\page_sides_process_float_cutspace
{
\global
\c_page_sides_float_type
\pluseight
\page_sides_handle_float
}
119
\def
\page_sides_process_float_margin
{
\global
\c_page_sides_float_type
\pluseight
\page_sides_handle_float
}
120 121
\def
\page_sides_check_horizontal_skips
122
{
\ifcase
\c_page_sides_skipmode
123
\or
% high
124
\or
% low
125
\or
% fit
126
\global
\d_page_sides_margin
\zeropoint
127
\fi
}
128 129
\def
\page_sides_apply_horizontal_shift
130
{
\ifdim
\d_page_sides_maximum
>
\zeropoint
131
\ifcase
\c_page_sides_float_type
132
% invalid
133
\or
134
% backspace
135
\or
136
\global
\d_page_sides_shift
\dimexpr
137
-
\d_page_sides_maximum
138
-
\rightorleftpageaction
\leftedgedistance
\rightedgedistance
139
-
\rightorleftpageaction
\leftmarginwidth
\rightmarginwidth
140
-
\rightorleftpageaction
\leftmargindistance
\rightmargindistance
141
-
\compensatedinnermakeupmargin
142
\relax
143
\or
144
\global
\d_page_sides_shift
\dimexpr
145
-
\d_page_sides_maximum
146
-
\rightorleftpageaction
\leftmargindistance
\rightmargindistance
147
-
\compensatedinnermakeupmargin
148
\relax
149
\or
150
% left
151
\or
152
% right
153
\or
154
\global
\d_page_sides_shift
\dimexpr
155
-
\d_page_sides_maximum
156
-
\rightorleftpageaction
\leftmargindistance
\rightmargindistance
157
-
\compensatedinnermakeupmargin
158
\relax
159
\or
160
\global
\d_page_sides_shift
\dimexpr
161
-
\d_page_sides_maximum
162
-
\rightorleftpageaction
\leftedgedistance
\rightedgedistance
163
-
\rightorleftpageaction
\leftmarginwidth
\rightmarginwidth
164
-
\rightorleftpageaction
\leftmargindistance
\rightmargindistance
165
-
\compensatedinnermakeupmargin
166
\relax
167
\or
168
% cutspace
169
\fi
170
\fi
171
\ifdim
\d_page_sides_shift
=
\zeropoint
\relax
172
\ifnum
\c_page_sides_float_type
=
\plusfour
173
\global\advance
\d_page_sides_shift
\d_page_sides_extrashift
174
\global
\d_page_sides_extrashift
\zeropoint
175
\else\ifnum
\c_page_sides_float_type
=
\plusfive
176
\global\advance
\d_page_sides_shift
\d_page_sides_extrashift
177
\global
\d_page_sides_extrashift
\zeropoint
178
\fi\fi
179
\else
180
\ifnum
\c_page_sides_float_type
<
\plusfour
181
\global
\c_page_sides_float_type
\plusfour
182
\else\ifnum
\c_page_sides_float_type
>
\plusfive
183
\global
\c_page_sides_float_type
\plusfive
184
\fi\fi
185
\fi
}
186 187
\def
\page_sides_set_skips
188
{
\global
\d_page_sides_rightskip
\zeropoint
189
\global
\d_page_sides_leftskip
\zeropoint
190
\ifcase
\c_page_sides_float_type
191
\or
% backspace
192
\global
\d_page_sides_leftskip
\dimexpr
193
+
\rightorleftpageaction
\backspace
\cutspace
194
+
\compensatedinnermakeupmargin
195
\relax
196
\or
% leftedge
197
\global
\d_page_sides_leftskip
\dimexpr
198
+
\rightorleftpageaction
\leftmargindistance
\rightmargindistance
199
+
\rightorleftpageaction
\leftmarginwidth
\rightmarginwidth
200
+
\rightorleftpageaction
\leftedgedistance
\rightedgedistance
201
+
\compensatedinnermakeupmargin
202
\relax
203
\or
% leftmargin
204
\global
\d_page_sides_leftskip
\dimexpr
205
+
\rightorleftpageaction
\leftmargindistance
\rightmargindistance
206
+
\compensatedinnermakeupmargin
207
\relax
208
\or
% leftside
209
\or
% rightside
210
\or
% rightmargin
211
\global
\d_page_sides_rightskip
\dimexpr
212
+
\rightorleftpageaction
\rightmargindistance
\leftmargindistance
213
+
\compensatedinnermakeupmargin
214
\relax
215
\or
% rightedge
216
\global
\d_page_sides_rightskip
\dimexpr
217
+
\rightorleftpageaction
\rightmargindistance
\leftmargindistance
218
+
\rightorleftpageaction
\rightmarginwidth
\leftmarginwidth
219
+
\rightorleftpageaction
\rightedgedistance
\leftedgedistance
220
+
\compensatedinnermakeupmargin
221
\relax
222
\or
% cutspace
223
\global
\d_page_sides_rightskip
\dimexpr
224
+
\rightorleftpageaction
\cutspace
\backspace
225
+
\compensatedinnermakeupmargin
226
\relax
227
\fi
228
\global
\d_page_sides_leftoffset
\d_page_sides_rightskip
229
\global
\d_page_sides_rightoffset
\d_page_sides_leftskip
230
\ifdim
\d_page_sides_rightskip
>
\zeropoint
231
\global\advance
\d_page_sides_rightskip
\rightskip
232
\fi
233
\ifdim
\d_page_sides_leftskip
>
\zeropoint
234
\global\advance
\d_page_sides_leftskip
\leftskip
235
\fi
}
236 237
%D Shifts get applied to the float box:
238 239
\def
\page_sides_relocate_float
#
1
%
240
{
\global\setbox
\floatbox
\hpack
241
{
\ifnum
\c_page_sides_float_type
=
\plusfour
242
\kern
\d_page_sides_leftshift
243
\else\ifnum
\c_page_sides_float_type
=
\plusone
244
\kern
\d_page_sides_leftshift
245
\fi\fi
246
\ifnum
\c_page_sides_float_type
>
\plusfour
247
\kern
-
\d_page_sides_extrashift
248
\else
249
\kern
\d_page_sides_shift
250
\fi
251
\vbox
{
#
1
\ifnum
\c_page_sides_align
=
\plusfour
\removedepth
\fi
}
%
252
\ifnum
\c_page_sides_float_type
>
\plusfour
253
\kern
\d_page_sides_shift
254
\else
255
\kern
-
\d_page_sides_extrashift
256
\fi
257
\ifnum
\c_page_sides_float_type
=
\pluseight
258
\kern
\d_page_sides_rightshift
259
\else\ifnum
\c_page_sides_float_type
=
\plusfive
260
\kern
\d_page_sides_rightshift
261
\fi\fi
}}
262 263
%D The vertical skips are a nightmare and this mechanism is about as complex
264
%D as one can get it.
265 266
\def
\page_sides_check_vertical_skips
267
{
\ifdim
\d_page_sides_topskip
<
\zeropoint
\d_page_sides_topskip
\zeropoint
\fi
268
\ifdim
\d_page_sides_bottomskip
<
\zeropoint
\d_page_sides_bottomskip
\zeropoint
\fi
269
\ifdim
\d_page_sides_midskip
<
\zeropoint
\d_page_sides_midskip
\zeropoint
\fi
270
%
271
\global
\d_page_sides_toptotal
\dimexpr
\d_page_sides_topskip
+
\d_page_sides_topoffset
\relax
272
\global
\d_page_sides_bottomtotal
\dimexpr
\d_page_sides_bottomskip
+
\d_page_sides_bottomoffset
\relax
273
\ifcase
\c_page_sides_skipmode
274
\or
% high
275
\global
\d_page_sides_toptotal
\d_page_sides_topoffset
276
\or
% low
277
\global
\d_page_sides_bottomtotal
\d_page_sides_bottomoffset
278
\or
% fit
279
\global
\d_page_sides_toptotal
\d_page_sides_topoffset
280
\global
\d_page_sides_bottomtotal
\d_page_sides_bottomoffset
281
\fi
}
282 283
%D These shifts get (selectively) applied with a bit of optional tracing.
284 285
\def
\page_sides_apply_vertical_shift_normal
286
{
\global\setbox
\floatbox
\hpack
% why extra box
287
{
\vpack
288
{
\forgetall
289
\hsize\wd
\floatbox
290
\vskip
\privatescratchdimen
291
\offinterlineskip
292
\box
\floatbox
293
% somehow we need this \scratchbox magic, but at least it's the same as the
294
% tracer now
295
\setbox
\scratchbox
\emptybox
296
\wd
\scratchbox
\hsize
297
\ht
\scratchbox
\d_page_sides_bottomtotal
298
\box
\scratchbox
299
\vskip
-
\d_page_sides_bottomtotal
300
\ifnum
\c_page_sides_align
=
\plusfive
301
\vskip
-
\lineheight
302
\fi
}}}
303 304
\def
\page_sides_apply_vertical_shift_traced
305
{
\global\setbox
\floatbox
\hpack
% why extra box
306
{
\backgroundline
[
trace
:
r
]
{
\ruledhpack
{
\vpack
307
{
\forgetall
308
\hsize\wd
\floatbox
309
\vskip
\privatescratchdimen
310
\offinterlineskip
311
\backgroundline
312
[
trace
:
g
]
%
313
{
\ruledhpack
{
\box
\floatbox
}}
%
314
\par
315
\blackrule
316
[
\c!color
=
trace
:
s
,
%
317
\c!height
=
\d_page_sides_bottomtotal
,
%
318
\c!depth
=
\zeropoint
,
%
319
\c!width
=
\hsize
]
%
320
\vskip
-
\d_page_sides_bottomtotal
321
\ifnum
\c_page_sides_align
=
\plusfive
322
\vskip
-
\lineheight
323
\fi
}}}}}
324 325
\def
\page_sides_apply_vertical_shift
326
{
\ifnum
\c_page_sides_align
=
\plusfour
327
\getnoflines
{
\ht
\floatbox
}
%
328
\privatescratchdimen
\dimexpr
\noflines
\lineheight
-
\strutdp
\relax
329
\getrawnoflines
\d_page_sides_toptotal
330
\advance
\privatescratchdimen
\noflines
\lineheight
331
\page_sides_force_depth
332
\ht
\floatbox
\privatescratchdimen
333
\dp
\floatbox
\zeropoint
334
\fi
335
\ifcase
\c_page_sides_align
\else
336
\global
\d_page_sides_toptotal
\zeropoint
337
\fi
338
\privatescratchdimen
339
\ifnum
\c_page_sides_float_type
<
\plusfour
340
\d_page_sides_toptotal
341
\else\ifnum
\c_page_sides_float_type
>
\plusfive
342
\d_page_sides_toptotal
343
\else
344
\zeropoint
345
\fi\fi
346
% the top of the box is at the previous baseline
347
\ifcase
\c_page_sides_align
348
% 0 normal
349
\advance
\privatescratchdimen\strutdp
% or \openstrutdepth
350
\or
% 1 height
351
\advance
\privatescratchdimen\strutdp
% or \openstrutdepth
352
\or
% 2 line
353
\or
% 3 depth
354
\advance
\privatescratchdimen\lineheight
% or \openlineheight
355
\advance
\privatescratchdimen\strutdp
% or \openstrutdepth
356
\or
% 4 grid
357
\privatescratchdimen
\zeropoint
358
\or
359
\advance
\privatescratchdimen\strutht
% or \openstrutheight
360
\fi
361
% new
362
\global
\c_page_sides_lines_done
\zerocount
363
\ifnum
\c_page_sides_n_of_lines
>
\zerocount
364
\advance
\privatescratchdimen
\c_page_sides_n_of_lines
\lineheight
365
\fi
366
\iftracesidefloats
367
\page_sides_apply_vertical_shift_traced
% uses \privatescratchdimen
368
\else
369
\page_sides_apply_vertical_shift_normal
% uses \privatescratchdimen
370
\fi
371
\ifnum
\c_page_sides_float_type
<
\plusfour
372
\global
\d_page_sides_toptotal
\zeropoint
373
\else\ifnum
\c_page_sides_float_type
>
\plusfive
374
\global
\d_page_sides_toptotal
\zeropoint
375
\fi\fi
376
\global
\d_page_sides_downshift
\zeropoint
}
377 378
%D We have a few virtual dimensions. I'm not sure what to do with \type
379
%D {\pagedepth} and \type {\pageshrink} in the next two. If we ever need
380
%D that it will become options.
381 382
\def
\e_page_sides_flush_criterium
383
{
\dimexpr
384
\d_page_sides_vsize
385
-
\d_page_sides_bottomtotal
386
-
\pagetotal
387
\relax
}
388 389
\def
\e_page_sides_room_criterium
390
{
\dimexpr
391
\d_page_sides_vsize
392
-
\d_page_sides_bottomtotal
% added here too
393
-
\pagetotal
394
\relax
}
395 396
%D In order to get a consistent spacing we force a strutdepth unless the
397
%D preceding material has more depth than that already. This way anchoring
398
%D becomes predictable.
399 400
\unexpanded
\def
\page_sides_force_depth
401
{
\iftracesidefloats
402
\begingroup
403
\c_page_force_strut_depth_trace_mode
\plusone
404
\ifconditional
\c_page_sides_check_same_page
405
\forcestrutdepthplus
406
\else
407
\forcestrutdepth
408
\fi
409
\endgroup
410
\else
411
\ifconditional
\c_page_sides_check_same_page
412
\forcestrutdepthplus
413
\else
414
\forcestrutdepth
415
\fi
416
\fi
417
\page_otr_command_set_vsize
}
% new
418 419
\def
\page_sides_flush_floats
420
{
\par
421
\ifdim
\e_page_sides_flush_criterium
>
\zeropoint
422
\page_sides_flush_floats_progress
423
\page_sides_flush_floats_after_next
424
\fi
425
\page_sides_flush_floats_reset
}
426 427
\def
\page_sides_flush_floats_text
428
{
\par
429
% what with \c_anch_backgrounds_text_level>\plusone
430
\ifdim
\e_page_sides_flush_criterium
>
\zeropoint
431
\page_sides_flush_floats_progress
432
\page_sides_flush_floats_after_none
433
\fi
434
\page_sides_flush_floats_reset
}
435 436
\def
\page_sides_flush_floats_reset
437
{
\global
\d_page_sides_vsize
\d_page_sides_vsize_reset
438
% also here if used at all \global\holdinginserts\zerocount
439
\global
\setfalse
\c_page_sides_short
440
\global
\setfalse
\c_page_sides_flag
441
\global
\c_page_sides_checks_done
\zerocount
}
442 443
\def
\page_sides_flush_floats_after_none
% we force a flush
444
{
\ifdim
\d_page_sides_midskip
>
\zeropoint
445
\blank
[
\the
\d_page_sides_midskip
]
446
\fi
447
\ignoreparskip
448
\blank
[
\v!disable
]
}
449 450
\def
\page_sides_flush_floats_after_next
% we have two successive ones
451
{
\ifdim
\d_page_sides_bottomskip
>
\zeropoint
452
\blank
[
\the
\d_page_sides_bottomskip
]
453
\fi
454
\ignoreparskip
455
\blank
[
\v!disable
]
}
456 457
%D A rudimentary checker:
458 459
\unexpanded
\def
\doifelsesidefloat
460
{
\par
461
\ifdim
\e_page_sides_room_criterium
>
\zeropoint
% -\pagedepth
462
\expandafter
\firstoftwoarguments
463
\else
464
\expandafter
\secondoftwoarguments
465
\fi
}
466 467
\let
\doifsidefloatelse
\doifelsesidefloat
468 469
%D Sometimes we need to fill up the space alongside a side float and this
470
%D is where we define the helpers. A user can enforce a smaller step. We use
471
%D large steps when possible.
472 473
\installcorenamespace
{
sidefloatsteps
}
474 475
\setvalue
{
\??sidefloatsteps\v!line
}{
\strut
}
476
\setvalue
{
\??sidefloatsteps\v!big
}{
\strut
}
477
\setvalue
{
\??sidefloatsteps\v!medium
}{
\halflinestrut
}
% was \halfstrut
478
\setvalue
{
\??sidefloatsteps\v!small
}{
\noheightstrut
}
% was \quarterstrut
479 480
\def
\page_sides_flush_floats_tracer
481
{
\dontleavehmode
482
\ruledhpack
\bgroup
\backgroundline
[
trace
:
b
]
{
%
483
\llap
{
\smash
{
\vrule
\s!width
4
\points
\s!height
.
4
\points
\s!depth
.
4
\points
}}
%
484
\ifnum
\recurselevel
=
\plusone
485
\llap
{
\smash
{
\smallinfofont
\the
\scratchdimen
}
\hskip
.
5
\leftmargindistance
}
%
486
\else\ifodd
\recurselevel
487
\llap
{
\smash
{
\smallinfofont
\recurselevel
}
\hskip
.
5
\leftmargindistance
}
%
488
\fi\fi
489
\page_sides_flush_floats_normal
490
\kern\hsize
491
\egroup
}}
492 493
\def
\page_sides_flush_floats_normal
494
{
\ifdim
\scratchdimen
>
\htdp\strutbox
495
\strut
496
\else
497
\m_pages_strut
498
\fi
}
499 500
\def
\page_sides_flush_floats_progress
501
{
\begingroup
502
\page_sides_force_depth
503
\parskip
\zeropoint
504
\let
\page_sides_flush_floats
\relax
505
\edef
\m_pages_strut
506
{
\ifcsname
\??sidefloatsteps
\rootfloatparameter
\c!step
\endcsname
507
\lastnamedcs
508
\else
509
\noheightstrut
510
\fi
}
%
511
\forgetall
512
\offinterlineskip
513
\doloop
514
{
\scratchdimen
\e_page_sides_flush_criterium
515
\ifdim
\scratchdimen
>
\onepoint
% good enough, can become configurable
516
\ifnum
\recurselevel
>
\plushundred
% safeguard, sort of deadcycles
517
\exitloop
518
\else
\iftracesidefloats
519
\page_sides_flush_floats_tracer
\par
520
\else
521
\page_sides_flush_floats_normal
\par
522
\fi\fi
523
\else
524
\page_sides_force_depth
525
\exitloop
526
\fi
}
%
527
\endgroup
}
528 529
%D We force a parskip and ignore it afterwards. We can nil it by setting the
530
%D \type {spacebeforeside} parameter. We can have a leading blank so we need
531
%D to make sure that we use blank to inject the parskip and then ignore
532
%D the one injected by the engine.
533 534
\def
\page_sides_inject_before
535
{
\page_sides_force_depth
536
\ifdim
\parskip
>
\zeropoint
537
\ifdim
\parskip
>
\d_strc_floats_top
538
\ifdim
\d_strc_floats_top
>
\zeropoint
539
\ignoreparskip
540
\blank
[
\v!white
]
%
541
\else
542
\checkedblank
[
\rootfloatparameter
\c!spacebeforeside
]
%
543
\fi
544
\else
545
\checkedblank
[
\rootfloatparameter
\c!spacebeforeside
]
%
546
\fi
547
\else
548
\checkedblank
[
\rootfloatparameter
\c!spacebeforeside
]
%
549
\fi
}
550 551
%D We are now done with \type {spacebefore} and the parskip is already
552
%D injected. The dummy line makes sure that we anchor properly and it
553
%D also can serve as tracer.
554 555
\def
\page_sides_inject_dummy_line_normal
556
{
\hpack
to
\availablehsize
{
\strut
\hss
}}
557 558
\def
\page_sides_inject_dummy_line_traced
559
{
\ruledhpack
to
\availablehsize
{
\backgroundline
[
trace
:
c
]
{
\page_sides_inject_dummy_line_normal
}}}
560 561
\def
\page_sides_inject_dummy_lines
562
{
\par
563
\nointerlineskip
564
% \ifnum\lastpenalty>\zerocount
565
% \penalty\plustenthousand
566
% \fi
567
\dontleavehmode
568
\iftracesidefloats
569
\page_sides_inject_dummy_line_traced
570
\else
571
\page_sides_inject_dummy_line_normal
572
\fi
573
\par
574
% on an empty page we have topskip, say 12pt
575
\ignoreparskip
576
% this can be 18.5pt
577
\kern
-
\dimexpr
\lineheight
+
\strutdp
\relax
578
% so we can actually have a -2.5pt skip on top
579
\ignoreparskip
580
\blank
[
\v!samepage
]
581
\blank
[
\v!disable
]
582
% now say we are negative now
583
\ifdim
\pagetotal
<
\zeropoint
584
% then we're at the top of the page ... quite messy .. i really need to
585
% make the page builder a bit more flexible .. should we do something now?
586
\fi
}
587 588
%D Checkers:
589 590
\def
\page_sides_check_floats_after_par
591
{
\page_sides_check_floats_indeed
592
\ifdim
\d_page_sides_pagetotal
=
\pagetotal
\else
593
\glet
\page_sides_check_floats
\page_sides_check_floats_indeed
594
\page_sides_flush_floats
595
\global
\c_page_sides_n_of_lines
\zerocount
% here !
596
\fi
}
597 598
\unexpanded
\def
\page_sides_flush_floats_after_par
599
{
\global
\d_page_sides_pagetotal
\pagetotal
600
\glet
\page_sides_check_floats
\page_sides_check_floats_after_par
}
601 602
\unexpanded
\def
\page_sides_forget_floats
603
{
\global
\d_page_sides_vsize
\d_page_sides_vsize_reset
604
\global
\c_page_sides_n_of_lines
\zerocount
605
% also here if used at all \global\holdinginserts\zerocount
606
\global
\setfalse
\c_page_sides_short
607
\global
\setfalse
\c_page_sides_flag
}
608 609
%D Here comes the output routine. We either go the fast route or we use the
610
%D normal one (stored in \type {\page_otr_command_side_float_output}. We no
611
%D longer have this fuzzy code around with penalties and indentation and
612
%D such.
613 614
\def
\page_sides_output_routine
615
{
\page_otr_command_side_float_output
616
\ifconditional
\c_page_sides_short
617
\global
\setfalse
\c_page_sides_short
618
\else
619
\global
\d_page_sides_vsize
\d_page_sides_vsize_reset
620
\global
\c_page_sides_n_of_lines
\zerocount
621
\fi
}
622 623
\def
\page_sides_place_float
624
{
\ifnum
\c_page_sides_float_type
=
\plusfour
\kern
\d_page_sides_toptotal
\fi
625
\ifnum
\c_page_sides_float_type
=
\plusfive
\kern
\d_page_sides_toptotal
\fi
626
\ifgridsnapping
627
\page_sides_place_float_grid
628
\else
629
\page_sides_place_float_normal
630
\fi
631
\par
632
\kern
-
\d_page_sides_height
633
\penalty
1
0
0
0
1
% oeps, this will change
634
\normalbaselines
}
635 636
\def
\page_sides_place_float_normal
637
{
\page_sides_push_float_inline
\firstofoneargument
}
638 639
%D The following needs some more work .. consider this a quick hack. We probably
640
%D need an mkiv hanging grid option.
641 642
\def
\page_sides_place_snap_to_grid
#
1
%
643
{
\edef
\p_grid
{
\floatparameter
\c!grid
}
%
644
\ifx
\p_grid
\empty
\else
645
\snaptogrid
[
\p_grid
]
%
646
\fi
647
\hpack
{
#
1
}}
648 649
\def
\page_sides_place_float_grid
650
{
\getrawnoflines
\d_page_sides_height
% raw ?
651
\d_page_sides_height
\noflines
\lineheight
652
\page_sides_push_float_inline
\page_sides_place_snap_to_grid
}
653 654
\let
\strc_floats_mark_par_as_free
\relax
655 656
\def
\page_sides_push_float_inline
#
1
%
657
{
\begingroup
658
\reseteverypar
% needed !
659
\parskip
\zeropoint
% needed !
660
\nointerlineskip
661
\page_sides_set_skips
662
\page_floats_report_total
663
\relax
664
\lefttoright
665
\strc_floats_mark_par_as_free
666
\ifcase
\c_page_sides_float_type
667
% invalid
668
\or
% backspace
669
\noindent
#
1
{
\llap
{
\rlap
{
\box
\floatbox
}
\kern
\d_page_sides_leftskip
}}
\hfill
670
\or
% leftedge
671
\noindent
#
1
{
\llap
{
\box
\floatbox
\kern
\d_page_sides_leftskip
}}
\hfill
672
\or
% leftmargin
673
\noindent
#
1
{
\llap
{
\box
\floatbox
\kern
\d_page_sides_leftskip
}}
\hfill
674
\or
% leftside
675
\noindent
#
1
{
\box
\floatbox
}
\hfill
676
\or
% rightside
677
\hfill
#
1
{
\box
\floatbox
}
%
678
\or
% rightmargin
679
\hfill
#
1
{
\rlap
{
\kern
\d_page_sides_rightskip
\box
\floatbox
}}
%
680
\or
% rightedge
681
\hfill
#
1
{
\rlap
{
\kern
\d_page_sides_rightskip
\box
\floatbox
}}
%
682
\or
% cutspace
683
\hfill
#
1
{
\rlap
{
\kern
\d_page_sides_rightskip
\llap
{
\box
\floatbox
}}}
%
684
\fi
685
\endgroup
}
686 687
% \def\page_sides_analyse_progress
688
% {\d_page_sides_progress\d_page_sides_vsize
689
% \ifconditional\c_page_sides_flag
690
% \advance\d_page_sides_progress-\d_page_sides_page_total
691
% \global\setfalse\c_page_sides_flag
692
% \else
693
% \advance\d_page_sides_progress-\pagetotal
694
% \fi}
695 696
% test case
697
%
698
% \usemodule[art-01]
699
% \starttext
700
% \dorecurse{40}{\line{#1}}
701
% \placefigure[left]{}{}
702
% \input ward
703
% \startitemize
704
% \item word \item word \item word \item word
705
% \stopitemize
706
% \input ward
707
% \page
708
% \stoptext
709 710
\def
\page_sides_analyse_progress
711
{
%\page_otr_command_set_vsize % this is new, otherwise topfloats are not taken into account
712
\d_page_sides_progress
\d_page_sides_vsize
713
\ifconditional
\c_page_sides_flag
714
\advance
\d_page_sides_progress
-
\d_page_sides_page_total
715
\global
\setfalse
\c_page_sides_flag
716
\else
717
\ifdim
\dimexpr
\d_page_sides_progress
+
\d_page_sides_bottomtotal
\relax
>
\pagegoal
718
% we adapt pagegoal because we can already have placed something with
719
% everypar and we hope that it triggers a flush, see test above
720
\pagegoal\dimexpr\pagegoal
-
\d_page_sides_bottomtotal
\relax
721
\fi
722
\advance
\d_page_sides_progress
-
\pagetotal
723
\fi
}
724 725
\def
\page_sides_analyse_space_stage_one
726
{
\global
\settrue
\c_page_sides_flag
727
% \ifdim\pagegoal=\maxdimen
728
% \pagegoal\textheight % maybe
729
% \fi
730
\global
\d_page_sides_page_total
\pagetotal
% global
731
\ifnum
\c_page_sides_float_type
<
\plusfour
732
\global
\d_page_sides_width
\zeropoint
733
\else\ifnum
\c_page_sides_float_type
>
\plusfive
734
\global
\d_page_sides_width
\zeropoint
735
\else
736
\global
\d_page_sides_width
\dimexpr\wd
\floatbox
+
\d_page_sides_margin
\relax
737
\fi\fi
738
\ifdim
\d_page_sides_width
<
\zeropoint
739
\global
\d_page_sides_width
\zeropoint
740
\fi
741
\global
\d_page_sides_hsize
\dimexpr\hsize
-
\d_page_sides_width
\relax
742
\global
\d_page_sides_height
\dimexpr\ht
\floatbox
+
\dp
\floatbox
+
\d_page_sides_toptotal
\relax
743
\global
\d_page_sides_vsize
\dimexpr
\d_page_sides_height
+
\d_page_sides_page_total
\relax
744
\scratchdimenone
\d_page_sides_vsize
745
\scratchdimentwo
\pagegoal
746
\ifcase
\c_page_sides_tolerance
747
\ifcase
\c_page_sides_method
748
% method 0 : raw
749
\or
750
% method 1 : safe (default)
751
\advance
\scratchdimentwo
-
\strutdp
752
\or
753
% method 2 : tight (grid default)
754
\advance
\scratchdimenone
-
\onepoint
755
\fi
756
\or
757
% tolerant
758
\advance
\scratchdimentwo
-
.
5
\strutdp
759
\or
760
% verytolerant
761
% \advance\scratchdimenone -\onepoint (maybe)
762
\else
763
\advance
\scratchdimentwo
-
\strutdp
764
\fi
}
765 766
\def
\page_sides_analyse_space_stage_two
767
{
% how about \pagedepth
768
\ifdim
\scratchdimenone
>
\scratchdimentwo
769
\global
\setfalse
\c_page_floats_room
770
\else
771
\ifdim
\dimexpr\pagegoal
-
\d_page_sides_vsize
\relax
<
\d_page_sides_bottomtotal
772
% just weird: \global\advance\d_page_sides_vsize \scratchdimenone
773
\global
\settrue
\c_page_sides_short
774
% why was this \global\holdinginserts\plusone
775
\else
776
\global\advance
\d_page_sides_vsize
\d_page_sides_bottomtotal
% wins over inbetween
777
\global
\setfalse
\c_page_sides_short
778
\fi
779
\global
\settrue
\c_page_floats_room
780
\fi
}
781 782
\def
\page_sides_analyse_space
783
{
\page_sides_analyse_space_stage_one
784
\ifconditional
\c_page_sides_check_same_page
785
\ifdim
\d_spac_prevcontent
>
\zeropoint
786
\ifdim
\dimexpr
\scratchdimenone
+
\d_spac_prevcontent
>
\scratchdimentwo
787
\clf_pushatsame
788
\setbox
\scratchbox
\vpack
{
\clf_popatsame
}
%
789
\page
790
\box
\scratchbox
791
\vskip
-
\lineskip
792
\page_sides_analyse_space_stage_one
793
\fi
794
\fi
795
\fi
796
\page_sides_analyse_space_stage_two
}
797 798
%D As we have no clear end of one or more paragraphs we only have pre float
799
%D skips.
800 801
\newconstant
\c_page_sides_page_method
% will be: \c_page_sides_page_method\plusone
802 803
\def
\page_otr_force_new_page_one
804
{
\vskip
\d_page_sides_height
805
\penalty\outputpenalty
806
\vskip
-
\dimexpr
\d_page_sides_height
-
\strutdp
\relax
807
\prevdepth
\strutdp
}
808
%\ignoreparskip}
809 810
\def
\page_sides_handle_float
#
1
%
811
{
\page_sides_initialize_checker
812
\page_sides_check_horizontal_skips
813
\page_sides_check_vertical_skips
814
\page_sides_apply_horizontal_shift
815
\page_sides_check_previous_float
816
\page_sides_inject_before
817
\page_sides_inject_dummy_lines
818
\page_sides_relocate_float
{
#
1
}
%
819
\page_sides_apply_vertical_shift
820
\page_sides_analyse_space
821
\ifconditional
\c_page_floats_room
822
\global
\setfalse
\c_page_sides_delayed
823
% we're ok
824
\else
825
\global
\settrue
\c_page_sides_delayed
826
\global
\c_page_sides_m_of_lines
\c_page_sides_n_of_lines
827
\ifcase
\c_page_sides_page_method
828
\page_otr_fill_and_eject_page
829
\or
830
\page_otr_force_new_page_one
831
\else
832
\page_otr_fill_and_eject_page
833
\fi
834
\global
\c_page_sides_n_of_lines
\c_page_sides_m_of_lines
835
\page_sides_analyse_space
836
%\page_sides_inject_before
837
\page_sides_inject_dummy_lines
838
\fi
839
\page_sides_place_float
840
\global
\setfalse
\c_page_sides_delayed
841
\page_sides_check_floats_reset
842
\page_sides_wrapup
}
843 844
\def
\page_sides_wrapup
845
{
% we need to do this aftergroup
846
\aftergroup\par
847
\aftergroup
\ignoreparskip
848
\aftergroup\ignorespaces
}
849 850
\def
\page_sides_check_floats_indeed
851
{
\page_sides_analyse_progress
852
\ifdim
\d_page_sides_progress
>
\zeropoint
853
\page_sides_check_floats_set
854
\else
855
\page_sides_check_floats_reset
856
\fi
857
\parskip
\s_spac_whitespace_parskip
}
% not needed
858 859
% \let\page_sides_check_floats\page_sides_check_floats_indeed
860 861
\let
\page_sides_check_floats
\relax
862 863
\def
\page_sides_initialize_checker
864
{
\ifx
\page_sides_check_floats
\relax
865
\glet
\page_sides_check_floats
\page_sides_check_floats_indeed
866
\clf_enablesidefloatchecker
867
\glet
\page_sides_initialize_checker
\relax
868
\fi
}
869 870
\unexpanded
\def
\page_sides_check_floats_tracer
871
{
\begingroup
872
\dontleavehmode
873
\ifnum
\c_page_sides_float_type
>
\plusfour
874
\rlap
875
{
\hskip
\availablehsize
% d_page_sides_width % kern
876
\color
[
trace
:
o
]
%
877
{
\rlap
{
\kern
.
2
5
\bodyfontsize\showstruts\strut
}
%
878
\vrule
\s!height
.
5
\points
\s!depth
.
5
\points
\s!width
\d_page_sides_width
}}
%
879
\else
880
\hskip
-
\d_page_sides_width
% kern
881
\color
[
trace
:
o
]
%
882
{
\vrule
\s!height
.
5
\points
\s!depth
.
5
\points
\s!width
\d_page_sides_width
883
\llap
{
\showstruts\strut
\kern
.
2
5
\bodyfontsize
}}
%
884
\fi
885
\endgroup
}
886 887
% tricky test:
888 889
% \starttext
890
% \dorecurse{33}{\line{#1}}
891
% \placefigure[left]{}{}
892
% \input ward
893
% \startitemize
894
% \item word \item word \item word \item word
895
% \stopitemize
896
% \input ward
897
% \page
898
% \placefigure[left]{}{}
899
% \dontleavehmode \begingroup \input ward \par \endgroup
900
% \dontleavehmode \begingroup \input ward \par \endgroup
901
% \dontleavehmode \begingroup \input ward \par \endgroup
902
% \input ward
903
% \stoptext
904 905
\unexpanded
\def
\page_sides_check_floats_set
906
{
\edef
\p_sidethreshold
{
\floatparameter
\c!sidethreshold
}
%
907
\ifconditional
\c_page_sides_delayed
908
% For Alan's hanging right float that moved to the next page.
909
\d_page_sides_progress
\zeropoint
910
\fi
911
\ifx
\p_sidethreshold
\v!old
912
\d_page_sides_progression
\dimexpr
\d_page_sides_progress
+
\strutht
-
\roundingeps
\relax
913
\c_page_sides_n_of_hang
\d_page_sides_progression
914
\divide
\c_page_sides_n_of_hang
\baselineskip\relax
915
\else
916
\d_page_sides_progression
917
\ifx
\p_sidethreshold
\empty
918
\d_page_sides_progress
919
\else
920
\dimexpr
\d_page_sides_progress
-
\p_sidethreshold
\relax
921
\fi
922
\getnoflines
\d_page_sides_progression
923
% this can be an option
924
\ifdim
\dimexpr
\noflines
\lineheight
>
\dimexpr\pagegoal
-
\pagetotal\relax
925
\getrawnoflines
\d_page_sides_progression
926
\fi
927
%
928
\c_page_sides_n_of_hang
\noflines
929
\fi
930
\global
\c_page_sides_hangafter
\zerocount
931
\ifnum
\c_page_sides_n_of_hang
>
\zerocount
932
\ifcase
\c_page_sides_n_of_lines
933
\else
934
\ifcase
\c_page_sides_lines_done
935
\global
\c_page_sides_lines_done
\c_page_sides_n_of_hang
936
\else
937
\privatescratchcounter
\c_page_sides_lines_done
938
\advance
\privatescratchcounter
-
\c_page_sides_n_of_hang
939
\global\advance
\c_page_sides_n_of_lines
-
\privatescratchcounter
940
\fi
941
\fi
942
\ifnum
\c_page_sides_n_of_lines
>
\zerocount
943
\privatescratchtoks
\emptytoks
944
\privatescratchcounter
\c_page_sides_n_of_lines
945
\privatescratchdimen
\dimexpr\hsize
-
\d_page_sides_width
\relax
946
\dorecurse
\c_page_sides_n_of_lines
947
{
\toksapp
\privatescratchtoks
{
\zeropoint
\hsize
}}
%
948
\ifnum
\c_page_sides_n_of_hang
>
\c_page_sides_n_of_lines
949
\advance
\c_page_sides_n_of_hang
-
\c_page_sides_n_of_lines
\relax
950
\advance
\privatescratchcounter
\c_page_sides_n_of_hang
951
\dorecurse
\c_page_sides_n_of_hang
% weird, shouldn't that be scratchcounter
952
{
\ifnum
\c_page_sides_float_type
>
\plusfour
953
\toksapp
\privatescratchtoks
{
\zeropoint
\privatescratchdimen
}
%
954
\else
955
\toksapp
\privatescratchtoks
{
\d_page_sides_width
\privatescratchdimen
}
%
956
\fi
}
%
957
\fi
958
\parshape
959
\numexpr
\privatescratchcounter
+
\plusone
\relax
960
\the
\privatescratchtoks
961
\zeropoint
\hsize
962
\relax
963
\else
964
\hangindent
\ifnum
\c_page_sides_float_type
>
\plusfour
-
\fi
\d_page_sides_width
965
\hangafter
-
\c_page_sides_n_of_hang
966
\global
\c_page_sides_hangafter
\hangafter
967
\fi
968
\fi
969
\global\advance
\c_page_sides_checks_done
\plusone
970
\iftracesidefloats
971
\page_sides_check_floats_tracer
972
\fi
}
973 974
\unexpanded
\def
\page_sides_check_floats_reset
975
{
\ifcase
\c_page_sides_checks_done
\else
976
\ifcase
\c_page_sides_hangafter
\else
977
% we need to deal with par's ending in a group which would restore
978
% hang parameters
979
\global
\c_page_sides_hangafter
\zerocount
980
\hangindent
\zeropoint
981
\fi
982
% \global % no, otherwise a next hangindent won't work
983
\c_page_sides_checks_done
\zerocount
984
\fi
}
985 986
\unexpanded
\def
\page_sides_synchronize_floats
987
{
\ifinner
\else
988
\page_sides_check_floats
989
\fi
}
990 991
\unexpanded
\def
\page_sides_check_previous_float
992
{
\page_sides_analyse_progress
993
\ifdim
\d_page_sides_progress
>
\zeropoint
\relax
994
\ifconditional
\c_page_sides_short
995
\global
\setfalse
\c_page_sides_short
996
\page_otr_fill_and_eject_page
997
\else
998
\kern
\d_page_sides_progress
999
\fi
1000
\fi
}
1001 1002
% \def\adjustsidefloatdisplaylines % public, will change
1003
% {\aftergroup\page_sides_adjust_display_lines}
1004
%
1005
% \def\page_sides_adjust_display_lines
1006
% {\par
1007
% \noindent
1008
% \ignorespaces}
1009 1010
%D We need to hook it into the other otr's. This code will be adapted once we rename
1011
%D the callers. We use \type {\def} as they can be redefined! Some will become obsolete
1012 1013
\unexpanded
\def
\checksidefloat
{
\page_sides_check_floats
}
1014
\unexpanded
\def
\flushsidefloats
{
\page_sides_flush_floats_text
}
1015
\unexpanded
\def
\flushsidefloatsafterpar
{
\page_sides_flush_floats_after_par
}
1016
\unexpanded
\def
\forgetsidefloats
{
\page_sides_forget_floats
}
1017
%unexpanded\def\synchronizesidefloats {\page_sides_synchronize_floats}
1018 1019
\protect
\endinput
1020