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 getdiscpart = nuts.getdiscpart
30local getdisc = nuts.getdisc
31local setdisc = nuts.setdisc
32local getlanguage = nuts.getlanguage
33local getboth = nuts.getboth
34local setlist = nuts.setlist
35local setlink = nuts.setlink
36local isglyph = nuts.isglyph
37
38local copy_node = nuts.copy
39local remove_node = nuts.remove
40
41
42local nextdisc = nuts.traversers.disc
43local nextglyph = nuts.traversers.glyph
44
45local new_disc = nuts.pool.disc
46
47local nodecodes = nodes.nodecodes
48local disccodes = nodes.disccodes
49
50local disc_code = nodecodes.disc
51local glyph_code = nodecodes.glyph
52
53local discoptioncodes = tex.discoptioncodes
54local pre_part_code = discoptioncodes.pre
55local post_part_code = discoptioncodes.post
56local replace_part_code = discoptioncodes.replace
57local always_part_code = discoptioncodes.always
58
59local explicitdisc_code = disccodes.explicit
60
61local a_visualize = attributes.private("visualizediscretionary")
62local setattribute = tex.setattribute
63
64local getlanguagedata = languages.getdata
65local prehyphenchar = language.prehyphenchar
66local posthyphenchar = language.posthyphenchar
67
68local check_regular = true
69
70local setlistcolor = nodes.tracers.colors.setlist
71
72function languages.visualizediscretionaries(head)
73 for d in nextdisc, head do
74 if getattr(d,a_visualize) then
75 local pre, post, replace = getdisc(d)
76 if pre then
77 setlistcolor(pre,"darkred")
78 end
79 if post then
80 setlistcolor(post,"darkgreen")
81 end
82 if replace then
83 setlistcolor(replace,"darkblue")
84 end
85 end
86 end
87 for g in nextglyph, head do
88 if getattr(g,a_visualize) then
89 local c = getdiscpart(g)
90 if c == pre_part_code then
91 setlistcolor(g,"darkmagenta")
92 elseif c == post_part_code then
93 setlistcolor(g,"darkcyan")
94 elseif c == replace_part_code then
95 setlistcolor(g,"darkyellow")
96 elseif c == always_part_code then
97 setlistcolor(g,"darkgray")
98 end
99 end
100 end
101 return head
102end
103
104local enabled = false
105
106function languages.showdiscretionaries(v)
107 if v == false then
108 setattribute(a_visualize,unsetvalue)
109 else
110 if not enabled then
111 enableaction("processors","languages.visualizediscretionaries")
112 enabled = true
113 end
114 setattribute(a_visualize,1)
115 end
116end
117
118interfaces.implement {
119 name = "showdiscretionaries",
120 actions = languages.showdiscretionaries
121}
122
123do
124
125 local toutf = nodes.listtoutf
126 local utfchar = utf.char
127 local f_disc = string.formatters["{%s}{%s}{%s}"]
128 local replace = lpeg.replacer( {
129 [utfchar(0x200C)] = "|",
130 [utfchar(0x200D)] = "|",
131 }, nil, true)
132
133 local function convert(list)
134 return list and replace(toutf(list)) or ""
135 end
136
137 function languages.serializediscretionary(d)
138 local pre, post, replace = getdisc(d)
139 return f_disc(convert(pre),convert(post),convert(replace))
140 end
141
142end
143
144
145
146local wiped = 0
147
148local flattendiscretionaries = nuts.flattendiscretionaries
149
150
151
152 function languages.flatten(head)
153 local h, n = flattendiscretionaries(head)
154 wiped = wiped + n
155 return h, n > 0
156 end
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197function languages.nofflattened()
198 return wiped
199end
200
201
202
203local flatten = languages.flatten
204
205nodes.handlers.flattenline = flatten
206
207function nodes.handlers.flatten(head,where)
208 if head and (where == "box" or where == "adjustedhbox") then
209 return flatten(head)
210 end
211 return head
212end
213
214directives.register("hyphenator.flatten",function(v)
215
216 setaction("processors","nodes.handlers.flatten",v)
217 setaction("contributers","nodes.handlers.flattenline",v)
218end)
219
220
221
222function languages.explicithyphen(template)
223 local pre, post
224 local disc = new_disc()
225 if template then
226 local langdata = getlanguagedata(getlanguage(template))
227 local instance = langdata and langdata.instance
228 if instance then
229 local prechr = prehyphenchar(instance)
230 local postchr = posthyphenchar(instance)
231 if prechr >= 0 then
232 pre = copy_node(template)
233 setchar(pre,prechr)
234 end
235 if postchr >= 0 then
236 post = copy_node(template)
237 setchar(post,postchr)
238 end
239 end
240 end
241 setdisc(disc,pre,post,nil,explicitdisc_code,tex.exhyphenpenalty)
242 return disc
243end
244 |