1if not modules then modules = { } end modules['s-math-characters'] = {
2 version = 1.001,
3 comment = "companion to s-math-characters.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
9
10
11moduledata.math = moduledata.math or { }
12moduledata.math.characters = moduledata.math.characters or { }
13
14local concat = table.concat
15local lower = string.lower
16local utfchar = utf.char
17local round = math.round
18local setmetatableindex = table.setmetatableindex
19local sortedhash = table.sortedhash
20
21local context = context
22
23local fontdata = fonts.hashes.identifiers
24local chardata = characters.data
25local blocks = characters.blocks
26
27local no_description = "no description, private to font"
28
29local limited = true
30local fillinthegaps = true
31local upperlimit = 0x0007F
32local upperlimit = 0xF0000
33
34local f_unicode = string.formatters["%U"]
35local f_slot = string.formatters["%s/%0X"]
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
92function moduledata.math.characters.showlist(specification)
93 specification = interfaces.checkedspecification(specification)
94 local id = specification.number
95 local list = specification.list
96 local showvirtual = specification.virtual == "all"
97 local method = specification.method
98 if not id then
99 id = font.current()
100 end
101 if list == "" then
102 list = nil
103 end
104 local blocks = characters.blocks
105 local tfmdata = fontdata[id]
106 local characters = tfmdata.characters
107 local descriptions = tfmdata.descriptions
108 local resources = tfmdata.resources
109 local lookuptypes = resources.lookuptypes
110 local virtual = tfmdata.properties.virtualized
111 local names = { }
112 local gaps = mathematics.gaps
113 local sorted = { }
114 if type(list) == "string" then
115
116 local b = blocks[list]
117 if b then
118 sorted = { }
119 for i=b.first,b.last do
120 sorted[#sorted+1] = gaps[i] or i
121 end
122 else
123 sorted = utilities.parsers.settings_to_array(list)
124 for i=1,#sorted do
125 sorted[i] = tonumber(sorted[i])
126 end
127 end
128 elseif type(list) == "table" then
129 sorted = list
130 for i=1,#sorted do
131 sorted[i] = tonumber(sorted[i])
132 end
133 elseif fillinthegaps then
134 sorted = table.keys(characters)
135 for k, v in next, gaps do
136 if characters[v] then
137 sorted[#sorted+1] = k
138 end
139 end
140 table.sort(sorted)
141 else
142 sorted = table.sortedkeys(characters)
143 end
144 if virtual then
145 local fonts = tfmdata.fonts
146 for i=1,#fonts do
147 local id = fonts[i].id
148 local name = fontdata[id].properties.name
149 names[i] = (name and file.basename(name)) or id
150 end
151 end
152 if check then
153 for k, v in sortedhash(blocks) do
154 if v.math then
155 local first = v.first
156 local last = v.last
157 local f, l = 0, 0
158 if first and last then
159 for unicode=first,last do
160 local code = gaps[unicode] or unicode
161 local char = characters[code]
162 if char and not (char.commands and not showvirtual) then
163 f = unicode
164 break
165 end
166 end
167 for unicode=last,first,-1 do
168 local code = gaps[unicode] or unicode
169 local char = characters[code]
170 if char and not (char.commands and not showvirtual) then
171 l = unicode
172 break
173 end
174 end
175 context.showmathcharacterssetrange(k,f,l)
176 end
177 end
178 end
179 else
180
181 local function collectalllookups(tfmdata,script,language)
182 local all = setmetatableindex(function(t,k) local v = setmetatableindex("table") t[k] = v return v end)
183 local shared = tfmdata.shared
184 local rawdata = shared and shared.rawdata
185 if rawdata then
186 local features = rawdata.resources.features
187 if features.gsub then
188 for kind, feature in next, features.gsub do
189 local validlookups, lookuplist = fonts.handlers.otf.collectlookups(rawdata,kind,script,language)
190 if validlookups then
191 for i=1,#lookuplist do
192 local lookup = lookuplist[i]
193 local steps = lookup.steps
194 for i=1,lookup.nofsteps do
195 local coverage = steps[i].coverage
196 if coverage then
197 for k, v in next, coverage do
198 all[k][lookup.type][kind] = v
199 end
200 end
201 end
202 end
203 end
204 end
205 end
206 end
207 return all
208 end
209
210 local alllookups = collectalllookups(tfmdata,"math","dflt")
211
212 local luametatex = LUATEXENGINE == "luametatex"
213
214
215
216if method == "manual" then
217
218 context.starttabulate { "|T||||pl|" }
219 for _, unicode in next, sorted do
220 if not limited or unicode < upperlimit then
221 local code = gaps[unicode] or unicode
222 local char = characters[code]
223 local desc = descriptions[code]
224 local info = chardata[unicode] or chardata[code]
225 if char then
226 local mathclass = info.mathclass
227 local mathspec = info.mathspec
228 local mathsymbol = info.mathsymbol
229 local description = lower(info.description or no_description)
230 local names = { }
231 if mathclass or mathspec then
232 if mathclass then
233 names[info.mathname or ""] = mathclass
234 end
235 if mathspec then
236 for i=1,#mathspec do
237 local mi = mathspec[i]
238 names[mi.name or ""] = mi.class
239 end
240 end
241 end
242
243 if next(names) then
244 local doit = true
245 for k, v in sortedhash(names) do
246 context.NC() if doit then context("%U",unicode) end
247 context.NC() if doit then context.char(unicode) end
248 context.NC() if k ~= "" then context.tex(k) end
249 context.NC() context.ex(v)
250 context.NC() if doit then context(description) end
251 context.NC() context.NR()
252 doit = false
253 end
254 else
255 local mathname = info.mathname
256 context.NC() context("%U",unicode)
257 context.NC() context.char(unicode)
258 context.NC() if mathname then context.tex(mathname) end
259 context.NC() context("ordinary")
260 context.NC() context(lower(description))
261 context.NC() context.NR()
262 end
263 end
264 end
265 end
266 context.stoptabulate()
267
268else
269
270 context.showmathcharactersstart()
271 for _, unicode in next, sorted do
272 if not limited or unicode < upperlimit then
273 local code = gaps[unicode] or unicode
274 local char = characters[code]
275 local desc = descriptions[code]
276 local info = chardata[code]
277 if char then
278
279 local commands = char.commands
280 if commands and not showvirtual then
281
282 else
283 local next_sizes = char.next
284 local vparts = char.vparts or char.vert_variants
285 local hparts = char.hparts or char.horiz_variants
286 local mathclass = info.mathclass
287 local mathspec = info.mathspec
288 local mathsymbol = info.mathsymbol
289 local description = info.description or no_description
290 context.showmathcharactersstartentry(
291 )
292 context.showmathcharactersreference(
293 f_unicode(unicode)
294 )
295 context.showmathcharactersentryhexdectit(
296 f_unicode(code),
297 code,
298 lower(description)
299 )
300 if luametatex then
301 context.showmathcharactersentrywdhtdpicta(
302 code
303 )
304 else
305 context.showmathcharactersentrywdhtdpicta(
306 round(char.width or 0),
307 round(char.height or 0),
308 round(char.depth or 0),
309 round(char.italic or 0),
310 round(char.topanchor or char.topaccent or 0)
311 )
312 end
313 if virtual and commands then
314 local t = { }
315 for i=1,#commands do
316 local ci = commands[i]
317 if ci[1] == "slot" then
318 local fnt, idx = ci[2], ci[3]
319 t[#t+1] = f_slot(names[fnt] or fnt,idx)
320 end
321 end
322 if #t > 0 then
323 context.showmathcharactersentryresource(concat(t,", "))
324 end
325 end
326 if mathclass or mathspec then
327 context.showmathcharactersstartentryclassspec()
328 if mathclass then
329 context.showmathcharactersentryclassname(mathclass,info.mathname or "no name")
330 end
331 if mathspec then
332 for i=1,#mathspec do
333 local mi = mathspec[i]
334 context.showmathcharactersentryclassname(mi.class,mi.name or "no name")
335 end
336 end
337 context.showmathcharactersstopentryclassspec()
338 end
339 if mathsymbol then
340 context.showmathcharactersentrysymbol(f_unicode(mathsymbol),mathsymbol)
341 end
342 if next_sizes then
343 local n, done = 0, { }
344 context.showmathcharactersstartnext()
345 while next_sizes do
346 n = n + 1
347 if done[next_sizes] then
348 context.showmathcharactersnextcycle(n)
349 break
350 else
351 done[next_sizes] = true
352 context.showmathcharactersnextentry(n,f_unicode(next_sizes),next_sizes)
353 next_sizes = characters[next_sizes]
354 vparts = next_sizes.vparts or next_sizes.vert_variants or vparts
355 hparts = next_sizes.hparts or next_sizes.horiz_variants or hparts
356 if next_sizes then
357 next_sizes = next_sizes.next
358 end
359 end
360 end
361 context.showmathcharactersstopnext()
362 if vparts or hparts then
363 context.showmathcharactersbetweennextandvariants()
364 end
365 end
366 if vparts then
367 context.showmathcharactersstartvparts()
368 for i=1,#vparts do
369 local vi = vparts[i]
370 context.showmathcharactersvpartsentry(i,f_unicode(vi.glyph),vi.glyph)
371 end
372 context.showmathcharactersstopvparts()
373 end
374 if hparts then
375 context.showmathcharactersstarthparts()
376 for i=1,#hparts do
377 local hi = hparts[#hparts-i+1]
378 context.showmathcharactershpartsentry(i,f_unicode(hi.glyph),hi.glyph)
379 end
380 context.showmathcharactersstophparts()
381 end
382 local lookups = alllookups[unicode]
383 if lookups then
384 local variants = { }
385 local singles = lookups.gsub_single
386 local alternates = lookups.gsub_alternate
387 if singles then
388 for lookupname, code in next, singles do
389 variants[code] = lookupname
390 end
391 end
392 if singles then
393 for lookupname, codes in next, alternates do
394 for i=1,#codes do
395 variants[codes[i]] = lookupname .. " : " .. i
396 end
397 end
398 end
399 if next(variants) then
400 context.showmathcharactersstartlookupvariants()
401 local i = 0
402 for variant, lookuptype in sortedhash(variants) do
403 i = i + 1
404 context.showmathcharacterslookupvariant(i,f_unicode(variant),variant,lookuptype)
405 end
406 context.showmathcharactersstoplookupvariants()
407 end
408 end
409 context.showmathcharactersstopentry()
410 end
411 end
412 end
413 end
414 context.showmathcharactersstop()
415
416end
417
418 end
419end
420 |