1if not modules then modules = { } end modules ['typo-pnc'] = {
2 version = 1.001,
3 comment = "companion to typo-pnc.mkiv",
4 author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5 copyright = "PRAGMA ADE / ConTeXt Development Team",
6 license = "see context related readme files"
7}
8
9local nodes = nodes
10local fonts = fonts
11
12local enableaction = nodes.tasks.enableaction
13
14local nuts = nodes.nuts
15local tonut = nodes.tonut
16
17local new_kern = nuts.pool.kern
18local insertafter = nuts.insertafter
19
20local nextglyph = nuts.traversers.glyph
21
22local getchar = nuts.getchar
23local getfont = nuts.getfont
24local getboth = nuts.getboth
25local getnext = nuts.getnext
26local getattr = nuts.getattr
27local getid = nuts.getid
28local getsubtype = nuts.getsubtype
29local getwidth = nuts.getwidth
30local setwidth = nuts.setwidth
31local findattribute = nuts.findattribute
32
33local glyph_code <const> = nodes.nodecodes.glyph
34local glue_code <const> = nodes.nodecodes.glue
35local spaceskip_code <const> = nodes.gluecodes.spaceskip
36
37local parameters = fonts.hashes.parameters
38local categories = characters.categories
39
40local texsetattribute = tex.setattribute
41
42local unsetvalue <const> = attributes.unsetvalue
43
44local period <const> = 0x2E
45
46local factor = 0.5
47
48
49
50typesetters = typesetters or { }
51local typesetters = typesetters
52
53local periodkerns = typesetters.periodkerns or { }
54typesetters.periodkerns = periodkerns
55
56local report = logs.reporter("period kerns")
57local trace = false
58
59trackers.register("typesetters.periodkerns",function(v) trace = v end)
60
61periodkerns.mapping = periodkerns.mapping or { }
62periodkerns.factors = periodkerns.factors or { }
63
64local a_periodkern <const> = attributes.private("periodkern")
65
66storage.register("typesetters/periodkerns/mapping", periodkerns.mapping, "typesetters.periodkerns.mapping")
67storage.register("typesetters/periodkerns/factors", periodkerns.factors, "typesetters.periodkerns.factors")
68
69local mapping = periodkerns.mapping
70local factors = periodkerns.factors
71
72function periodkerns.handler(head)
73 local _, start = findattribute(head,a_periodkern,glyph_code)
74 if start then
75 for current, char, font in nextglyph, start do
76 if char == period then
77 local a = getattr(current,a_periodkern)
78 if a then
79 local factor = mapping[a]
80 if factor then
81 local prev, next = getboth(current)
82 if prev and next and getid(prev) == glyph_code and getid(next) == glyph_code then
83 local pchar = getchar(prev)
84 local pcode = categories[pchar]
85 if pcode == "lu" or pcode == "ll" then
86 local nchar = getchar(next)
87 local ncode = categories[nchar]
88 if ncode == "lu" or ncode == "ll" then
89 local next2 = getnext(next)
90 if next2 and getid(next2) == glyph_code and getchar(next2) == period then
91
92 local fontspace, inserted
93 if factor ~= 0 then
94 fontspace = parameters[getfont(current)].space
95 inserted = factor * fontspace
96 insertafter(head,current,new_kern(inserted))
97 if trace then
98 report("inserting space at %C . [%p] %C .",pchar,inserted,nchar)
99 end
100 end
101 local next3 = getnext(next2)
102 if next3 and getid(next3) == glue_code and getsubtype(next3) == spaceskip_code then
103 local width = getwidth(next3)
104 local space = fontspace or parameters[getfont(current)].space
105 if width > space then
106 local next4 = getnext(next3)
107 if next4 and getid(next4) == glyph_code then
108 local fchar = getchar(next4)
109 if categories[fchar] ~= "lu" then
110
111 if trace then
112 if inserted then
113 report("reverting space at %C . [%p] %C . [%p->%p] %C",pchar,inserted,nchar,width,space,fchar)
114 else
115 report("reverting space at %C . %C . [%p->%p] %C",pchar,nchar,width,space,fchar)
116 end
117 end
118 setwidth(next3,space)
119 else
120 if trace then
121 if inserted then
122 report("keeping space at %C . [%p] %C . [%p] %C",pchar,inserted,nchar,width,fchar)
123 else
124 report("keeping space at %C . %C . [%p] %C",pchar,nchar,width,fchar)
125 end
126 end
127 end
128 end
129 end
130 end
131 end
132 end
133 end
134 end
135 end
136 end
137 end
138 end
139 end
140 return head
141end
142
143local enabled = false
144
145function periodkerns.set(factor)
146 factor = tonumber(factor) or 0
147 if not enabled then
148 enableaction("processors","typesetters.periodkerns.handler")
149 enabled = true
150 end
151 local a = factors[factor]
152 if not a then
153 a = #mapping + 1
154 factors[factors], mapping[a] = a, factor
155 end
156 factor = a
157 texsetattribute(a_periodkern,factor)
158 return factor
159end
160
161
162
163interfaces.implement {
164 name = "setperiodkerning",
165 actions = periodkerns.set,
166 arguments = "string"
167}
168
169
170 |