summaryrefslogtreecommitdiff
path: root/doc/context/sources/general/manuals/spacing/spacing-spaces.tex
blob: 0d7f64379d0147e1ce651c185f59951b3dc0b3d9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
% language=uk

\environment spacing-style

\startcomponent spacing-periods

\startchapter[title=Spacing]

\startsection[title=Spaces]

When \TEX\ reads its input and transforms content it into a node list spaces are
turned into glue nodes of subtype \quote {spaceskip} or \quote {xspaceskip}. In
pseudo code, this is what happens:

\starttyping
if spacefactor >= 2000 and xspaceskip ~= 0 then
    space   = xspaceskip_space
    stretch = xspaceskip_stretch
    shrink  = xspaceskip_shrink
    subtype = xspaceskip
else
    if spaceskip == 0 then
        space   = font_space
        stretch = font_stretch
        shrink  = font_shrink
    else
        space   = spaceskip_space
        stretch = spaceskip_stretch
        shrink  = spaceskip_shrink
    end
    if space_factor >= 2000
        space = space + font_extraspace
    end
    stretch = stretch * space_factor
    shrink  = shrink  * space_factor
    subtype = spaceskip
end
insert_glue(space,stretch,shrink,subtype)
\stoptyping

We demonstrate the effects in a few examples. You can use \typ {\showmakeup [space]} to
visualize spaces.

