lang-dis.lua /size: 6013 b    last modification: 2021-10-28 13:50
1if not modules then modules = { } end modules ['lang-dis'] = {
2    version   = 1.001,
3    comment   = "companion to lang-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 concat = table.concat
10
11local tex                = tex
12local nodes              = nodes
13
14local tasks              = nodes.tasks
15local nuts               = nodes.nuts
16
17local enableaction       = tasks.enableaction
18local setaction          = tasks.setaction
19
20local setfield           = nuts.setfield
21local getnext            = nuts.getnext
22local getprev            = nuts.getprev
23local getid              = nuts.getid
24local getattr            = nuts.getattr
25local getsubtype         = nuts.getsubtype
26local setsubtype         = nuts.setsubtype
27local getchar            = nuts.getchar
28local setchar            = nuts.setchar
29local getdisc            = nuts.getdisc
30local setdisc            = nuts.setdisc
31local getlanguage        = nuts.getlanguage
32local getboth            = nuts.getboth
33local setlist            = nuts.setlist
34local setlink            = nuts.setlink
35local isglyph            = nuts.isglyph
36
37local copy_node          = nuts.copy
38local remove_node        = nuts.remove
39----- flushnode          = nuts.flushnode
40
41local nextdisc           = nuts.traversers.disc
42
43local new_disc           = nuts.pool.disc
44
45local nodecodes          = nodes.nodecodes
46local disccodes          = nodes.disccodes
47
48local disc_code          = nodecodes.disc
49local glyph_code         = nodecodes.glyph
50
51local explicitdisc_code  = disccodes.explicit
52
53local a_visualize        = attributes.private("visualizediscretionary")
54local setattribute       = tex.setattribute
55
56local getlanguagedata    = languages.getdata
57local prehyphenchar      = lang.prehyphenchar
58local posthyphenchar     = lang.posthyphenchar
59
60local check_regular      = true
61
62local setlistcolor = nodes.tracers.colors.setlist
63
64function languages.visualizediscretionaries(head)
65    for d in nextdisc, head do
66        if getattr(d,a_visualize) then
67            local pre, post, replace = getdisc(d)
68            if pre then
69                setlistcolor(pre,"darkred")
70            end
71            if post then
72                setlistcolor(post,"darkgreen")
73            end
74            if replace then
75                setlistcolor(replace,"darkblue")
76            end
77        end
78    end
79    return head
80end
81
82local enabled = false
83
84function languages.showdiscretionaries(v)
85    if v == false then
86        setattribute(a_visualize,unsetvalue)
87    else -- also nil
88        if not enabled then
89            enableaction("processors","languages.visualizediscretionaries")
90            enabled = true
91        end
92        setattribute(a_visualize,1)
93    end
94end
95
96interfaces.implement {
97    name    = "showdiscretionaries",
98    actions = languages.showdiscretionaries
99}
100
101do
102
103    local toutf   = nodes.listtoutf
104    local utfchar = utf.char
105    local f_disc  = string.formatters["{%s}{%s}{%s}"]
106    local replace = lpeg.replacer( {
107        [utfchar(0x200C)] = "|",
108        [utfchar(0x200D)] = "|",
109    }, nil, true)
110
111    local function convert(list)
112        return list and replace(toutf(list)) or ""
113    end
114
115    function languages.serializediscretionary(d) -- will move to tracer
116        local pre, post, replace = getdisc(d)
117        return f_disc(convert(pre),convert(post),convert(replace))
118    end
119
120end
121
122-- --
123
124local wiped = 0
125
126local flattendiscretionaries = nuts.flattendiscretionaries -- todo in nodes
127
128-- if flattendiscretionaries then
129
130    function languages.flatten(head)
131        local h, n = flattendiscretionaries(head)
132        wiped = wiped + n
133        return h, n > 0
134    end
135
136-- else
137--
138--     local function wipe(head,delayed)
139--         local p, n = getboth(delayed)
140--         local _, _, h, _, _, t = getdisc(delayed,true)
141--         if p or n then
142--             if h then
143--                 setlink(p,h)
144--                 setlink(t,n)
145--                 setfield(delayed,"replace")
146--             else
147--                 setlink(p,n)
148--             end
149--         end
150--         if head == delayed then
151--             head = h
152--         end
153--         wiped = wiped + 1
154--         flushnode(delayed)
155--         return head
156--     end
157--
158--     function languages.flatten(head)
159--         local delayed = nil
160--         for d in nextdisc, head do
161--             if delayed then
162--                 head = wipe(head,delayed)
163--             end
164--             delayed = d
165--         end
166--         if delayed then
167--             return wipe(head,delayed), true
168--         else
169--             return head, false
170--         end
171--     end
172--
173-- end
174
175function languages.nofflattened()
176    return wiped -- handy for testing
177end
178
179-- experiment: for now not in not in export mode!
180
181local flatten = languages.flatten
182
183nodes.handlers.flattenline = flatten
184
185function nodes.handlers.flatten(head,where)
186    if head and (where == "box" or where == "adjusted_hbox") then
187        return flatten(head)
188    end
189    return head
190end
191
192directives.register("hyphenator.flatten",function(v)
193    -- use with care
194    setaction("processors","nodes.handlers.flatten",v)
195    setaction("contributers","nodes.handlers.flattenline",v)
196end)
197
198-- moved here:
199
200function languages.explicithyphen(template)
201    local pre, post
202    local disc = new_disc()
203    if template then
204        local langdata = getlanguagedata(getlanguage(template))
205        local instance = langdata and langdata.instance
206        if instance then
207            local prechr  = prehyphenchar(instance)
208            local postchr = posthyphenchar(instance)
209            if prechr >= 0 then
210                pre = copy_node(template)
211                setchar(pre,prechr)
212            end
213            if postchr >= 0 then
214                post = copy_node(template)
215                setchar(post,postchr)
216            end
217        end
218    end
219    setdisc(disc,pre,post,nil,explicitdisc_code,tex.exhyphenpenalty)
220    return disc
221end
222