s-fonts-coverage.lua /size: 4533 b    last modification: 2020-07-01 14:35
1if not modules then modules = { } end modules ['s-fonts-coverage'] = {
2    version   = 1.001,
3    comment   = "companion to s-fonts-coverage.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
9moduledata.fonts          = moduledata.fonts          or { }
10moduledata.fonts.coverage = moduledata.fonts.coverage or { }
11
12local upper, format = string.upper, string.format
13local lpegmatch = lpeg.match
14local concat = table.concat
15
16local context = context
17local NC, NR, HL = context.NC, context.NR, context.HL
18local char, bold, getvalue = context.char, context.bold, context.getvalue
19
20local chardata = characters.data
21
22function moduledata.fonts.coverage.showdifference(specification)
23    moduledata.fonts.coverage.showcomparison(specification,true)
24end
25
26function moduledata.fonts.coverage.showcomparison(specification,difference)
27
28    specification = interfaces.checkedspecification(specification)
29
30    local fontfiles = utilities.parsers.settings_to_array(specification.list or "")
31    local pattern   = upper(specification.pattern or "")
32    local slot      = specification.slot or ""
33
34    local present = { }
35    local names   = { }
36    local files   = { }
37    local chars   = { }
38    local slots   = false
39
40    if slot ~= "" then
41        slot = utilities.parsers.settings_to_array(slot)
42        for i=1,#slot do
43            local s = tonumber(slot[i])
44            if not s then
45                -- next one
46            elseif slots then
47                slots[s] = true
48            else
49                slots = { [s] = true }
50            end
51        end
52    elseif not pattern then
53        -- skip
54    elseif pattern == "" then
55        pattern = nil
56    elseif tonumber(pattern) then
57        pattern = tonumber(pattern)
58    else
59        pattern = lpeg.oneof(utilities.parsers.settings_to_array(pattern))
60        pattern = (1-pattern)^0 * pattern
61    end
62
63    for i=1,#fontfiles do
64        local fontname = format("testfont-%s",i)
65        local fontfile = fontfiles[i]
66        local fontsize = tex.dimen.bodyfontsize
67        local id, fontdata = fonts.definers.define {
68            name = fontfile,
69            size = fontsize,
70            cs   = fontname,
71        }
72        if id and fontdata then
73            for k, v in next, fontdata.characters do
74                present[k] = true
75            end
76            names[#names+1] = fontname
77            files[#files+1] = fontfile
78            chars[#names]   = fontdata.characters
79        end
80    end
81
82    local t = { }
83
84    context.starttabulate { "|Tr" .. string.rep("|l",#names) .. "|" }
85    for i=1,#files do
86        local file = files[i]
87        t[#t+1] = i .. "=" .. file
88        NC()
89            context(i)
90        NC()
91            context(file)
92        NC()
93        NR()
94    end
95    context.stoptabulate()
96
97    context.setupfootertexts {
98        table.concat(t," ")
99    }
100
101    local nofnames = #names
102
103    context.starttabulate { "|Tl" .. string.rep("|c",nofnames) .. "|Tl|" }
104    NC()
105    bold("unicode")
106    NC()
107    for i=1,nofnames do
108        bold(i)
109        NC()
110    end
111    bold("description")
112    NC()
113    NR()
114    HL()
115    for k, v in table.sortedpairs(present) do
116        local skip = false
117        if difference then
118            local n = 0
119            for i=1,nofnames do
120                if chars[i][k] then
121                    n= n + 1
122                end
123            end
124            skip = n == nofnames
125        end
126        if skip then
127            -- ignore
128        elseif k <= 0 then
129            -- ignore
130        elseif k >= 0x110000 then
131            logs.report("warning","weird character %U",k)
132        else
133            local description = chardata[k].description
134            local wantedslot  = true
135            if slots then
136                wantedslot = slots[k]
137            elseif pattern then
138                wantedslot = pattern == k or (description and lpegmatch(pattern,description))
139            end
140            if wantedslot then
141                NC()
142                    context("%05X",k)
143                NC()
144                for i=1,nofnames do
145                    getvalue(names[i])
146                    if chars[i][k] then
147                        char(k)
148                    else
149                        -- missing
150                    end
151                    NC()
152                end
153                    context(description)
154                NC()
155                NR()
156            end
157        end
158    end
159    context.stoptabulate()
160
161end
162