spac-ver.mkiv /size: 79 Kb    last modification: 2020-07-01 14:35
1
%D \module
2
%D [ file=spac-ver,
3
%D version=2009.10.16, % 1997.03.31, was core-spa.tex
4
%D title=\CONTEXT\ Spacing Macros,
5
%D subtitle=Vertical,
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
Spacing
Macros
/
Vertical
}
15 16
\unprotect
17 18
\registerctxluafile
{
spac
-
ver
}{
optimize
}
19 20
% todo: use usernodes ?
21 22
% todo: itemize : intro ... only when there is one or two lines preceding and then
23
% keep these together i.e. \blank[intro]
24 25
% Isn't it about time to get rid of topskip i.e. make it equivalent to
26
% \openstrutheight so that we can remove delta code.
27
%
28
% There might be more namespace protection.
29 30
%D There are two ways to influence the interline spacing. The most general and often
31
%D most consistent way is using
32
%D
33
%D \showsetup{setupinterlinespace}
34
%D
35
%D For instance
36
%D
37
%D \starttyping
38
%D \setupinterlinespace[line=2.8ex]
39
%D \stoptyping
40
%D
41
%D This setting adapts itself to the bodyfontsize, while for instance saying
42
%D
43
%D \starttyping
44
%D \setupinterlinespace[line=12pt]
45
%D \stoptyping
46
%D
47
%D sets things fixed for all sizes, which is definitely not what we want. Therefore
48
%D one can also say:
49
%D
50
%D \starttyping
51
%D \definebodyfontenvironment[9pt][interlinespace=11pt]
52
%D \stoptyping
53
%D
54
%D One can still use \type {\setupinterlinespace} (without arguments) to set the
55
%D interline space according to the current font, e.g. a \type {\bfa}.
56 57
% will be cleaned up but it will stay messy because we accept so
58
% many variants
59 60
\newif
\iflocalinterlinespace
61 62
\newskip
\s_spac_vspacing_temp
\s_spac_vspacing_temp
\bigskipamount
63 64
\def
\skipfactor
{
.
7
5
}
65
\def
\skipgluefactor
{
.
2
5
}
66 67
\def
\normalskipamount
68
{
\openlineheight
69
\ifgridsnapping
\else
\ifblankflexible
70
\s!plus
\skipgluefactor
\openlineheight
71
\s!minus
\skipgluefactor
\openlineheight
72
\fi
\fi
73
\relax
}
74 75
\ifdefined
\bodyfontinterlinespace
\else
76
\let
\bodyfontinterlinespace
\empty
77
\fi
78 79
\unexpanded
\def
\presetnormallineheight
% each bodyfont
80
{
\edef
\normallineheight
{
\interlinespaceparameter
\c!line
}
%
81
\iflocalinterlinespace
\else
82
\edef
\m_spac_normallineheight
{
\bodyfontinterlinespace
}
%
83
\ifx
\m_spac_normallineheight
\empty
\else
84
\let
\normallineheight
\m_spac_normallineheight
85
\fi
86
\fi
}
87 88
\unexpanded
\def
\setupspecifiedinterlinespace
[#
1
]
%
89
{
\setupcurrentinterlinespace
[#
1
]
%
90
\spac_linespacing_setup_specified_interline_space
}
91 92
\def
\spac_linespacing_setup_specified_interline_space
93
{
\edef
\strutheightfactor
{
\interlinespaceparameter
\c!height
}
%
94
\edef
\strutdepthfactor
{
\interlinespaceparameter
\c!depth
}
%
95
\edef
\minimumstrutheight
{
\interlinespaceparameter
\c!minheight
}
%
96
\edef
\minimumstrutdepth
{
\interlinespaceparameter
\c!mindepth
}
%
97
\edef
\minimumlinedistance
{
\interlinespaceparameter
\c!distance
}
%
98
\edef
\normallineheight
{
\interlinespaceparameter
\c!line
}
%
99
\edef
\topskipfactor
{
\interlinespaceparameter
\c!top
}
%
100
\edef
\maxdepthfactor
{
\interlinespaceparameter
\c!bottom
}
%
101
\edef
\m_spac_vertical_baseline_stretch_factor
{
\interlinespaceparameter
\c!stretch
}
%
102
\edef
\m_spac_vertical_baseline_shrink_factor
{
\interlinespaceparameter
\c!shrink
}
%
103
% often topskip does more bad than good, so:
104
\ifx
\topskipfactor
\v!height
105
\let
\topskipfactor
\strutheightfactor
106
\fi
107
\setfontparameters
% redundant, can be \setstrut, test first
108
\updateraggedskips
}
% yes indeed
109 110
\installcorenamespace
{
interlinespacerelative
}
111 112
\let
\setrelativeinterlinespace
\relax
% used elsewhere
113
\let
\currentrelativeinterlinespace
\empty
114 115
\setvalue
{
\??interlinespacerelative\v!on
}{
\oninterlineskip
}
116
\setvalue
{
\??interlinespacerelative\v!off
}{
\offinterlineskip
}
117
\setvalue
{
\??interlinespacerelative\v!reset
}{
\let
\currentrelativeinterlinespace
\empty
118
\let
\setrelativeinterlinespace
\relax
119
\setfontparameters
}
120
\setvalue
{
\??interlinespacerelative\v!auto
}{
\let
\setrelativeinterlinespace
\spac_linespacing_set_relative_interlinespace
}
121 122
\def
\spac_linespacing_set_specified_relative_interlinespace
#
1
% fragile?
123
{
\doifelsedimenstring
{
#
1
}
124
{
\setupspecifiedinterlinespace
[
\c!line
=#
1
]
}
125
{
\assignvalue
{
#
1
}
\currentrelativeinterlinespace
{
1
.
0
0
}{
1
.
2
5
}{
1
.
5
0
}
%
126
\spacing
\currentrelativeinterlinespace
}}
127 128
\unexpanded
\def
\setuprelativeinterlinespace
[#
1
]
%
129
{
\processcommalist
[#
1
]
\spac_linespacing_setup_relative_interlinespace
}
130 131
\def
\spac_linespacing_setup_relative_interlinespace
#
1
%
132
{
\ifcsname
\??interlinespacerelative
#
1
\endcsname
133
\lastnamedcs
134
\else
135
\spac_linespacing_set_specified_relative_interlinespace
{
#
1
}
%
136
\fi
}
137 138
\def
\spac_linespacing_set_relative_interlinespace
139
{
\ifx
\currentrelativeinterlinespace
\empty
\else
140
\spacing
\currentrelativeinterlinespace
141
\fi
}
142 143
\unexpanded
\def
\spac_linespacing_setup_use
144
{
\ifcsname
\namedinterlinespacehash
\m_spac_interlinespace
\s!parent
\endcsname
145
\let
\currentinterlinespace
\m_spac_interlinespace
146
\spac_linespacing_setup_specified_interline_space
147
% \else
148
% we only support named interlinespaces
149
\fi
}
150 151
\unexpanded
\def
\useinterlinespaceparameter
#
1
% see footnotes
152
{
\edef
\m_spac_interlinespace
{
#
1
\c!interlinespace
}
%
153
\ifx
\m_spac_interlinespace
\empty
\else
154
\spac_linespacing_setup_use
155
\fi
}
156 157
\newtoks
\everysetupglobalinterlinespace
158
\newtoks
\everysetuplocalinterlinespace
159 160
\newconditional
\interlinespaceisset
161 162
\installcorenamespace
{
interlinespace
}
163 164
\installcommandhandler
\??interlinespace
{
interlinespace
}
\??interlinespace
165 166
\installmacrostack
\currentinterlinespace
167 168
\unexpanded
\def
\setupinterlinespace
169
{
\dodoubleempty
\spac_linespacing_setup
}
170 171
\ifdefined
\setupinterlinespace_double
\else
172
\let
\setupinterlinespace_double
\setup_interlinespace
% for a while
173
\fi
174 175
\def
\spac_linespacing_setup
[#
1
][#
2
]
%
176
{
\settrue
\interlinespaceisset
% reset has to be done when needed
177
\ifsecondargument
178
\setupinterlinespace_double
[#
1
][#
2
]
%
179
\else
\iffirstargument
180
\ifcsname
\namedinterlinespacehash
{
#
1
}
\s!parent
\endcsname
181
\edef
\currentinterlinespace
{
#
1
}
%
182
\spac_linespacing_setup_specified_interline_space
183
%\dosetupspecifiedinterlinespaceindeed
184
\else
185
\spac_linespacing_setup_specified_or_relative
[#
1
]
%
186
\fi
187
\else
188
\let
\currentinterlinespace
\empty
189
\spac_linespacing_synchronize_local
190
\fi\fi
}
191 192
\def
\spac_linespacing_setup_specified_or_relative
[#
1
]
%
193
{
\doifelseassignment
{
#
1
}
\setupspecifiedinterlinespace
\setuprelativeinterlinespace
[#
1
]
%
194
\the
\iflocalinterlinespace
\everysetuplocalinterlinespace
\else
\everysetupglobalinterlinespace
\fi
}
195 196
\def
\spac_linespacing_synchronize_local
% adapts to the font
197
{
\localinterlinespacetrue
198
\setfontparameters
199
\updateraggedskips
% funny one here
200
\the
\everysetuplocalinterlinespace
201
\localinterlinespacefalse
}
202 203
\unexpanded
\def
\dosetupcheckedinterlinespace
#
1
% often a chain
204
{
\edef
\p_spac_checked_interlinespace
{
#
1
}
%
205
\ifx
\p_spac_checked_interlinespace
\empty
206
\spac_linespacing_synchronize_local
207
\else\ifcsname
\namedinterlinespacehash
\p_spac_checked_interlinespace
\s!parent
\endcsname
% we could have a \s!check
208
\push_macro_currentinterlinespace
209
\let
\currentinterlinespace
\p_spac_checked_interlinespace
210
\spac_linespacing_setup_specified_interline_space
% \dosetupspecifiedinterlinespaceindeed
211
\iflocalinterlinespace
212
\the
\everysetuplocalinterlinespace
213
\else
214
\localinterlinespacetrue
215
\the
\everysetuplocalinterlinespace
216
\localinterlinespacefalse
217
\fi
218
\pop_macro_currentinterlinespace
219
\else
220
\normalexpanded
{
\noexpand
\doifelseassignment
{
\p_spac_checked_interlinespace
}
%
221
\setupspecifiedinterlinespace
\setuprelativeinterlinespace
[
\p_spac_checked_interlinespace
]
}
%
222
\iflocalinterlinespace
223
\the
\everysetuplocalinterlinespace
224
\else
225
\localinterlinespacetrue
226
\the
\everysetuplocalinterlinespace
227
\localinterlinespacefalse
228
\fi
229
\fi\fi
}
230 231
\unexpanded
\def
\setuplocalinterlinespace
[#
1
]
%
232
{
\localinterlinespacetrue
233
\push_macro_currentinterlinespace
234
\setupinterlinespace
[#
1
]
%
235
\pop_macro_currentinterlinespace
236
\localinterlinespacefalse
}
237 238
\let
\switchtointerlinespace\setuplocalinterlinespace
239 240
%D Helpers
241 242
\newskip
\s_spac_lastskip
243
\newdimen
\d_spac_prevdepth
244
\newcount
\c_spac_spacefactor
245
\newdimen
\d_spac_prevcontent
% set by lua
246 247
\unexpanded
\def
\removelastskip
248
{
\ifvmode\ifzeropt
\lastskip\else\vskip
-
\lastskip\fi\fi
}
249 250
\def
\doifoutervmode
251
{
\ifvmode
252
\ifinner
253
\doubleexpandafter\gobbleoneargument
254
\else
255
\doubleexpandafter\firstofoneargument
256
\fi
257
\else
258
\expandafter
\gobbleoneargument
259
\fi
}
260 261
\unexpanded
\def
\dosomebreak
#
1
%
262
{
\doifoutervmode
263
{
\s_spac_lastskip
\lastskip
264
\removelastskip
265
#
1
\relax
266
\ifzeropt
\s_spac_lastskip
267
% avoid interference with footnotes
268
\else
269
\vskip
\s_spac_lastskip
270
\fi
}}
271 272
\unexpanded
\def
\packed
273
{
\nointerlineskip
}
274 275
\unexpanded
\def
\godown
[#
1
]
%
276
{
\relax
277
\ifhmode
\endgraf
\fi
278
\ifvmode
\nointerlineskip
\vskip
#
1
\relax\fi
}
279 280
\unexpanded
\def
\smallskip
{
\vskip
\smallskipamount
}
281
\unexpanded
\def
\medskip
{
\vskip
\medskipamount
}
282
\unexpanded
\def
\bigskip
{
\vskip
\bigskipamount
}
283 284
\unexpanded
\def
\smallbreak
285
{
\par
286
\ifvmode\ifdim
\lastskip
<
\smallskipamount
287
\removelastskip
288
\penalty
-
\plusfifty
289
\smallskip
290
\fi\fi
}
291 292
\unexpanded
\def
\medbreak
293
{
\par
294
\ifvmode\ifdim
\lastskip
<
\medskipamount
295
\removelastskip
296
\penalty
-
\plusonehundred
297
\medskip
298
\fi\fi
}
299 300
\unexpanded
\def
\bigbreak
301
{
\par
302
\ifvmode\ifdim
\lastskip
<
\bigskipamount
303
\removelastskip
304
\penalty
-
\plustwohundred
305
\bigskip
306
\fi\fi
}
307 308
\unexpanded
\def
\break
{
\penalty
-
\plustenthousand
}
% can be hmode or vmode
309
\unexpanded
\def
\nobreak
{
\penalty
\plustenthousand
}
% can be hmode or vmode
310
\unexpanded
\def
\allowbreak
{
\penalty
\zerocount
}
% can be hmode or vmode
311 312
\unexpanded
\def
\goodbreak
{
\par\ifvmode\penalty
-
\plusfivehundred
\relax\fi
}
% forces vmode
313
\unexpanded
\def
\filbreak
{
\par\ifvmode\vfil\penalty
-
\plustwohundred
\vfilneg\fi
}
% forces vmode
314 315
%D Made slightly more readable:
316 317
\unexpanded
\def
\vglue
{
\afterassignment
\spac_helpers_vglue_indeed
\s_spac_lastskip
=
}
318
\unexpanded
\def
\hglue
{
\afterassignment
\spac_helpers_hglue_indeed
\s_spac_lastskip
=
}
319
\unexpanded
\def
\topglue
{
\par\ifvmode
\nointerlineskip\vglue
-
\topskip
\vglue
\fi
}
320 321
\def
\spac_helpers_vglue_indeed
322
{
\par
323
\ifvmode
324
\d_spac_prevdepth
\prevdepth
325
\hrule
\s!height
\zeropoint
326
\nobreak
327
\vskip
\s_spac_lastskip
328
\prevdepth
\d_spac_prevdepth
329
\fi
}
330 331
\def
\spac_helpers_hglue_indeed
332
{
\dontleavehmode
333
\c_spac_spacefactor
\spacefactor
334
\vrule
\s!width
\zeropoint
335
\nobreak
336
\hskip
\s_spac_lastskip
337
\spacefactor
\c_spac_spacefactor
}
338 339
%D We adapt plain's \type {\removelastskip} a bit:
340 341
\unexpanded
\def
\removelastskip
% also in supp-box
342
{
\ifvmode\ifzeropt
\lastskip\else\vskip
-
\lastskip\fi\fi
}
343 344
% The whitespace handler. We could cache settings but normally there are not
345
% that many in a set.
346 347
\installcorenamespace
{
whitespacemethod
}
348 349
\newskip
\s_spac_whitespace_parskip
\s_spac_whitespace_parskip
\zeropoint
350
\newconditional
\c_spac_whitespace_flexible
\settrue
\c_spac_whitespace_flexible
351
\newconstant
\c_spac_whitespace_grid_mode
% option in layout / 1=permit_half_lines
352 353
%def\v_spac_whitespace_current{\zeropoint}
354
\let
\v_spac_whitespace_current
\v!none
355 356
\unexpanded
\def
\setupwhitespace
357
{
\doifelsenextoptionalcs
\spac_whitespace_setup_yes
\spac_whitespace_setup_nop
}
358 359
\def
\spac_whitespace_setup_nop
360
{
\ifx
\v_spac_whitespace_current
\v!none
\else
361
\spac_whitespace_setup
362
\fi
}
363 364
\let
\synchronizewhitespace
\spac_whitespace_setup_nop
365 366
\def
\spac_whitespace_setup_yes
[#
1
]
%
367
{
\edef
\m_spac_whitespace_asked
{
#
1
}
%
368
\ifx
\m_spac_whitespace_asked
\empty
369
\spac_whitespace_setup_nop
370
\else
371
\let
\v_spac_whitespace_current
\m_spac_whitespace_asked
372
\spac_whitespace_setup
373
\fi
}
374 375
\def
\spac_whitespace_setup
% quick test for no list
376
{
\ifcsname
\??whitespacemethod
\v_spac_whitespace_current
\endcsname
377
\lastnamedcs
378
\else
379
\expandafter
\processcommalist
\expandafter
[
\v_spac_whitespace_current
]
\spac_whitespace_setup_method
% can be raw
380
\fi\relax
381
\ifgridsnapping
382
\spac_whitespace_setup_grid
383
\else
384
\spac_whitespace_setup_normal
385
\fi
386
\parskip
\s_spac_whitespace_parskip
}
387 388
\def
\spac_whitespace_setup_normal
389
{
\ifconditional
\c_spac_whitespace_flexible
\else
390
\s_spac_whitespace_parskip
\plusone
\s_spac_whitespace_parskip
391
\fi
}
392 393
\def
\spac_whitespace_setup_grid
394
{
\setfalse
\c_spac_whitespace_flexible
395
\ifdim
\s_spac_whitespace_parskip
>
\zeropoint
396
\s_spac_whitespace_parskip
397
\ifcase
\c_spac_whitespace_grid_mode
398
\baselineskip
399
\or
400
\ifdim
\scratchdimen
=
\baselineskip
% maybe range
401
\baselineskip
402
\else
403
\numexpr
\s_spac_whitespace_parskip
/
\dimexpr
.
5
\lineheight
\relax\relax\dimexpr
.
5
\lineheight
\relax
404
\fi
405
\else
406
\baselineskip
407
\fi
408
\fi
}
409 410
\unexpanded
\def
\installwhitespacemethod
#
1
#
2
%
411
{
\setvalue
{
\??whitespacemethod
#
1
}{
#
2
}}
412 413
\installwhitespacemethod
\v!fix
{}
414
\installwhitespacemethod
\v!fixed
{
\setfalse
\c_spac_whitespace_flexible
}
415
\installwhitespacemethod
\v!flexible
{
\settrue
\c_spac_whitespace_flexible
}
416 417
\installwhitespacemethod
\v!line
{
\s_spac_whitespace_parskip
\baselineskip
}
418
\installwhitespacemethod
\v!halfline
{
\s_spac_whitespace_parskip
.
5
\baselineskip
}
419
\installwhitespacemethod
\v!quarterline
{
\s_spac_whitespace_parskip
.
2
5
\baselineskip
}
420
\installwhitespacemethod
\v!none
{
\s_spac_whitespace_parskip
\zeropoint
}
421
\installwhitespacemethod
\v!big
{
\s_spac_whitespace_parskip
\bigskipamount
}
422
\installwhitespacemethod
\v!medium
{
\s_spac_whitespace_parskip
\medskipamount
}
423
\installwhitespacemethod
\v!small
{
\s_spac_whitespace_parskip
\smallskipamount
}
424 425
\installwhitespacemethod
\s!default
{
\spac_whitespace_setup_nop
}
% also covers none
426 427
\def
\spac_whitespace_setup_method
#
1
%
428
{
\ifcsname
\??whitespacemethod
#
1
\endcsname
429
\lastnamedcs
430
\else
431
\s_spac_whitespace_parskip
#
1
\fi
432
\relax
}
433 434
\unexpanded
\def
\forgetparskip
435
{
\s_spac_whitespace_parskip
\zeropoint
436
\parskip
\zeropoint
437
\let
\v_spac_whitespace_current
\v!none
}
438 439
\appendtoks
440
\forgetparskip
441
\to
\everyforgetall
442 443
% \installwhitespacemethod \s!unknown {\s_spac_whitespace_parskip\commalistelement\relax}
444
%
445
% \def\spac_whitespace_setup_method#1%
446
% {\csname\??whitespacemethod\ifcsname\??whitespacemethod#1\endcsname#1\else\s!unknown\endcsname\relax}
447 448
\unexpanded
\def
\nowhitespace
{
\directcheckedvspacing
\v!nowhite
}
% {\vspacing[\v!nowhite]}
449
\unexpanded
\def
\whitespace
{
\directcheckedvspacing
\v!white
}
% {\vspacing[\v!white]}
450 451
\setupwhitespace
452
[
\v!none
]
453 454
% Packed:
455 456
% todo: when packed blocks blank, we need to enable forced
457 458
\newconditional
\c_spac_packed_blank
\settrue
\c_spac_packed_blank
459
\newcount
\c_spac_packed_level
460 461
\unexpanded
\def
\startpacked
462
{
\dosingleempty
\spac_packed_start
}
463 464
\def
\spac_packed_start
[#
1
]
% nesting afvangen
465
{
\global\advance
\c_spac_packed_level
\plusone
466
\par
467
\ifnum
\c_spac_packed_level
=
\plusone
\ifvmode
468
\begingroup
469
\whitespace
% not combined
470
\directcheckedvspacing
\v!disable
% \blank[\v!disable]% or \inhibitblank
471
\doifelse
{
#
1
}
\v!blank
\settrue\setfalse
\c_spac_packed_blank
472
\setupwhitespace
[
\v!none
]
% or \forgetparskip
473
\fi
\fi
}
474 475
\unexpanded
\def
\stoppacked
476
{
\par
477
\ifnum
\c_spac_packed_level
=
\plusone
\ifvmode
478
\endgroup
479
\fi
\fi
480
\global\advance
\c_spac_packed_level
\minusone
}
481 482
\unexpanded
\def
\startunpacked
483
{
\directdefaultvspacing
% \blank
484
\begingroup
}
485 486
\unexpanded
\def
\stopunpacked
487
{
\endgroup
488
\directdefaultvspacing
}
% \blank}
489 490
% \prevdepth crosses pageboundaries!
491
%
492
% todo: a version that works ok inside a box
493 494
% global : outer hsize + keep skips
495
% local : inner hsize + reset skips
496 497
\installcorenamespace
{
linesaround
}
498 499
\let
\spac_lines_vbox
\vbox
500 501
\installtextracker
502
{
linecorrection
.
boxes
}
503
{
\let
\spac_lines_vbox
\ruledvbox
}
504
{
\let
\spac_lines_vbox
\vbox
}
505 506
\let
\v_spac_lines_around_action_set
\relax
507
\let
\m_spac_lines_around
\empty
508 509
\newconstant
\c_spac_lines_correction_mode
510 511
\setvalue
{
\??linesaround\v!blank
}{
\blank
}
512
\letvalue
{
\??linesaround
\empty
}
\relax
513
\setvalue
{
\??linesaround\s!unknown
}{
\directcheckedvspacing
\m_spac_lines_around
}
% \blank[\m_spac_lines_around]}
514 515
\def
\spac_lines_action_around
% we used to let this one but it's cleaner this way
516
{
\csname
\??linesaround
% i.e. do it twice
517
\ifcsname
\??linesaround
\m_spac_lines_around
\endcsname
\m_spac_lines_around
\else
\s!unknown
\fi
518
\endcsname
}
519 520
\unexpanded
\def
\startlinecorrection
521
{
\endgraf
522
\begingroup
523
\setconstant
\c_spac_lines_correction_mode
\plusone
524
\dosingleempty
\spac_lines_start_correction
}
525 526
\unexpanded
\def
\startlocallinecorrection
527
{
\endgraf
528
\begingroup
529
\setconstant
\c_spac_lines_correction_mode
\plustwo
530
\dosingleempty
\spac_lines_start_correction
}
531 532
\unexpanded
\def
\spac_lines_start_correction
[#
1
]
%
533
{
\edef
\m_spac_lines_around
{
#
1
}
%
534
\spac_lines_action_around
535
\d_spac_prevdepth
\prevdepth
536
\spac_lines_initialize_corrections
537
\offbaselinecorrection
% ???
538
\setbox
\scratchbox
\spac_lines_vbox
\bgroup
539
\ifcase
\c_spac_lines_correction_mode
540
% nothing
541
\or
542
% global
543
\or
544
% local
545
\setlocalhsize
546
\hsize
\localhsize
547
\forgetbothskips
548
\fi
549
\ignorespaces
}
550 551
\unexpanded
\def
\spac_lines_stop_correction
552
{
\removeunwantedspaces
553
\egroup
554
\ifgridsnapping
555
\spac_lines_stop_correction_ongrid
556
\else
557
\spac_lines_stop_correction_normal
558
\fi
559
\endgroup
}
560 561
\unexpanded
\def
\spac_lines_stop_correction_ongrid
562
{
\directcheckedvspacing
\v!white
% \blank[\v!white]%
563
\spac_lines_action_around
564
\snaptogrid
\hpack
{
\box
\scratchbox
}
%
565
\directcheckedvspacing
\v!white
566
\spac_lines_action_around
}
567 568
\unexpanded
\def
\spac_lines_stop_correction_normal
569
{
\directcheckedvspacing
\v!nowhite
% \blank[\v!nowhite]%
570
\ifdim
\parskip
>
\zeropoint
571
% too fuzzy otherwise
572
\else
573
% doesn't like whitespace
574
\ifdim
\d_spac_prevdepth
<
\maxdimen
575
\unless\ifdim
\d_spac_prevdepth
<
\zeropoint
576
\ifdim
\d_spac_prevdepth
<
\strutdp
\relax
577
\pushlastnode
578
\ifdim
\d_spac_prevdepth
>
\zeropoint
579
\kern
-
\d_spac_prevdepth
580
\fi
581
\kern
\strutdp
582
\prevdepth
\strutdp
583
\poplastnode
584
\fi
585
\fi
586
\fi
587
\fi
588
\ifdim
\pagegoal
<
\maxdimen
589
% \blank[\v!white,\the\d_spac_lines_correction_before]% \blank[\v!white]\dotopbaselinecorrection
590
\directcheckedvspacing
{
\v!white
,
\the
\d_spac_lines_correction_before
}
% \blank[\v!white]\dotopbaselinecorrection
591
\fi
592
\nointerlineskip
% new
593
\noindent
% not \dontleavehmode !
594
\ifcase
\c_spac_lines_correction_mode
595
% nothing
596
\or
597
% global
598
\hskip
-
\leftskip
% more tricky would be hangindent so we ignore that one
599
\or
600
% local
601
\fi
602
\box
\scratchbox
603
\endgraf
604
%
605
% eventually i'll get it right ... (i also need to check all whitespace code elsewhere)
606
%
607
% \blank[\the\d_spac_lines_correction_after]% \dobotbaselinecorrection
608
% \directcheckedvspacing{\the\d_spac_lines_correction_after}% \dobotbaselinecorrection
609
\directcheckedvspacing
{
\v!white
,
\the
\d_spac_lines_correction_after
}
% \dobotbaselinecorrection
610
% \allowbreak % new, otherwise problems when many in a row
611
\prevdepth
\strutdp
612
\spac_lines_action_around
}
613 614
\let
\stoplinecorrection
\spac_lines_stop_correction
615
\let
\stoplocallinecorrection
\spac_lines_stop_correction
616 617
% todo:
618 619
\unexpanded
\def
\correctwhitespace
620
{
\dowithnextboxcs
\correctwhitespacefinish
\vbox
}
621 622
\unexpanded
\def
\correctwhitespacefinish
623
{
\startbaselinecorrection
624
\flushnextbox
625
\stopbaselinecorrection
}
626 627
\unexpanded
\def
\verticalstrut
{
\vpack
{
\hsize
\zeropoint
\forgetall\strut
}}
628
\unexpanded
\def
\horizontalstrut
{
\hpack
{
\strut
}}
629 630
%D Here follow some presets related to interline spacing and therefore also struts.
631
%D The values 2.8, 0.07, 0.72 and 0.28 originate in \INRSTEX, a package that we used
632
%D a while after we decided that \LATEX\ was not flexible enough. After that
633
%D \CONTEXT\ evolved, from some wrapper code around (old) \LATEX\ (on a floppy
634
%D disk), to using modules from \INRSTEX\ (which also fit on a floppy) and finally
635
%D all written from scratch. I simply didn't understand all that \TEX\ code at that
636
%D time, and it was easier to figure it out myself. But \unknown\ some settings
637
%D stayed, as the height|/|depth ratios, and they never proved to be bad ones! The
638
%D same is true for the font size relations.
639 640
%D \starttabulate
641
%D \NC \type {\lineheight} \NC the height of a line \NC \NR
642
%D \NC \type {\spacing{number}} \NC adapting the interline space \NC \NR
643
%D \NC \type {\normalbaselines} \NC initialize the interline spacing \NC \NR
644
%D \NC \type {\setstrut} \NC initialize \type {\strut} \NC \NR
645
%D \NC \type {\setnostrut} \NC disable the \type {\strut}, \type {\endstrut}, \type {\begstrut} \NC \NR
646
%D \NC \type {\setteststrut} \NC initialize the visual \type {\strut} \NC \NR
647
%D \NC \type {\resetteststrut} \NC disable the visual \type {\strut} \NC \NR
648
%D \NC \type {\setfontparameters} \NC synchronize parameters with foints \NC \NR
649
%D \stoptabulate
650
%D
651
%D \unknown\ and many more (this is a decades old list).
652
%D
653
%D The lineheight is the sum of the height and depth of \type {strut}, which is
654
%D an invisible blob that can be used to enforce the proper dimensions.
655
%D
656
%D Such a blob, when placed at the beginning of a paragraph can have side effects
657
%D that can be prevented with \type {\dontleavehmode}. Never use \type
658
%D {\leavevmode}!
659 660
\newdimen
\strutdimen
661
\newdimen\lineheight
662
\newdimen
\openlineheight
663
\newdimen
\openstrutheight
664
\newdimen
\openstrutdepth
665
\newdimen
\topskipgap
666
\newdimen
\struttotal
667 668
\def
\strutheightfactor
{
.
7
2
}
669
\def
\strutdepthfactor
{
.
2
8
}
670 671
\def
\baselinefactor
{
2
.
8
}
672 673
\let
\m_spac_vertical_baseline_stretch_factor
\zerocount
674
\let
\m_spac_vertical_baseline_shrink_factor
\zerocount
675 676
\def
\minimumstrutheight
{
\zeropoint
}
677
\def
\minimumstrutdepth
{
\zeropoint
}
678 679
\def
\normallineheight
{
\baselinefactor
\exheight
}
680
\def
\minimumlinedistance
{
\lineskip
}
681 682
\def
\strutheight
{
\zeropoint
}
683
\def
\strutdepth
{
\zeropoint
}
684
\def
\strutwidth
{
\zeropoint
}
685 686
\let
\spacingfactor
\plusone
687 688
\def
\topskipfactor
{
1
.
0
}
689
\def
\maxdepthfactor
{
0
.
5
}
690 691
\def
\systemtopskipfactor
{
\topskipfactor
}
692
\def
\systemmaxdepthfactor
{
\maxdepthfactor
}
693 694
\ifdefined
\globalbodyfontsize
\else
695
\newdimen
\globalbodyfontsize
696
\globalbodyfontsize
=
1
2
pt
697
\fi
698 699
\ifdefined
\normalizedbodyfontsize
\else
700
\def
\normalizedbodyfontsize
{
1
2
pt
}
701
\fi
702 703
\unexpanded
\def
\topskipcorrection
704
{
\simpletopskipcorrection
705
\vskip
-
\struttotal
706
\verticalstrut
}
707 708
\unexpanded
\def
\simpletopskipcorrection
709
{
\ifdim
\topskip
>
\openstrutheight
710
% == \vskip\topskipgap
711
\vskip\topskip
712
\vskip
-
\openstrutheight
713
\fi
}
714 715
\unexpanded
\def
\settopskip
% the extra test is needed for the lbr family
716
{
\topskip
717
\ifgridsnapping
718
\zeropoint
719
\else
720
\systemtopskipfactor
\globalbodyfontsize
721
\ifcase
\bottomraggednessmode
% ragged bottom
722
\s!plus
5
\globalbodyfontsize
723
\fi
724
\fi
725
%\relax
726
\topskipgap
\topskip
727
\advance
\topskipgap
-
\openstrutheight
\relax
728
\ifdim
\minimumstrutheight
>
\zeropoint
729
\ifdim
\topskip
<
\minimumstrutheight
730
\topskip
\minimumstrutheight
\relax
731
\fi
732
\else
733
\ifdim
\topskip
<
\strutheightfactor
\openlineheight
734
\topskip
\strutheightfactor
\openlineheight
\relax
735
\fi
736
\fi
}
737 738
\unexpanded
\def
\setmaxdepth
739
{
\maxdepth
\systemmaxdepthfactor
\globalbodyfontsize
}
740 741
\let
\normalbaselineskip
\relax
\newskip
\normalbaselineskip
% these got lost in the transition to mkiv due
742
\let
\normallineskip
\relax
\newskip
\normallineskip
% to auto-\normal* definitions and registers
743
\let
\normallineskiplimit
\relax
\newdimen\normallineskiplimit
% being protected
744 745
\unexpanded
\def
\normalbaselines
746
{
\baselineskip
\normalbaselineskip
747
\lineskip
\normallineskip
748
\lineskiplimit
\normallineskiplimit
}
749 750
\unexpanded
\def
\flexiblebaselines
751
{
\baselineskip
\normalbaselineskip
752
\lineskip
1
\normallineskip
\s!plus
1
\s!fill
753
\lineskiplimit
\normallineskiplimit
}
754 755
\unexpanded
\def
\setnormalbaselines
756
{
\ifdim
\normallineheight
>
\zeropoint
757
\lineheight
\normallineheight
758
\fi
759
\openlineheight
\spacingfactor
\lineheight
760
\openstrutheight
\ifdim
\minimumstrutheight
>
\zeropoint
761
\minimumstrutheight
% new
762
\else
763
\strutheightfactor
\openlineheight
764
\fi
765
\openstrutdepth
\ifdim
\minimumstrutdepth
>
\zeropoint
766
\minimumstrutdepth
% new
767
\else
768
\strutdepthfactor
\openlineheight
769
\fi
770
\ifdim
\dimexpr
\minimumstrutdepth
+
\minimumstrutheight
\relax
>
\zeropoint
771
\openlineheight
\dimexpr
\openstrutheight
+
\openstrutdepth
\relax
% new
772
\fi
773
\normalbaselineskip
\openlineheight
774
\ifgridsnapping
\else
775
\s!plus
\m_spac_vertical_baseline_stretch_factor
\openlineheight
776
\s!minus
\m_spac_vertical_baseline_shrink_factor
\openlineheight
777
\fi
778
\normallineskip
\minimumlinedistance
\relax
% \onepoint\relax
779
\normallineskiplimit
\zeropoint
\relax
780
\normalbaselines
}
781 782
\unexpanded
\def
\spacing
#
1
% vertical
783
{
\ifgridsnapping
784
\let
\spacingfactor
\plusone
785
\else
786
\edef
\spacingfactor
{
#
1
}
%
787
\fi
788
\edef
\systemtopskipfactor
{
\withoutpt
\the\dimexpr
#
1
\dimexpr
\topskipfactor
\points
}
%
789
\edef
\systemmaxdepthfactor
{
\withoutpt
\the\dimexpr
#
1
\dimexpr
\maxdepthfactor
\points
}
%
790
\setnormalbaselines
791
\setstrut
}
792 793
% \unexpanded\def\forgetverticalstretch % \forgetspacing
794
% {\spacing\plusone}
795 796
\unexpanded
\def
\forgetverticalstretch
797
{
\let
\spacingfactor
\plusone
798
\let
\systemtopskipfactor
\topskipfactor
799
\let
\systemmaxdepthfactor
\maxdepthfactor
800
\setnormalbaselines
801
\setstrut
}
802 803
\appendtoks
804
\forgetverticalstretch
805
\to
\everyforgetall
% needed in otr
806 807
%D Sometimes one needs to freeze the interlinespacing
808
%D
809
%D \starttyping
810
%D \rm \saveinterlinespace .... {\ss \restoreinterlinespace .... \endgraf}
811
%D \stoptyping
812 813
\let
\restoreinterlinespace
\relax
814 815
\unexpanded
\def
\saveinterlinespace
816
{
\unexpanded
\edef
\restoreinterlinespace
817
{
\lineheight
\the
\lineheight
818
\openstrutheight
\the
\openstrutheight
819
\openstrutdepth
\the
\openstrutdepth
820
\openlineheight
\the
\openlineheight
821
\normalbaselineskip
\the
\normalbaselineskip
822
\normallineskip
\the
\normallineskip
823
\normallineskiplimit
\the
\normallineskiplimit
824
\noexpand\def\noexpand
\normallineheight
{
\the\dimexpr
\normallineheight
}
%
825
\noexpand
\normalbaselines
}}
826 827
%D This is the plain definition:
828
%D
829
%D \starttyping
830
%D \def\strut{\relax\ifmmode\copy\strutbox\else\unhcopy\strutbox\fi}
831
%D \stoptyping
832
%D
833
%D which could be:
834
%D
835
%D \starttyping
836
%D \def\strut{\relax\ifmmode\copy\else\unhcopy\fi\strutbox}
837
%D \stoptyping
838
%D
839
%D But we do things differently.
840 841
\newbox\strutbox
842 843
\setbox
\strutbox
\hpack
{
\vrule
\s!height
8
.
5
pt
\s!depth
3
.
5
pt
\s!width
\zeropoint
}
% just a start
844 845
\def
\strut
{
\relax\ifmmode\copy\else\unhcopy\fi
\strutbox
}
846 847
% \unexpanded\def\strut
848
% {\relax
849
% \ifmmode\copy\else\dontleavehmode\unhcopy\fi\strutbox}
850 851
\let
\normalstrut
\strut
852 853
%D The double \type {\hbox} construction enables us to backtrack boxes.
854 855
\let
\strutht
\undefined
\newdimen\strutht
856
\let
\strutdp
\undefined
\newdimen\strutdp
857 858
\unexpanded
\def
\setstrut
859
{
\ifgridsnapping
860
\setstrutgridyes
861
\else
862
\setstrutgridnop
863
\fi
}
864 865
\unexpanded
\def
\setstrutgridyes
866
{
\strutht
\spacingfactor
\dimexpr
867
\ifdim
\minimumstrutheight
>
\zeropoint
868
\minimumstrutheight
869
\else
870
\strutheightfactor
\dimexpr
\normallineheight
871
\fi
872
\strutdp
\dimexpr
873
\ifdim
\minimumstrutdepth
>
\zeropoint
874
\minimumstrutdepth
875
\else
876
\normallineheight
-
\strutht
877
\fi
878
\dosetstrut
}
879 880
\unexpanded
\def
\setstrutgridnop
881
{
\strutht
\spacingfactor
\dimexpr
882
\ifdim
\minimumstrutheight
>
\zeropoint
883
\minimumstrutheight
884
\else
885
\strutheightfactor
\dimexpr
\normallineheight
886
\fi
887
\strutdp
\spacingfactor
\dimexpr
888
\ifdim
\minimumstrutdepth
>
\zeropoint
889
\minimumstrutdepth
890
\else
891
\strutdepthfactor
\dimexpr
\normallineheight
892
\fi
893
\dosetstrut
}
894 895
\unexpanded
\def
\setcharstrut
#
1
%
896
{
\setbox
\strutbox
\hbox
{
#
1
}
% no \hpack, in case we have smallcaps
897
\strutht
\ht
\strutbox
898
\strutdp
\dp
\strutbox
899
\dosetstrut
}
900 901
\unexpanded
\def
\settightstrut
902
{
\setcharstrut
{
(
}}
903 904
\unexpanded
\def
\setfontstrut
905
{
\setcharstrut
{
(
gplQT
}}
906 907
\unexpanded
\def
\setcapstrut
% could be M, but Q has descender
908
{
\setcharstrut
{
Q
}}
909 910
%D Handy for math (used in mathml):
911 912
\unexpanded
\def
\charhtstrut
913
{
\begingroup
914
\setcharstrut
{
GJY
}
%
915
\vrule
\s!width
\zeropoint
\s!depth
\zeropoint
\s!height
\strutht
916
\endgroup
}
917 918
\unexpanded
\def
\chardpstrut
919
{
\begingroup
920
\setcharstrut
{
gjy
}
%
921
\vrule
\s!width
\zeropoint
\s!depth
\strutdp
\s!height
\zeropoint
922
\endgroup
}
923 924
%D Because of all the callbacks in mkiv, we avoid unnecessary boxes ... maybe use an
925
%D attribute so that we can tag boxes that don't need a treatment; tests with using
926
%D an attribute so far have shown that it's slower because testing the attribute
927
%D takes time too.
928 929
\unexpanded
\def
\dosetstrut
930
{
\let
\strut
\normalstrut
931
\ifabsnum
\dimexpr
\strutht
+
\strutdp
-
\lineheight
\relax
<
\plustwo
932
% compensate rounding error /- 1sp to avoid too many
933
% 1sp baselineskips in for instance verbatim
934
% \strutht\dimexpr\lineheight-\strutdp\relax
935
% better:
936
\strutdp
\dimexpr
\lineheight
-
\strutht
\relax
937
\struttotal
\lineheight
938
\else
939
\struttotal
\dimexpr
\strutht
+
\strutdp
\relax
940
\fi
941
\edef
\strutheight
{
\the
\strutht
}
%
942
\edef
\strutdepth
{
\the
\strutdp
}
%
943
\ifdim
\strutwidth
=
\zeropoint
944
\spac_struts_set_hide
945
\else
946
\spac_struts_set_vide
947
\fi
}
948 949
\def
\spac_struts_set_hide
950
{
\setbox
\strutbox
\hpack
951
{
\vrule
952
\s!width
\zeropoint
953
\s!height
\strutht
954
\s!depth
\strutdp
}}
955 956
\newconstant
\c_strut_visual_mode
957 958
\def
\spac_struts_set_vide
959
{
\setbox
\strutbox
\hpack
% at some time this extra wrapping was needed
960
{
\spac_struts_vide_hbox
to
\zeropoint
961
{
\ifcase
\c_strut_visual_mode
962
\spac_struts_black
963
\or
964
\spac_struts_color
965
\else
966
\spac_struts_black
967
\fi
}}}
968 969
\def
\spac_struts_black
970
{
\vrule
971
\s!width
\strutwidth
972
\s!height
\strutht
973
\s!depth
\strutdp
974
\hss
}
975 976
\def
\spac_struts_color
977
{
\hss
% new, will be option
978
\scratchwidth
.
1
\struthtdp
979
\begingroup
980
\directcolor
[
f
:
b
:
t
]
%
981
\vrule
982
\s!width
\scratchwidth
983
\s!height
\strutht
984
\s!depth
\strutdp
985
\kern
-
\scratchwidth
986
\vrule
987
\s!width
\scratchwidth
988
\s!height
\zeropoint
989
\s!depth
\strutdp
990
\endgroup
991
\kern
-
.
6
2
5
\scratchwidth
992
\vrule
993
\s!width
.
2
5
\scratchwidth
994
\s!height
\strutht
995
\s!depth
\strutdp
996
\hss
}
997 998
\let
\spac_struts_vide_hbox
\hbox
% overloaded in trac-vis.mkiv
999 1000
%D The dimen \type {\struttotal} holds the exact size of the strut; occasionally a
1001
%D one scaled point difference can show up with the lineheight. This is more
1002
%D efficient (less callbacks):
1003 1004
\newbox
\b_spac_struts_empty
\setbox
\b_spac_struts_empty
\emptyhbox
1005 1006
\def
\spac_struts_set_hide
1007
{
\setbox
\strutbox
\copy
\b_spac_struts_empty
1008
\ht
\strutbox\strutht
1009
\dp
\strutbox\strutdp
}
1010 1011
\unexpanded
\def
\strut
% still callbacks for \hbox{\strut}
1012
{
\relax
1013
\dontleavehmode
1014
\copy
\strutbox
}
1015 1016
% \unexpanded\def\strut % slightly faster
1017
% {\relax
1018
% \ifmmode\copy\else\dontleavehmode\unhcopy\fi\strutbox}
1019 1020
\let
\normalstrut
\strut
1021 1022
\unexpanded
\def
\halfstrut
1023
{
\relax
1024
\dontleavehmode
1025
\begingroup
1026
\setbox
\scratchbox
\copy
\strutbox
1027
\ht
\scratchbox
\dimexpr
\strutht
/
\plustwo
\relax
1028
\dp
\scratchbox
\dimexpr
\strutdp
/
\plustwo
\relax
1029
\box
\scratchbox
1030
\endgroup
}
1031 1032
\unexpanded
\def
\quarterstrut
1033
{
\relax
1034
\dontleavehmode
1035
\begingroup
1036
\setbox
\scratchbox
\copy
\strutbox
1037
\ht
\scratchbox
\dimexpr
\strutht
/
\plusfour
\relax
1038
\dp
\scratchbox
\dimexpr
\strutdp
/
\plusfour
\relax
1039
\box
\scratchbox
1040
\endgroup
}
1041 1042
\unexpanded
\def
\depthstrut
1043
{
\relax
1044
\dontleavehmode
1045
\begingroup
1046
\setbox
\scratchbox
\copy
\strutbox
1047
\ht
\scratchbox
\dimexpr
\strutht
-
\struthtdp
/
\plustwo
\relax
% assumes that ht > lineheight/2
1048
\box
\scratchbox
1049
\endgroup
}
1050 1051
\unexpanded
\def
\halflinestrut
1052
{
\relax
1053
\dontleavehmode
1054
\begingroup
1055
\setbox
\scratchbox
\copy
\strutbox
1056
\ht
\scratchbox
\dimexpr
\strutht
-
.
5
\strutht
-
.
5
\strutdp
\relax
1057
\box
\scratchbox
1058
\endgroup
}
1059 1060
\unexpanded
\def
\noheightstrut
1061
{
\relax
1062
\dontleavehmode
1063
\begingroup
1064
\setbox
\scratchbox
\copy
\strutbox
1065
\ht
\scratchbox
\zeropoint
1066
\box
\scratchbox
1067
\endgroup
}
1068 1069
%D Sometimes a capstrut comes in handy
1070
%D
1071
%D \starttabulate[|Tl|l|l|]
1072
%D \NC yes \NC normal strut \NC {\showstruts\setupstrut[yes]\strut} \NC \NR
1073
%D \NC no \NC no strut \NC {\showstruts\setupstrut[no]\strut} \NC \NR
1074
%D \NC kap \NC a capital strut (i.e. Q) \NC {\showstruts\setupstrut[cap]\strut} \NC \NR
1075
%D \NC A B \unknown \NC a character strut (e.g. A) \NC {\showstruts\setupstrut[A]\strut} \NC \NR
1076
%D \NC \NC a normal strut \NC {\showstruts\setupstrut\strut} \NC \NR
1077
%D \stoptabulate
1078
%D
1079
%D Beware: using an unknown value results in char struts.
1080 1081
\installcorenamespace
{
struts
}
1082 1083
\unexpanded
\def
\setupstrut
1084
{
\dosingleempty
\spac_struts_setup
}
1085 1086
\def
\spac_struts_setup
[#
1
]
%
1087
{
\edef
\m_strut
{
#
1
}
%
1088
\ifcsname
\??struts
\m_strut
\endcsname
1089
\lastnamedcs
1090
\else
1091
\setcharstrut
\m_strut
1092
\fi
}
1093 1094
\unexpanded
\def
\synchronizestrut
#
1
% no [] parsing, faster for internal
1095
{
\edef
\m_strut
{
#
1
}
%
1096
\ifcsname
\??struts
\m_strut
\endcsname
1097
\lastnamedcs
1098
\else
1099
\setcharstrut
\m_strut
1100
\fi
}
1101 1102
\unexpanded
\def
\dosynchronizestrut
#
1
% no [] parsing, faster for internal
1103
{
\ifcsname
\??struts
#
1
\endcsname
1104
\lastnamedcs
1105
\else
1106
\setcharstrut
{
#
1
}
%
1107
\fi
}
1108 1109
\unexpanded
\def
\showstruts
% adapts .. is wrong
1110
{
\c_strut_visual_mode
\zerocount
1111
\setteststrut
1112
\settestcrlf
}
1113 1114
\unexpanded
\def
\showcolorstruts
% adapts .. is wrong
1115
{
\c_strut_visual_mode
\plusone
1116
\setteststrut
1117
\settestcrlf
}
1118 1119
\unexpanded
\def
\setteststrut
1120
{
\def
\strutwidth
{
.
8
pt
}
%
1121
\setstrut
}
1122 1123
\unexpanded
\def
\dontshowstruts
1124
{
\unsetteststrut
1125
\settestcrlf
}
1126 1127
\unexpanded
\def
\unsetteststrut
1128
{
\let
\strutwidth
\zeropoint
1129
\setstrut
}
1130 1131
\def
\autostrutfactor
{
1
.
1
}
1132 1133
\unexpanded
\def
\setautostrut
1134
{
\begingroup
1135
\setbox
\scratchbox
\copy
\strutbox
1136
\setstrut
1137
\ifdim
\strutht
>
\autostrutfactor
\ht
\scratchbox
1138
\endgroup
\setstrut
1139
\else\ifdim
\strutdp
>
\autostrutfactor
\dp
\scratchbox
1140
\endgroup
\setstrut
1141
\else
1142
\endgroup
1143
\fi\fi
}
1144 1145
\newbox
\nostrutbox
\setbox
\nostrutbox
\emptyhbox
1146 1147
\newtoks
\everysetnostrut
1148 1149
\unexpanded
\def
\setnostrut
1150
{
\the
\everysetnostrut
}
1151 1152
\appendtoks
1153
\setbox
\strutbox
\copy
\nostrutbox
1154
\let
\strut\empty
1155
\let
\endstrut\empty
1156
\let
\begstrut\empty
1157
\to
\everysetnostrut
1158 1159
%D When enabled, sigstruts will remove themselves if nothing goes inbetween. For
1160
%D practical reasons we define some boundary characters here.
1161 1162
\unexpanded
\def
\leftboundary
{
\protrusionboundary
\plusone
}
1163
\unexpanded
\def
\rightboundary
{
\protrusionboundary
\plustwo
}
1164
\unexpanded
\def
\signalcharacter
{
\boundary
\plusone
\char
\zerocount
\boundary
\plustwo
}
% not the same as strut signals
1165 1166
\newsignal
\strutsignal
\setfalse
\sigstruts
1167 1168
\unexpanded
\def
\begstrut
1169
{
\relax\ifcase
\strutht
1170
% \ignorespaces % maybe
1171
\else
1172
\spac_struts_beg
1173
\fi
}
1174 1175
\def
\spac_struts_beg
1176
{
\ifconditional
\sigstruts
1177
\spac_struts_beg_signal
1178
\else
1179
\spac_struts_beg_normal
1180
\fi
1181
\ignorespaces
}
1182 1183
\def
\spac_struts_beg_signal
1184
{
\noindent
\horizontalstrut
1185
\penalty
\plustenthousand
1186
\hskip
-
\strutsignal
1187
\hskip
\strutsignal
}
1188 1189
\def
\spac_struts_beg_normal
1190
{
\boundary
\plusone
1191
\strut
1192
%\boundary\plusone
1193
\penalty
\plustenthousand
1194
%\boundary\plusone
1195
\hskip
\zeropoint
}
1196 1197
\unexpanded
\def
\endstrut
1198
{
\relax\ifhmode
1199
\ifcase
\strutht
1200
% \removeunwantedspaces % maybe
1201
\else
1202
\spac_struts_end
1203
\fi
1204
\fi
}
1205 1206
\def
\spac_struts_end
1207
{
\ifconditional
\sigstruts
1208
\spac_struts_end_signal
1209
\else
1210
\spac_struts_end_normal
1211
\fi
}
1212 1213
\def
\spac_struts_end_signal
1214
{
\ifdim
\lastskip
=
\strutsignal
1215
\unskip
1216
\unskip
1217
\unpenalty
1218
\setbox
\scratchbox
\lastbox
1219
\else
1220
\penalty
\plustenthousand
1221
\hskip
\zeropoint
1222
\strut
1223
\fi
}
1224 1225
\def
\spac_struts_end_normal
1226
{
\removeunwantedspaces
1227
\penalty
\plustenthousand
1228
%\boundary\plustwo
1229
\hskip
\zeropoint
1230
%\boundary\plustwo
1231
\strut
1232
\boundary
\plustwo
}
1233 1234
% unsave:
1235
%
1236
% \def\pseudostrut
1237
% {\bgroup
1238
% \setnostrut
1239
% \normalstrut
1240
% \egroup}
1241
%
1242
% try:
1243
%
1244
% \startchemie
1245
% \chemie[ONE,Z0,SB15,MOV1,SB15,Z0][C,C]
1246
% \stopchemie
1247
%
1248
% so:
1249 1250
\unexpanded
\def
\pseudostrut
1251
{
\noindent
}
% better: \dontleavehmode
1252 1253
\let
\pseudobegstrut
\pseudostrut
1254
\let
\pseudoendstrut
\removeunwantedspaces
1255 1256
\unexpanded
\def
\resetteststrut
1257
{
\def
\strutwidth
{
\zeropoint
}
% no let
1258
\setstrut
}
1259 1260
\ifdefined
\setfontparameters
\else
1261
\def
\setfontparameters
{
\the
\everybodyfont
}
1262
\fi
1263 1264
%D Keyword based strutting:
1265 1266
\letvalue
{
\??struts\v!yes
}
\setstrut
1267
\letvalue
{
\??struts\v!auto
}
\setautostrut
1268
\letvalue
{
\??struts\v!no
}
\setnostrut
1269
\letvalue
{
\??struts\v!cap
}
\setcapstrut
1270
\letvalue
{
\??struts\v!fit
}
\setfontstrut
1271
\letvalue
{
\??struts\v!line
}
\setstrut
1272
\letvalue
{
\??struts\s!default
}
\setstrut
1273
\letvalue
{
\??struts
\empty
}
\setstrut
1274 1275
%D Handy:
1276 1277
\def
\baselinedistance
{
\the
\lineheight
}
1278 1279
%D We need \type {\normaloffinterlineskip} because the new definition contains an
1280
%D assignment, and |<|don't ask me why|>| this assignment gives troubles in for
1281
%D instance the visual debugger.
1282 1283
\unexpanded
\def
\offinterlineskip
1284
{
\baselineskip
-
\thousandpoint
1285
\lineskip
\zeropoint
1286
\lineskiplimit
\maxdimen
1287
% We also need this here now; thanks to taco for figuring that out!
1288
\def
\minimumlinedistance
{
\zeropoint
}}
1289 1290
\unexpanded
\def
\nointerlineskip
1291
{
\prevdepth
-
\thousandpoint
}
1292 1293
\let
\normaloffinterlineskip
\offinterlineskip
% knuth's original
1294 1295
%D This is tricky. The prevdepth value is still set to the last one even if there is
1296
%D nothing on the page. The same is true for prevgraf, which doesn't resemble the
1297
%D value on the current page.
1298
%D
1299
%D So, here we kick in a checker but it has to happen after the output group and it
1300
%D only has to be done once (output can trigger itself!).
1301
%D
1302
%D However, prevgraf is somehow bound to hangindent so we can get very nasty side
1303
%D effects. So, in tne end we use our own variable!
1304 1305
\ifdefined
\getnofpreviouslines
1306
% defined public at the lua end
1307
\else
1308
\let
\getnofpreviouslines
\!!zerocount
1309
\fi
1310 1311
\unexpanded
\def
\page_otr_synchronize_page_yes
1312
{
\aftergroup
\page_otr_synchronize_page_indeed
1313
\glet
\page_otr_synchronize_page
\relax
}
1314 1315
% \unexpanded\def\page_otr_synchronize_page_indeed
1316
% {\clf_synchronizepage
1317
% \glet\page_otr_synchronize_page\page_otr_synchronize_page_yes}
1318
%
1319
% This has to become an otr method: \s!page_otr_command_synchonize_page
1320 1321
\unexpanded
\def
\page_otr_synchronize_page_indeed
1322
{
\ifx
\currentoutputroutine
\s!multicolumn
\else
\clf_synchronizepage
\fi
1323
\glet
\page_otr_synchronize_page
\page_otr_synchronize_page_yes
}
1324 1325
\let
\page_otr_synchronize_page
\page_otr_synchronize_page_yes
1326 1327
\appendtoks
1328
\page_otr_synchronize_page
1329
\to
\everyaftershipout
1330 1331
%D My own one:
1332 1333
\unexpanded
\def
\spac_helpers_push_interlineskip_yes
1334
{
\edef
\oninterlineskip
1335
{
\baselineskip
\the\baselineskip
1336
\lineskip
\the\lineskip
1337
\lineskiplimit\the\lineskiplimit
1338
\noexpand\edef\noexpand
\minimumlinedistance
{
\the\dimexpr
\minimumlinedistance
}
%
1339
\let\noexpand
\offinterlineskip
\noexpand
\normaloffinterlineskip
}}
% \noexpand not needed
1340 1341
\unexpanded
\def
\spac_helpers_push_interlineskip_nop
1342
{
\let
\oninterlineskip
\setnormalbaselines
}
1343 1344
\unexpanded
\def
\offinterlineskip
1345
{
\ifdim
\baselineskip
>
\zeropoint
1346
\spac_helpers_push_interlineskip_yes
1347
\else
1348
\spac_helpers_push_interlineskip_nop
1349
\fi
1350
\normaloffinterlineskip
}
1351 1352
\let
\oninterlineskip
\relax
1353 1354
\unexpanded
\def
\leaveoutervmode
1355
{
\ifvmode\ifinner
\else
1356
\leavevmode
1357
\fi\fi
}
1358 1359
\unexpanded
\def
\resetpenalties
#
1
%
1360
{
\ifdefined
#
1
%
1361
#
1
\minusone
1362
\fi
}
1363 1364
\unexpanded
\def
\setpenalties
#
1
#
2
#
3
%
1365
{
\ifdefined
#
1
% space before #3 prevents lookahead problems, needed when #3=text
1366
#
1
\numexpr
#
2
+
\plusone
\relax
\space
\doexpandedrecurse
{
\the\numexpr
#
2
\relax
}{
#
3
}
\zerocount
\relax
1367
\fi
}
1368 1369
%D \macros
1370
%D {keeplinestogether}
1371
%D
1372
%D Dirty hack, needed in margin content that can run of a page.
1373 1374
% just before margintexts ... will eventually be done differently in mkiv using
1375
% attributes
1376 1377
\newcount
\c_spac_keep_lines_together
1378
\let
\restoreinterlinepenalty
\relax
1379 1380
\unexpanded
\def
\spac_penalties_restore
1381
{
\glet
\restoreinterlinepenalty
\relax
1382
\global
\resetpenalties
\interlinepenalties
1383
\global
\c_spac_keep_lines_together
\zerocount
}
1384 1385
\unexpanded
\def
\keeplinestogether
#
1
%
1386
{
\ifnum
#
1
>
\c_spac_keep_lines_together
1387
\global
\c_spac_keep_lines_together
#
1
%
1388
\global
\setpenalties
\interlinepenalties
\c_spac_keep_lines_together
\plustenthousand
1389
\glet
\restoreinterlinepenalty
\spac_penalties_restore
1390
\fi
}
1391 1392
\def
\defaultdisplaywidowpenalty
{
5
0
}
1393
\def
\defaultwidowpenalty
{
2
0
0
0
}
% was: 1000
1394
\def
\defaultclubpenalty
{
2
0
0
0
}
% was: 800
1395
\def
\defaultbrokenpenalty
{
1
0
0
}
1396
\def
\defaultdoublehyphendemerits
{
1
0
0
0
0
}
1397
\def
\defaultfinalhyphendemerits
{
5
0
0
0
}
1398
\def
\defaultadjdemerits
{
1
0
0
0
0
}
1399 1400
\def
\defaultgriddisplaywidowpenalty
{
0
}
1401
\def
\defaultgridwidowpenalty
{
0
}
1402
\def
\defaultgridclubpenalty
{
0
}
1403
\def
\defaultgridbrokenpenalty
{
0
}
1404
\def
\defaultgriddoublehyphendemerits
{
1
0
0
0
0
}
% always was so
1405
\def
\defaultgridfinalhyphendemerits
{
5
0
0
0
}
% always was so
1406
\def
\defaultgridadjdemerits
{
1
0
0
0
0
}
% always was so
1407 1408
\unexpanded
\def
\nopenalties
1409
{
\widowpenalty
\zerocount
1410
\clubpenalty
\zerocount
1411
\brokenpenalty
\zerocount
1412
\doublehyphendemerits
\zerocount
1413
\finalhyphendemerits
\zerocount
1414
\adjdemerits
\zerocount
}
1415 1416
\unexpanded
\def
\setdefaultpenalties
1417
{
\directsetup
{
\systemsetupsprefix
\s!default
}}
1418 1419
\startsetups
[
\systemsetupsprefix
\s!reset
]
1420
\resetpenalties
\widowpenalties
1421
\resetpenalties
\clubpenalties
1422
\resetpenalties
\interlinepenalties
1423
\stopsetups
1424 1425
%D We use \directsetup because it's faster and we know there is no csl:
1426 1427
\startsetups
[
\systemsetupsprefix
\s!default
]
1428 1429
\directsetup
{
\systemsetupsprefix
\s!reset
}
1430 1431
\widowpenalty
\defaultwidowpenalty
1432
\clubpenalty
\defaultclubpenalty
1433
\displaywidowpenalty
\defaultdisplaywidowpenalty
1434
\brokenpenalty
\defaultbrokenpenalty
1435
\doublehyphendemerits
\defaultdoublehyphendemerits
1436
\finalhyphendemerits
\defaultfinalhyphendemerits
1437
\adjdemerits
\defaultadjdemerits
1438 1439
\stopsetups
1440 1441
\startsetups
[
\v!grid
]
[
\systemsetupsprefix
\s!default
]
1442 1443
\directsetup
{
\systemsetupsprefix
\s!reset
}
1444 1445
\widowpenalty
\defaultgridwidowpenalty
1446
\clubpenalty
\defaultgridclubpenalty
1447
\displaywidowpenalty
\defaultgriddisplaywidowpenalty
1448
\brokenpenalty
\defaultgridbrokenpenalty
1449
\doublehyphendemerits
\defaultgriddoublehyphendemerits
1450
\finalhyphendemerits
\defaultgridfinalhyphendemerits
1451
\adjdemerits
\defaultgridadjdemerits
1452 1453
\stopsetups
1454 1455
%D As an illustration:
1456 1457
\startsetups
[
\systemsetupsprefix
\v!strict
]
1458 1459
\directsetup
{
\systemsetupsprefix
\s!reset
}
1460 1461
\setpenalties
\widowpenalties
\plustwo
\maxdimen
1462
\setpenalties
\clubpenalties
\plustwo
\maxdimen
1463
\brokenpenalty
\maxdimen
1464
\doublehyphendemerits
\defaultdoublehyphendemerits
1465
\finalhyphendemerits
\defaultfinalhyphendemerits
1466
\adjdemerits
\defaultadjdemerits
1467 1468
\stopsetups
1469 1470
\setdefaultpenalties
% will happen later in \setuplayout
1471 1472
%D To be checked:
1473 1474
\newbox
\b_spac_struts_saved
1475 1476
\unexpanded
\def
\savestrut
{
\setbox
\b_spac_struts_saved
\copy
\strutbox
}
1477
\unexpanded
\def
\savedstrut
{
\copy
\b_spac_struts_saved
}
1478 1479
%D Good old blank redone:
1480 1481
%definesystemattribute[kernchars] [public]
1482
\definesystemattribute
[
skipcategory
]
[
public
]
1483
\definesystemattribute
[
skippenalty
]
[
public
]
1484
\definesystemattribute
[
skiporder
]
[
public
]
1485
\definesystemattribute
[
snapmethod
]
[
public
]
1486
\definesystemattribute
[
snapvbox
]
[
public
]
1487
%definesystemattribute[snapcategory] [public]
1488 1489
% TODO: NAMED SNAPPERS
1490 1491
\installcorenamespace
{
gridsnappers
}
1492
\installcorenamespace
{
gridsnapperattributes
}
1493
\installcorenamespace
{
gridsnappersets
}
1494 1495
\newskip
\bodyfontlineheight
1496
\newdimen
\bodyfontstrutheight
1497
\newdimen
\bodyfontstrutdepth
1498 1499
\newskip
\globalbodyfontlineheight
% why a skip
1500
\newdimen
\globalbodyfontstrutheight
1501
\newdimen
\globalbodyfontstrutdepth
1502 1503
\def
\snappedvboxattribute
{
\ifgridsnapping
attr
\snapvboxattribute
\c_attr_snapmethod
\fi
}
1504
\def
\setlocalgridsnapping
{
\ifgridsnapping
\c_attr_snapvbox
\c_attr_snapmethod
\fi
}
1505 1506
\def
\spac_grids_set_local_snapping
#
1
%
1507
{
\ifgridsnapping
1508
\doifsomething
{
#
1
}
%
1509
{
\spac_grids_snap_value_set
{
#
1
}
%
1510
\c_attr_snapvbox
\c_attr_snapmethod
}
%
1511
\fi
}
1512 1513
% \unexpanded\def\installsnapvalues#1#2% todo: a proper define
1514
% {\edef\currentsnapper{#1:#2}%
1515
% \ifcsname\??gridsnapperattributes\currentsnapper\endcsname \else
1516
% \setevalue{\??gridsnapperattributes\currentsnapper}{\clf_definesnapmethod{#1}{#2}}%
1517
% \fi
1518
% \setevalue{\??gridsnappers#1}{\c_attr_snapmethod\csname\??gridsnapperattributes\currentsnapper\endcsname\space}}
1519 1520
\def
\spac_grids_expand_snapper
#
1
%
1521
{
\edef
\m_spac_snapper
1522
{
\ifx
\m_spac_snapper
\empty
\else
\m_spac_snapper
,
\fi
1523
\ifcsname
\??gridsnappersets
#
1
\endcsname
1524
\lastnamedcs\else
#
1
%
1525
\fi
}}
1526 1527
\unexpanded
\def
\installsnapvalues
#
1
#
2
%
1528
{
\let
\m_spac_snapper
\empty
1529
\rawprocesscommacommand
[#
2
]
\spac_grids_expand_snapper
1530
\edef
\currentsnapper
{
#
1
:
\m_spac_snapper
}
%
1531
\ifcsname
\??gridsnapperattributes
\currentsnapper
\endcsname
1532
\scratchcounter
\lastnamedcs
% already defined
1533
\else
1534
\scratchcounter
\clf_definesnapmethod
{
#
1
}{
\m_spac_snapper
}
%
1535
\setevalue
{
\??gridsnapperattributes
\currentsnapper
}{
\the
\scratchcounter
}
%
1536
\fi
1537
\setevalue
{
\??gridsnappers
#
1
}{
\c_attr_snapmethod
\the
\scratchcounter
\relax
}
%
1538
\letvalue
{
\??gridsnappersets
#
1
}
\m_spac_snapper
}
1539 1540
\def
\theexpandedsnapperset
#
1
{
\begincsname
\??gridsnappersets
#
1
\endcsname
}
% only for manuals
1541 1542
\unexpanded
\def
\usegridparameter
#
1
% no checking here
1543
{
\edef
\m_spac_grid_asked
{
#
1
\c!grid
}
%
1544
\ifx
\m_spac_grid_asked
\empty
1545
\c_attr_snapvbox
\attributeunsetvalue
1546
\else
1547
\spac_grids_snap_value_set
\m_spac_grid_asked
1548
\c_attr_snapvbox
\c_attr_snapmethod
1549
\fi
}
1550 1551
\unexpanded
\def
\definegridsnapping
1552
{
\dodoubleargument
\spac_grids_define
}
1553 1554
\def
\spac_grids_define
[#
1
][#
2
]
%
1555
{
\installsnapvalues
{
#
1
}{
#
2
}}
1556 1557
\edef
\spac_grids_snap_value_reset
1558
{
%\gridsnappingfalse
1559
\c_attr_snapmethod
\attributeunsetvalue
}
1560 1561
\def
\spac_grids_snap_value_set
#
1
%
1562
{
%\gridsnappingtrue
1563
\begincsname
\??gridsnappers
#
1
\endcsname
}
1564 1565
% maybe:
1566
%
1567
% \def\spac_grids_snap_value_set#1%
1568
% {%\gridsnappingtrue
1569
% \ifcsname\??gridsnappers#1\endcsname
1570
% \lastnamedcs
1571
% \else
1572
% \definegridsnapping[#1][#1]%
1573
% \begincsname\??gridsnappers#1\endcsname
1574
% \fi}
1575 1576
\def
\spac_grids_snap_value_auto
#
1
%
1577
{
\ifcsname
\??gridsnappers
#
1
\endcsname
1578
\lastnamedcs
1579
\else
1580
\installsnapvalues
\s!dummy
{
#
1
}
%
1581
\csname
\??gridsnappers\s!dummy
\endcsname
1582
\fi
}
1583 1584
% \installsnapvalues{loose} {\v!maxdepth:0.8,\v!maxheight:0.8,\v!strut}
1585
% \installsnapvalues{normal}{\v!maxdepth:1.0,\v!maxheight:1.0,\v!strut}
1586
% \installsnapvalues{tight} {\v!maxdepth:1.2,\v!maxheight:1.2,\v!strut}
1587 1588
% none don't enlarge
1589
% halfline enlarge by halfline/halfline
1590
% line enlarge by line/line
1591
% strut enlarge by ht/dp (default)
1592
% first align to top line
1593
% last align to bottom line
1594
% mindepth round depth down
1595
% maxdepth round depth up
1596
% minheight round height down
1597
% maxheight round height up
1598
% local use local interline space
1599
% offset:-3tp vertical shift within box
1600
% bottom:lines
1601
% top:lines
1602
% box centers a box rounded upwards (box:.5 -> tolerance)
1603
% min centers a box rounded downwards
1604
% max centers a box rounded upwards
1605 1606
%D We're not downward compatible with \MKII ! Not yet in interface file:
1607 1608
\definegridsnapping
[
\v!normal
]
[
\v!maxheight
,
\v!maxdepth
,
\v!strut
]
1609
\definegridsnapping
[
\v!standard
]
[
\v!maxheight
,
\v!maxdepth
,
\v!strut
]
1610
\definegridsnapping
[
\v!yes
]
[
\v!maxheight
,
\v!maxdepth
,
\v!strut
]
1611 1612
\definegridsnapping
[
\v!strict
]
[
\v!maxdepth
:
0
.
8
,
\v!maxheight
:
0
.
8
,
\v!strut
]
1613
\definegridsnapping
[
\v!tolerant
]
[
\v!maxdepth
:
1
.
2
,
\v!maxheight
:
1
.
2
,
\v!strut
]
1614
\definegridsnapping
[
\v!verytolerant
]
[
\v!maxdepth
:
1
.
4
,
\v!maxheight
:
1
.
4
,
\v!strut
]
1615 1616
\definegridsnapping
[
\v!tolerant
:
1
0
]
[
\v!maxdepth
:
1
.
1
,
\v!maxheight
:
1
.
1
,
\v!strut
]
% 10 pct tolerance
1617
\definegridsnapping
[
\v!tolerant
:
2
0
]
[
\v!maxdepth
:
1
.
2
,
\v!maxheight
:
1
.
2
,
\v!strut
]
% 20 pct tolerance
1618
\definegridsnapping
[
\v!tolerant
:
3
0
]
[
\v!maxdepth
:
1
.
3
,
\v!maxheight
:
1
.
3
,
\v!strut
]
% 30 pct tolerance
1619
\definegridsnapping
[
\v!tolerant
:
4
0
]
[
\v!maxdepth
:
1
.
4
,
\v!maxheight
:
1
.
4
,
\v!strut
]
% 40 pct tolerance
1620 1621
\definegridsnapping
[
\v!top
]
[
\v!minheight
,
\v!maxdepth
,
\v!strut
]
1622
\definegridsnapping
[
\v!bottom
]
[
\v!maxheight
,
\v!mindepth
,
\v!strut
]
1623
\definegridsnapping
[
\v!both
]
[
\v!minheight
,
\v!mindepth
,
\v!strut
]
1624 1625
\definegridsnapping
[
\v!broad
]
[
\v!maxheight
,
\v!maxdepth
,
\v!strut
,
0
.
8
]
% maybe 0.85
1626
\definegridsnapping
[
\v!fit
]
[
\v!maxheight
,
\v!maxdepth
,
\v!strut
,
1
.
2
]
% tight 0.15
1627 1628
\definegridsnapping
[
\v!first
]
[
\v!first
]
1629
\definegridsnapping
[
\v!last
]
[
\v!last
]
1630
\definegridsnapping
[
\v!high
]
[
\v!minheight
,
\v!maxdepth
,
\v!none
]
1631
\definegridsnapping
[
\v!one
]
[
\v!minheight
,
\v!mindepth
]
1632
\definegridsnapping
[
\v!low
]
[
\v!maxheight
,
\v!mindepth
,
\v!none
]
1633
\definegridsnapping
[
\v!none
]
[
\v!none
]
1634
\definegridsnapping
[
\v!line
]
[
\v!line
]
1635
\definegridsnapping
[
\v!strut
]
[
\v!strut
]
1636
\definegridsnapping
[
\v!box
]
[
\v!box
]
1637
\definegridsnapping
[
\v!min
]
[
\v!min
]
1638
\definegridsnapping
[
\v!max
]
[
\v!max
]
1639 1640
\definegridsnapping
[
\v!middle
]
[
\v!maxheight
,
\v!maxdepth
]
% used in placement
1641 1642
\definegridsnapping
[
\v!math
]
[
\v!maxdepth
:
1
.
0
5
,
\v!maxheight
:
1
.
0
5
,
\v!strut
]
% experimental, maybe 1.1
1643
\definegridsnapping
[
\v!math
:
\v!line
]
[
\v!math
,
\v!line
,
\v!split
]
1644
\definegridsnapping
[
\v!math
:
\v!halfline
]
[
\v!math
,
\v!halfline
,
\v!split
]
1645
\definegridsnapping
[
\v!math
:
-
\v!line
]
[
\v!math
,
-
\v!line
,
\v!split
]
1646
\definegridsnapping
[
\v!math
:
-
\v!halfline
][
\v!math
,
-
\v!halfline
,
\v!split
]
1647 1648
\unexpanded
\def
\synchronizelocallinespecs
1649
{
\bodyfontlineheight
\normallineheight
1650
\bodyfontstrutheight
\strutht
1651
\bodyfontstrutdepth
\strutdp
}
1652 1653
\unexpanded
\def
\synchronizegloballinespecs
1654
{
\global
\globalbodyfontlineheight
\normallineheight
1655
\global
\globalbodyfontstrutheight
\strutht
1656
\global
\globalbodyfontstrutdepth
\strutdp
}
1657 1658
\appendtoks
1659
\synchronizegloballinespecs
1660
\synchronizelocallinespecs
1661
\to
\everysetupglobalinterlinespace
1662 1663
\appendtoks
1664
\synchronizelocallinespecs
1665
\to
\everysetuplocalinterlinespace
1666 1667
%D We still have to synchronize these:
1668 1669
\unexpanded
\def
\synchronizeskipamounts
1670
{
\bigskipamount
1671
\skipfactor
\baselineskip
1672
\s!plus
\skipgluefactor
\baselineskip
1673
\s!minus
\skipgluefactor
\baselineskip
1674
\relax
1675
\medskipamount
\bigskipamount
\divide
\medskipamount
\plustwo
1676
\smallskipamount\bigskipamount
\divide
\smallskipamount\plusfour
}
1677 1678
%D Snapping.
1679 1680
\newif
\ifgridsnapping
1681 1682
%unexpanded\def\moveongrid {\dosingleempty\spac_grids_move_on}
1683
\unexpanded
\def
\snaptogrid
{
\dosingleempty
\spac_grids_snap_to
}
1684
\unexpanded
\def
\placeongrid
{
\dosingleempty
\spac_grids_place_on
}
1685 1686
\unexpanded
\def
\startgridsnapping
1687
{
\dosingleempty
\spac_grids_start_snapping
}
1688 1689
\unexpanded
\def
\spac_grids_start_snapping
[#
1
]
%
1690
{
\snaptogrid
[#
1
]
\vbox
\bgroup
}
1691 1692
\unexpanded
\def
\stopgridsnapping
1693
{
\egroup
}
1694 1695
% \def\spac_grids_move_on[#1]%
1696
% {[obsolete]} % gone, unless we set an attribute
1697 1698
\def
\spac_grids_place_on
[#
1
]
%
1699
{
\snaptogrid
[#
1
]
\vbox
}
% mark as done
1700 1701
\def
\spac_grids_snap_to
[#
1
]
% list or predefined
1702
{
\ifgridsnapping
1703
\expandafter
\spac_grids_snap_to_indeed
1704
\else
1705
\expandafter
\gobbleoneargument
1706
\fi
{
#
1
}}
1707 1708
\def
\spac_grids_snap_to_indeed
#
1
%
1709
{
\bgroup
1710
\spac_grids_snap_value_reset
1711
\dowithnextbox
{
\spac_grids_snap_to_finish
{
#
1
}}}
1712 1713
% eventually there will always be a line snap
1714 1715
\def
\spac_grids_snap_to_finish
#
1
%
1716
{
\ifvbox
\nextbox
% this will go away
1717
\clf_vspacingcollapse
\nextbox
\relax
% isn't that already done?
1718
\fi
1719
\doifelsenothing
{
#
1
}{
\spac_grids_snap_value_set
\v!normal
}{
\spac_grids_snap_value_set
{
#
1
}}
%
1720
\clf_vspacingsnap
\nextbox
\c_attr_snapmethod
\relax
1721
\ifvbox
\nextbox
\vbox\else\hbox\fi
attr
\snapmethodattribute
\zerocount
{
\box
\nextbox
}
% no pack (?), we snap
1722
\egroup
}
1723 1724
\def
\spac_grids_check_nop
1725
{
\gridsnappingfalse
1726
\resetsystemmode
\v!grid
1727
\spac_grids_snap_value_reset
}
1728 1729
\def
\spac_grids_check_yes
1730
{
\gridsnappingtrue
1731
\setsystemmode
\v!grid
1732
\spac_grids_snap_value_set
\askedgridmode
}
1733 1734
\unexpanded
\def
\synchronizegridsnapping
1735
{
\edef
\askedgridmode
{
\layoutparameter
\c!grid
}
%
1736
\ifx
\askedgridmode
\v!no
% official
1737
\spac_grids_check_nop
1738
\else\ifx
\askedgridmode
\v!off
% for taco and luigi
1739
\spac_grids_check_nop
1740
\else\ifx
\askedgridmode
\empty
% to be sure
1741
\spac_grids_check_nop
1742
\else
1743
\spac_grids_check_yes
1744
\fi\fi\fi
}
1745 1746
\unexpanded
\def
\setupgridsnapping
[#
1
]
% less overhead than setuplayout (needs testing)
1747
{
\setlayoutparameter
\c!grid
{
#
1
}
\synchronizegridsnapping
}
1748 1749
\unexpanded
\def
\checkgridmethod
#
1
%
1750
{
\edef
\p_grid
{
#
1
}
%
1751
\ifx
\p_grid
\empty
1752
\let
\checkedgridmethod
\empty
1753
\let
\checkedgridscope
\v!local
1754
\else
1755
\splitatcolon
\p_grid
\checkedgridscope
\checkedgridmethod
1756
\ifx
\checkedgridmethod
\empty
1757
\ifx
\checkedgridscope
\v!local
\else\ifx
\checkedgridscope
\v!global
\else
1758
\let
\checkedgridmethod
\checkedgridscope
1759
\let
\checkedgridscope
\v!local
1760
\fi\fi
1761
\fi
1762
\fi
}
1763 1764
\unexpanded
\def
\applygridmethod
#
1
#
2
#
3
% content localsettings (used in head rendering)
1765
{
\checkgridmethod
{
#
1
}
%
1766
\ifx
\checkedgridscope
\v!global
1767
\ifx
\checkedgridmethod
\empty
\else
1768
% we assume that the call is grouped because grouping here has the side
1769
% effect that the eventually constructed line will get the value outside
1770
% the group
1771
%
1772
% overkill: \setupgridsnapping[\checkedgridmethod]%
1773
% maybe : \spac_grids_snap_value_auto\checkedgridmethod
1774
\spac_grids_snap_value_set
\checkedgridmethod
1775
\fi
1776
\hbox
{
#
3
}
%
1777
\else
1778
% the extra hbox will trigger the global snapper on top of the local and
1779
% we really need that in this case (compatibility etc etc) so here we don't
1780
% het an already done hit (otherwise we would not snap)
1781
\hbox
\bgroup
1782
\ifx
\checkedgridmethod
\empty
\else
1783
\ifconditional
\headisdisplay
1784
#
2
%
1785
\fi
1786
\fi
1787
\snaptogrid
[
\checkedgridmethod
]
\hbox
{
#
3
}
%
1788
\egroup
1789
\fi
}
1790 1791
\unexpanded
\gdef
\page_layouts_calculate_overshoot
1792
{
\ifgridsnapping\ifcase
\layoutlines
1793
\getnoflines
\textheight
1794
\textovershoot
\dimexpr
\noflines
\globalbodyfontlineheight
-
\textheight
\relax
1795
\fi\fi
}
1796 1797
\unexpanded
\def
\page_layouts_report_overshoot
1798
{
\page_layouts_calculate_overshoot
1799
\ifdim
\textovershoot
>
\zeropoint
1800
\writestatus
\m!layouts
{
gridmode
,
\space
1801
noflines
:
\the
\noflines
,
\space
1802
textheight
:
\the
\textheight
,
\space
1803
textovershoot
:
\the
\textovershoot
\space
1804
(
maybe
set
number
of
lines
instead
)
%
1805
}
%
1806
\fi
1807
\glet
\page_layouts_report_overshoot
\page_layouts_calculate_overshoot
}
1808 1809
\appendtoks
1810
\page_layouts_report_overshoot
1811
\to
\everybeforepagebody
1812 1813
%D Visualization:
1814 1815
\definepalet
1816
[
grid
]
1817
[
one
=
red
,
1818
two
=
green
,
1819
three
=
blue
,
1820
four
=
gray
]
1821 1822
\unexpanded
\def
\setgridtracebox
#
1
[#
2
]
% % maybe reverse the order
1823
{
\setbox
\nextbox
#
1
%
1824
{
\hbox
1825
{
\hbox
to
\zeropoint
1826
{
\setlayoutcomponentattribute
{
\v!grid
:
\v!test
}
%
1827
\color
[
grid
:
#
2
]
{
\ruledhbox
\layoutcomponentboxattribute
{
\fakebox\nextbox
}}
%
1828
\hss
}
%
1829
\flushnextbox
}}}
1830 1831
\setnewconstant
\gridboxlinenomode
\plusone
% 0:nothing 1:all 2:lines 3:frame 4:l/r
1832
\setnewconstant
\gridboxlinemode
\plusone
1833 1834
\unexpanded
\def
\gridboxvbox
1835
{
\ifcase
\gridboxlinemode
1836
\vpack
1837
\or
1838
\ruledvpack
1839
\or
1840
\vpack
1841
\or
1842
\ruledvpack
1843
\else
1844
\ruledvpack
1845
\fi
}
1846 1847
\def
\gridboxwidth
{
\ifcase
\gridboxlinemode
0
\or
.
5
\or
.
5
\or
0
\else
.
5
\fi
\linewidth
}
1848 1849
\unexpanded
\def
\setgridbox
#
1
#
2
#
3
% maybe ifgridsnapping at outer level
1850
{
\setbox
#
1
\gridboxvbox
to
#
3
% given size
1851
{
\forgetall
1852
\resetvisualizers
1853
\resetteststrut
1854
\offinterlineskip
1855
\hsize
#
2
%
1856
\ifcase
\gridboxlinenomode
\or\or\or
1857
\gridboxlinenomode
\doifoddpageelse
\plusone\plustwo
% 3: outer
1858
\or
1859
\gridboxlinenomode
\doifoddpageelse
\plustwo\plusone
% 4: inner
1860
\fi
1861
\topskipcorrection
1862
\gridboxvbox
% calculated size
1863
{
\getrawnoflines
{
#
3
}
% \getnoflines{#3}%
1864
\scratchdimen
\dimexpr
#
2
+
\lineheight
\relax
1865
\dorecurse
\noflines
1866
{
\strut
1867
\hskip
-
.
5
\lineheight
\relax
1868
\ifcase
\gridboxlinenomode
\or
1869
\rlap
1870
{
\hskip\dimexpr
.
2
\bodyfontsize
+
\scratchdimen
\relax
1871
\infofont
\hbox
to
\emwidth
{
\hss
\recurselevel
}}
%
1872
\or
1873
\llap
1874
{
\infofont
\hbox
to
\emwidth
{
\hss
\recurselevel
}
%
1875
\hskip
.
2
\bodyfontsize
}
%
1876
\fi
1877
\vrule
1878
\s!height
\gridboxwidth
1879
\s!depth
\gridboxwidth
1880
\s!width
\scratchdimen
1881
\par
}}
1882
\vfill
}}
1883 1884
%D This has become obsolete:
1885 1886
\def
\fuzzysnappedbox
#
1
#
2
% \box<n> \unvbox<n>
1887
{
#
1
#
2
}
1888 1889
\def
\moveboxontogrid
#
1
#
2
#
3
% will become obsolete, but it needs checking
1890
{}
1891 1892
%D Helper:
1893 1894
\unexpanded
\def
\spac_helpers_assign_skip
#
1
#
2
% ook nog \v!halfline+fuzzysnap
1895
{
\doifelse
{
#
2
}
\v!line
1896
{
#
1
\ifgridsnapping
1897
\bodyfontlineheight
1898
\else
1899
\openlineheight
1900
\fi
}
1901
{
\ifgridsnapping
1902
\assigndimension
{
#
2
}{
#
1
}{
.
2
5
\bodyfontlineheight
}{
.
5
\bodyfontlineheight
}
\bodyfontlineheight
1903
\else
1904
\assigndimension
{
#
2
}{
#
1
}
\smallskipamount\medskipamount\bigskipamount
1905
\fi
}
%
1906
\relax
}
1907 1908
% \start \dosetstretch{.25em} \setuptolerance[tolerant,stretch] \input tufte \endgraf \stop
1909
% \start \dosetstretch{.5em} effe flink doorfietsen \stop
1910 1911
% experimental code, not yet interfaced:
1912 1913
% category:
1914
%
1915
% 0 == discard discard
1916
% 1 == only if larger largest
1917
% 2 == force even if smaller force
1918
% 3 == only take penalty component penalty
1919
% 4 == add to existing skip add
1920
% 5 == disable (ignore following) disable
1921
% 6 == kill whitespace nowhite
1922
% 7 == discard previous back
1923
% 10 == no topskip
1924
%
1925
% penalty: larger wins
1926
% order: larger wins
1927
% category:2,order:5,penalty:10000,skip:value|kw
1928
%
1929
% \defineblankmethod [\v!joinedup] {\ifvmode\nointerlineskip\fi}
1930 1931
% todo, in grid mode: builders.vspacing.fixed = false
1932
%
1933
% \ifgridsnapping will go
1934 1935
\installcorenamespace
{
vspacingamount
}
1936 1937
\unexpanded
\def
\definevspacingamount
1938
{
\dotripleempty
\spac_vspacing_define_amount
}
1939 1940
\def
\spac_vspacing_define_amount
[#
1
][#
2
][#
3
]
% can be combined
1941
{
\ifthirdargument
1942
\setvalue
{
\??vspacingamount
#
1
}{
\ifgridsnapping
#
3
\else
#
2
\fi
}
%
1943
\else
\ifsecondargument
1944
\setvalue
{
\??vspacingamount
#
1
}{
\ifgridsnapping
\lineheight
\else
#
2
\fi
}
%
1945
\else
1946
\setvalue
{
\??vspacingamount
#
1
}{
\lineheight
}
%
1947
\fi\fi
1948
\clf_vspacingsetamount
{
#
1
}}
1949 1950
\def
\spac_vspacing_no_topskip
% use grouped
1951
{
\c_attr_skipcategory
\plusten
}
1952 1953
% \installcorenamespace{vspacingamountnormal}
1954
% \installcorenamespace{vspacingamountgrid}
1955 1956
% \def\spac_vspacing_define_amount[#1][#2][#3]% can be combined
1957
% {\ifcsname n>#1\endcsname\else
1958
% \expandafter\newtoks\csname n>#1\endcsname
1959
% \expandafter\newtoks\csname g>#1\endcsname
1960
% \fi
1961
% \csname n>#1\endcsname{#2}%
1962
% \csname g>#1\endcsname{#3}%
1963
% \clf_vspacingsetamount{#1}}
1964 1965
\unexpanded
\def
\definevspacing
1966
{
\dodoubleempty
\spac_vspacing_define
}
1967 1968
\def
\spac_vspacing_define
[#
1
][#
2
]
%
1969
{
\clf_vspacingdefine
{
#
1
}{
#
2
}}
1970 1971
%D The injector code (generated at the \LUA\ end):
1972 1973
\newtoks
\everybeforeblankhandling
1974
\newtoks
\everyafterblankhandling
1975 1976
\newconditional
\c_space_vspacing_done
1977
\newconditional
\c_space_vspacing_fixed
1978
\newconditional
\c_space_ignore_parskip
1979 1980
\appendtoks
1981
\s_spac_vspacing_temp
\zeropoint
1982
\c_attr_skipcategory
\plusone
1983
\c_attr_skippenalty
\attributeunsetvalue
1984
\c_attr_skiporder
\attributeunsetvalue
1985
\ifgridsnapping
1986
\settrue
\c_space_vspacing_fixed
1987
\else
1988
\setfalse
\c_space_vspacing_fixed
1989
\fi
1990
\to
\everybeforeblankhandling
1991 1992
\appendtoks
1993
\s_spac_vspacing_temp
\plusone
\s_spac_vspacing_temp
1994
\ifconditional
\c_space_vspacing_fixed
\else
1995
\s!plus
\skipgluefactor
\s_spac_vspacing_temp
1996
\s!minus
\skipgluefactor
\s_spac_vspacing_temp
1997
\fi
1998
\relax
1999
\to
\everyafterblankhandling
2000 2001
\unexpanded
\def
\setblankpacked
2002
{
\settrue
\c_space_ignore_parskip
}
2003 2004
\unexpanded
\def
\setblankcategory
#
1
%
2005
{
\settrue
\c_space_vspacing_done
2006
\c_attr_skipcategory
#
1
\relax
}
2007 2008
\unexpanded
\def
\setblankorder
#
1
%
2009
{
\c_attr_skiporder
#
1
\relax
}
2010 2011
\unexpanded
\def
\fixedblankskip
2012
{
\settrue
\c_space_vspacing_fixed
}
2013 2014
\unexpanded
\def
\flexibleblankskip
2015
{
\setfalse
\c_space_vspacing_fixed
}
2016 2017
% \unexpanded\def\addblankskip#1#2#3%
2018
% {\settrue\c_space_vspacing_done
2019
% \advance\s_spac_vspacing_temp#1\dimexpr\ifgridsnapping#3\else#2\fi\relax\relax}
2020 2021
\unexpanded
\def
\setblankpenalty
#
1
%
2022
{
\flushblankhandling
2023
\settrue
\c_space_vspacing_done
2024
\c_attr_skipcategory
\plusthree
2025
\c_attr_skippenalty
#
1
\relax
2026
\flushblankhandling
}
2027 2028
\unexpanded
\def
\startblankhandling
% move this to \vspacing
2029
{
\par
2030
\ifvmode
2031
\expandafter
\dostartblankhandling
2032
\else
2033
\expandafter
\nostartblankhandling
2034
\fi
}
2035 2036
\unexpanded
\def
\nostartblankhandling
#
1
\stopblankhandling
2037
{}
2038 2039
\def
\dostartblankhandling
2040
{
\begingroup
2041
\setfalse
\c_space_vspacing_done
2042
\setfalse
\c_space_ignore_parskip
2043
\the
\everybeforeblankhandling
}
2044 2045
\unexpanded
\def
\stopblankhandling
2046
{
\the
\everyafterblankhandling
2047
\ifconditional
\c_space_vspacing_done
2048
\vskip
\s_spac_vspacing_temp
2049
\fi
2050
\ifconditional
\c_space_ignore_parskip
2051
\endgroup
\ignoreparskip
2052
\else
2053
\endgroup
2054
\fi
}
2055 2056
\unexpanded
\def
\flushblankhandling
2057
{
\the
\everyafterblankhandling
2058
\ifconditional
\c_space_vspacing_done
2059
\vskip
\s_spac_vspacing_temp
2060
\fi
2061
\setfalse
\c_space_vspacing_done
2062
\the
\everybeforeblankhandling
}
2063 2064
\unexpanded
\def
\addpredefinedblankskip
#
1
#
2
%
2065
{
\settrue
\c_space_vspacing_done
2066
\advance
\s_spac_vspacing_temp
#
1
\dimexpr\csname
\??vspacingamount
#
2
\endcsname\relax
}
2067 2068
% \unexpanded\def\addpredefinedblankskip#1#2%
2069
% {\settrue\c_space_vspacing_done
2070
% \advance\s_spac_vspacing_temp#1\dimexpr\the\csname\ifgridsnapping g\else n\fi>#2\endcsname\relax}
2071 2072
\unexpanded
\def
\addaskedblankskip
#
1
#
2
%
2073
{
\settrue
\c_space_vspacing_done
2074
\advance
\s_spac_vspacing_temp
#
1
\dimexpr
#
2
\relax
}
2075 2076
% The main spacer:
2077 2078
\unexpanded
\def
\vspacing
2079
{
\doifelsenextoptionalcs
\spac_vspacing_yes
\spac_vspacing_nop
}
2080 2081
\def
\spac_vspacing_yes
2082
{
\ifinpagebody
% somewhat weird
2083
\singleexpandafter
\spac_vspacing_yes_indeed
2084
\else
\ifconditional
\c_spac_packed_blank
2085
\doubleexpandafter
\spac_vspacing_yes_indeed
2086
\else
2087
\doubleexpandafter
\spac_vspacing_yes_ignore
2088
\fi\fi
}
2089 2090
\def
\spac_vspacing_nop
2091
{
\ifinpagebody
% somewhat weird
2092
\singleexpandafter
\spac_vspacing_nop_indeed
2093
\else
\ifconditional
\c_spac_packed_blank
2094
\doubleexpandafter
\spac_vspacing_nop_indeed
2095
\else
2096
\doubleexpandafter
\spac_vspacing_nop_ignore
2097
\fi\fi
}
2098 2099
\def
\spac_vspacing_yes_indeed
[#
1
]
%
2100
{
\ifmmode
\else\par
\clf_vspacing
{
#
1
}
\fi
}
2101 2102
\def
\spac_vspacing_yes_ignore
[#
1
]
%
2103
{
\ifmmode
\else\par\fi
}
2104 2105
\def
\spac_vspacing_nop_indeed
2106
{
\ifmmode
\else\par
\clf_vspacing
{
\currentvspacing
}
\fi
}
2107 2108
\def
\spac_vspacing_nop_ignore
2109
{
\ifmmode
\else\par\fi
}
2110 2111
% \unexpanded\def\directvspacing#1%
2112
% {\par\clf_vspacing{#1}}
2113
%
2114
%
2115
% \def\directdefaultvspacing
2116
% {\ifinpagebody % somewhat weird
2117
% \clf_vspacing{\currentvspacing}%
2118
% \else\ifconditional\c_spac_packed_blank
2119
% \clf_vspacing{\currentvspacing}%
2120
% \fi\fi}
2121
%
2122
% \unexpanded\def\useblankparameter#1% faster local variant
2123
% {\edef\m_spac_blank_asked{#1\c!blank}%
2124
% \ifx\m_spac_blank_asked\empty\else
2125
% \clf_vspacing{\m_spac_blank_asked}
2126
% \fi}
2127 2128
\installcorenamespace
{
vspacing
}
2129 2130
\unexpanded
\def
\directvspacing
#
1
%
2131
{
\par
2132
\ifcsname
\??vspacing
#
1
\endcsname
2133
\lastnamedcs
2134
\else
2135
\spac_vspacing_yes_preset
{
#
1
}
%
2136
\fi
}
2137 2138
\def
\spac_vspacing_yes_preset
#
1
%
2139
{
\setxvalue
{
\??vspacing
#
1
}{
\clf_vspacing
{
#
1
}}
%
2140
%\writestatus{}{}%
2141
%\writestatus{#1}{\expandafter\meaning\csname\??vspacing#1\endcsname}%
2142
%\writestatus{}{}%
2143
\csname
\??vspacing
#
1
\endcsname
}
2144 2145
\def
\spac_vspacing_yes_indeed
[#
1
]
%
2146
{
\ifmmode
\else
2147
\directvspacing
{
#
1
}
%
2148
\fi
}
2149 2150
\def
\spac_vspacing_nop_indeed
2151
{
\ifmmode
\else
2152
\directvspacing
\currentvspacing
2153
\fi
}
2154 2155
\def
\directdefaultvspacing
2156
{
\ifinpagebody
% somewhat weird
2157
\directvspacing
\currentvspacing
2158
\else
\ifconditional
\c_spac_packed_blank
2159
\directvspacing
\currentvspacing
2160
\fi\fi
}
2161 2162
\def
\directcheckedvspacing
2163
{
\ifinpagebody
% somewhat weird
2164
\expandafter
\directvspacing
2165
\else
\ifconditional
\c_spac_packed_blank
2166
\doubleexpandafter
\directvspacing
2167
\else
2168
\doubleexpandafter\gobbleoneargument
2169
\fi\fi
}
2170 2171
\unexpanded
\def
\usespecificblankparameter
#
1
#
2
% faster local variant
2172
{
\edef
\m_spac_blank_asked
{
#
1
#
2
}
%
2173
\ifx
\m_spac_blank_asked
\empty
\else
2174
\directvspacing
\m_spac_blank_asked
2175
\fi
}
2176 2177
\unexpanded
\def
\useblankparameter
#
1
% faster local variant
2178
{
\usespecificblankparameter
#
1
\c!blank
}
2179 2180
%D Handy (and faster):
2181 2182
\unexpanded
\def
\directvpenalty
#
1
%
2183
{
\begingroup
2184
\c_attr_skipcategory
\plusthree
2185
\c_attr_skippenalty
#
1
\relax
2186
\c_attr_skiporder
\attributeunsetvalue
2187
\vskip
\zeropoint
2188
\endgroup
}
2189 2190
\unexpanded
\def
\directvskip
#
1
%
2191
{
\begingroup
2192
\c_attr_skipcategory
\plusone
2193
\c_attr_skippenalty
\attributeunsetvalue
2194
\c_attr_skiporder
\attributeunsetvalue
2195
\vskip
#
1
\relax
2196
\endgroup
}
2197 2198
%D These depend on bigskipamount cum suis so we'd better sync them:
2199 2200
\unexpanded
\def
\setupvspacing
2201
{
\doifelsenextoptionalcs
\setupvspacing_yes
\setupvspacing_nop
}
2202 2203
\let
\currentvspacing
\s!default
% hm, default, standard ...
2204 2205
\def
\setupvspacing_yes
[#
1
]
%
2206
{
\edef
\currentvspacing
{
#
1
}
%
2207
\spac_whitespace_setup_nop
% yes or no, was forgotten
2208
}
2209 2210
\def
\setupvspacing_nop
2211
{
\ifx
\empty
\currentvspacing
% mistakenly had an \else
2212
\let
\currentvspacing
\s!default
2213
\fi
2214
\spac_whitespace_setup_nop
}
2215 2216
\unexpanded
\def
\restorestandardblank
% or default ?
2217
{
\let
\currentvspacing
\v!standard
}
2218 2219
\let
\synchronizevspacing
\setupvspacing_nop
2220 2221
%D The \type {category:4} is default.
2222 2223
\definevspacingamount
[
\v!none
]
[
\zeropoint
]
[
\zeropoint
]
2224
\definevspacingamount
[
\v!big
]
[
\bigskipamount
]
[
\bodyfontlineheight
]
2225
\definevspacingamount
[
\v!medium
]
[
\medskipamount
]
[
.
5
\bodyfontlineheight
]
2226
\definevspacingamount
[
\v!small
]
[
\smallskipamount
]
[
.
2
5
\bodyfontlineheight
]
2227
\definevspacingamount
[
\v!line
]
[
\openlineheight
]
[
\bodyfontlineheight
]
2228
\definevspacingamount
[
\v!halfline
]
[
.
5
\openlineheight
]
[
.
5
\bodyfontlineheight
]
2229
\definevspacingamount
[
\v!quarterline
]
[
.
2
5
\openlineheight
]
[
.
2
5
\bodyfontlineheight
]
2230
\definevspacingamount
[
\v!formula
]
[
\medskipamount
]
[
.
5
\bodyfontlineheight
]
2231
\definevspacingamount
[
\v!white
]
[
\parskip
]
[
\bodyfontwhitespace
]
2232
\definevspacingamount
[
\v!height
]
[
\strutht
]
[
\bodyfontstrutheight
]
2233
\definevspacingamount
[
\v!depth
]
[
\strutdp
]
[
\bodyfontstrutdepth
]
2234 2235
\definevspacingamount
[
\v!standard
]
[
.
7
5
\openlineheight
]
[
.
7
5
\openlineheight
]
% mkii compatible
2236 2237
\def
\bodyfontwhitespace
2238
{
\dimexpr
2239
\ifzeropt
\parskip
2240
\zeropoint
2241
\else
\ifgridsnapping
2242
\bodyfontlineheight
2243
\else
2244
\parskip
2245
\fi\fi
2246
\relax
}
2247 2248
%D used in itemize \unknown\ always test this:
2249 2250
\newdimen
\d_spac_overlay
2251 2252
\def
\spac_overlay_lines
2253
{
\directcheckedvspacing
{
\v!back
,
\v!overlay
}
% \blank[\v!back,\v!overlay]%
2254
\nointerlineskip
}
2255 2256
% \startitemize[n]
2257
% \item \input zapf
2258
% \item \startitemize[a]
2259
% \item \input knuth
2260
% \stopitemize
2261
% \stopitemize
2262
%
2263
% \strut \hfill first line \blank[overlay] second line \hfill \strut
2264
%
2265
% \ruledvbox {
2266
% \strut \hfill line 1 \blank[overlay]
2267
% line 2 \hfill \strut \blank[overlay]
2268
% \strut \hfill line 3 \hfill \strut
2269
% }
2270
%
2271
% \dorecurse{50}
2272
% {\startitemize[n] \startitem \startitemize[a] \item #1 \stopitemize \stopitem \stopitemize}
2273 2274
\definevspacing
[
\v!preference
][
penalty
:
-
5
0
0
]
% goodbreak
2275
\definevspacing
[
\v!samepage
]
[
penalty
:
1
0
0
0
0
]
% nobreak
2276 2277
\definevspacing
[
\v!always
]
[
category
:
0
]
% hm, internally it's discard
2278
\definevspacing
[
\v!max
]
[
category
:
1
]
2279
\definevspacing
[
\v!force
]
[
category
:
2
]
2280
\definevspacing
[
\v!disable
]
[
category
:
5
]
2281
\definevspacing
[
\v!nowhite
]
[
category
:
6
]
2282
\definevspacing
[
\v!back
]
[
category
:
7
]
2283
\definevspacing
[
\v!packed
]
[
category
:
8
]
% noparskip (kind of special)
2284
\definevspacing
[
\v!overlay
]
[
category
:
9
]
2285
\definevspacing
[
\v!enable
]
[
category
:
1
0
]
2286 2287
%definevspacing[\v!noparskip] [category:8]
2288
%definevspacing[\v!notopskip] [category:11]
2289 2290
\definevspacing
[
\v!weak
]
[
order
:
0
]
2291
\definevspacing
[
\v!strong
]
[
order
:
1
0
0
]
2292 2293
\definevspacing
[
\s!default
]
[
\v!white
]
% was big for a while
2294 2295
\newcount
\c_spac_vspacing_special_base
\c_spac_vspacing_special_base
=
3
2
2
5
0
% 4000
2296
\newcount
\c_spac_vspacing_special_step
\c_spac_vspacing_special_step
=
1
0
% 250
2297
\newcount
\c_spac_vspacing_special_done
2298 2299
% 2019-05-31 : upgraded a bit to more distinctive samepage-[level]-[0|1|2] names
2300 2301
\unexpanded
\def
\spac_vspacing_define_same_step
#
1
#
2
% alternatively we could have samepage-n-m
2302
{
\begingroup
2303
\scratchcounterone
\numexpr
\plusthree
*
#
1
+
#
2
\relax
2304
\scratchcountertwo
\numexpr
\c_spac_vspacing_special_base
+
\c_spac_vspacing_special_step
*
\scratchcounterone
\relax
2305
%\writestatus{defined}{\v!samepage-\number#1-\number#2\space=>\space penalty:\the\scratchcountertwo}%
2306
\normalexpanded
{
\definevspacing
[
\v!samepage
-
\number
#
1
-
\number
#
2
][
penalty
:
\the
\scratchcountertwo
]
}
%
2307
\endgroup
}
2308 2309
\unexpanded
\def
\spac_vspacing_define_same_page
#
1
%
2310
{
\dostepwiserecurse
\c_spac_vspacing_special_done
{
#
1
}
\plusone
2311
{
\spac_vspacing_define_same_step
\recurselevel
\zerocount
% before
2312
\spac_vspacing_define_same_step
\recurselevel
\plusone
% after
2313
\spac_vspacing_define_same_step
\recurselevel
\plustwo
}
% % whatever
2314
\global
\c_spac_vspacing_special_done
#
1
\relax
}
2315 2316
\spac_vspacing_define_same_page
{
1
2
}
% 12 levels should be more than enough as a start
2317 2318
\def
\spac_vspacing_same_page
#
1
#
2
% level offset (starts at 0)
2319
{
\ifnum
#
1
>
\c_spac_vspacing_special_done
2320
\spac_vspacing_define_same_page
{
#
1
}
%
2321
\fi
2322
%\writestatus{used}{\v!samepage-\number#1-\number#2}%
2323
\vspacing
[
\v!samepage
-
\number
#
1
-
\number
#
2
]
}
2324 2325
\definevspacing
[
\v!default
]
[
\v!big
]
% todo: needs to adapt to \setupblank
2326
\definevspacing
[
\v!before
]
[
\v!default
]
% but we need to avoid circular references
2327
\definevspacing
[
\v!inbetween
][
\v!default
]
% then
2328
\definevspacing
[
\v!after
]
[
\v!before
]
2329 2330
\setupvspacing
2331
[
\v!big
]
% alternatively [\v!standard]
2332 2333
%D Maybe at some point we will differ between \type {\vspacing} and \type {\blank}
2334
%D (we needed the first one while playing with the new code).
2335 2336
% We keep this one as reference
2337
%
2338
% \unexpanded\def\inhibitblank
2339
% {\vspacing[\v!disable]}
2340
%
2341
% but use the following more efficient variant instead:
2342 2343
\unexpanded
\def
\inhibitblank
2344
{
\ifvmode
2345
\begingroup
2346
\c_attr_skipcategory
\plusfive
2347
\vskip
\zeropoint
2348
\endgroup
2349
\fi
}
2350 2351
\let
\doinhibitblank
\inhibitblank
% keep this command, used in styles
2352 2353
\let
\defineblank
\definevspacing
2354
\let
\setupblank
\setupvspacing
2355
\let
\blank
\vspacing
2356
\let
\synchronizeblank
\synchronizevspacing
2357
\let
\defineblankmethod
\definevspacingamount
2358 2359
%D The following command is for Wolfgang. It has to be used with care as it does
2360
%D {\em not} work in tandem with the other spacing commands.
2361 2362
\installcorenamespace
{
vspace
}
2363 2364
\unexpanded
\def
\definevspace
2365
{
\dotripleempty
\spac_vspace_define
}
2366 2367
\def
\spac_vspace_define
[#
1
][#
2
][#
3
]
%
2368
{
\ifthirdargument
2369
\setvalue
{
\??vspace
#
1
:
#
2
}{
#
3
}
%
2370
\else
2371
\setvalue
{
\??vspace
:
#
1
}{
#
2
}
%
2372
\fi
}
2373 2374
\letvalue
{
\??vspace
:
\s!unknown
}
\zeropoint
2375 2376
\unexpanded
\def
\vspace
2377
{
\dodoubleempty
\spac_vspace_inject
}
2378 2379
% \def\spac_vspace_inject[#1][#2]% use \lastnamedcs
2380
% {\par
2381
% \ifvmode
2382
% \removelastskip
2383
% \vskip
2384
% \csname\??vspace
2385
% \ifsecondargument
2386
% \ifcsname\??vspace#1:#2\endcsname
2387
% #1:#2%
2388
% \else\ifcsname\??vspace:#2\endcsname
2389
% :#2%
2390
% \else
2391
% :\s!unknown
2392
% \fi\fi
2393
% \else\iffirstargument
2394
% \ifcsname\??vspace:#1\endcsname
2395
% :#1%
2396
% \else
2397
% :\s!unknown
2398
% \fi
2399
% \else
2400
% \ifcsname\??vspace:\s!default\endcsname
2401
% :\s!default
2402
% \else
2403
% :\s!unknown
2404
% \fi
2405
% \fi\fi
2406
% \endcsname
2407
% \relax
2408
% \fi}
2409 2410
\def
\spac_vspace_unknown
2411
{
\csname
\??vspace
:
\s!unknown
\endcsname
}
2412 2413
\def
\spac_vspace_inject
[#
1
][#
2
]
% use \lastnamedcs
2414
{
\par
2415
\ifvmode
2416
\removelastskip
2417
\vskip
2418
\ifsecondargument
2419
\ifcsname
\??vspace
#
1
:
#
2
\endcsname
2420
\lastnamedcs
2421
\else\ifcsname
\??vspace
:
#
2
\endcsname
2422
\lastnamedcs
2423
\else
2424
\spac_vspace_unknown
2425
\fi\fi
2426
\else
\iffirstargument
2427
\ifcsname
\??vspace
:
#
1
\endcsname
2428
\lastnamedcs
2429
\else
2430
\spac_vspace_unknown
2431
\fi
2432
\else
2433
\ifcsname
\??vspace
:
\s!default
\endcsname
2434
\lastnamedcs
2435
\else
2436
\spac_vspace_unknown
2437
\fi
2438
\fi\fi
2439
\relax
2440
\fi
}
2441 2442
%D Some preliminary code: a simple and fast hanger, for usage in macros.
2443 2444
\installcorenamespace
{
hanging
}
2445 2446
\installdirectcommandhandler
\??hanging
{
hanging
}
2447 2448
\setuphanging
2449
[
\c!distance
=
.
5
\emwidth
,
2450
\c!location
=
\v!left
,
2451
\c!n
=
\zerocount
]
2452 2453
\unexpanded
\def
\starthanging
2454
{
\dontleavehmode
\bgroup
2455
\dosingleempty
\spac_hanging_start
}
2456 2457
\unexpanded
\def
\stophanging
2458
{
\endgraf
2459
\egroup
}
2460 2461
\let
\m_spac_hanging_location
\empty
2462 2463
\def
\spac_hanging_start
[#
1
]
%
2464
{
\doifelseassignment
{
#
1
}
2465
{
\let
\m_spac_hanging_location
\empty
2466
\setupcurrenthanging
[#
1
]
}
%
2467
{
\edef
\m_spac_hanging_location
{
#
1
}}
%
2468
\ifx
\m_spac_hanging_location
\empty
2469
\edef
\m_spac_hanging_location
{
\directhangingparameter
\c!location
}
%
2470
\fi
2471
\dowithnextboxcs
\spac_hanging_finish
\hbox
}
2472 2473
\def
\spac_hanging_finish
2474
{
\scratchdistance
\directhangingparameter
\c!distance
\relax
2475
\ifdim
\ht
\nextbox
>
\strutht
2476
\setbox
\nextbox
\tbox
{
\box
\nextbox
}
%
2477
\fi
2478
\scratchcounter
\directhangingparameter
\c!n
\relax
2479
\ifnum
\scratchcounter
>
\zerocount
2480
\hangafter
-
\scratchcounter
2481
\else
2482
\getboxheight
\scratchdimen
\of
\box
\nextbox
2483
\getnoflines
\scratchdimen
2484
\hangafter
-
\noflines
2485
\fi
2486
\ht
\nextbox\strutht
2487
\dp
\nextbox\strutdp
2488
\scratchwidth
\dimexpr\wd
\nextbox
+
\scratchdistance
\relax
2489
\ifx
\m_spac_hanging_location
\v!right
2490
\hangindent
\ifconditional
\displaylefttoright
-
\fi
\scratchwidth
2491
\rlap
{
\hskip\dimexpr\hsize
-
\leftskip
-
\wd
\nextbox
\relax\box
\nextbox
}
% \leftskip is new
2492
\else
2493
\hangindent
\ifconditional
\displaylefttoright
\else
-
\fi
\scratchwidth
2494
\llap
{
\box
\nextbox
\hskip
\scratchdistance
}
%
2495
\fi
2496
\ignorespaces
}
2497 2498 2499
%D \macros
2500
%D {startfixed}
2501
%D
2502
%D \starttyping
2503
%D \startitemize
2504
%D \startitem \externalfigure[cow][height=1cm] \stopitem
2505
%D \startitem \externalfigure[cow][height=1cm] \stopitem
2506
%D
2507
%D \startitem \startfixed \externalfigure[cow][height=1cm]\stopfixed \stopitem
2508
%D \startitem \startfixed[high]\externalfigure[cow][height=1cm]\stopfixed \stopitem
2509
%D \startitem \startfixed[low] \externalfigure[cow][height=1cm]\stopfixed \stopitem
2510
%D \startitem \startfixed[lohi]\externalfigure[cow][height=1cm]\stopfixed \stopitem
2511
%D
2512
%D \startitem test \par \startfixed \externalfigure[koe][height=1cm]\stopfixed \stopitem
2513
%D \startitem test \par \startfixed[high]\externalfigure[koe][height=1cm]\stopfixed \stopitem
2514
%D \startitem test \par \startfixed[low] \externalfigure[koe][height=1cm]\stopfixed \stopitem
2515
%D \startitem test \par \startfixed[lohi]\externalfigure[koe][height=1cm]\stopfixed \stopitem
2516
%D \stopitemize
2517
%D \stopbuffer
2518
%D
2519
%D \typebuffer \getbuffer
2520 2521
\installcorenamespace
{
fixedalternatives
}
2522 2523
\unexpanded
\def
\startfixed
2524
{
\bgroup
2525
\dosingleempty
\typo_fixed_start
}
2526 2527
\def
\typo_fixed_start
2528
{
\ifhmode
2529
\expandafter
\typo_fixed_start_h
2530
\else
2531
\expandafter
\typo_fixed_start_v
2532
\fi
}
2533 2534
\def
\typo_fixed_start_h
[#
1
]
%
2535
{
\let
\stopfixed
\typo_fixed_stop_h
2536
\dowithnextbox
{
\typo_fixed_finish
{
#
1
}}
%
2537
\vbox
\bgroup
2538
%ignorespaces
2539
\setlocalhsize
}
2540 2541
\unexpanded
\def
\typo_fixed_stop_h
2542
{
%removeunwantedspaces
2543
\egroup
2544
\egroup
}
2545 2546
\def
\typo_fixed_start_v
[#
1
]
%
2547
{
\let
\stopfixed
\typo_fixed_stop_v
2548
\startbaselinecorrection
}
2549 2550
\unexpanded
\def
\typo_fixed_stop_v
2551
{
\stopbaselinecorrection
2552
\egroup
}
2553 2554
\letvalue
{
\??fixedalternatives
\v!high
}
\bbox
2555
\letvalue
{
\??fixedalternatives
\v!low
}
\tbox
2556
\letvalue
{
\??fixedalternatives
\v!middle
}
\vcenter
2557
\letvalue
{
\??fixedalternatives
\v!lohi
}
\vcenter
2558
\letvalue
{
\??fixedalternatives\s!unknown
}
\tbox
2559
\letvalue
{
\??fixedalternatives\s!default
}
\tbox
2560 2561
\unexpanded
\def
\typo_fixed_finish
#
1
%
2562
{
\expandnamespacevalue
\??fixedalternatives
{
#
1
}
\s!default
{
\box
\nextbox
}}
2563 2564
% %D Forgotten already:
2565
%
2566
% \def\shapefill{\vskip\zeropoint\s!plus\lineheight\s!minus\lineheight\relax}
2567 2568
%D Nasty:
2569 2570
% \writestatus{1}{\the\prevdepth} \blank[force,5*big] { \writestatus{1}{\the\prevdepth} \baselineskip1cm xxxxxxxxx \par } \page
2571
% \writestatus{2}{\the\prevdepth} \blank[force,5*big] { \writestatus{2}{\the\prevdepth} \baselineskip1cm xxxxxxxxx \par } \page
2572
% \writestatus{3}{\the\prevdepth} \blank[force,5*big] { \writestatus{3}{\the\prevdepth} \baselineskip5cm xxxxxxxxx \par } \page
2573
% \writestatus{4}{\the\prevdepth} \input tufte \page
2574
% \writestatus{5}{\the\prevdepth} \input tufte \page
2575
% \writestatus{6}{\the\prevdepth} \blank[force,5*big] { \writestatus{6}{\the\prevdepth} \baselineskip1cm xxxxxxxxx \par } \page
2576 2577
% \writestatus{1}{\the\prevdepth} \null\vskip4cm { \writestatus{1}{\the\prevdepth} \baselineskip1cm xxxxxxxxx \par } \page
2578
% \writestatus{2}{\the\prevdepth} \null\vskip4cm { \writestatus{2}{\the\prevdepth} \baselineskip1cm xxxxxxxxx \par } \page
2579
% \writestatus{3}{\the\prevdepth} \null\vskip4cm { \writestatus{3}{\the\prevdepth} \baselineskip5cm xxxxxxxxx \par } \page
2580
% \writestatus{4}{\the\prevdepth} \input tufte \page
2581
% \writestatus{5}{\the\prevdepth} \input tufte \page
2582
% \writestatus{6}{\the\prevdepth} \null\vskip4cm { \writestatus{6}{\the\prevdepth} \baselineskip1cm xxxxxxxxx \par } \page
2583 2584
\appendtoks
2585
\ifvmode
\prevdepth
\zeropoint
\fi
% consistent, else first page -1000pt .. needed for fixed,3*big first/successive pages consistency
2586
\to
\everystarttext
2587 2588
\prevdepth
\zeropoint
2589 2590
%D Helper:
2591 2592
\unexpanded
\def
\checkedblank
[#
1
]
%
2593
{
\edef
\p_blank
{
#
1
}
%
2594
\ifx
\p_blank
\empty
2595
% ignore
2596
\else\ifx
\p_blank
\v!none
2597
% ignore
2598
\else
2599
\blank
[
\p_blank
]
%
2600
\fi\fi
}
2601 2602
% \unexpanded\def\applycheckedblankwith#1#2#3%
2603
% {\edef\p_blank{#2}%
2604
% \ifx\p_blank\empty
2605
% % ignore
2606
% \else\ifx\p_blank\v!none
2607
% % ignore
2608
% \else
2609
% \edef\p_before{#1}%
2610
% \edef\p_after {#3}%
2611
% \blank[\ifx\p_before\empty\else\p_before,\fi\p_blank\ifx\p_after\empty\else,\p_after\fi]%
2612
% \fi\fi}
2613 2614
% \setupwhitespace[line]
2615
% \prerollblank[2*line] \the\prerolledblank
2616
% \prerollblank[-2*line] \the\prerolledblank
2617 2618
\newskip
\prerolledblank
2619 2620
\unexpanded
\def
\prerollblank
[#
1
]
%
2621
{
\begingroup
2622
\edef
\p_blank
{
#
1
}
%
2623
\ifx
\p_blank
\empty
2624
\global
\prerolledblank
\zeropoint
2625
\else\ifx
\p_blank
\v!none
2626
\global
\prerolledblank
\zeropoint
2627
\else
2628
% don't mess with \arskip here!
2629
\scratchskip
\plusten
\lineheight
2630
\setbox
\scratchbox
\vbox
2631
{
\vskip
\scratchskip
2632
\kern
\zeropoint
2633
\blank
[
\p_blank
]
}
%
2634
% \dimexpr doesn't work well with skips
2635
\advance
\scratchskip
-
\ht
\scratchbox
2636
\global
\prerolledblank
-
\scratchskip
2637
\fi\fi
2638
\endgroup
}
2639 2640
\newcount
\c_spac_vspacing_ignore_parskip
2641 2642
% \setupwhitespace[line]
2643
% \setuphead[subject][after={\blank[packed]},style=\bfb]
2644
% \subject{foo}
2645
% test \par
2646
% test \par
2647
% \blank[packed] % \ignoreparskip
2648
% test \par
2649
% test \par
2650
% \ignoreparskip
2651
% test \par
2652
% test \par
2653
% \setuphead[subject][after={\blank[nowhite]},style=\bfb]
2654
% \subject{foo}
2655
% test \par
2656
% test \par
2657 2658
% only main vertical list
2659 2660
\unexpanded
\def
\ignoreparskip
{
\c_spac_vspacing_ignore_parskip
\plusone
}
2661 2662
\protect
\endinput
2663