font-imp-tweaks.lua /size: 3995 b    last modification: 2021-10-28 13:50
1if not modules then modules = { } end modules ['font-imp-tweaks'] = {
2    version   = 1.001,
3    comment   = "companion to font-ini.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
9if not context then return end
10
11local addfeature = fonts.handlers.otf.addfeature
12
13-- The mapping directives avoids a check and copying of the (kind of special code
14-- mapping tables.
15
16addfeature {
17    name    = "uppercasing",
18    type    = "substitution",
19    prepend = true,
20    mapping = true,
21 -- valid   = function() return true end,
22    data    = characters.uccodes
23}
24
25addfeature {
26    name    = "lowercasing",
27    type    = "substitution",
28    prepend = true,
29    mapping = true,
30 -- valid   = function() return true end,
31    data    = characters.lccodes
32}
33
34if CONTEXTLMTXMODE > 0 then
35
36    local nuts       = nodes.nuts
37    local isnextchar = nuts.isnextchar
38    local getdisc    = nuts.getdisc
39    local setchar    = nuts.setchar
40
41    local disc_code  = nodes.nodecodes.disc
42
43    local lccodes    = characters.lccodes
44    local uccodes    = characters.uccodes
45
46    function fonts.handlers.otf.handlers.ctx_camelcasing(head,dataset,sequence,initialrl,font,dynamic)
47        local first   = false
48        local current = head
49     -- local scale   = 1000
50     -- local xscale  = 1000
51     -- local yscale  = 1000
52        local function check(current)
53            while current do
54                -- scale, xscale, yscale = getscales(current)
55                local nxt, char, id = isnextchar(current,font,dynamic) -- ,scale,xscale,yscale)
56                if char then
57                    if first then
58                        local lower = lccodes[char]
59                        if lower ~= char then
60                            setchar(current,lower)
61                        end
62                    else
63                        local upper = uccodes[char]
64                        if upper ~= char then
65                            setchar(current,upper)
66                        end
67                        first = true
68                    end
69                elseif id == disc_code then
70                    local pre, post, replace = getdisc(current)
71                    if pre then
72                        check(pre)
73                    end
74                    if post then
75                        check(post)
76                    end
77                    if replace then
78                        check(replace)
79                    end
80                else
81                    first = false
82                end
83                current = nxt
84            end
85        end
86        check(current)
87        return head
88    end
89
90    addfeature {
91        nocheck = true,
92        name    = "camelcasing",
93        type    = "ctx_camelcasing",
94        prepend = true,
95        data    = "action",
96    }
97
98end
99
100do -- for the moment this is mostly a demo feature
101
102    local digit  = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" }
103    local single = { "'" }
104    local double = { '"' }
105
106    local singleprime = 0x2032 -- "′"
107    local doubleprime = 0x2033 -- "″"
108
109    addfeature {
110     -- nocheck = true,
111        name    = "primes",
112        type    = "chainsubstitution",
113        lookups = {
114            {
115                type = "substitution",
116                data = { ["'"] = singleprime },
117            },
118            {
119                type = "substitution",
120                data = { ["'"] = doubleprime },
121            },
122        },
123        data = {
124            rules = {
125                {
126                    before  = { digit },
127                    current = { single },
128                    after   = { digit },
129                    lookups = { 1 },
130                },
131                {
132                    before  = { digit },
133                    current = { single, single },
134                    lookups = { 2, 0 }, -- zero: gsub_remove
135                },
136            },
137        },
138    }
139
140end
141