summaryrefslogtreecommitdiff
path: root/tex/context/modules/mkiv/s-fonts-coverage.lua
blob: 2408fc9a31c3a694adc83dbfb55e91344d919f10 (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
if not modules then modules = { } end modules ['s-fonts-coverage'] = {
    version   = 1.001,
    comment   = "companion to s-fonts-coverage.mkiv",
    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
    copyright = "PRAGMA ADE / ConTeXt Development Team",
    license   = "see context related readme files"
}

moduledata.fonts          = moduledata.fonts          or { }
moduledata.fonts.coverage = moduledata.fonts.coverage or { }

local upper, format = string.upper, string.format
local lpegmatch = lpeg.match
local concat = table.concat

local context = context
local NC, NR, HL = context.NC, context.NR, context.HL
local char, bold, getvalue = context.char, context.bold, context.getvalue

local chardata = characters.data

function moduledata.fonts.coverage.showdifference(specification)
    moduledata.fonts.coverage.showcomparison(specification,true)
end

function moduledata.fonts.coverage.showcomparison(specification,difference)

    specification = interfaces.checkedspecification(specification)

    local fontfiles = utilities.parsers.settings_to_array(specification.list or "")
    local pattern   = upper(specification.pattern or "")
    local slot      = specification.slot or ""

    local present = { }
    local names   = { }
    local files   = { }
    local chars   = { }
    local slots   = false

    if slot ~= "" then
        slot = utilities.parsers.settings_to_array(slot)
        for i=1,#slot do
            local s = tonumber(slot[i])
            if not s then
                -- next one
            elseif slots then
                slots[s] = true
            else
                slots = { [s] = true }
            end
        end
    elseif not pattern then
        -- skip
    elseif pattern == "" then
        pattern = nil
    elseif tonumber(pattern) then
        pattern = tonumber(pattern)
    else
        pattern = lpeg.oneof(utilities.parsers.settings_to_array(pattern))
        pattern = (1-pattern)^0 * pattern
    end

    for i=1,#fontfiles do
        local fontname = format("testfont-%s",i)
        local fontfile = fontfiles[i]
        local fontsize = tex.dimen.bodyfontsize
        local id, fontdata = fonts.definers.define {
            name = fontfile,
            size = fontsize,
            cs   = fontname,
        }
        if id and fontdata then
            for k, v in next, fontdata.characters do
                present[k] = true
            end
            names[#names+1] = fontname
            files[#files+1] = fontfile
            chars[#names]   = fontdata.characters
        end
    end

    local t = { }

    context.starttabulate { "|Tr" .. string.rep("|l",#names) .. "|" }
    for i=1,#files do
        local file = files[i]
        t[#t+1] = i .. "=" .. file
        NC()
            context(i)
        NC()
            context(file)
        NC()
        NR()
    end
    context.stoptabulate()

    context.setupfootertexts {
        table.concat(t," ")
    }

    local nofnames = #names

    context.starttabulate { "|Tl" .. string.rep("|c",nofnames) .. "|Tl|" }
    NC()
    bold("unicode")
    NC()
    for i=1,nofnames do
        bold(i)
        NC()
    end
    bold("description")
    NC()
    NR()
    HL()
    for k, v in table.sortedpairs(present) do
        local skip = false
        if difference then
            local n = 0
            for i=1,nofnames do
                if chars[i][k] then
                    n= n + 1
                end
            end
            skip = n == nofnames
        end
        if skip then
            -- ignore
        elseif k <= 0 then
            -- ignore
        elseif k >= 0x110000 then
            logs.report("warning","weird character %U",k)
        else
            local description = chardata[k].description
            local wantedslot  = true
            if slots then
                wantedslot = slots[k]
            elseif pattern then
                wantedslot = pattern == k or (description and lpegmatch(pattern,description))
            end
            if wantedslot then
                NC()
                    context("%05X",k)
                NC()
                for i=1,nofnames do
                    getvalue(names[i])
                    if chars[i][k] then
                        char(k)
                    else
                        -- missing
                    end
                    NC()
                end
                    context(description)
                NC()
                NR()
            end
        end
    end
    context.stoptabulate()

end