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

local lpegmatch = lpeg.match
local utfsplit = utf.split
local settings_to_array = utilities.parsers.settings_to_array

local fonts              = fonts
local otf                = fonts.handlers.otf
local registerotffeature = otf.features.register
local addotffeature      = otf.addfeature

-- This is a quick and dirty hack.

local lookups = { }
local protect = { }
local revert  = { }
local zwjchar = 0x200C
local zwj     = { zwjchar }

addotffeature {
    name    = "blockligatures",
    type    = "chainsubstitution",
    nocheck = true, -- because there is no 0x200C in the font
    prepend = true, -- make sure we do it early
    future  = true, -- avoid nilling due to no steps yet
    lookups = {
        {
            type = "multiple",
            data = lookups,
        },
    },
    data = {
        rules = protect,
    }
}

addotffeature {
    name     = "blockligatures",
    type     = "chainsubstitution",
    nocheck  = true,  -- because there is no 0x200C in the font
    append   = true,  -- this is done late
    overload = false, -- we don't want to overload the previous definition
    lookups  = {
        {
            type = "ligature",
            data = lookups,
        },
    },
    data = {
        rules = revert,
    }
}

registerotffeature {
    name        = 'blockligatures',
    description = 'block certain ligatures',
}

local splitter = lpeg.splitat(":")

local function blockligatures(str)

    local t = settings_to_array(str)

    for i=1,#t do
        local ti = t[i]
        local before, current, after = lpegmatch(splitter,ti)
        if current and after then -- before is returned when no match
            -- experimental joke
            if before then
                before = utfsplit(before)
                for i=1,#before do
                    before[i] = { before[i] }
                end
            end
            if current then
                current = utfsplit(current)
            end
            if after then
                after = utfsplit(after)
                for i=1,#after do
                    after[i] = { after[i] }
                end
            end
        else
            before  = nil
            current = utfsplit(ti)
            after   = nil
        end
        if #current > 1 then
            local one = current[1]
            local two = current[2]
            lookups[one] = { one, zwjchar }
            local one = { one }
            local two = { two }
            local new = #protect + 1
            protect[new] = {
                before  = before,
                current = { one, two },
                after   = after,
                lookups = { 1 }, -- not shared !
            }
            revert[new] = {
             -- before = before,
                current = { one, zwj },
             -- after   = { two, unpack(after) },
                after   = { two },
                lookups = { 1 }, -- not shared !
            }
        end
    end
end

-- blockligatures("\0\0")

otf.helpers.blockligatures = blockligatures

-- blockligatures("fi,ff")
-- blockligatures("fl")
-- blockligatures("u:fl:age")

if context then

    interfaces.implement {
        name      = "blockligatures",
        arguments = "string",
        actions   = blockligatures,
    }

end