ontarget-profiles.tex /size: 20 Kb    last modification: 2024-01-16 10:21
1% language=us runpath=texruns:manuals/ontarget
2
3% timestamp: Scary Pockets with Leland Sklar: https://www.youtube.com/watch?v=1UOVLdPslmo
4% around 19 minutes in ... interesting! Hopefully I once see LS live!
5
6% we can yscale too
7
8\usebodyfont[modern,10pt]
9\usebodyfont[lucida,10pt]
10\usebodyfont[pagella,10pt]
11\usebodyfont[bonum,10pt]
12\usebodyfont[antykwa,10pt]
13
14\startcomponent ontarget-profiles
15
16\environment ontarget-style
17
18\startchapter[title={Profiles}]
19
20\startsection[title=Introduction]
21
22Among the typesetting problems that relate to math are inline formulas that have
23a bit too much height or depth but not so much as to justify some additional
24interline space. For that reason in \CONTEXT\ \MKII\ we have some snapping
25features that can be enabled that limit the dimensions. In \MKIV\ a more
26extensive profile feature was written (we talked about it at meetings in 2015)
27that look at the bottom and top of lines in order to determine if lines can be
28moved closer, but in practice snapping and profiling are never really used. In
29the end it was more an academic exercise which is not uncommon when it comes to
30\TEX\ user demands and practice.
31
32As part of exploring math micro typography these features surfaced again during
33some discussion about weird mechanisms and we actually wondered if we could revive
34this now that we also control other aspects of math typesetting in more detail.
35One condition is that the overhead is not that high. Users accept some overhead
36for protrusion and expansion that relate to horizontal optimization so a little
37extra overhead for vertical optimization should not be a problem.
38
39Of course, as with protrusion and especially expansion, the question is if
40readers will notice it. Best would be to set up some experiments but, although
41one can argue that research is important, in practice it always boils down to a
42visual impression, feel good and, like it or not, exploration, trial and error.
43And so a simplified variant of profiling was implemented and applied to a math
44intensive math book used in academia. Instead of proper experiments some unaware
45bystanders were asked if they noticed a difference and to our surprise that was
46the case! And these were not even math students but kids who were more familiar
47with children books and phones. That convinced us that we were on the right
48track, that we need to explain a little about what we actually do, and that we
49should tell users what to look at when this gets applied.
50
51With an introduction like this, mentioning \quote {research}, \quote {academia},
52\quote {students} and \quote {typography} we're sure that future generations will
53be convinced that what  is discussed next has a strong fundament so here we go!
54
55\stopsection
56
57\startsection[title=A first example]
58
59We start with a simple example. Because in practice profiling always kicks in
60when possible one really need to handcraft an example that can be used for
61demonstration: \in {figure} [fig:profile].
62
63\definelineprofile[MyLineProfileA][step=1pt,factor=0.125]
64\definelineprofile[MyLineProfileB][step=1pt,factor=0.250]
65\definelineprofile[MyLineProfileC][step=1pt,factor=1.000]
66
67\startbuffer
68    \hsize 7cm
69    no no no no  no  no no no no no no no no no no no no \im{x^{2^{A^P}}+x_{2_g}}. no no no no no no no no no  no  no no no no no no no no no no no no no \im{\frac{1+A^{2^x}}{2+B_2}} no no no no no no no no no no no no no no no no no.\blank
70    no no no yes yes no no no no no no no no no no no    \im{x^{2^{A^P}}+x_{2_g}}. no no no no no no no no yes yes no no no no no no no no no no no no \im{\frac{1+A^{2^x}}{2+B_2}} no no no no no no no no no no no no no no no no no.\par
71\stopbuffer
72
73\startbuffer[set]
74\showmakeup[line]
75\enabletrackers[profiling.lines.show]
76\stopbuffer
77
78\startbuffer[reset]
79\disabletrackers[profiling.lines.show]
80\stopbuffer
81
82\startplacefigure[reference=fig:profile]
83\startcombination[2*2]
84    {\getbuffer[set]\vbox{\hsize7cm\resetlineprofile                \getbuffer}\getbuffer[reset]}{\type{no profile}}
85    {\getbuffer[set]\vbox{\hsize7cm\setlineprofile  [MyLineProfileA]\getbuffer}\getbuffer[reset]}{\type{step=1pt,factor=0.125}}
86    {\getbuffer[set]\vbox{\hsize7cm\setlineprofile  [MyLineProfileB]\getbuffer}\getbuffer[reset]}{\type{step=1pt,factor=0.250}}
87    {\getbuffer[set]\vbox{\hsize7cm\setlineprofile  [MyLineProfileC]\getbuffer}\getbuffer[reset]}{\type{step=1pt,factor=1.000}}
88\stopcombination
89\stopplacefigure
90
91In order to see what happens it is important to understand how \TEX\ sees lines.
92Actually, the concept of lines in \TEX\ is rather limited: lines are just
93horizontal boxes where the baselines are separated by \type {\baselineskip} and
94when the distance is larger than that dimensions a \type {\lineskip} gets added.
95
96\appendtoks\showmakeup[reset]\to\everybeforeoutput
97
98\startlines \showmakeup[line]
99these are a few
100lines of text
101where lines have depths
102or no real
103height at all
104\stoplines
105
106Between all these lines some skip needs to be added: the \type {\baselineskip}
107minus the height and depth. If we add struts the lines get the optimal height and
108depth so then no skips are inserted:
109
110\startlines \showmakeup[line] \showstruts
111\strut these are a few
112\strut lines of text
113\strut where lines have depths
114\strut or no real
115\strut height at all
116\stoplines
117
118When we increase the depth a little, for instance 1.2 times the normal strut depth,
119we see that some additional space, the \type {\lineskip} gets added:
120
121\startlines \showmakeup[line] \showstruts
122\strut these {\vrule depth 1.2\strutdp width .25em \relax} are a few
123\strut lines of {\vrule depth 1.2\strutdp width .25em \relax} text
124\strut where lines have {\vrule depth 1.2\strutdp width .25em \relax} depths
125\strut or {\vrule depth 1.2\strutdp width .25em \relax} no real
126\strut height at {\vrule depth 1.2\strutdp width .25em \relax} all
127\stoplines
128
129However, there is no real reason to do that here because the
130larger rules don't clash with text or other content. So this is what we get when
131we pass the \type {profile} option to \type {\setupalign}:
132
133\def\MyStrut{\vrule depth 1.2\strutdp width .25em \relax}
134
135\enabletrackers[profiling.lines.show]
136\startpacked \setupalign[profile]
137\strut these {\MyStrut} are a few \crlf
138\strut lines of {\MyStrut} text \crlf
139\strut where lines have {\MyStrut} depths \crlf
140\strut or {\MyStrut} no real \crlf
141\strut height at {\MyStrut} all
142\stoppacked
143\disabletrackers[profiling.lines.show]
144
145Profiling works per paragraph, so when we add a \type {\par} in the middle we get
146this:
147
148\enabletrackers[profiling.lines.show]
149\startpacked \setupalign[profile]
150\strut these {\MyStrut} are a few \crlf
151\strut lines of {\MyStrut} text  \crlf
152\strut where lines have {\MyStrut} depths \par
153\strut or {\MyStrut} no real  \crlf
154\strut height at {\MyStrut} all
155\stoppacked
156\disabletrackers[profiling.lines.show]
157
158But, we can actually setup the profiler to look back. Setting up the main
159(document) profiler happens with:
160
161\starttyping
162\setuplineprofile
163  [factor=0.125,      % default
164   paragraph=yes,     % default: no
165   step=0.5\emwidth]  % default
166\stoptyping
167
168but as with most \CONTEXT\ mechanisms you can define your own profiler. The step
169tells what granularity to use when comparing positions in a line. The factor sets
170the threshold for the interline skip. We saw these two differ in the first
171example we gave.
172
173\stopsection
174
175\startsection[title=Profiled math]
176
177We will give several examples of math profiling.
178In the examples we will switch font to Latin Modern,
179since the effect is more visible for that font.
180Most of our examples will be \quotation{real} (slightly modified) ones,
181but we start with a rather artificial example. Below we have
182two occurrences of a fraction. Note that the profiling only kicks
183in for the second one. The reason is that on the line above the first
184one we only have letters (x) with no depth, while in the second one,
185we have added one letter (g) that has depth.
186
187\startbuffer \hsize 8cm
188xxx xxxx xxxx xx xxx xx xx xxx xxxx xxx xx xxx xxx xx xx xxx x xxxxx xxxxx
189xxx xxxx xxxx xx xxx xx xx xxx xxxx xxx xx xxx xxx xx xx xxx x xxxxx xxxxx
190\im{\frac{1}{2}} xxx xxx xx xx xxx xxxx xxxxxxx xxxx xxxx xxxxx xxx xxxx xxx
191xxx xxx xxx xxx xxx xxxx xxxxxx xxxxxxx xxxgxxx xxx xxx xxx xx x xxxxxxx xxx
192\im{\frac{1}{2}} xxx xxxx xxxx xx xxx xx xx xxx xxxx xxx xx xxx xxx xx xx
193xxx x xxxxx xxxxx.\par
194\stopbuffer
195
196\starttextdisplay
197\switchtobodyfont[modern,9pt]
198\startcombination[nx=2,ny=1,distance=1cm]
199    {\getbuffer[set]\vtop{\hsize8cm\resetlineprofile                \getbuffer}\getbuffer[reset]}{\type{no profile}           }
200    {\getbuffer[set]\vtop{\hsize8cm\setlineprofile  [MyLineProfileA]\getbuffer}\getbuffer[reset]}{\type{step=1pt,factor=0.125}}
201\stopcombination
202\stoptextdisplay
203
204We next show a simple paragraph where the mechanism gets applied in three out of five line breaks.
205
206\startbuffer \hsize 8cm
207The results of Section 6.3 show that the same phenomenon is encountered when
208treating the norms of inverses: \im{\fenced[doublebar][size=0]{B_n^{-1}}_p}
209converges to \im{N_p} very fast if \im{N_p > N_p^0}, while the convergence
210may be slow if \im{N_p = N_p^0}. As the following proposition reveals, at
211least for \im{p = 2} the strict inequality \im{N_2 > N_2^0} is the generic
212case.\par
213\stopbuffer
214
215\starttextdisplay
216\startcombination[nx=2,ny=1,distance=1cm]
217    {\switchtobodyfont[modern,9pt]\getbuffer[set]\vtop{\hsize8cm\resetlineprofile                \getbuffer}\getbuffer[reset]}{\type{no profile}           }
218    {\switchtobodyfont[modern,9pt]\getbuffer[set]\vtop{\hsize8cm\setlineprofile  [MyLineProfileA]\getbuffer}\getbuffer[reset]}{\type{step=1pt,factor=0.125}}
219\stopcombination
220\stoptextdisplay
221
222We have shown the lines and used the helper to show where the profiling
223is applied. We show the same example but without these helpers. After
224all, this is how we usually see it.
225
226\starttextdisplay
227\startcombination[nx=2,ny=1,distance=1cm]
228    {\switchtobodyfont[modern,9pt]\vtop{\hsize8cm\resetlineprofile                \getbuffer}\getbuffer[reset]}{\type{no profile}           }
229    {\switchtobodyfont[modern,9pt]\vtop{\hsize8cm\setlineprofile  [MyLineProfileA]\getbuffer}\getbuffer[reset]}{\type{step=1pt,factor=0.125}}
230\stopcombination
231\stoptextdisplay
232
233If the paragraph is slightly reformulated, the profiling might change.
234Below we show an example where the subscript (p) on the fourth line gets
235too close to the superscript (0) on the last line.
236
237\startbuffer \hsize 8cm
238The results of Section 6.3 show that the same phenomenon is encountered when
239treating the norms of inverses: \im{\fenced[doublebar][size=0]{B_n^{-1}}_p}
240converges to \im{N_p} very fast if \im{N_p > N_p^0}, while the convergence
241may be slow if \im{N_p = N_p^0}.
242At least for \im{p = 2} the strict inequality \im{N_2 > N_2^0} is the generic
243case.\par
244\stopbuffer
245
246\starttextdisplay
247\startcombination[nx=2,ny=1,distance=1cm]
248    {\switchtobodyfont[modern,9pt]\getbuffer[set]\vtop{\hsize8cm\resetlineprofile                \getbuffer}\getbuffer[reset]}{\type{no profile}           }
249    {\switchtobodyfont[modern,9pt]\getbuffer[set]\vtop{\hsize8cm\setlineprofile  [MyLineProfileA]\getbuffer}\getbuffer[reset]}{\type{step=1pt,factor=0.125}}
250\stopcombination
251\stoptextdisplay
252
253We can configure the amount of space that shall be added with the \type{factor} key.
254
255% MS: Fixing a shift issue in the one below took one timestamp loop:
256
257\starttextdisplay
258\startcombination[nx=2,ny=1,distance=1cm]
259    {\switchtobodyfont[modern,9pt]\getbuffer[set]\vtop{\hsize8cm\setlineprofile  [MyLineProfileA]\getbuffer}\getbuffer[reset]}{\type{step=1pt,factor=0.125}    }
260    {\switchtobodyfont[modern,9pt]\getbuffer[set]\vtop{\hsize8cm\setlineprofile  [MyLineProfileC]\getbuffer}\getbuffer[reset]}{\type{step=1pt,factor=1}}
261\stopcombination
262\stoptextdisplay
263
264\startbuffer \hsize 8cm
265This shows that the sequence \im{(f_n)} is a Cauchy sequence in \im{L^1(\reals)}
266and therefore it converges in norm to some \im{\sum_{k=1}^n \hat{f} \in L^1(\reals)}, by
267Thereom~2.8.1. On the other hand, by Theorem~2.8.2, there exists an increasing
268sequence of positive integers \im{q_n} such that \im{f_{q_n} \to \tilde{f}}
269almost everywhere.\par
270\stopbuffer
271
272\starttextdisplay
273\startcombination[nx=2,ny=2,distance=1cm]
274    {\switchtobodyfont[modern,9pt]\getbuffer[set]\vtop{\hsize8cm\resetlineprofile                \getbuffer}\getbuffer[reset]}{\type{no profile}           }
275    {\switchtobodyfont[modern,9pt]\getbuffer[set]\vtop{\hsize8cm\setlineprofile  [MyLineProfileA]\getbuffer}\getbuffer[reset]}{\type{step=1pt,factor=0.125}}
276\stopcombination
277\stoptextdisplay
278
279\stopsection
280
281\startsection[title=Line spacing]
282
283When we enable the line profiler on a 300 page math course with plenty inline
284formulas, the number of \quote {corrections} varies a lot with the fonts. Some
285simple tests show that Latin Modern, Bonum and EBGaramond get quite some applied,
286while Lucida, Dejavu, Antykwa, Erewhon and   Libertinus only see a few corrections.
287Pagella, Termes and StixTwo end up in the middle.
288
289The trigger is not always text or math. The course material has quite some
290structure, like numbered descriptions. In \CONTEXT\ we use plenty of struts to
291make sure that spacing is consistent and the keyword that starts a description
292therefore gets them. Normally that is not an issue but when the height of the
293next line exceeds the strut height we get a clash and line skip will be added.
294One can argue that the strut spoils the typesetting but in general it does more
295good than harm, at least in \CONTEXT. It looks like the profiler is quite capable
296of getting rid of the cases where it interferes (or more precisely: where it
297doesn't run into the next line).
298
299The reason why we get a line skip added is simple: when the depth of the first
300line equals strut depth and the height of the second one equals strut height
301we're okay. When one of them is less we're also okay because \TEX\ will adapt the
302baseline skip so that it compensated the difference. However, when the first line
303has strut depth (due to the present strut) and the second line more than strut
304height (resulting for instance from a formula) the lines are considered
305overflowing in each other and therefore interline skip gets added.
306
307When we end up in this situation the profiler can bring down the line skip when
308it concludes that the strut is not running into the next line. However when the
309formula sits directly below the strut we cannot really determine what is right so
310then we just keep the skip. This situation occurs seldom. In many cases struts
311are optional so one can always disable them (locally).
312
313As the mentioned test document uses Lucida as body font, in the three cases where
314we actually get a clash, one definitely relates to the strut: the overflow in the
315second line occurs close to the right margin and the strut in the first line sits
316at the left margin so we can get rid of the line skip, which leave us with only
317two cases. However, there is another observation, one that involves the baseline
318distance or line height.
319
320In \CONTEXT\ the ratio between the strut height and depth is 72:28 which works
321quite well for most fonts. If we look at Lucida shapes we see that the depth is
322normally small so we can actually decide to change that ratio. It is however not
323clear how that will influence decisions. Assuming more height will help with for
324instance formulas that have superscripts, but an inline integral with subscript
325might suffer. For other fonts, like EBGaramond, that have some extremely deep
326shapes changing rations won't help anyway. We win here and loose there.
327
328\startbuffer[text-001]
329    abcdefghijklmnopqrstuvwxyz
330    ABCDEFGHIJKLMNOPQRSTUVWXYZ
331    1234567890
332    ()[]/\{\}\|
333    .,!?@\#\$\%^&*_-+=
334\stopbuffer
335
336\startbuffer[math-001]
337     $\int\sum\sqrt{}$
338\stopbuffer
339
340\startbuffer[math-002]
341     x_2^2
342\stopbuffer
343
344\newbox\MyHtDpBoxA
345\newbox\MyHtDpBoxB
346\newbox\MyHtDpBoxC
347
348\def\CheckThemA#1%
349  {\begingroup
350   \switchtobodyfont[#1,10pt]%
351   \starttabulate[||r|]
352     \FL
353     \BC \rlap{#1} \NC \NC \NR
354     \FL
355     \NC strut ht \EQ \the\strutht \NC \NR
356     \NC strut dp \EQ \the\strutdp \NC \NR
357   % \NC height   \EQ \meaningless\strutheightfactor \NC \NR
358   % \NC depth    \EQ \meaningless\strutdepthfactor \NC \NR
359     \NC ex       \EQ \the\exheight \NC \NR
360     \LL
361   \stoptabulate
362   \endgroup}
363
364\def\CheckThemB#1%
365  {\begingroup
366   \switchtobodyfont[#1,10pt]%
367   \setbox\MyHtDpBoxA\ruledhpack\bgroup\inlinebuffer[text-001]\egroup
368   \setbox\MyHtDpBoxB\ruledhpack\bgroup\inlinebuffer[math-001]\egroup
369   \setbox\MyHtDpBoxC\ruledhpack\bgroup\inlinebuffer[math-002]\egroup
370   \def\ShowThem##1##2%
371     {\cldcontext{"\letterpercent 0.2f",\number##1##2/\number\htdp##2}
372      \NC
373      \the##1##2%
374      \NC}
375   \starttabulate[|r|r|i2r|r|i2r|r|]
376     \FL
377        \NS[1][c] \bf text-001
378        \NS[1][c] \bf math-001
379        \NS[1][c] \bf math-002
380%         \rlap{\quad\quad#1}
381     \NR
382     \FL
383     \NC
384        \ShowThem\ht\MyHtDpBoxA
385        \ShowThem\ht\MyHtDpBoxB
386        \ShowThem\ht\MyHtDpBoxC
387     \NR
388     \NC
389        \ShowThem\dp\MyHtDpBoxA
390        \ShowThem\dp\MyHtDpBoxB
391        \ShowThem\dp\MyHtDpBoxC
392     \NR
393     \LL
394   \stoptabulate
395   \endgroup}
396
397We will look into a few fonts to get a better impression how all this relates. We
398will use 10pt sizes. When we compare Lucida, Latin Modern, Bonum and Pagella we
399notice that we start out with design sizes that are quite different.
400
401\CheckThemA{lucida}
402\CheckThemA{modern}
403\CheckThemA{bonum}
404\CheckThemA{pagella}
405
406This is why we always use ratios (the 0.72 and 0.28) as well as abstract
407dimensions like \type {ex} and \type {em} so that we adapt to what the font
408provides. Because the default (total) line height is set to \type {2.8ex} we get
409larger values in for instance Lucida.
410
411In the next tables we use three samples, with \type {text-001} being:
412
413\typebuffer[text-001]
414
415The two math samples are:
416
417\typebuffer[math-001]
418
419and
420
421\typebuffer[math-002]
422
423For text the ratios are not that far off the defaults, but for math they start
424to differ and the distance becomes larger. For Lucida we get:
425
426\CheckThemB{lucida}
427
428Modern gives:
429
430\CheckThemB{modern}
431
432And bonum moves in the other direction:
433
434\CheckThemB{bonum}
435
436Pagella also differs:
437
438\CheckThemB{pagella}
439
440Changing the ratios for the sake of math makes not that much sense because
441profiling depends a lot on what math ends up inline. When we looked around a bit
442for realistic examples we got the impression that seeing some clash (read:
443getting uneven line spacing) might be a reason why small formulas eventually end
444up as display. Without mentioning names, we noticed that a reprint of a book
445actually got reformatted and when we looked for the slashing formulas in the
446original they had become display instead. With proper profiling there is no need
447for that. On top of that one can argue that some inline rendering can be done
448better anyway, like using skewed fraction instead of ruled ones. Can we predict
449that math with many superscripts goes well with a font with relatively high
450shapes? As soon as some parenthesis are used we get depth anyway and how likely
451is it that math without these is used inline? It also depends on the amount of
452math: two lines with superscripted math will drive \TEX\ to use line skip so we
453need to profile anyway. For that reason we will not adapt the ratios, just like
454we keep the default line spacing. There are of course fonts with extreme heights
455(like the Computer Modern Dunhill variant) but no one will use those artistic
456variants in a math document. If you want to go fancy and distinctive, Antykwa is
457a good choice and that one actually scores pretty good with the defaults!
458
459\CheckThemA{antykwa}
460
461\CheckThemB{antykwa}
462
463\stopsection
464
465\startsection[title=Conclusion]
466
467So, should we enable profiling on mixed text|-|math documents or not? One
468possible reason for not doing it is that it adds overhead, but in practice it's
469not that much compared to processing the rest. It is no problem to find
470complaints on the internet about \LUATEX\ performing worse than its ancestors so
471if you're in that category: don't use profiling because it sets you back a few
472percent runtime. However, when you're a demanding \CONTEXT\ user who mixes in a
473lot of math, you might give it a try. It will intercept a couple of cases where
474struts (assuming structure is used) trigger a line skip, and it might also catch
475a couple of cases where \TEX\ found lines getting too close. Tweaking the \type
476{factor} and \type {step} can actually be fun. Because it does influence page
477breaks it is not something to be applied last minute. And, talking performance,
478this kind of vertical optimization comes cheaper than horizontal optimization
479using expansion (hz) and protrusion.
480
481\stopsection
482
483\stopchapter
484
485\stopcomponent
486
487% \framed[width=7cm,offset=overlay,align={lohi,normal}]{\getbuffer}
488% \framed[width=7cm,offset=overlay,align={lohi,normal,profile}]{\getbuffer}
489
490% maybe add an interline callback ...
491
492% Test different fonts
493% lots: modern, bonum, ebgaramond,
494% some: pagella, termes, stixtwo
495% few:  lucida, dejavu, antykwa, kurier, erewhon, libertinus
496
497% Strut can force lineheight and depth.
498
499% antykwa size of vertical bar is maybe too big. Change step?
500
501% antykwa \Biggl(1+\frac{1}{n}\Biggr)^n
502
503% cambria, superscripts sit a bit high (we did not change it)
504
505% the role of font parameters (superscripts... not enough steps in i.e. square roots)
506
507% dp / ht relation and struts
508