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

local type, next = type, next

local currentfont       = font.current
local setmetatableindex = table.setmetatableindex
local utfbyte           = utf.byte

local hashes            = fonts.hashes
local fontdata          = hashes.characters
local emwidths          = hashes.emwidths

local frequencies       = languages.frequencies or { }
languages.frequencies   = frequencies

local frequencydata     = { }
local frequencyfile     = string.formatters["lang-frq-%s.lua"]
local frequencycache    = { }

setmetatableindex(frequencydata, function(t,language)
    local fullname = resolvers.findfile(frequencyfile(language))
    local v = fullname ~= "" and dofile(fullname)
    if not v or not v.frequencies then
        v = t.en
    end
    t[language] = v
    return v
end)

setmetatableindex(frequencycache, function(t,language)
    local dataset = frequencydata[language]
    local frequencies = dataset.frequencies
    if not frequencies then
        return t.en
    end
    local v = { }
    setmetatableindex(v, function(t,font)
        local average = emwidths[font] / 2
        if frequencies then
            local characters = fontdata[font]
            local sum, tot = 0, 0
            for k, v in next, frequencies do
                local character = characters[k] -- characters[type(k) == "number" and k or utfbyte(k)]
                tot = tot + v
                sum = sum + v * (character and character.width or average)
            end
            average = sum / tot -- widths
        end
        t[font] = average
        return average
    end)
    t[language] = v
    return v
end)

function frequencies.getdata(language)
    return frequencydata[language]
end

function frequencies.averagecharwidth(language,font)
    return frequencycache[language or "en"][font or currentfont()]
end

-- Just because we can, we also have a setter ...

local dimension_value = tokens.values.dimension
local scanstring      = tokens.scanners.string
local scandimension   = tokens.scanners.dimension

interfaces.implement {
    name      = "languagecharwidth",
    public    = true,
    usage     = "value",
    actions   = function(what)
        local language = scanstring()
        local font     = currentfont()
        if what == "value" then
            return dimension_value, frequencycache[language][font] or 0
        else
            frequencycache[language][font] = scandimension(false,false,true)
        end
    end,
}