1if not modules then modules = { } end modules ['node-MET'] = {
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
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49local type, select = type, select
50local setmetatableindex = table.setmetatableindex
51
52
53
54local metatable = nil
55
56do
57 local glyph = node.new("glyph",0)
58 metatable = getmetatable(glyph)
59 node.free(glyph)
60end
61
62
63
64
65
66
67
68nodes = nodes or { }
69local nodes = nodes
70
71local nodecodes = nodes.nodecodes
72
73nodes.copy = node.copy
74nodes.copylist = node.copylist
75nodes.copy_node = node.copy
76nodes.currentattributes = node.currentattributes
77nodes.remove = node.remove
78nodes.fields = node.fields
79nodes.flush = node.flushnode
80nodes.flushlist = node.flushlist
81nodes.flushnode = node.flushnode
82nodes.getattribute = node.getattribute
83nodes.hasattribute = node.hasattribute
84nodes.hasfield = node.hasfield
85nodes.insertafter = node.insertafter
86nodes.insertbefore = node.insertbefore
87
88
89nodes.isnode = node.isnode
90nodes.isdirect = node.isdirect
91nodes.isnut = node.isdirect
92nodes.new = node.new
93nodes.setattribute = node.setattribute
94nodes.tail = node.tail
95nodes.tostring = node.tostring or tostring
96nodes.traverse = node.traverse
97nodes.traverseid = node.traverseid
98nodes.unsetattribute = node.unsetattribute
99nodes.write = node.write
100nodes.usedlist = node.usedlist
101
102nodes.getpropertiestable = node.get_properties_table
103nodes.getproperty = node.getproperty
104nodes.setproperty = node.setproperty
105
106
107nodes.serialized = node.serialized
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126local n_getfield = node.getfield
127local n_getattr = node.getattribute
128
129local n_setfield = node.setfield
130local n_setattr = n_setfield
131
132nodes.getfield = n_getfield
133nodes.setfield = n_setfield
134nodes.getattr = n_getattr
135nodes.setattr = n_setattr
136nodes.takeattr = nodes.unsetattribute
137
138local function n_getid (n) return n_getfield(n,"id") end
139local function n_getsubtype(n) return n_getfield(n,"subtype") end
140
141nodes.getid = n_getid
142nodes.getsubtype = n_getsubtype
143
144local function n_getchar(n) return n_getfield(n,"char") end
145local function n_setchar(n,c) return n_setfield(n,"char",c) end
146local function n_getfont(n) return n_getfield(n,"font") end
147local function n_setfont(n,f) return n_setfield(n,"font",f) end
148
149nodes.getchar = n_getchar
150nodes.setchar = n_setchar
151nodes.getfont = n_getfont
152nodes.setfont = n_setfont
153
154local function n_getlist (n) return n_getfield(n,"list") end
155local function n_setlist (n,l) return n_setfield(n,"list",l) end
156local function n_getleader(n) return n_getfield(n,"leader") end
157local function n_setleader(n,l) return n_setfield(n,"leader",l) end
158
159nodes.getlist = n_getlist
160nodes.setlist = n_setlist
161nodes.getleader = n_getleader
162nodes.setleader = n_setleader
163
164local function n_getnext(n) return n_getfield(n,"next") end
165local function n_setnext(n,nn) return n_setfield(n,"next",nn) end
166local function n_getprev(n) return n_getfield(n,"prev") end
167local function n_setprev(n,pp) return n_setfield(n,"prev",pp) end
168local function n_getboth(n) return n_getfield(n,"prev"), n_getfield(n,"next") end
169local function n_setboth(n,pp,nn) return n_setfield(n,"prev",pp), n_setfield(n,"next",nn) end
170
171nodes.getnext = n_getnext
172nodes.setnext = n_setnext
173nodes.getprev = n_getprev
174nodes.setprev = n_setprev
175nodes.getboth = n_getboth
176nodes.setboth = n_setboth
177
178local function n_setlink(...)
179
180 local h = nil
181 for i=1,select("#",...) do
182 local n = select(i,...)
183 if not n then
184
185 elseif h then
186 n_setfield(h,"next",n)
187 n_setfield(n,"prev",h)
188 else
189 h = n
190 end
191 end
192 return h
193end
194
195nodes.setlink = n_setlink
196
197nodes.getbox = node.getbox or tex.getbox
198nodes.setbox = node.setbox or tex.setbox
199
200local n_flushnode = nodes.flushnode
201local n_copy_node = nodes.copy
202local n_copy_list = nodes.copylist
203local n_find_tail = nodes.tail
204local n_insertafter = nodes.insertafter
205local n_insertbefore = nodes.insertbefore
206local n_slide = nodes.slide
207
208local n_remove_node = node.remove
209
210local function remove(head,current,free_too)
211 local t = current
212 head, current = n_remove_node(head,current)
213 if not t then
214
215 elseif free_too then
216 n_flushnode(t)
217 t = nil
218 else
219 n_setboth(t)
220 end
221 return head, current, t
222end
223
224nodes.remove = remove
225
226function nodes.delete(head,current)
227 return remove(head,current,true)
228end
229
230
231
232
233
234
235
236function nodes.replace(head,current,new)
237 if not new then
238 head, current, new = false, head, current
239
240 end
241 local prev = n_getprev(current)
242 local next = n_getnext(current)
243 if next then
244 n_setlink(new,next)
245 end
246 if prev then
247 n_setlink(prev,new)
248 end
249 if head then
250 if head == current then
251 head = new
252 end
253 n_flushnode(current)
254 return head, new
255 else
256 n_flushnode(current)
257 return new
258 end
259end
260
261
262
263function nodes.append(head,current,...)
264 for i=1,select("#",...) do
265 head, current = n_insertafter(head,current,(select(i,...)))
266 end
267 return head, current
268end
269
270function nodes.prepend(head,current,...)
271 for i=1,select("#",...) do
272 head, current = n_insertbefore(head,current,(select(i,...)))
273 end
274 return head, current
275end
276
277function nodes.linked(...)
278 local head, last
279 for i=1,select("#",...) do
280 local next = select(i,...)
281 if next then
282 if head then
283 n_setlink(last,next)
284 else
285 head = next
286 end
287 last = n_find_tail(next)
288 end
289 end
290 return head
291end
292
293function nodes.concat(list)
294 local head, tail
295 for i=1,#list do
296 local li = list[i]
297 if li then
298 if head then
299 n_setlink(tail,li)
300 else
301 head = li
302 end
303 tail = n_slide(li)
304 end
305 end
306 return head, tail
307end
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363local n_remove_node = nodes.remove
364
365metatable.__concat = function(n1,n2)
366 if not n1 then
367 return n2
368 elseif not n2 then
369 return n1
370 elseif n1 == n2 then
371
372 return n2
373 else
374 local tail = n_find_tail(n1)
375 n_setlink(tail,n2)
376 return n1
377 end
378end
379
380metatable.__mul = function(n,multiplier)
381 if type(multiplier) ~= "number" then
382 n, multiplier = multiplier, n
383 end
384 if multiplier <= 1 then
385 return n
386 elseif n_getnext(n) then
387 local head
388 for i=2,multiplier do
389 local h = n_copy_list(n)
390 if head then
391 local t = n_find_tail(h)
392 n_setlink(t,head)
393 end
394 head = h
395 end
396 local t = n_find_tail(n)
397 n_setlink(t,head)
398 else
399 local head
400 for i=2,multiplier do
401 local c = n_copy_node(n)
402 if head then
403 n_setlink(c,head)
404 end
405 head = c
406 end
407 n_setlink(n,head)
408 end
409 return n
410end
411
412metatable.__sub = function(first,second)
413 if type(second) == "number" then
414 local tail = n_find_tail(first)
415 for i=1,second do
416 local prev = n_getprev(tail)
417 n_flushnode(tail)
418 if prev then
419 tail = prev
420 else
421 return nil
422 end
423 end
424 if tail then
425 n_setnext(tail)
426 return first
427 else
428 return nil
429 end
430 else
431
432 local firsttail = n_find_tail(first)
433 local prev = n_getprev(firsttail)
434 if prev then
435 local secondtail = n_find_tail(second)
436 n_setlink(secondtail,firsttail)
437 n_setlink(prev,second)
438 return first
439 else
440 local secondtail = n_find_tail(second)
441 n_setlink(secondtail,first)
442 return second
443 end
444 end
445end
446
447metatable.__add = function(first,second)
448 if type(first) == "number" then
449 local head = second
450 for i=1,first do
451 local second = n_getnext(head)
452 n_flushnode(head)
453 if second then
454 head = second
455 else
456 return nil
457 end
458 end
459 if head then
460 n_setprev(head)
461 return head
462 else
463 return nil
464 end
465 else
466
467 local next = n_getnext(first)
468 if next then
469 local secondtail = n_find_tail(second)
470 n_setlink(first,second)
471 n_setlink(secondtail,next)
472 else
473 n_setlink(first,second)
474 end
475 return first
476 end
477end
478
479metatable.__len = function(current)
480 local length = 0
481 while current do
482 current = n_getnext(current)
483 length = length + 1
484 end
485 return length
486end
487
488metatable.__div = function(list,action)
489 return action(list) or list
490end
491
492metatable.__pow = function(n,multiplier)
493 local tail = n
494 local head = nil
495 if n_getnext(n) then
496 if multiplier == 1 then
497 head = n_copy_list(n)
498 else
499 for i=1,multiplier do
500 local h = n_copy_list(n)
501 if head then
502 local t = n_find_tail(h)
503 n_setlink(t,head)
504 end
505 head = h
506 end
507 end
508 else
509 if multiplier == 1 then
510 head = n_copy_node(n)
511 else
512 for i=2,multiplier do
513 local c = n_copy_node(n)
514 if head then
515 n_setlink(head,c)
516 end
517 head = c
518 end
519 end
520 end
521
522 return head
523end
524
525metatable.__unm = function(head)
526 local last = head
527 local first = head
528 local current = n_getnext(head)
529 while current do
530 local next = n_getnext(current)
531 n_setlink(current,first)
532 first = current
533 current = next
534 end
535 n_setprev(first)
536 n_setnext(last)
537 return first
538end
539 |