m-oldfun.mkiv /size: 20 Kb    last modification: 2021-10-28 13:51
1%D \module
2%D   [       file=m-oldfun, % was: supp-fun
3%D        version=1995.10.10,
4%D          title=\CONTEXT\ Support Macros,
5%D       subtitle=Fun Stuff,
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\ifcase\contextlmtxmode\else\endinput\fi
15
16\unprotect
17
18%D Beware, these macros wil be replaced and at some point this
19%D module will not be preloaded any more.
20
21%D This module implements some typographics tricks that can
22%D be fun when designing document layouts. The examples use
23%D macros that are typical to \CONTEXT, but non \CONTEXT\
24%D users can use the drop caps and first line treatment
25%D macros without problems. This module will be extended
26%D when the need for more of such tricks arises.
27
28\writestatus{loading}{ConTeXt Support Macros / Fun Stuff}
29
30%D \macros
31%D   {DroppedCaps, DroppedString, DroppedIndent, DroppedLines}
32%D
33%D \startbuffer
34%D \DroppedCaps
35%D   {\color[green]} {SerifBold}
36%D   {\the\dimexpr2.2\baselineskip} {2pt} {\the\baselineskip} {2}
37%D   Let's start
38%D \stopbuffer
39%D
40%D \getbuffer with dropped caps, those blown up first
41%D characters of a paragraph. It's hard to implement a general
42%D mechanism that suits all situations, but dropped caps are so
43%D seldomly used that we can permit ourselves a rather user
44%D unfriendly implementation.
45%D
46%D \typebuffer
47%D
48%D As we will see, there are 7 different settings involved. The
49%D first argument takes a command that is used to do whatever
50%D fancy things we want to do, but normally this one will be
51%D empty. The second argument takes the font. Because we're
52%D dealing with something very typographic, there is no real
53%D reason to adopt complicated font switching schemes, a mere
54%D name will do. Font encodings can bring no harm, because the
55%D alphanumeric characters are nearly always located at their
56%D natural position in the encoding vector.
57%D
58%D \startbuffer
59%D \DroppedCaps
60%D   {\color[red]} {SerifBold}
61%D   {\the\baselineskip} {0pt} {0pt} {1}
62%D   This simple
63%D \stopbuffer
64%D
65%D \getbuffer case shows us what happens when we apply minimal
66%D values. Here we used:
67%D
68%D \typebuffer
69%D
70%D \startbuffer
71%D \DroppedCaps
72%D   {\color[red]} {SerifBold}
73%D   {\the\dimexpr2\baselineskip} {0pt} {\the\baselineskip} {2}
74%D   Is this ugly
75%D \stopbuffer
76%D
77%D \getbuffer example the third argument tells
78%D this macro that we want a dropped capital scaled to the
79%D baseline distance. The two zero point arguments are the
80%D horizontal and vertical offsets and the last arguments
81%D determines the hanging indentation. In this paragraph we
82%D set the height to two times the baselinedistance and use
83%D two hanging lines:
84%D
85%D \typebuffer
86%D
87%D Here, the first character is moved down one baseline. Here
88%D we also see why the horizontal offset is important. The
89%D first example (showing the~L) sets this to a few points and
90%D also used a slightly larger height.
91%D
92%D Of course common users (typist) are not supposed to see this
93%D kind of fuzzy definitions, but fortunately \TEX\ permits us
94%D to hide them in macros. Using a macro also enables us to
95%D garantee consistency throughout the document:
96%D
97%D \startbuffer
98%D \def\MyDroppedCaps%
99%D   {\DroppedCaps
100%D      {\color[green]} {SerifBold}
101%D      {\the\dimexpr5\baselineskip} {3pt} {\the\dimexpr3\baselineskip} {4}}
102%D
103%D \MyDroppedCaps The implementation
104%D \stopbuffer
105%D
106%D \typebuffer
107%D
108%D \getbuffer of the general macro is rather simple and only
109%D depends on the arguments given and the dimensions of the
110%D strut box. We explicitly load the font, which is no problem
111%D because \TEX\ does not load a font twice. We could have
112%D combined some arguments, like the height, vertical offset
113%D and the number of lines, but the current implementation
114%D proved to be the most flexible. One should be aware of the
115%D fact that the offsets depend on the design of the glyphs
116%D used.
117
118\let\DroppedIndent\!!zeropoint \def\DroppedLines{0}
119
120\def\DroppedString{ABCDEFGHIJKLMNOPQRSTUVWXYZ}
121
122\let\globaldropcaps\global % will be an option, but on by default
123
124\unexpanded\def\localdropcaps{\let\globaldropcaps\relax}
125
126\chardef\DroppedStatus = 0 % 0=done 1=starting 2=doing 3=error
127\chardef\DropMode      = 0 % 1 == marginhang
128
129\ifx\keeplinestogether\undefined
130  \let\keeplinestogether\gobbleoneargument
131\fi
132
133\unexpanded\def\DroppedCaps#1#2#3#4#5#6#7% does not yet handle accented chars
134  {\defconvertedargument\asciia{#7}%
135   \defconvertedcommand \asciib{\DroppedString}%
136   \doifelseinstring\asciia\asciib
137     {\noindentation
138      \dontleavehmode
139      \checkindentation % redo this one
140     %\ifhmode\hskip-\parindent\fi % sensitive for context mechanism
141      \keeplinestogether{#6}%
142      \setbox0\hbox{\definedfont[#2 at #3]#1{#7}\hskip#4}%
143      \ifdim\dp0>\strutdp % one of those Q's , will be option
144        \setbox2\hbox{\raise\dp0\hbox{\lower\strutdp\copy0}}%
145        \ht2\ht0
146        \dp0\strutdp
147        \setbox0\box2
148      \fi
149      \setbox0\hbox
150        {\ifnum\DropMode=\plusone
151           \hskip-\wd0\wd0\zeropoint
152         \fi
153         \lower#5\box0}%
154      \ht0\strutht
155      \dp0\strutdp
156      \ifnum\DropMode=\plusone
157        \globaldropcaps\let\DroppedIndent\!!zeropoint
158        \globaldropcaps\edef\DroppedLines{\number\maxdimen}%
159        \globaldropcaps\chardef\DroppedStatus\plusthree
160      \else
161        \globaldropcaps\edef\DroppedIndent{\the\wd0}%
162        \globaldropcaps\edef\DroppedLines {\number#6}%
163        \globaldropcaps\chardef\DroppedStatus\plustwo
164        \globaldropcaps\hangindent\DroppedIndent
165        \globaldropcaps\hangafter-\DroppedLines
166%         \noindent
167        \noindentation
168        \checkindentation % redo this one
169        \hskip-\DroppedIndent
170      \fi
171      \vbox{\forgetall\box0}%
172      \nobreak
173      \let\next\ignorespaces} % Could be a one character word !
174     {\globaldropcaps\let\DroppedIndent\!!zeropoint
175      \globaldropcaps\edef\DroppedLines{\number\maxdimen}%
176      \globaldropcaps\chardef\DroppedStatus\plusthree
177      \def\next{#7}}%
178   \let\globaldropcaps\global
179   \next}
180
181%D Before we go to the next topic, we summarize this command:
182%D
183%D \starttyping
184%D \DroppedCaps
185%D   {command} {font}
186%D   {height} {hoffset} {voffset} {lines}
187%D \stoptyping
188%D
189%D Sometimes you need to make sure that the global settings are
190%D kept local, as in:
191%D
192% %D \startbuffer
193% %D \defineparagraphs[SomePar][n=2,rule=on]
194% %D \setupparagraphs [SomePar][1][width=.5\textwidth]
195% %D \setupparagraphs [SomePar][2][width=.5\textwidth]
196%D \startbuffer
197%D \defineparagraphs[SomePar][n=2,rule=on]
198%D \setupparagraphs [SomePar][1][width=.5\textwidth]
199%D \setupparagraphs [SomePar][2][width=.5\textwidth]
200%D
201%D \startSomePar
202%D   \localdropcaps\NiceDroppedCaps{}{cmr12}{0pt}{2}Here we need
203%D   to explicitly keep the hanging indentation local, like it or
204%D   not.
205%D \SomePar
206%D   \localdropcaps\NiceDroppedCaps{}{cmr12}{0pt}{2}Here we need
207%D   to explicitly keep the hanging indentation local, like it or
208%D   not.
209%D \stopSomePar
210%D \stopbuffer
211%D
212%D \typebuffer \getbuffer
213
214%D \macros
215%D   {AutoDroppedCaps, CheckDroppedCaps}
216%D
217%D {\em To be documented.}
218
219% example usage
220%
221% \def\bpar{\ifvmode\CheckDroppedCaps\fi}
222% \def\epar{\ifhmode\par\fi\CheckDroppedCaps}
223
224\newcount\lastprevgraf
225\newcount\droppedlines
226
227\unexpanded\def\CheckDroppedCaps
228  {\global\lastprevgraf\prevgraf}
229
230\unexpanded\def\AutoDroppedCaps % will be proper core stuff since it
231  {\globaldropcaps\chardef\DroppedStatus\plusone
232   \global\lastprevgraf\zerocount
233   \global\droppedlines\zerocount
234   \EveryPar{\doAutoDroppedCaps}}
235
236\let\AutoDroppedNext\relax
237
238\ifx\AutoDroppedCapsCommand\undefined
239    \unexpanded\def\AutoDroppedCapsCommand{\NiceDroppedCaps{}{SerifBold}{.125em}{3}}
240\fi
241
242\unexpanded\def\doAutoDroppedCaps
243  {\ifcase\DroppedStatus % done
244     \let\next\relax
245   \or % starting
246   % \ifnum\lastprevgraf>0 % tricky, probably a wrong par
247   %   \globaldropcaps\chardef\DroppedStatus=3 % and inhibits dropped
248   %   \let\next\relax % caps after titles and more than once
249   % \else % so let's nill this rubishly code fragment
250       \let\next\AutoDroppedCapsCommand
251   % \fi % and hope for the best
252   \or % doing
253     \global\advance\droppedlines \lastprevgraf
254     \ifnum\droppedlines=\zerocount
255       \globaldropcaps\chardef\DroppedStatus\zerocount
256       \let\next\relax
257     \else\ifnum\droppedlines>\zerocount
258       \ifnum\droppedlines<\DroppedLines\relax
259         \globaldropcaps\hangindent\DroppedIndent
260         \globaldropcaps\hangafter-\DroppedLines
261         \globaldropcaps\advance\hangafter \droppedlines
262         \hskip-\parindent % brrr
263         \let\next\AutoDroppedNext
264       \else
265         \globaldropcaps\chardef\DroppedStatus\zerocount
266         \let\next\relax
267       \fi
268     \else
269       \globaldropcaps\chardef\DroppedStatus\zerocount
270       \let\next\relax
271     \fi\fi
272   \or % error
273     \globaldropcaps\chardef\DroppedStatus\zerocount
274     \let\next\relax
275   \fi
276   \next}
277
278%D \macros
279%D   {LineDroppedCaps, NiceDroppedCaps}
280%D
281%D To save definitions, we also provide:
282%D
283%D \starttyping
284%D \LineDroppedCaps {command} {font} {hoffset} {lines}
285%D \NiceDroppedCaps {command} {font} {hoffset} {lines}
286%D \stoptyping
287%D
288%D The first command scales the font to the exact height, while
289%D the second command scales the font to a nice 2.5 times the
290%D line height, a value that gives a pleasant grayness.
291
292\unexpanded\def\DoLineDroppedCaps#1#2#3#4#5% compensation command font offset lines
293  {\scratchcounter#5%
294   \advance\scratchcounter \minusone
295   \scratchdimen\scratchcounter\baselineskip
296   \advance\scratchdimen #1%
297   \NormalizeFontHeight\DummyFont{W}\scratchdimen{#3}%
298   \DroppedCaps{#2}{#3}\TheNormalizedFontSize{#4}
299     {\scratchcounter\baselineskip}{#5}}
300
301\unexpanded\def\LineDroppedCaps% command font offset lines
302  {\DoLineDroppedCaps{\strutht}}
303
304\unexpanded\def\NiceDroppedCaps% command font offset lines
305  {\DoLineDroppedCaps{.5\baselineskip}}
306
307%D \macros
308%D   {TreatFirstLine}
309%D
310%D \startbuffer
311%D \TreatFirstLine {\sc} {} {} {}
312%D Instead of limiting its action to one token, the next macro
313%D treats the whole first line. This paragraph was typeset by
314%D saying:
315%D \stopbuffer
316%D
317%D \getbuffer
318%D
319%D \typebuffer
320%D
321%D \startbuffer
322%D \TreatFirstLine {\startcolor[red]\bf} {\stopcolor} {} {}
323%D The combined color and font effect is also possible,
324%D although one must be careful in using macros that accumulate
325%D grouping, but the commands used here are pretty save in that
326%D respect.
327%D \stopbuffer
328%D
329%D \getbuffer
330%D
331%D \typebuffer
332%D
333%D Before we explain the third and fourth argument, we show the
334%D implementation. Those who know a bit about the way \TEX\
335%D treats tokens, will probably see in one glance that this
336%D alternative works all right for most text||only situations
337%D in which there is enough text available for the first line,
338%D but that more complicated things will blow. One has to live
339%D with that. A workaround is rather trivial but obscures the
340%D principles used.
341
342\unexpanded\def\TreatFirstLine#1#2#3#4% before, after, first, next
343  {\leavevmode
344   \bgroup
345   \forgetall
346   \bgroup
347   #1%
348   \setbox0\emptybox
349   \setbox2\emptybox
350   \def\grabfirstline##1 %
351     {\setbox2\hbox
352        {\ifvoid0
353           {#3{\ignorespaces##1}}%
354         \else
355           \unhcopy0\ {#4{##1}}%
356         \fi}%
357      \ifdim\wd2=\zeropoint
358        \setbox0\emptybox
359        \setbox2\emptybox
360        \expandafter\grabfirstline
361      \else\ifdim\wd2>\hsize
362        \hbox to \hsize{\strut\unhbox0}#2\egroup
363        \break##1\
364        \egroup
365      \else
366        \setbox0\box2
367        \doubleexpandafter\grabfirstline
368      \fi\fi}%
369   \grabfirstline}
370
371%D \startbuffer
372%D \gdef\FunnyCommand
373%D   {\getrandomfloat\FunnyR{0}{1}%
374%D    \getrandomfloat\FunnyG{0}{1}%
375%D    \getrandomfloat\FunnyB{0}{1}%
376%D    \definecolor[FunnyColor][r=\FunnyR,g=\FunnyG,b=\FunnyB]%
377%D    \color[FunnyColor]}
378%D
379%D %\TreatFirstLine {\bf} {} {\FunnyCommand} {\FunnyCommand}
380%D The third and fourth argument can be used to gain special
381%D effects on the individual words. Of course one needs ...
382%D \stopbuffer
383%D
384%D \getbuffer
385%D to know a bit more about the macro package used to get real
386%D nice effects, but this example probably demonstrates the
387%D principles well.
388%D
389%D \typebuffer
390%D
391%D Like in dropped caps case, one can hide such treatments in a
392%D macro, like:
393%D
394%D \starttyping
395%D \def\MyTreatFirstLine%
396%D   {\TreatFirstLine{\bf}{}{\FunnyCommand}{\FunnyCommand}}
397%D \stoptyping
398
399%D \macros
400%D   {reshapebox}
401%D
402%D \startbuffer
403%D \beginofshapebox
404%D When using \CONTEXT, one can also apply this funny command
405%D to whole lines by using the reshape mechanism. Describing
406%D this interesting mechanism falls outside the scope of this
407%D module, so we only show the trick. This is an example of
408%D low level \CONTEXT\ functionality: it's all there, and it's
409%D stable, but not entirely meant for novice users.
410%D \endofshapebox
411%D
412%D \reshapebox{\FunnyCommand{\box\shapebox}} \flushshapebox
413%D \stopbuffer
414%D
415%D \getbuffer
416%D
417%D \typebuffer
418%D
419%D This mechanism permits hyphenation and therefore gives
420%D better results than the previously discussed macro
421%D \type{\TreatFirstLine}.
422
423%D \macros
424%D   {TreatFirstCharacter}
425%D
426%D \startbuffer
427%D \TreatFirstCharacter{\bf\color[green]} Just to be
428%D \stopbuffer
429%D
430%D \getbuffer complete we also offer a very simple one
431%D character alternative, that is not that hard to understand:
432
433\unexpanded\def\TreatFirstCharacter#1#2% command, character
434  {{#1{#2}}}
435
436%D A previous paragraph started with:
437%D
438%D \typebuffer
439
440%D \macros
441%D   {StackCharacters}
442%D
443%D The next hack deals with vertical stacking.
444
445\unexpanded\def\StackCharacters#1#2#3#4% sequence vsize vskip command
446  {\vbox #2
447     {\forgetall
448      \baselineskip\zeropoint
449      \def\StackCharacter##1{#4{##1}\cr\noalign{#3}}%
450      \halign
451        {\hss##\hss&##\cr
452         \handletokens#1\with\StackCharacter\cr}}}
453
454%D \startbuffer
455%D \StackCharacters{CONTEXT}{}{\vskip.2ex}{\FunnyCommand}
456%D \stopbuffer
457%D
458%D Such a stack looks like:
459%D
460%D \startlinecorrection
461%D \hbox to \hsize
462%D    {$\hss\bfd
463%D     \vcenter{\StackCharacters{TEX}    {}{\vskip.2ex}{\FunnyCommand}}%
464%D     \hss
465%D     \vcenter{\StackCharacters{CON}    {}{\vskip.2ex}{\FunnyCommand}}
466%D     \hss
467%D     \vcenter{\StackCharacters{TEXT}   {}{\vskip.2ex}{\FunnyCommand}}
468%D     \hss
469%D     \vcenter{\StackCharacters{CONTEXT}{}{\vskip.2ex}{\FunnyCommand}}
470%D     \hss$}
471%D \stoplinecorrection
472%D
473%D and is typeset by saying:
474%D
475%D \typebuffer
476%D
477%D An alternative would have been
478%D
479%D \starttyping
480%D \StackCharacters {CONTEXT} {to 5cm} {\vfill} {\FunnyCommand}
481%D \stoptyping
482
483%D \macros
484%D   {processtokens}
485%D
486%D At a lower level horizontal and vertical manipulations are
487%D already supported by:
488%D
489%D \starttyping
490%D \processtokens {begin} {between} {end} {space} {text}
491%D \stoptyping
492%D
493%D \startbuffer[a]
494%D \processtokens
495%D   {\hbox to .5\hsize\bgroup} {\hfill}
496%D   {\egroup} {\space} {LET'S HAVE}
497%D \stopbuffer
498%D
499%D \startbuffer[b]
500%D \processtokens
501%D   {\vbox\bgroup\raggedcenter\hsize1em}
502%D   {\vskip.25ex} {\egroup} {\strut} {FUN}
503%D \stopbuffer
504%D
505%D This macro is able to typeset:
506%D
507%D \leavevmode\hbox to \hsize
508%D   {$\hfil\hfil
509%D    \vcenter{\bf\getbuffer[a]}%
510%D    \hfil
511%D    \vcenter{\bfd\getbuffer[b]}%
512%D    \hfil\hfil$}
513%D
514%D which was specified as:
515%D
516%D \typebuffer[a]
517%D \typebuffer[b]
518
519%D \macros
520%D   {NormalizeFontHeight, NormalizeFontWidth,
521%D    TheNormalizedFontSize}
522%D
523%D Next we introduce some font manipulation macros. When we
524%D want to typeset some text spread in a well defined area, it
525%D can be considered bad practice to manipulate character and
526%D word spacing. In such situations the next few macros can be
527%D of help:
528%D
529%D \starttyping
530%D \NormalizeFontHeight \name {sample text} {height} {font}
531%D \NormalizeFontWidth  \name {sample text} {width}  {font}
532%D \stoptyping
533%D
534%D These are implemented using an auxilliary macro:
535
536\unexpanded\def\NormalizeFontHeight{\NormalizeFontSize\ht}
537\unexpanded\def\NormalizeFontWidth {\NormalizeFontSize\wd}
538
539\unexpanded\def\NormalizeFontSize#1#2#3#4#5%
540  {\bgroup
541   \dimen0=#4% #4 can be \ht0 or so
542   \setbox0\hbox{\definedfont[#5 at 5pt]#3}% 10pt
543   \ifdim\wd0>\zeropoint
544     \dimen2=#10 % #1 is \wd or \ht
545     \dimen4=\maxdimen % 10000pt
546     \divide\dimen4 \dimen2
547     \divide\dimen0 1638 % 1000
548     \dimen0=\number\dimen4\dimen0
549     \divide \dimen0 \plustwo % ...
550     \xdef\TheNormalizedFontSize{\the\dimen0}%
551   \else
552     \dimen0\bodyfontsize
553   \fi
554   \normalexpanded{\egroup\def\noexpand#2{\definedfont[#5 at \the\dimen0]}}}
555
556%D Afterwards, we have access to the calculated size by:
557
558\let\TheNormalizedFontSize\!!zeropoint
559
560%D Extra:
561
562\unexpanded\def\WidthSpanningText#1#2#3% text width font
563  {\hbox{\NormalizeFontWidth\temp{#1}{#2}{#3}\temp\the\everydefinedfont#1}}
564
565%D Consider for instance:
566%D
567%D \startbuffer
568%D \NormalizeFontHeight \tmp {X} {2\baselineskip} {cmr10}
569%D
570%D {\tmp To Be Or Not To Be}
571%D \stopbuffer
572%D
573%D \typebuffer
574%D
575%D This shows up as (we also show the baselines):
576%D
577%D {\showbaselines\getbuffer}
578%D
579%D The horizontal counterpart is:
580%D
581%D \startbuffer
582%D \NormalizeFontWidth \tmp {This Line Fits} {\hsize} {cmr10}
583%D
584%D \hbox{\tmp This Line Fits}
585%D \stopbuffer
586%D
587%D \typebuffer
588%D
589%D The calculated font scale is avaliable in the macro
590%D \type{\NormalizedFontSize}.
591%D
592%D \startlinecorrection
593%D \ruledhbox{\getbuffer}
594%D \stoplinecorrection
595%D
596%D One can of course combine these macros with the ones
597%D described earlier, like in:
598%D
599%D \starttyping
600%D \NormalizeFontHeight {text} \DroppedFont {2\baselineskip} {cmbx12}
601%D
602%D \def\NicelyDroppedCaps
603%D   {\DroppedCaps
604%D      {\color[green]}
605%D      {\DroppedFont}
606%D      {2pt}
607%D      {\baselineskip}
608%D      {2}}
609%D \stoptyping
610%D
611%D It's up to the reader to test this one.
612
613\unexpanded\def\FirstNCharacters#1#2% \FirstNCharacters{3}{fr{\"o}beln}
614  {\bgroup
615   \scratchcounter\zerocount
616   \def\docommand##1%
617     {\ifnum\scratchcounter=#1\else
618        ##1\relax % catches ##1 = \"e and alike
619        \advance\scratchcounter\plusone
620      \fi}
621   \handletokens#2\with\docommand
622   \egroup}
623
624%D \macros
625%D   {FittingText}
626%D
627%D First used in Pascal (demo-bbv):
628%D
629%D \startbuffer
630%D \ruledvbox{\FittingText{3cm}{1cm}{Serif}{24pt}{1pt}{1}
631%D   {\veryraggedright
632%D    \hangindent1em\hangafter1\relax
633%D    \begstrut \dorecurse{8}{Bram Marta }\unskip \endstrut}}
634%D
635%D \ruledvbox{\FittingText{3cm}{1cm}{Serif}{24pt}{1pt}{1}
636%D   {\raggedleft\begstrut Bram\\Marta \unskip\endstrut}}
637%D \stopbuffer
638%D
639%D \typebuffer
640%D
641%D \startlinecorrection
642%D \getbuffer
643%D \stoplinecorrection
644
645% #1 width #2 height #3 font #4 size #5 step #6 interlinie #7 text
646
647\unexpanded\def\FittingText#1#2#3#4#5#6#7%
648  {\bgroup
649   \forgetall
650   \dontcomplain
651   \setuptolerance[\v!verytolerant]% == \tolerance4500
652   \hsize#1%
653   \enforced\def\\{\softbreak}%
654   \!!heighta#4%
655   \!!heightb#2%
656   \doloop
657     {\ifdim\!!heighta>\onepoint
658        \expanded{\definefont[\s!dummy][#3 at \the\!!heighta][\c!interlinespace=#6]}%
659        \getvalue\s!dummy
660        \setbox\scratchbox\vbox{#7\endgraf}%
661        \ifdim\ht\scratchbox>\!!heightb
662          \advance\!!heighta-#5%
663        \else
664          \beginshapebox
665          \unvcopy\scratchbox
666          \endshapebox
667          \global\dimen1\hsize
668          \reshapebox
669            {\setbox\shapebox\hbox{\unhbox\shapebox}%
670             \ifdim\wd\shapebox>\dimen1
671               \global\dimen1\wd\shapebox
672             \fi}%
673          \ifdim\dimen1>\hsize
674            \advance\!!heighta-#5%
675          \else
676            \exitloop
677          \fi
678        \fi
679      \else
680        \exitloop
681      \fi}%
682  %\writestatus{\strippedcsname\FittingText}{height: \the\!!heighta}%
683   \unvbox\scratchbox
684   \egroup}
685
686% \font width gap font spec text
687
688\unexpanded\def\NormalizeFontWidthSpread#1#2#3#4#5#6%
689  {\global\setfalse\NFSpread
690   \scratchdimen#3%
691   \scratchdimen-.5\scratchdimen
692   \advance\scratchdimen#2\relax
693   \NormalizeFontWidth
694     #1%
695     {\enforced\def\+{\global\settrue\NFSpread\gobbleuntil\relax}%
696      \enforced\def\\{\gobbleuntil\relax}% newline
697      \setupspacing
698      #6\relax}%
699     {\scratchdimen}%
700     {#4}%
701   \ifconditional\NFSpread
702     % de gap valt in de binding
703   \else
704     \definefont[\strippedcsname#1][#4 #5]%
705   \fi}
706
707\unexpanded\def\SpreadGapText#1#2%
708  {{\def\+{\kern#1}#2}}
709
710\unexpanded\def\GapText#1#2#3#4#5% width distance font spec title
711  {\bgroup
712   \NormalizeFontWidthSpread\DummyFont{#1}{#2}{#3}{#4}{#5}%
713   \DummyFont\setupspacing\SpreadGapText{#2}{#5}\endgraf
714   \egroup}
715
716\protect \endinput
717