\def\ShowSpaces#1#2#3%
  {\blank
   \start
   \startsubsubsubject[title={case #1: \type{#2} and \type {#3}}]
   \dontleavehmode
   #2\relax
   #3\relax
   \showmakeup[space]%
 % \definedfont[Serif*default]%
   \nonfrenchspacing
   \strut x\space x.\space x\crlf
   \frenchspacing
   \strut x\space x.\space x\par
   \stop
   \stopsubsubject
   \blank}

\ShowSpaces{1}{\spacefactor2000}{\xspaceskip100pt}

\starttabulate[|l|l|]
\HL
\NC \type {\spacefactor} \NC $\geq 2000$ \NC \NR
\NC \type {\xspaceskip}  \NC $\neq    0$ \NC \NR
\HL
\NC space   \NC xspaceskip_space   \NC \NR
\NC stretch \NC xspaceskip_stretch \NC \NR
\NC shrink  \NC xspaceskip_shrink  \NC \NR
\NC subtype \NC xspaceskip         \NC \NR
\HL
\stoptabulate

\ShowSpaces{2}{\spacefactor1000}{\spaceskip0pt}

\starttabulate[|l|l|]
\HL
\NC \type {\spacefactor} \NC $\lt 2000$ \NC \NR
\NC \type {\spaceskip}   \NC $\eq    0$ \NC \NR
\HL
\NC space   \NC font_space   \NC \NR
\NC stretch \NC font_stretch \NC \NR
\NC shrink  \NC font_shrink  \NC \NR
\NC subtype \NC spaceskip    \NC \NR
\HL
\stoptabulate

\ShowSpaces{3}{\spacefactor2000}{\spaceskip0pt}

\starttabulate[|l|l|]
\HL
\NC \type {\spacefactor} \NC $\geq 2000$ \NC \NR
\NC \type {\spaceskip}   \NC $\eq     0$ \NC \NR
\HL
\NC space   \NC font_space $+$ extraspace_font \NC \NR
\NC stretch \NC font_stretch                   \NC \NR
\NC shrink  \NC font_shrink                    \NC \NR
\NC subtype \NC spaceskip                      \NC \NR
\HL
\stoptabulate

\ShowSpaces{4}{\spacefactor1000}{\spaceskip100pt}

\starttabulate[|l|l|]
\HL
\NC \type {\spacefactor} \NC $\lt  2000$ \NC \NR
\NC \type {\spaceskip}   \NC $\neq    0$ \NC \NR
\HL
\NC space   \NC font_space                         \NC \NR
\NC stretch \NC font_stretch $\times$ space_factor \NC \NR
\NC shrink  \NC font_shrink  $\times$ space_factor \NC \NR
\NC subtype \NC spaceskip                          \NC \NR
\HL
\stoptabulate

\ShowSpaces{5}{\spacefactor2000}{\spaceskip100pt}

\starttabulate[|l|l|]
\HL
\NC \type {\spacefactor} \NC $\geq 2000$ \NC \NR
\NC \type {\spaceskip}   \NC $\neq    0$ \NC \NR
\HL
\NC space   \NC font_space   $+$ extraspace_font   \NC \NR
\NC stretch \NC font_stretch $\times$ space_factor \NC \NR
\NC shrink  \NC font_shrink  $\times$ space_factor \NC \NR
\NC subtype \NC spaceskip                          \NC \NR
\HL
\stoptabulate

The width of a space relates to the design of a font and therefore the t width of
the space, its stretch and its shrink are taken from the font and scaled
accordingly. Normally we take the space character in the font as reference.
Traditional \TEX\ fonts don't have that character but \OPENTYPE\ fonts have. When
there is no space character, in the case of a monospaced font we take the
emwidth, otherwise we take half the emwidth. As a last resort we can take the
average width of characters. And of even that fails we take half of the font
units. But, as mentioned, modern fonts have a space.

In the \CONTEXT\ font loader we use a stretch that is 1/2 of the width of a space
and the shrink is 1/3 the width of a space. These values are familiar for those
who come from traditional \TEX.

As with many variables, you can overload these values when a font is loaded by
setting the \type {spacing} feature. Here is how this is done:

\startbuffer
\definefontfeature
  [morespace]
  [spacing=0.50 plus 0.50 minus 0.250]
\definefontfeature
  [lessspace]
  [spacing=0.25 plus 0.25 minus 0.125]
\definefontfeature
  [extramorespace]
  [spacing=0.50 plus 0.50 minus 0.250 extra 2.00]
\definefontfeature
  [extralessspace]
  [spacing=0.25 plus 0.25 minus 0.125 extra 2.00]

\definedfont[Serif*default]
    \inleft{\infofont default}
    \samplefile{klein}\par
    \blank
\definedfont[Serif*default,morespace]
    \inleft{\infofont morespace}
    \samplefile{klein}\par
    \blank
\definedfont[Serif*default,extramorespace]
    \inleft{\infofont extramorespace}
    \samplefile{klein}\par
    \blank
\definedfont[Serif*default,lessspace]
    \inleft{\infofont lessspace}
    \samplefile{klein}\par
    \blank
\definedfont[Serif*default,extralessspace]
    \inleft{\infofont extralessspace}
    \samplefile{klein}\par
    \blank
\stopbuffer

\typebuffer

For demonstration purposes we use a somewhat excessive \type {extra}
specification. By default the extra space is equal to the shrink.

\blank \start
    \showmakeup[space]
    \getbuffer
\stop \blank

\stopsection

\startsection[title=Expansion]

Spaces become glue that can shrink or stretch. In the worst case words will come
too close, or the gap will be large. Even worse is that this can lead to
successive lines in a paragraph looking different with respect to spacing. A solution
for this is to use font expansion, although the benefits are often less than
some users want (you) to believe.

This mechanism is enabled with \type {\setupalign}. There are two variants (\type
{hz} and \type {fullhz}) and a reset (\type {nohz}). In \in {figure} [fig:expansion]
we use the following font definition:

\startbuffer
\definefont[testfont][Normal*default,quality @ 9pt]
\stopbuffer

\typebuffer \getbuffer

We use \type {\showfontexpansion} to view the effective expansion factors of each
glyph. When \type {fullhz} is used fontkerns also can get expanded. Zero values
are not shown. The font kern factors are shown below the character factors. They
can be neglected and one can even wonder if they need a treatment especially
because kerns are also used for relative positioning, accent anchoring and
cursive attachments.

\startplacefigure[reference=fig:expansion,title={The two expansion methods in action.}]
    \startcombination[nx=3,ny=2,location=top]
                                                           {\framed[foregroundstyle=\testfont,width=.3\textwidth,align={normal,tolerant,nohz}]  {\showfontexpansion\samplefile{ward}}}   {}
                                                           {\framed[foregroundstyle=\testfont,width=.3\textwidth,align={normal,tolerant,fullhz}]{\showfontexpansion\samplefile{ward}}}   {}
                                                           {\framed[foregroundstyle=\testfont,width=.3\textwidth,align={normal,tolerant,hz}]    {\showfontexpansion\samplefile{ward}}}   {}
       {\scale[width=.3\textwidth]{\clip[nx=2,ny=4,x=2,y=3]{\framed[foregroundstyle=\testfont,width=.3\textwidth,align={normal,tolerant,nohz}]  {\showfontexpansion\samplefile{ward}}}}} {\tttf{nohz}}
       {\scale[width=.3\textwidth]{\clip[nx=2,ny=4,x=2,y=3]{\framed[foregroundstyle=\testfont,width=.3\textwidth,align={normal,tolerant,fullhz}]{\showfontexpansion\samplefile{ward}}}}} {\tttf{fullhz}}
       {\scale[width=.3\textwidth]{\clip[nx=2,ny=4,x=2,y=3]{\framed[foregroundstyle=\testfont,width=.3\textwidth,align={normal,tolerant,hz}]    {\showfontexpansion\samplefile{ward}}}}} {\tttf{hz}}
    \stopcombination
\stopplacefigure

\stopsection

\startsection[title=Looseness]

The \type {\looseness} parameter can be used to let the par builder add more
lines, but that condition is only met when the demand is reasonable. So we need
stretch and often also tolerance to achieve it.

\starttyping
\looseness=1 ... text ... \par
\stoptyping

This setting is reset afterwards. Because \type {framed} does some grouping deep down,
we need either to use it in there like this:

\starttyping
\framed
  [align={normal,verytolerant,stretch},strut=no]
  {\looseness1 ... \par}
\stoptyping

which is somewhat clumsy, or we can do:

\starttyping
\framed
  [align={normal,verytolerant,stretch,2*more}]
  {...}
\stoptyping

This is demonstrated in \in {figure} [fig:looseness].

\startplacefigure[reference=fig:looseness,title={Looseness in action.}]
    \dontcomplain
    \startcombination[location=top,nx=3,ny=1]
        {\framed[foregroundstyle=small,align={normal,verytolerant,stretch},       width=.3\textwidth]{\samplefile{sapolsky}\unskip}} {}
        {\framed[foregroundstyle=small,align={normal,verytolerant,stretch,1*more},width=.3\textwidth]{\samplefile{sapolsky}\unskip}} {\type {1*more}}
        {\framed[foregroundstyle=small,align={normal,verytolerant,stretch,2*more},width=.3\textwidth]{\samplefile{sapolsky}\unskip}} {\type {2*more}}
    \stopcombination
\stopplacefigure

\stopsection

\stopchapter

\stopcomponent