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
|
if not modules then modules = { } end modules ['typo-pnc'] = {
version = 1.001,
comment = "companion to typo-pnc.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
license = "see context related readme files"
}
local nodes = nodes
local fonts = fonts
local enableaction = nodes.tasks.enableaction
local nuts = nodes.nuts
local tonut = nodes.tonut
local nodecodes = nodes.nodecodes
local gluecodes = nodes.gluecodes
local glyph_code = nodecodes.glyph
local glue_code = nodecodes.glue
local spaceskip_code = gluecodes.spaceskip
local new_kern = nuts.pool.kern
local insertafter = nuts.insertafter
local nextglyph = nuts.traversers.glyph
local getchar = nuts.getchar
local getfont = nuts.getfont
local getboth = nuts.getboth
local getnext = nuts.getnext
local getattr = nuts.getattr
local getid = nuts.getid
local getsubtype = nuts.getsubtype
local getwidth = nuts.getwidth
local setwidth = nuts.setwidth
local parameters = fonts.hashes.parameters
local categories = characters.categories
local texsetattribute = tex.setattribute
local unsetvalue = attributes.unsetvalue
local period = 0x2E
local factor = 0.5
-- alternative: tex.getlccode and tex.getuccode
typesetters = typesetters or { }
local typesetters = typesetters
local periodkerns = typesetters.periodkerns or { }
typesetters.periodkerns = periodkerns
local report = logs.reporter("period kerns")
local trace = false
trackers.register("typesetters.periodkerns",function(v) trace = v end)
periodkerns.mapping = periodkerns.mapping or { }
periodkerns.factors = periodkerns.factors or { }
local a_periodkern = attributes.private("periodkern")
storage.register("typesetters/periodkerns/mapping", periodkerns.mapping, "typesetters.periodkerns.mapping")
storage.register("typesetters/periodkerns/factors", periodkerns.factors, "typesetters.periodkerns.factors")
local mapping = periodkerns.mapping
local factors = periodkerns.factors
function periodkerns.handler(head)
for current, char, font in nextglyph, head do
if char == period then
local a = getattr(current,a_periodkern)
if a then
local factor = mapping[a]
if factor then
local prev, next = getboth(current)
if prev and next and getid(prev) == glyph_code and getid(next) == glyph_code then
local pchar = getchar(prev)
local pcode = categories[pchar]
if pcode == "lu" or pcode == "ll" then
local nchar = getchar(next)
local ncode = categories[nchar]
if ncode == "lu" or ncode == "ll" then
local next2 = getnext(next)
if next2 and getid(next2) == glyph_code and getchar(next2) == period then
-- A.B.
local fontspace, inserted
if factor ~= 0 then
fontspace = parameters[getfont(current)].space -- can be sped up
inserted = factor * fontspace
insertafter(head,current,new_kern(inserted))
if trace then
report("inserting space at %C . [%p] %C .",pchar,inserted,nchar)
end
end
local next3 = getnext(next2)
if next3 and getid(next3) == glue_code and getsubtype(next3) == spaceskip_code then
local width = getwidth(next3)
local space = fontspace or parameters[getfont(current)].space -- can be sped up
if width > space then -- space + extraspace
local next4 = getnext(next3)
if next4 and getid(next4) == glyph_code then
local fchar = getchar(next4)
if categories[fchar] ~= "lu" then
-- A.B.<glue>X
if trace then
if inserted then
report("reverting space at %C . [%p] %C . [%p->%p] %C",pchar,inserted,nchar,width,space,fchar)
else
report("reverting space at %C . %C . [%p->%p] %C",pchar,nchar,width,space,fchar)
end
end
setwidth(next3,space)
else
if trace then
if inserted then
report("keeping space at %C . [%p] %C . [%p] %C",pchar,inserted,nchar,width,fchar)
else
report("keeping space at %C . %C . [%p] %C",pchar,nchar,width,fchar)
end
end
end
end
end
end
end
end
end
end
end
end
end
end
return head
end
local enabled = false
function periodkerns.set(factor)
factor = tonumber(factor) or 0
if not enabled then
enableaction("processors","typesetters.periodkerns.handler")
enabled = true
end
local a = factors[factor]
if not a then
a = #mapping + 1
factors[factors], mapping[a] = a, factor
end
factor = a
texsetattribute(a_periodkern,factor)
return factor
end
-- interface
interfaces.implement {
name = "setperiodkerning",
actions = periodkerns.set,
arguments = "string"
}
|