1if not modules then modules = { } end modules ['lang-url'] = {
2 version = 1.001,
3 comment = "companion to lang-url.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 utfcharacters, utfbyte, utfchar = utf.characters, utf.byte, utf.char
10local min, max = math.min, math.max
11
12local context = context
13local ctx_pushcatcodes = context.pushcatcodes
14local ctx_popcatcodes = context.popcatcodes
15
16local implement = interfaces.implement
17local variables = interfaces.variables
18
19local v_before = variables.before
20local v_after = variables.after
21
22local is_letter = characters.is_letter
23
24
30
31local urls = { }
32languages.urls = urls
33
34local characters = utilities.storage.allocate {
35 ["!"] = "before",
36 ['"'] = "before",
37 ["#"] = "before",
38 ["$"] = "before",
39 ["%"] = "before",
40 ["&"] = "before",
41 ["("] = "before",
42 ["*"] = "before",
43 ["+"] = "before",
44 [","] = "before",
45 ["-"] = "before",
46 ["."] = "before",
47 ["/"] = "before",
48 [":"] = "before",
49 [";"] = "before",
50 ["<"] = "before",
51 ["="] = "before",
52 [">"] = "before",
53 ["?"] = "before",
54 ["@"] = "before",
55 ["["] = "before",
56 ["\\"] = "before",
57 ["^"] = "before",
58 ["_"] = "before",
59 ["`"] = "before",
60 ["{"] = "before",
61 ["|"] = "before",
62 ["~"] = "before",
63
64 ["'"] = "after",
65 [")"] = "after",
66 ["]"] = "after",
67 ["}"] = "after",
68}
69
70local mapping = utilities.storage.allocate {
71
72}
73
74urls.characters = characters
75urls.mapping = mapping
76urls.lefthyphenmin = 2
77urls.righthyphenmin = 3
78urls.discretionary = nil
79urls.packslashes = false
80
81directives.register("hyphenators.urls.packslashes",function(v) urls.packslashes = v end)
82
83local trace = false trackers.register("hyphenators.urls",function(v) trace = v end)
84local report = logs.reporter("hyphenators","urls")
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148local function action(hyphenatedurl,str,left,right,disc)
149
150 left = max( left or urls.lefthyphenmin, 2)
151 right = min(#str-(right or urls.righthyphenmin)+2,#str)
152 disc = disc or urls.discretionary
153
154 local word = nil
155 local pack = urls.packslashes
156 local length = 0
157 local list = utf.split(str)
158 local size = #list
159 local prev = nil
160
161 for i=1,size do
162 local what = nil
163 local dodi = false
164 local char = list[i]
165 length = length + 1
166 char = mapping[char] or char
167 if char == disc then
168 dodi = true
169 elseif pack and char == "/" and (list[i+1] == "/" or prev == "/") then
170 what = "c"
171 else
172 local how = characters[char]
173 if how == v_before then
174 what = "b"
175 elseif how == v_after then
176 word = false
177 what = "a"
178 else
179 local letter = is_letter[char]
180 if length <= left or length >= right then
181 if word and letter then
182 what = "L"
183 else
184 what = "C"
185 end
186 elseif word and letter then
187 what = "l"
188 else
189 what = "c"
190 end
191 word = letter
192 end
193 end
194 if dodi then
195 list[i] = "\\lang_url_d "
196 else
197 list[i] = "\\lang_url_" .. what .. "{" .. utfbyte(char) .. "}"
198 end
199 prev = char
200 end
201 if trace then
202 report("old : %s",str)
203 report("new : %t",list)
204 end
205 ctx_pushcatcodes("prtcatcodes")
206 context("%t",list)
207 ctx_popcatcodes()
208end
209
210
211
212table.setmetatablecall(hyphenatedurl,action)
213
214
215
216function urls.setcharacters(str,value)
217 for s in utfcharacters(str) do
218 characters[s] = value or v_before
219 end
220end
221
222
223
224implement {
225 name = "sethyphenatedurlcharacters",
226 actions = urls.setcharacters,
227 arguments = "2 strings",
228}
229
230implement {
231 name = "hyphenatedurl",
232 scope = "private",
233 actions = function(...) action(hyphenatedurl,...) end,
234 arguments = { "string", "integer", "integer", "string" }
235}
236 |