typo-rep.lua /size: 3986 b    last modification: 2021-10-28 13:50
1if not modules then modules = { } end modules ['typo-rep'] = {
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
9-- This was rather boring to program (more of the same) but I could
10-- endure it by listening to a couple cd's by The Scene and The Lau
11-- on the squeezebox on my desk.
12
13local next, type, tonumber = next, type, tonumber
14
15local trace_stripping = false  trackers.register("nodes.stripping",  function(v) trace_stripping = v end)
16                               trackers.register("fonts.stripping",  function(v) trace_stripping = v end)
17
18local report_stripping = logs.reporter("fonts","stripping")
19
20local nodes           = nodes
21local enableaction    = nodes.tasks.enableaction
22
23local nuts            = nodes.nuts
24
25local getnext         = nuts.getnext
26local getchar         = nuts.getchar
27local isglyph         = nuts.isglyph
28
29local getattr         = nuts.getattr
30
31local remove_node     = nuts.remove
32local replace_node    = nuts.replace
33local copy_node       = nuts.copy
34
35local nodecodes       = nodes.nodecodes
36
37local chardata        = characters.data
38local collected       = false
39
40local a_stripping     = attributes.private("stripping")
41
42local texsetattribute = tex.setattribute
43local unsetvalue      = attributes.unsetvalue
44
45local v_reset         = interfaces.variables.reset
46
47-- todo: other namespace -> typesetters
48
49nodes.stripping  = nodes.stripping  or { } local stripping  = nodes.stripping
50stripping.glyphs = stripping.glyphs or { } local glyphs     = stripping.glyphs
51
52local function initialize()
53    for k, v in next, chardata do
54        if v.category == "cf" and not v.visible and not glyphs[k] then
55            glyphs[k] = true
56        end
57    end
58    initialize = nil
59end
60
61local function process(what,head,current,char)
62    if what == true then
63        if trace_stripping then
64            report_stripping("deleting %C from text",char)
65        end
66        head, current = remove_node(head,current,true)
67    elseif type(what) == "function" then
68        head, current = what(head,current)
69        current = getnext(current)
70        if trace_stripping then
71            report_stripping("processing %C in text",char)
72        end
73    elseif what then  -- assume node
74        head, current = replace_node(head,current,copy_node(what))
75        current = getnext(current)
76        if trace_stripping then
77            report_stripping("replacing %C in text",char)
78        end
79    end
80    return head, current
81end
82
83function nodes.handlers.stripping(head) -- use loop
84    local current = head
85    while current do
86        local char, id = isglyph(current)
87        if char then
88            -- it's more efficient to keep track of what needs to be kept
89            local todo = getattr(current,a_stripping)
90            if todo == 1 then
91                local what = glyphs[char]
92                if what then
93                    head, current = process(what,head,current,char)
94                else -- handling of spacing etc has to be done elsewhere
95                    current = getnext(current)
96                end
97            else
98                current = getnext(current)
99            end
100        else
101            current = getnext(current)
102        end
103    end
104    return head
105end
106
107local enabled = false
108
109function stripping.set(n) -- number or 'reset'
110    if n == v_reset then
111        n = unsetvalue
112    else
113        n = tonumber(n)
114        if n then
115            if not enabled then
116                if initialize then initialize() end
117                enableaction("processors","nodes.handlers.stripping")
118                enabled = true
119            end
120        else
121            n = unsetvalue
122        end
123    end
124    texsetattribute(a_stripping,n)
125end
126
127-- interface
128
129interfaces.implement {
130    name      = "setcharacterstripping",
131    actions   = stripping.set,
132    arguments = "string"
133}
134