1 if 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.tostring = node.tostring or tostring
74nodes.copy = node.copy
75nodes.copynode = node.copy
76nodes.copylist = node.copy_list
77nodes.delete = node.delete
78nodes.dimensions = node.dimensions
79nodes.rangedimensions = node.rangedimensions
80nodes.endofmath = node.end_of_math
81nodes.flush = node.flush_node
82nodes.flushnode = node.flush_node
83nodes.flushlist = node.flush_list
84nodes.free = node.free
85nodes.insertafter = node.insert_after
86nodes.insertbefore = node.insert_before
87nodes.hpack = node.hpack
88nodes.new = node.new
89nodes.tail = node.tail
90nodes.traverse = node.traverse
91nodes.traverseid = node.traverse_id
92nodes.traversechar = node.traverse_char
93nodes.traverseglyph = node.traverse_glyph
94nodes.traverselist = node.traverse_list
95nodes.slide = node.slide
96nodes.vpack = node.vpack
97nodes.fields = node.fields
98nodes.isnode = node.is_node
99nodes.isdirect = node.is_direct
100nodes.isnut = node.is_direct
101nodes.setglue = node.setglue
102nodes.usesfont = node.uses_font
103
104nodes.firstglyph = node.first_glyph
105nodes.hasglyph = node.has_glyph
106
107nodes.currentattributes = node.current_attributes or node.current_attr
108nodes.hasfield = node.has_field
109nodes.last_node = node.last_node
110nodes.usedlist = node.usedlist
111nodes.protrusionskippable = node.protrusion_skippable
112nodes.checkdiscretionaries = node.check_discretionaries
113nodes.write = node.write
114nodes.flattendiscretionaries = node.flatten_discretionaries
115
116nodes.count = node.count
117nodes.length = node.length
118
119nodes.hasattribute = node.has_attribute
120nodes.setattribute = node.set_attribute
121nodes.findattribute = node.find_attribute
122nodes.unsetattribute = node.unset_attribute
123
124nodes.protectglyph = node.protect_glyph
125nodes.protectglyphs = node.protect_glyphs
126nodes.unprotectglyph = node.unprotect_glyph
127nodes.unprotectglyphs = node.unprotect_glyphs
128nodes.kerning = node.kerning
129nodes.ligaturing = node.ligaturing
130nodes.hyphenating = node.hyphenating
131nodes.mlisttohlist = node.mlist_to_hlist
132
133nodes.effectiveglue = node.effective_glue
134nodes.getglue = node.getglue
135nodes.setglue = node.setglue
136nodes.iszeroglue = node.iszeroglue
137
138nodes.tonode = function(n) return n end
139nodes.tonut = function(n) return n end
140
141
142
143
144local n_getfield = node.getfield
145local n_getattr = node.get_attribute
146
147local n_setfield = node.setfield
148local n_setattr = n_setfield
149
150nodes.getfield = n_getfield
151nodes.setfield = n_setfield
152nodes.getattr = n_getattr
153nodes.setattr = n_setattr
154nodes.takeattr = nodes.unsetattribute
155
156local function n_getid (n) return n_getfield(n,"id") end
157local function n_getsubtype(n) return n_getfield(n,"subtype") end
158
159nodes.getid = n_getid
160nodes.getsubtype = n_getsubtype
161
162local function n_getchar(n) return n_getfield(n,"char") end
163local function n_setchar(n,c) return n_setfield(n,"char",c) end
164local function n_getfont(n) return n_getfield(n,"font") end
165local function n_setfont(n,f) return n_setfield(n,"font",f) end
166
167nodes.getchar = n_getchar
168nodes.setchar = n_setchar
169nodes.getfont = n_getfont
170nodes.setfont = n_setfont
171
172local function n_getlist (n) return n_getfield(n,"list") end
173local function n_setlist (n,l) return n_setfield(n,"list",l) end
174local function n_getleader(n) return n_getfield(n,"leader") end
175local function n_setleader(n,l) return n_setfield(n,"leader",l) end
176
177nodes.getlist = n_getlist
178nodes.setlist = n_setlist
179nodes.getleader = n_getleader
180nodes.setleader = n_setleader
181
182local function n_getnext(n) return n_getfield(n,"next") end
183local function n_setnext(n,nn) return n_setfield(n,"next",nn) end
184local function n_getprev(n) return n_getfield(n,"prev") end
185local function n_setprev(n,pp) return n_setfield(n,"prev",pp) end
186local function n_getboth(n) return n_getfield(n,"prev"), n_getfield(n,"next") end
187local function n_setboth(n,pp,nn) return n_setfield(n,"prev",pp), n_setfield(n,"next",nn) end
188
189nodes.getnext = n_getnext
190nodes.setnext = n_setnext
191nodes.getprev = n_getprev
192nodes.setprev = n_setprev
193nodes.getboth = n_getboth
194nodes.setboth = n_setboth
195
196local function n_setlink(...)
197
198 local h = nil
199 for i=1,select("#",...) do
200 local n = select(i,...)
201 if not n then
202
203 elseif h then
204 n_setfield(h,"next",n)
205 n_setfield(n,"prev",h)
206 else
207 h = n
208 end
209 end
210 return h
211end
212
213nodes.setlink = n_setlink
214
215nodes.getbox = node.getbox or tex.getbox
216nodes.setbox = node.setbox or tex.setbox
217
218local n_flushnode = nodes.flush
219local n_copynode = nodes.copy
220local n_copylist = nodes.copylist
221local n_findtail = nodes.tail
222local n_insertafter = nodes.insertafter
223local n_insertbefore = nodes.insertbefore
224local n_slide = nodes.slide
225
226local n_remove_node = node.remove
227
228local function remove(head,current,free_too)
229 local t = current
230 head, current = n_remove_node(head,current)
231 if not t then
232
233 elseif free_too then
234 n_flushnode(t)
235 t = nil
236 else
237 n_setboth(t)
238 end
239 return head, current, t
240end
241
242nodes.remove = remove
243
244function nodes.delete(head,current)
245 return remove(head,current,true)
246end
247
248
249
250
251
252
253
254function nodes.replace(head,current,new)
255 if not new then
256 head, current, new = false, head, current
257
258 end
259 local prev = n_getprev(current)
260 local next = n_getnext(current)
261 if next then
262 n_setlink(new,next)
263 end
264 if prev then
265 n_setlink(prev,new)
266 end
267 if head then
268 if head == current then
269 head = new
270 end
271 n_flushnode(current)
272 return head, new
273 else
274 n_flushnode(current)
275 return new
276 end
277end
278
279
280
281function nodes.append(head,current,...)
282 for i=1,select("#",...) do
283 head, current = n_insertafter(head,current,(select(i,...)))
284 end
285 return head, current
286end
287
288function nodes.prepend(head,current,...)
289 for i=1,select("#",...) do
290 head, current = n_insertbefore(head,current,(select(i,...)))
291 end
292 return head, current
293end
294
295function nodes.linked(...)
296 local head, last
297 for i=1,select("#",...) do
298 local next = select(i,...)
299 if next then
300 if head then
301 n_setlink(last,next)
302 else
303 head = next
304 end
305 last = n_findtail(next)
306 end
307 end
308 return head
309end
310
311function nodes.concat(list)
312 local head, tail
313 for i=1,#list do
314 local li = list[i]
315 if li then
316 if head then
317 n_setlink(tail,li)
318 else
319 head = li
320 end
321 tail = n_slide(li)
322 end
323 end
324 return head, tail
325end
326
327function nodes.reference(n)
328 return n and tonut(n) or "<none>"
329end
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
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385local n_remove_node = nodes.remove
386
387metatable.__concat = function(n1,n2)
388 if not n1 then
389 return n2
390 elseif not n2 then
391 return n1
392 elseif n1 == n2 then
393
394 return n2
395 else
396 local tail = n_findtail(n1)
397 n_setlink(tail,n2)
398 return n1
399 end
400end
401
402metatable.__mul = function(n,multiplier)
403 if type(multiplier) ~= "number" then
404 n, multiplier = multiplier, n
405 end
406 if multiplier <= 1 then
407 return n
408 elseif n_getnext(n) then
409 local head
410 for i=2,multiplier do
411 local h = n_copylist(n)
412 if head then
413 local t = n_findtail(h)
414 n_setlink(t,head)
415 end
416 head = h
417 end
418 local t = n_findtail(n)
419 n_setlink(t,head)
420 else
421 local head
422 for i=2,multiplier do
423 local c = n_copynode(n)
424 if head then
425 n_setlink(c,head)
426 end
427 head = c
428 end
429 n_setlink(n,head)
430 end
431 return n
432end
433
434metatable.__sub = function(first,second)
435 if type(second) == "number" then
436 local tail = n_findtail(first)
437 for i=1,second do
438 local prev = n_getprev(tail)
439 n_flushnode(tail)
440 if prev then
441 tail = prev
442 else
443 return nil
444 end
445 end
446 if tail then
447 n_setnext(tail)
448 return first
449 else
450 return nil
451 end
452 else
453
454 local firsttail = n_findtail(first)
455 local prev = n_getprev(firsttail)
456 if prev then
457 local secondtail = n_findtail(second)
458 n_setlink(secondtail,firsttail)
459 n_setlink(prev,second)
460 return first
461 else
462 local secondtail = n_findtail(second)
463 n_setlink(secondtail,first)
464 return second
465 end
466 end
467end
468
469metatable.__add = function(first,second)
470 if type(first) == "number" then
471 local head = second
472 for i=1,first do
473 local second = n_getnext(head)
474 n_flushnode(head)
475 if second then
476 head = second
477 else
478 return nil
479 end
480 end
481 if head then
482 n_setprev(head)
483 return head
484 else
485 return nil
486 end
487 else
488
489 local next = n_getnext(first)
490 if next then
491 local secondtail = n_findtail(second)
492 n_setlink(first,second)
493 n_setlink(secondtail,next)
494 else
495 n_setlink(first,second)
496 end
497 return first
498 end
499end
500
501metatable.__len = function(current)
502 local length = 0
503 while current do
504 current = n_getnext(current)
505 length = length + 1
506 end
507 return length
508end
509
510metatable.__div = function(list,action)
511 return action(list) or list
512end
513
514metatable.__pow = function(n,multiplier)
515 local tail = n
516 local head = nil
517 if n_getnext(n) then
518 if multiplier == 1 then
519 head = n_copylist(n)
520 else
521 for i=1,multiplier do
522 local h = n_copylist(n)
523 if head then
524 local t = n_findtail(h)
525 n_setlink(t,head)
526 end
527 head = h
528 end
529 end
530 else
531 if multiplier == 1 then
532 head = n_copynode(n)
533 else
534 for i=2,multiplier do
535 local c = n_copynode(n)
536 if head then
537 n_setlink(head,c)
538 end
539 head = c
540 end
541 end
542 end
543
544 return head
545end
546
547metatable.__unm = function(head)
548 local last = head
549 local first = head
550 local current = n_getnext(head)
551 while current do
552 local next = n_getnext(current)
553 n_setlink(current,first)
554 first = current
555 current = next
556 end
557 n_setprev(first)
558 n_setnext(last)
559 return first
560end
561 |