node-gcm.lmt /size: 3027 b    last modification: 2021-10-28 13:51
1if not modules then modules = { } end modules ['node-gmc'] = {
2    version   = 1.001,
3    comment   = "companion to node-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
9local type, tostring = type, tostring
10
11local nodes         = nodes
12local ligature_code = nodes.glyphcodes.ligature
13local nuts          = nodes.nuts
14
15local getnext       = nuts.getnext
16local getsubtype    = nuts.getsubtype
17local copynode      = nuts.copy
18local flushlist     = nuts.flushlist
19local count         = nuts.count
20local isglyph       = nuts.isglyph
21local getprop       = nuts.getprop
22local setprop       = nuts.setprop
23
24local fastcopy      = table.fastcopy
25
26local report_error  = logs.reporter("node-aux:error")
27
28local function setcomponents(base,list)
29    local t = { }
30    local n = 0
31    local l = list
32    while list do
33        local char = isglyph(list)
34        if char then
35            n = n + 1
36            t[n] = char
37        end
38        list = getnext(list)
39    end
40    -- not yet as we need them
41    --
42    -- flushlist(l)
43    --
44    setprop(base,"components",n > 0 and t or false)
45end
46
47local function getcomponents(base)
48    return getprop(base,"components")
49end
50
51local function copynocomponents(base)
52    local copy = copynode(base)
53    setprop(copy,"components",false) -- no metatable lookup!
54    return copy
55end
56
57local function copyonlyglyphs(base)
58    local t = getprop(base,"components") -- also metatable
59    if t then
60        return fastcopy(t)
61    end
62end
63
64local function docount(t,marks)
65    local n = 0
66    if t then
67        for i=1,#t do
68            local c = t[i]
69            if type(c) == "table" then
70                n = n + docount(t,marks)
71            elseif not marks[c] then
72                n = n + 1
73            else
74                --marks don't count
75            end
76        end
77    end
78    return n
79end
80
81-- start is a mark and we need to keep that one
82
83local done = false
84
85local function countcomponents(base,marks)
86    local char = isglyph(base)
87    if char then
88        if getsubtype(base) == ligature_code then
89            if not done then
90                logs.report("fonts","!")
91                logs.report("fonts","! check countcomponents with mkiv !")
92                logs.report("fonts","!")
93                done = true
94            end
95            local t = getprop(base,"components")
96            if t then
97                return docount(t,marks)
98            end
99        elseif not marks[char] then
100            return 1
101        end
102    end
103    return 0
104end
105
106nuts.components = {
107    set              = setcomponents,
108    get              = getcomponents,
109    copyonlyglyphs   = copyonlyglyphs,
110    copynocomponents = copynocomponents,
111    count            = countcomponents,
112    flush            = flushlist,
113}
114
115nuts.setcomponents = function() report_error("unsupported: %a","setcomponents") end
116nuts.getcomponents = function() report_error("unsupported: %a","getcomponents") end
117