still-profiling.tex /size: 33 Kb    last modification: 2023-12-21 09:43
1% language=us
2
3\environment still-environment
4
5\enabledirectives[visualizers.fraction=2.5]
6
7\startcomponent still-profiling
8
9\startchapter[title=Profiling lines]
10
11\startsection[title=Introduction]
12
13Although \TEX\ is pretty good at typesetting simple texts like novels, in
14practice it's often used for getting more complex stuff on paper (or screen).
15Math is of course the first thing that comes to mind. If for instance you look at
16the books typeset by Don Knuth you will see a rendering that is rather consistent
17in spacing. This is no surprise as the author pays a lot of attention to detail
18and uses inline versus display math properly. No publisher will complain about
19the result.
20
21In the documents that I have to write styles for, the content is rather mixed,
22and in particular inline math can have display math properties. In a one-column
23layout this is not a real problem especially because lots of short sentences and
24white space is used: we're talking of secondary|-|school educational math where
25arguments for formatting something this or that way is not always rational and
26consistent but more based on \quotation {this is what the student expects},
27\quotation {the competitor also does it that way} or just \quotation {we like
28this more}. For instance in a recent project, the books with answers to questions
29had to be typeset in a multicolumn layout and because math was involved, we end
30up with lines with more height and depth than normal. That can not only result in
31more pages but also can make the result look a bit messy.
32
33\blank \dontleavehmode \start \showboxes This paragraph demonstrates how lines
34are handled: when a paragraph is broken into lines each line becomes a horizontal
35box with a height and depth determined by the size of the characters that make up
36the line. There is a minimal distance between baselines (\type {baselineskip})
37and when lines touch there can optionally be a \type {\lineskip}. In the end we
38get a vertical list of boxes and glue (either of not flexible) mixed with
39penalties that determine optimal paragraph breaks. This paragraph shows that
40there is normally enough space available to do the job. \par \stop \blank
41
42We already have some ways to control this. For instance the dimensions of math
43can be limited a bit and lines can be made to snap on a grid (which is what
44publishers often want anyway). However, another alternative is to look at the
45line and decide if successive lines can be moved closer, of course within the
46constraints of the height and and depth of the lines. There is no real way to see
47if some ugly clash can happen simply because when we run into boxed material
48there can be anything inside and the dimensions can be set on purpose. This means
49that we have to honour all dimensions and only can mess around with dimensions
50when we're reasonably confident. In \CONTEXT\ this messing is called profiling
51and that is what we will discuss next.
52
53\stopsection
54
55\startsection[title=Line heights and depths]
56
57\startbuffer[example-1]
58Regelmatig kom je procenten tegen. ‘Pro centum’ is Latijn en betekent per
59honderd, dus één van elke honderd, dus \math {\frac {1} {100}} deel. Met
60procenten rekenen is daarom rekenen met honderdsten: \math {45 \procent = \frac
61{45} {100} = 0,45}. Dus \math {45 \procent} van een geheel is het \math {\frac
62{45} {100}} deel ervan en dat kun je berekenen door te vermenigvuldigen met \math
63{0,45}.
64\stopbuffer
65
66\startbuffer[example-2]
67Je gaat uit van de bekende eigenschappen van machten. Bijvoorbeeld: \math {g^r *
68g^s = g^{(r+s)}}. Neem je hierin \math {r = ^{g}\log(a)} en \math {s = ^{g}\log
69b}, dan vind je: \math {g^{^{g}\log(a) + ^{g}\log(b)} = g^{^{g}\log a} \times
70g^{^{g}\log b} = a \times b}. Hierbij gebruik je de definitieformules.
71\stopbuffer
72
73\startbuffer[example-3]
74Omdat volgens de eigenschappen van machten en exponenten geldt \math {\frac {1}
75{x^4} = x^{-4} } is ook hier sprake van een machtsfunctie, namelijk \math {f(x) =
76\frac {6} {x^4} = 6 \times \frac {1} {x^4} = 6x^{-4}}.
77\stopbuffer
78
79In this section we will use some (Dutch) examples from documents that we've
80processed. We show unprofiled versions, with two different paragraph widths, in
81\in {figure} [fig:profiling:unprofiled-examples-widths]. All three examples shown
82demonstrate that as soon as we use something more complex than a number or
83variable in a subscript we exceed the normal line height, and thus the line
84spacing becomes somewhat irregular.
85
86\starttexdefinition ExampleRunUnprofiled #1
87    \vbox \bgroup
88        \switchtobodyfont[dejavu,10pt]
89        \raggedright
90        \hsize12cm
91        \inleft[scope=local]{\ttx hsize 12cm\\unprofiled}
92        \nl \vbox{\getbuffer[example-#1]}
93        \blank
94        \hsize10cm
95        \inleft[scope=local]{\ttx hsize 10cm\\unprofiled}
96        \nl \vbox{\getbuffer[example-#1]}
97    \egroup
98\stoptexdefinition
99
100\startplacefigure[reference=fig:profiling:unprofiled-examples-widths,title={Unprofiled examples.}]
101    \enabletrackers[profiling.show]
102    \startcombination[nx=1,ny=3]
103        \startcontent
104            \ExampleRunUnprofiled{1}
105        \stopcontent
106        \startcaption
107            example 1
108        \stopcaption
109        \startcontent
110            \ExampleRunUnprofiled{2}
111        \stopcontent
112        \startcaption
113            example 2
114        \stopcaption
115        \startcontent
116            \ExampleRunUnprofiled{3}
117        \stopcontent
118        \startcaption
119            example 3
120        \stopcaption
121    \stopcombination
122    \disabletrackers[profiling.show]
123\stopplacefigure
124
125The profiled rendering of the same examples are shown in \in {figure}
126[fig:profiling:profiled-examples-widths]. Here we use the minimal heights and
127depths plus a minimum distance of 1pt. This default method is called \type
128{strict}.
129
130\starttexdefinition ExampleRunProfiled #1
131    \vbox \bgroup
132        \switchtobodyfont[dejavu,10pt]
133        \raggedright
134        \hsize12cm
135        \inleft[scope=local]{\ttx hsize 12cm\\profiled}
136        \nl \profiledbox{\getbuffer[example-#1]}
137        \blank
138        \hsize10cm
139        \inleft[scope=local]{\ttx hsize 10cm\\profiled}
140        \nl \profiledbox{\getbuffer[example-#1]}
141    \egroup
142\stoptexdefinition
143
144\startplacefigure[reference=fig:profiling:profiled-examples-widths,title={Profiled examples.}]
145    \enabletrackers[profiling.show]
146    \startcombination[nx=1,ny=3]
147        \startcontent
148            \ExampleRunProfiled{1}
149        \stopcontent
150        \startcaption
151            example 1
152        \stopcaption
153        \startcontent
154            \ExampleRunProfiled{2}
155        \stopcontent
156        \startcaption
157            example 2
158        \stopcaption
159        \startcontent
160            \ExampleRunProfiled{3}
161        \stopcontent
162        \startcaption
163            example 3
164        \stopcaption
165    \stopcombination
166    \disabletrackers[profiling.show]
167\stopplacefigure
168
169In the first and last example there are some lines where the depth of one line
170combined with the height of the following exceeds the standard line height. This
171forces \TEX\ to insert \type {\lineskip} (mentioned in the demonstration
172paragraph above), a dimension that is normally set to a fraction of the line
173spacing (for instance 1pt for a 10pt body font and 12pt line spacing). When we
174are profiling, \type{\lineskip} is ignored and we use a settable distance
175instead. The second example (with superscripts) normally comes out fine as the
176math stays within limits and we make sure that smaller fractions and scripts stay
177within the natural limits of the line, but nested scripts can be an issue.
178
179% \unexpanded\def\fakeinmargin#1%
180%   {\dontleavehmode{\resetvisualizers\smash{\llap{#1}}}}
181
182% \unexpanded\def\fakestrut#1%
183%   {\fakeinmargin{\showstruts\strut\kern\dimexpr.5em+#1em/2\relax}}
184
185In \in {figure} [fig:profiling:zapf] we see the profile of a regular text with no
186math. The average text stays well within the limits of height and depth. If this
187doesn't happen for prose then you need to adapt the height|/|depth ratio to the
188ascender|/|descender ratio of the bodyfont. For regular text it makes no sense to
189use the profiler, it only slows down typesetting.
190
191\startplacefigure[reference=fig:profiling:zapf,title={Normal lines profiled (quote by Hermann Zapf)}]
192    \enabletrackers[profiling.show]
193    \switchtobodyfont[dejavu,10pt]
194    \profiledbox{\input{zapf}}
195    \disabletrackers[profiling.show]
196\stopplacefigure
197
198\stopsection
199
200\startsection[title=When lines exceed boundaries]
201
202Let's now take a more detailed look at what happens when lines get too high or
203low. First we'll zoom in on a simple example: in \in {figure}
204[fig:profiling:simple-text], we compare a sample text rendered using the variants
205of profiling currently implemented. (This is still experimental code so there
206might be more in the future). Seeing profiles helps to get a picture of the
207complications we have to deal with. In addition to the normal \type {vbox}
208variant (used in the previous examples), we show \type {none} which only
209analyzes, \type {strict} that uses the natural dimensions of lines and \type
210{fixed} that is supposed to cooperate with grid snapping.
211
212% \startbuffer[fake-1]
213% \hsize 2cm
214% \fakestrut2 first  x \par \fakestrut1 first  y \blank
215% \fakestrut2 second x \par \fakestrut1 second y \blank[2*big]
216% \fakestrut2 third  x \par \fakestrut1 third  y \par
217% \stopbuffer
218
219% \startbuffer[fake-2]
220% \hsize 2cm
221% \fakestrut2 line 1 \lower2ex\hbox{xxx}\par
222% \fakestrut1 line 2 \raise2ex\hbox{xxx}\par
223% \fakestrut2 line 3 \par
224% \stopbuffer
225
226% \startplacefigure[reference=fig:profiling:simple-text,title={Just a simple two line text.}]
227%     \switchtobodyfont[10pt]
228%     \enabletrackers[profiling.show]
229%     \startcombination[nx=1,ny=3]
230%         \startcontent
231%             \startcombination[nx=4,ny=1,distance=10mm,style=\tt]
232%                 {\kern1.5em\showboxes\vbox               {\getbuffer[fake-1]}} {vbox}
233%                 {\kern1.5em\showboxes\profiledbox[none]  {\getbuffer[fake-1]}} {none}
234%                 {\kern1.5em\showboxes\profiledbox[strict]{\getbuffer[fake-1]}} {strict}
235%                 {\kern1.5em\showboxes\profiledbox[fixed] {\getbuffer[fake-1]}} {fixed}
236%             \stopcombination
237%         \stopcontent
238%         \startcaption
239%             no excessive height and depth
240%         \stopcaption
241%         \startcontent
242%             \startcombination[nx=4,ny=1,distance=10mm,style=\tt]
243%                 {\kern1.5em\showboxes\vbox                             {\getbuffer[fake-2]}} {vbox}
244%                 {\kern1.5em\showboxes\profiledbox[none]  [distance=0pt]{\getbuffer[fake-2]}} {none}
245%                 {\kern1.5em\showboxes\profiledbox[strict][distance=0pt]{\getbuffer[fake-2]}} {strict}
246%                 {\kern1.5em\showboxes\profiledbox[fixed] [distance=0pt]{\getbuffer[fake-2]}} {fixed}
247%             \stopcombination
248%         \stopcontent
249%         \startcaption
250%             some excessive height and depth (distance=0pt)
251%         \stopcaption
252%         \startcontent
253%             \startcombination[nx=4,ny=1,distance=10mm,style=\tt]
254%                 {\kern1.5em\showboxes\vbox                             {\getbuffer[fake-2]}} {vbox}
255%                 {\kern1.5em\showboxes\profiledbox[none]  [distance=2pt]{\getbuffer[fake-2]}} {none}
256%                 {\kern1.5em\showboxes\profiledbox[strict][distance=2pt]{\getbuffer[fake-2]}} {strict}
257%                 {\kern1.5em\showboxes\profiledbox[fixed] [distance=2pt]{\getbuffer[fake-2]}} {fixed}
258%             \stopcombination
259%         \stopcontent
260%         \startcaption
261%             some excessive height and depth (distance=2pt)
262%         \stopcaption
263%     \stopcombination
264%     \disabletrackers[profiling.show]
265% \stopplacefigure
266
267\startbuffer[fake-1]
268\hsize 2cm \dontleavehmode
269line 1 \par
270line 2 \par
271line 3 \par
272\stopbuffer
273
274\startbuffer[fake-2]
275\hsize 2cm \dontleavehmode
276line 1 x\lower2ex\hbox{xxx}\par
277line 2 x\raise2ex\hbox{xxx}\par
278line 3 \par
279\stopbuffer
280
281\startbuffer[fake-3]
282\hsize 2cm \dontleavehmode
283x\lower2ex\hbox{xxx} line 1 \par
284line 2 x\raise2ex\hbox{xxx}\par
285line 3 \par
286\stopbuffer
287
288\startplacefigure[reference=fig:profiling:simple-text,title={Variants of profiling, using a constructed two-line text.}]
289    \switchtobodyfont[10pt]
290    \enabletrackers[profiling.show]
291    \startcombination[nx=1,ny=3]
292        \startcontent
293            \startcombination[nx=5,ny=1,distance=10mm,style=\tt]
294                {\showboxes\profiledbox[none]  [distance=0pt]{\getbuffer[fake-1]}} {none}
295                {\showboxes\profiledbox[strict][distance=0pt]{\getbuffer[fake-1]}} {strict/0pt}
296                {\showboxes\profiledbox[strict][distance=1pt]{\getbuffer[fake-1]}} {strict/1pt}
297                {\showboxes\profiledbox[fixed] [distance=0pt]{\getbuffer[fake-1]}} {fixed/0pt}
298                {\showboxes\profiledbox[fixed] [distance=1pt]{\getbuffer[fake-1]}} {fixed/1pt}
299            \stopcombination
300        \stopcontent
301        \startcaption
302            no excessive height and depth
303        \stopcaption
304        \startcontent
305            \startcombination[nx=5,ny=1,distance=10mm,style=\tt]
306                {\showboxes\profiledbox[none]  [distance=0pt]{\getbuffer[fake-2]}} {none}
307                {\showboxes\profiledbox[strict][distance=0pt]{\getbuffer[fake-2]}} {strict/0pt}
308                {\showboxes\profiledbox[strict][distance=1pt]{\getbuffer[fake-2]}} {strict/1pt}
309                {\showboxes\profiledbox[fixed] [distance=0pt]{\getbuffer[fake-2]}} {fixed/0pt}
310                {\showboxes\profiledbox[fixed] [distance=1pt]{\getbuffer[fake-2]}} {fixed/1pt}
311            \stopcombination
312        \stopcontent
313        \startcaption
314            some excessive height and depth (overlapping)
315        \stopcaption
316        \startcontent
317            \startcombination[nx=5,ny=1,distance=10mm,style=\tt]
318                {\showboxes\profiledbox[none]  [distance=0pt]{\getbuffer[fake-3]}} {none}
319                {\showboxes\profiledbox[strict][distance=0pt]{\getbuffer[fake-3]}} {strict/0pt}
320                {\showboxes\profiledbox[strict][distance=1pt]{\getbuffer[fake-3]}} {strict/1pt}
321                {\showboxes\profiledbox[fixed] [distance=0pt]{\getbuffer[fake-3]}} {fixed/0pt}
322                {\showboxes\profiledbox[fixed] [distance=1pt]{\getbuffer[fake-3]}} {fixed/1pt}
323            \stopcombination
324        \stopcontent
325        \startcaption
326            some excessive height and depth (out of touch)
327        \stopcaption
328    \stopcombination
329    \disabletrackers[profiling.show]
330\stopplacefigure
331
332\in {Figure} [fig:profiling:simple-text] we show what happens when we add some
333more excessive height and depth to lines. The samples are:
334
335\starttyping
336line 1 x\lower2ex\hbox{xxx}\par
337line 2 x\raise2ex\hbox{xxx}\par
338line 3 \par
339\stoptyping
340
341and:
342
343\starttyping
344x\lower2ex\hbox{xxx} line 1 \par
345line 2 x\raise2ex\hbox{xxx}\par
346line 3 \par
347\stoptyping
348
349Here the \type {strict} variant has some effect while \type {fixed} only has some
350influence on the height and depth of lines. Later we will see that \type {fixed}
351operates in steps and the default step is large so here we never meet the
352criteria for closing up. \footnote {In \CONTEXT\ we normally use \type {\high}
353and \type {\low} and both ensure that we don't exceed the natural height and
354depth.}
355
356A profiled box is typeset with \type {\profiledbox}. There is some control
357possible but the options are not yet set in stone so we won't use them all here.
358Profiling can be turned on for the whole document with \type {\setprofile} but
359I'm sure that will seldom happen, and these examples show why: one cannot
360beforehand say if the result looks good. Let's now apply profiling to a real
361text. If you play with this yourself you can show profiles in gray with a
362tracker:
363
364\starttyping
365\enabletrackers[profiling.show]
366\stoptyping
367
368\newbox\myprofiledbox
369
370\startbuffer[raw-1]
371\profiledbox
372  [strict]
373  [distance=0pt]
374  {\nl\getbuffer[example-1]}
375\stopbuffer
376
377\startbuffer[raw-2]
378\profiledbox
379  [strict]
380  [distance=1pt]
381  {\nl\getbuffer[example-1]}
382\stopbuffer
383
384\startbuffer[raw-3]
385\profiledbox
386  [strict]
387  [height=2\strutht,
388   depth=2\strutdp,
389   distance=1pt]
390  {\nl\getbuffer[example-1]}
391\stopbuffer
392
393\startplacefigure[reference=fig:profiling:distances,title={Examples width different dimensions.}]
394    \enabletrackers[profiling.show]
395    \startcombination[nx=1,ny=3]
396        \startcontent
397            \setbox\myprofiledbox\rawbuffer{raw-1}
398            \xdef\LastProfiledHeight{\the\htdp\myprofiledbox}
399            \box\myprofiledbox
400        \stopcontent
401        \startcaption
402            zero distance, resulting height \LastProfiledHeight
403        \stopcaption
404        \startcontent
405            \setbox\myprofiledbox\rawbuffer{raw-2}
406            \xdef\LastProfiledHeight{\the\htdp\myprofiledbox}
407            \box\myprofiledbox
408        \stopcontent
409        \startcaption
410            distance, resulting height \LastProfiledHeight
411        \stopcaption
412        \startcontent
413            \setbox\myprofiledbox\rawbuffer{raw-3}
414            \xdef\LastProfiledHeight{\the\htdp\myprofiledbox}
415            \box\myprofiledbox
416        \stopcontent
417        \startcaption
418            distance, double height and depth, resulting height \LastProfiledHeight
419        \stopcaption
420    \stopcombination
421    \disabletrackers[profiling.show]
422\stopplacefigure
423
424We show the effects of setting distances in \in {figure}
425[fig:profiling:distances]. We start with a zero distance:
426
427\typebuffer[raw-1]
428
429Because we don't want lines to touch we then set the minimum distance to a
430reasonable value (1pt).
431
432\typebuffer[raw-2]
433
434Finally we also double the height and depth of lines, something that normally will
435not be done. The defaults are the standard height and depth (the ones you get
436when you inject a so-called \type{\strut}).
437
438\typebuffer[raw-3]
439
440The problem with this kind of analysis is that deciding when and how to use this
441information to improve spacing is non|-|trivial. One of the characteristics of
442user demand is that it nearly always concerns rather specific situations and that
443suggested solutions could work only in those cases. But as soon as we have one
444exceptional situation, intervention is needed which in turn means that a
445mechanism has to be under complete user control. That itself assumes that the
446user still has control, which is not the case in automated workflows. In fact, as
447soon as one is in control over the source and rendering, there are often easier
448ways to deal with the few cases that need treatment. Possible interference can
449come from, for instance:
450
451\startitemize[packed]
452\startitem whitespace between paragraphs \stopitem
453\startitem section titles (using different fonts and spacing) \stopitem
454\startitem descriptions and other intermezzos \stopitem
455\startitem images that interrupt the flow, or end up next to text \stopitem
456\startitem ornaments like margin words (we catch some) \stopitem
457\startitem text backgrounds making spacing assumptions \stopitem
458\stopitemize
459
460After a few decades of using \TEX\ and writing solutions, it has become pretty
461clear that fully automated typesetting is a dream, if only because the input can
462be pretty weird and inconsistent and demands (from those who are accustomed to
463tweaking manually in a desktop publishing application) can be pretty weird and
464inconsistent too. So, the only real solution is to use some kind of artificial
465intelligence that one can feed with demands and constraints and that hopefully is
466clever enough to deal with the inconsistencies. As this kind of computing is
467unlikely to happen in my lifetime, poor man explicit solutions have to do the job
468for now. One can add all kinds of heuristics to the profiler but this can
469backfire when control is needed. Alternatively one can end up with many options
470like we have in grid snapping.
471
472\stopsection
473
474\startsection[title=Where to use profiling]
475
476In \CONTEXT\ there are four places (maybe a few more eventually) where this kind
477of control over spacing makes sense:
478
479\startitemize[packed]
480\startitem the main text flow in single column mode \stopitem
481\startitem multi|-|column mode, especially mixed columns \stopitem
482\startitem framed texts, used for all kinds of content \stopitem
483\startitem explicitly (balanced) split boxes \stopitem
484\stopitemize
485
486Because framed texts are used all over, for instance in tables, it means that if
487we provide control over spacing using profiles, many \CONTEXT\ mechanisms can use
488it. However, enabling this for all packaging has a significant overhead so it has
489to be used with care so that there is no performance hit when it is not used.
490Here is an easy example using \type {\framed}:
491
492\starttyping
493\framed
494  [align=normal,
495   profile=fixed,
496   frame=off]
497  {some text ...}
498\stoptyping
499
500For the following examples we define this helper:
501
502\startbuffer
503\starttexdefinition demo-profile-1 #1
504  \framed
505    [align=normal,profile=#1]
506    {xxx$\frac{1}{\frac{1}{\frac{1}{2}}}$
507     \par
508     $\frac{\frac{1}{\frac{1}{2}}}{2}$xxx}
509\stoptexdefinition
510\stopbuffer
511
512\typebuffer \getbuffer
513
514We apply this to predefined profiles. The macro is called like this:
515
516\starttyping
517\texdefinition{demo-profile-1}{fixed}
518\stoptyping
519
520\starttexdefinition unexpanded ProfileSteps #1
521    \startcombination[nx=5,ny=1]
522        {#1\hbox to 6em{\hss\texdefinition{demo-profile-1}            {}\hss}} {\small vbox}
523        {#1\hbox to 6em{\hss\texdefinition{demo-profile-1}       {fixed}\hss}} {\small\type{fixed}}
524        {#1\hbox to 6em{\hss\texdefinition{demo-profile-1}   {halffixed}\hss}} {\small\type{halffixed}}
525        {#1\hbox to 6em{\hss\texdefinition{demo-profile-1}{quarterfixed}\hss}} {\small\type{quarterfixed}}
526        {#1\hbox to 6em{\hss\texdefinition{demo-profile-1} {eightsfixed}\hss}} {\small\type{eightsfixed}}
527    \stopcombination
528\stoptexdefinition
529
530The outcome can depend on the font used: in \in {figure}
531[fig:profiling:profiles-fonts] we show Latin Modern, \TEX\ Gyre Pagella and
532Dejavu. Because in \CONTEXT\ the line height depends on the bodyfont; each case
533is different.
534
535\startplacefigure[reference=fig:profiling:profiles-fonts,title=A few fonts compared.]
536    \enabletrackers[profiling.show]
537    \startcombination[nx=1,ny=3]
538        \startcontent
539            \ProfileSteps{\switchtobodyfont[modern]}
540        \stopcontent
541        \startcaption
542            Latin Modern
543        \stopcaption
544        \startcontent
545            \ProfileSteps{\switchtobodyfont[pagella]}
546        \stopcontent
547        \startcaption
548            Pagella
549        \stopcaption
550        \startcontent
551            \ProfileSteps{\switchtobodyfont[dejavu]}
552        \stopcontent
553        \startcaption
554            Dejavu
555        \stopcaption
556    \stopcombination
557    \disabletrackers[profiling.show]
558\stopplacefigure
559
560\startplacefigure[reference=fig:profiling:profiles-boxedcolumns,title={Boxed columns without profile.}]
561    \enabletrackers[profiling.show]
562    \startcombination[nx=1,ny=3]
563        \startcontent
564            \startboxedcolumns[distance=2.2em,grid=yes,profile=none,frame=on]
565                \nl\getbuffer[example-1]
566            \stopboxedcolumns
567        \stopcontent
568        \startcaption
569            none on grid
570        \stopcaption
571        \startcontent
572            \startboxedcolumns[distance=2.2em,grid=yes,profile=strict,frame=on]
573                \nl\getbuffer[example-1]
574            \stopboxedcolumns
575        \stopcontent
576        \startcaption
577            strict on grid
578        \stopcaption
579        \startcontent
580            \startboxedcolumns[distance=2.2em,grid=yes,profile=fixed,frame=on]
581                \nl\getbuffer[example-1]
582            \stopboxedcolumns
583        \stopcontent
584        \startcaption
585            fixed on grid
586        \stopcaption
587    \stopcombination
588    \disabletrackers[profiling.show]
589\stopplacefigure
590
591As mentioned, we need this kind of profiling in multi|-|column typesetting, so
592let us have a look at that now. Columns are processed in grid mode but this is
593taken into account. We can simulate this by using boxed columns; see \in {figure}
594[fig:profiling:profiles-boxedcolumns]. One of the biggest problems is what to do
595with the bottom and top of a page or column. This will probably take a bit more
596to get right, and likely we will end up with different strategies. We can also
597think of special handlers but that will come with a high speed penalty. In the
598\type {strict} variant we don't mess with the dimension of a line too much, but
599the \type {fixed} alternative will get some more control.
600
601Although using this feature looks promising it is also dangerous. For instance a
602side effect can be that interline spacing becomes inconsistent and even ugly. It
603really depends on the content. Also, as soon as some grid snapping is used, the
604gain becomes less, simply because the solution space is smaller. Then of course
605there is the matter of overall look and feel: most documents that need this kind
606of magic look bad anyway, so why bother. In this respect it is comparable to
607applying protrusion and expansion. There are hardly any combinations of design
608and content where micro|-|typography makes sense to use: in prose perhaps, but
609not in mixed content. On the other hand, profiling makes more sense in mixed
610content than in prose.
611
612Not everything that is possible should be used. In \in {figure}
613[fig:profiling:fake-examples-1] we show some fake paragraphs with profiles
614applied, the first series (random range~2) has a few excessive snippets, the last
615one (random range~5) has many. In \in {figure} [fig:profiling:fake-examples-2] we
616show them in a different arrangement. Although there are differences it is hard
617to say if the results look better. We scaled down the results and used gray fake
618blurs instead of real text in order to get a better impression of the so-called
619(overall) grayness of a text.
620
621% \starttexdefinition profile-sample-set #1#2#3
622%     \startuseMPgraphic{random-thing}
623%         if round(uniformdeviate(10)) = 5 :
624%             fill unitsquare enlarged ((1mm,#2mm) randomized(1mm,#1mm)) withcolor \MPcolor{#3} ;
625%         else :
626%             fill unitsquare enlarged ((1mm,1mm) randomized(1mm,1mm)) withcolor \MPcolor{darkgray} ;
627%         fi ;
628%         draw origin withpen pencircle scaled 1mm ;
629%     \stopuseMPgraphic
630%     \setbox#1\hbox\bgroup
631%         \dorecurse {500} {%
632%             \dontleavehmode
633%             \bgroup
634%             \obeyMPboxdepth
635%             \useMPgraphic{random-thing}%
636%             \egroup
637%             \hskip 3mm plus 3mm minus 1mm\relax
638%         }%
639%     \egroup
640% \stoptexdefinition
641
642% \starttexdefinition profile-sample-get #1#2
643%     \scale
644%       [width=\dimexpr(\textwidth-2em)/4\relax]
645%       {\framed
646%         [offset=overlay,align=normal,profile=#2]
647%         {\unhcopy#1}}
648% \stoptexdefinition
649
650% \texdefinition{profile-sample-set}{0}{2}{darkred}
651% \texdefinition{profile-sample-set}{2}{3}{darkgreen}
652% \texdefinition{profile-sample-set}{4}{4}{darkblue}
653% \texdefinition{profile-sample-set}{6}{5}{darkyellow}
654
655\startMPdefinitions
656    color FakeRed    ; FakeRed    := \MPcolor{darkred} ;
657    color FakeGreen  ; FakeGreen  := \MPcolor{darkgreen} ;
658    color FakeBlue   ; FakeBlue   := \MPcolor{darkblue} ;
659    color FakeYellow ; FakeYellow := \MPcolor{darkyellow} ;
660    color FakeGray   ; FakeGray   := \MPcolor{darkgray} ;
661    def FakeInColor(expr h,c) =
662        if round(uniformdeviate(10)) = 5 :
663            fill unitsquare enlarged ((1mm,h*mm) randomized(1mm,h*mm)) withcolor c ;
664        else :
665            fill unitsquare enlarged ((1mm,1 mm) randomized(1mm,1 mm)) withcolor FakeGray ;
666        fi ;
667        draw origin withpen pencircle scaled 1mm ;
668    enddef ;
669\stopMPdefinitions
670
671\starttexdefinition profile-sample-set #1#2#3
672    \setbox#1\hbox\bgroup
673        \dorecurse {500} {%
674            \dontleavehmode
675            \bgroup
676            \obeyMPboxdepth
677            \startMPcode FakeInColor(#2,#3)\stopMPcode
678            \egroup
679            \hskip 3mm plus 3mm minus 1mm\relax
680        }%
681    \egroup
682\stoptexdefinition
683
684\starttexdefinition profile-sample-get #1#2
685    \scale
686      [width=\dimexpr(\textwidth-2em)/4\relax]
687      {\framed
688        [offset=overlay,align=normal,profile=#2]
689        {\unhcopy#1}}
690\stoptexdefinition
691
692\texdefinition{profile-sample-set}{0}{2}{FakeRed}
693\texdefinition{profile-sample-set}{2}{3}{FakeGreen}
694\texdefinition{profile-sample-set}{4}{4}{FakeBlue}
695\texdefinition{profile-sample-set}{6}{5}{FakeYellow}
696
697\startplacefigure
698  [reference=fig:profiling:fake-examples-1,
699  title={Some examples, each row has progressively more excessive snippets.}]
700    \startcombination[location=top,nx=4,ny=4]
701        {\texdefinition{profile-sample-get}{0}{none}}      {\tttf none      / 2}
702        {\texdefinition{profile-sample-get}{0}{strict}}    {\tttf strict    / 2}
703        {\texdefinition{profile-sample-get}{0}{fixed}}     {\tttf fixed     / 2}
704        {\texdefinition{profile-sample-get}{0}{halffixed}} {\tttf halffixed / 2}
705        {\texdefinition{profile-sample-get}{2}{none}}      {\tttf none      / 3}
706        {\texdefinition{profile-sample-get}{2}{strict}}    {\tttf strict    / 3}
707        {\texdefinition{profile-sample-get}{2}{fixed}}     {\tttf fixed     / 3}
708        {\texdefinition{profile-sample-get}{2}{halffixed}} {\tttf halffixed / 3}
709        {\texdefinition{profile-sample-get}{4}{none}}      {\tttf none      / 4}
710        {\texdefinition{profile-sample-get}{4}{strict}}    {\tttf strict    / 4}
711        {\texdefinition{profile-sample-get}{4}{fixed}}     {\tttf fixed     / 4}
712        {\texdefinition{profile-sample-get}{4}{halffixed}} {\tttf halffixed / 4}
713        {\texdefinition{profile-sample-get}{6}{none}}      {\tttf none      / 5}
714        {\texdefinition{profile-sample-get}{6}{strict}}    {\tttf strict    / 5}
715        {\texdefinition{profile-sample-get}{6}{fixed}}     {\tttf fixed     / 5}
716        {\texdefinition{profile-sample-get}{6}{halffixed}} {\tttf halffixed / 5}
717    \stopcombination
718\stopplacefigure
719
720\startplacefigure
721  [reference=fig:profiling:fake-examples-2,
722   title={The same examples, rearranged such that each row has  a different profiling variant.}]
723    \startcombination[location=top,nx=4,ny=4]
724        {\texdefinition{profile-sample-get}{0}{none}}      {\tttf none      / 2}
725        {\texdefinition{profile-sample-get}{2}{none}}      {\tttf none      / 3}
726        {\texdefinition{profile-sample-get}{4}{none}}      {\tttf none      / 4}
727        {\texdefinition{profile-sample-get}{6}{none}}      {\tttf none      / 5}
728        {\texdefinition{profile-sample-get}{0}{strict}}    {\tttf strict    / 2}
729        {\texdefinition{profile-sample-get}{2}{strict}}    {\tttf strict    / 3}
730        {\texdefinition{profile-sample-get}{4}{strict}}    {\tttf strict    / 4}
731        {\texdefinition{profile-sample-get}{6}{strict}}    {\tttf strict    / 5}
732        {\texdefinition{profile-sample-get}{0}{fixed}}     {\tttf fixed     / 2}
733        {\texdefinition{profile-sample-get}{2}{fixed}}     {\tttf fixed     / 3}
734        {\texdefinition{profile-sample-get}{4}{fixed}}     {\tttf fixed     / 4}
735        {\texdefinition{profile-sample-get}{6}{fixed}}     {\tttf fixed     / 5}
736        {\texdefinition{profile-sample-get}{0}{halffixed}} {\tttf halffixed / 2}
737        {\texdefinition{profile-sample-get}{2}{halffixed}} {\tttf halffixed / 3}
738        {\texdefinition{profile-sample-get}{4}{halffixed}} {\tttf halffixed / 4}
739        {\texdefinition{profile-sample-get}{6}{halffixed}} {\tttf halffixed / 5}
740    \stopcombination
741\stopplacefigure
742
743\stopsection
744
745\startsection[title=Conclusion]
746
747Although profiling seems interesting, in practice it does not have much value in
748an automated flow. Ultimately, in the project for which I investigated this
749trickery, only in the final stage was some last minute optimization of the
750rendering done. We did that by injecting directives. Think of page breaks that
751make the result look more balanced. Optimizing image placement happens in an
752earlier stage because the text can refer to images like \quotation {in the
753picture on the left, we see \unknown}. Controlling profiles is much harder. In
754fact, the more clever we are, the harder it gets to beat it when we want an
755exception. All these mechanisms: spacing, snapping, profiling, breaking pages,
756image placement, to mention a few, have to work together. For projects that
757depend on such placement, it might be better to write dedicated mechanisms than
758to try to fight with clever built|-|in features.
759
760In practice, probably only the \type {fixed} alternative makes sense and as that
761one has a boundary condition similar to (or equal, depending on other settings)
762snapping on gridsteps, the end result might not be that different from doing
763nothing. In \in {figure} [fig:profiling:fake-examples-3] you see that the vbox
764variant is not that bad. And extremely difficult content is unlikely to ever look
765perfect unless some manual intervention happens. Therefore, from the perspective
766of \quotation {fine points of text typesetting} some local (manual) control might
767be more interesting and relevant.
768
769\texdefinition{profile-sample-set}{0}{3}{FakeGreen}
770\texdefinition{profile-sample-set}{2}{3}{FakeGreen}
771\texdefinition{profile-sample-set}{4}{3}{FakeGreen}
772
773In the end, I didn't need this profiling feature at all: because there are
774expectations with respect to how many pages a book should have, typesetting in
775columns was not needed. It didn't save that many pages, and the result would
776never look that much better, simply because of the type of content. Large images
777were also spoiling the game. Nevertheless we will keep profiles in the core and
778it might even get extended. One question remains: at what point do we stop adding
779such features? The answer would be easier if \TEX\ wasn't so flexible.
780
781\startplacefigure[location=top,reference=fig:profiling:fake-examples-3,title=Three similar random cases.]
782    \startcombination[location=top,nx=3,ny=3]
783        {\texdefinition{profile-sample-get}{0}{}}       {\tttf vbox   1}
784        {\texdefinition{profile-sample-get}{0}{strict}} {\tttf strict 1}
785        {\texdefinition{profile-sample-get}{0}{fixed}}  {\tttf fixed  1}
786        {\texdefinition{profile-sample-get}{2}{}}       {\tttf vbox   2}
787        {\texdefinition{profile-sample-get}{2}{strict}} {\tttf strict 2}
788        {\texdefinition{profile-sample-get}{2}{fixed}}  {\tttf fixed  2}
789        {\texdefinition{profile-sample-get}{4}{}}       {\tttf vbox   3}
790        {\texdefinition{profile-sample-get}{4}{strict}} {\tttf strict 3}
791        {\texdefinition{profile-sample-get}{4}{fixed}}  {\tttf fixed  3}
792    \stopcombination
793\stopplacefigure
794
795\stopsection
796
797\stopchapter
798
799\page \enabledirectives[visualizers.fraction=default]
800
801\stopcomponent
802
803