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

local utfbyte, utfsplit = utf.byte, utf.split

local nuts                = nodes.nuts

local nextchar            = nuts.traversers.char

local getattr             = nuts.getattr
local setchar             = nuts.setchar

local insert_before       = nuts.insert_before
local copy_node           = nuts.copy

local texsetattribute     = tex.setattribute

local transliteration     = { }
languages.transliteration = transliteration

local a_transliteration   = attributes.private("transliteration")
local unsetvalue          = attributes.unsetvalue

local lastmapping         = 0
local loadedmappings      = { }

function transliteration.define(name,vector)
    local m = loadedmappings[vector]
    if m == nil then
        lastmapping = lastmapping + 1
        local data = require("lang-imp-" .. name)
        if data then
            local transliterations = data.transliterations
            if transliterations then
                for name, d in next, transliterations do
                    local vector = d.vector
                    if not vector then
                        local mapping = d.mapping
                        if mapping then
                            vector = { }
                            for k, v in next, mapping do
                                local vv = utfsplit(v)
                                for i=1,#vv do
                                    vv[i] = utfbyte(vv[i])
                                end
                                vector[utfbyte(k)] = vv
                            end
                            d.vector = vector
                        end
                    end
                    d.attribute = lastmapping
                    loadedmappings[name] = d
                    loadedmappings[lastmapping] = d
                end
            end
        end
        m = loadedmappings[vector] or false
    end
end

local enabled = false

function transliteration.set(vector)
    if not enabled then
        nodes.tasks.enableaction("processors", "languages.transliteration.handler")
        enabled = true
    end
    local m = loadedmappings[vector]
    texsetattribute(a_transliteration,m and m.attribute or unsetvalue)
end

function transliteration.handler(head)
    local aprev  = nil
    local vector = nil
    for current, char in nextchar, head do
        local a = getattr(current,a_transliteration)
        if a then
            if a ~= aprev then
                aprev = a
                vector = loadedmappings[a]
                if vector then
                    vector = vector.vector
                end
            end
            if vector then
                local t = vector[char]
                if t then
                    local n = #t
                    setchar(current,t[n])
                    local p = current
                    if n > 1 then
                        for i = n-1,1,-1 do
                            local g = copy_node(current)
                            setchar(g,t[i])
                            head, p = insert_before(head, p, g)
                        end
                    end
                end
            end
        end
    end
    return head
end

interfaces.implement {
    name      = "settransliteration",
    arguments = "string",
    actions   = transliteration.set,
}

interfaces.implement {
    name      = "definedtransliteration",
    arguments = "2 strings",
    actions   = transliteration.define,
}

nodes.tasks.prependaction("processors", "normalizers", "languages.transliteration.handler", nil, "nut", "disabled" )