1if not modules then modules = { } end modules ['node-nut'] = {
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
14local type, rawget = type, rawget
15
16local nodes = nodes
17local direct = node.direct
18
19local fastcopy = table.fastcopy
20
21local nodecodes = nodes.nodecodes
22local hlist_code = nodecodes.hlist
23local vlist_code = nodecodes.vlist
24local glyph_code = nodecodes.glyph
25
26local tonode = direct.tonode
27local tonut = direct.todirect
28
29local isnode = direct.isnode
30local isnut = direct.isdirect
31local isdirect = direct.isdirect
32
33local d_remove_node = direct.remove
34local d_flushnode = direct.flushnode
35local d_getnext = direct.getnext
36local d_getprev = direct.getprev
37local d_getid = direct.getid
38local d_getlist = direct.getlist
39local d_find_tail = direct.tail
40local d_insertafter = direct.insertafter
41local d_insertbefore = direct.insertbefore
42local d_slide = direct.slide
43local d_traverse = direct.traverse
44local d_setlink = direct.setlink
45local d_getboth = direct.getboth
46
47local nuts = {
48 addmargins = direct.addmargins,
49 addxoffset = direct.addxoffset,
50 addxymargins = direct.addxymargins,
51 addyoffset = direct.addyoffset,
52 append = direct.append,
53 appendaftertail = direct.appendaftertail,
54 checkdiscretionaries = direct.checkdiscretionaries,
55 collapsing = direct.collapsing,
56 copy = direct.copy,
57 copylist = direct.copylist,
58 copynode = direct.copy,
59 copyonly = direct.copyonly,
60 count = direct.count,
61 currentattributes = direct.currentattributes,
62 delete = direct.delete,
63 dimensions = direct.dimensions,
64 effectiveglue = direct.effectiveglue,
65 endofmath = direct.endofmath,
66 exchange = direct.exchange,
67 findattribute = direct.findattribute,
68 findnode = direct.findnode,
69 firstglyphnode = direct.firstglyphnode,
70 firstglyph = direct.firstglyph,
71 firstchar = direct.firstchar,
72 flattendiscretionaries = direct.flattendiscretionaries,
73 flattenleaders = direct.flattenleaders,
74 flush = d_flushnode,
75 flushlist = direct.flushlist,
76 flushnode = d_flushnode,
77 free = direct.free,
78 freeze = direct.freeze,
79 getanchors = direct.getanchors,
80 getattr = direct.getattribute,
81 getattribute = direct.getattribute,
82 getattributelist = direct.getattributelist,
83 getattributes = direct.getattributes,
84 getattrlist = direct.getattributelist,
85 getattrs = direct.getattributes,
86 getboth = d_getboth,
87 getbottom = direct.getbottom,
88 getbottomdelimiter = direct.getbottomdelimiter,
89 getbox = direct.getbox,
90 getboxglue = direct.getglue,
91 getchar = direct.getchar,
92 getchardict = direct.getchardict,
93 getcharspec = direct.getcharspec,
94 getchoice = direct.getchoice,
95 getclass = direct.getclass,
96 getcornerkerns = direct.getcornerkerns,
97 getdata = direct.getdata,
98 getdegree = direct.getdegree,
99 getdelimiter = direct.getdelimiter,
100 getmiddle = direct.getdelimiter,
101 getdenominator = direct.getdenominator,
102 getdepth = direct.getdepth,
103 getdir = direct.getdir,
104 getdirection = direct.getdirection,
105 getdisc = direct.getdisc,
106 getdiscpart = direct.getdiscpart,
107 getdiscretionary = direct.getdisc,
108 getexpansion = direct.getexpansion,
109 getfam = direct.getfam,
110 getfield = direct.getfield,
111 getfont = direct.getfont,
112 getgeometry = direct.getgeometry,
113 getglue = direct.getglue,
114 getglyphdata = direct.getglyphdata,
115 getglyphdimensions = direct.getglyphdimensions,
116 getheight = direct.getheight,
117 getid = d_getid,
118 getindex = direct.getindex,
119 getinputfields = direct.getinputfields,
120 getkern = direct.getkern,
121 getkerndimension = direct.getkerndimension,
122 getlang = direct.getlanguage,
123 getlanguage = direct.getlanguage,
124 getleader = direct.getleader,
125 getleftdelimiter = direct.getleftdelimiter,
126 getlist = d_getlist,
127 getlistdimensions = direct.getlistdimensions,
128 getmiddledelimiter = direct.getdelimiter,
129 getnext = d_getnext,
130 getnormalizedline = direct.getnormalizedline,
131 getnucleus = direct.getnucleus,
132 getnumerator = direct.getnumerator,
133 getoffsets = direct.getoffsets,
134 getoptions = direct.getoptions,
135 getorientation = direct.getorientation,
136 getparstate = direct.getparstate,
137 getpenalty = direct.getpenalty,
138 getpost = direct.getpost,
139 getpre = direct.getpre,
140 getprev = d_getprev,
141 getprime = direct.getprime,
142 getreplace = direct.getreplace,
143 getrightdelimiter = direct.getrightdelimiter,
144 getruledata = direct.getdata,
145 getruledimensions = direct.getruledimensions,
146 setruledimensions = direct.setruledimensions,
147 getscale = direct.getscale,
148 getscales = direct.getscales,
149 getscript = direct.getscript,
150 getshift = direct.getshift,
151 getslant = direct.getslant,
152 getspeciallist = direct.getspeciallist,
153 getstate = direct.getstate,
154 getsub = direct.getsub,
155 getsubpre = direct.getsubpre,
156 getsubtype = direct.getsubtype,
157 getsup = direct.getsup,
158 getsuppre = direct.getsuppre,
159 getsurround = direct.getkern,
160 gettop = direct.gettop,
161 gettopdelimiter = direct.gettopdelimiter,
162 gettotal = direct.gettotal,
163 getusedattributes = direct.getusedattributes,
164 getvalue = direct.getdata,
165 getwhd = direct.getwhd,
166 getwidth = direct.getwidth,
167 getweight = direct.getweight,
168 getwordrange = direct.getwordrange,
169 getxscale = direct.getxscale,
170 getxyscales = direct.getxyscales,
171 getyscale = direct.getyscale,
172 gluetostring = direct.gluetostring,
173 hasattribute = direct.hasattribute,
174 hasdimensions = direct.hasdimensions,
175 hasfield = direct.hasfield,
176 hasgeometry = direct.hasgeometry,
177 hasglyph = direct.hasglyph,
178 hasglyphoption = direct.hasglyphoption,
179 hasdiscoption = direct.hasdiscoption,
180 hpack = direct.hpack,
181 hyphenating = direct.hyphenating,
182 ignoremathskip = direct.ignoremathskip,
183 insertafter = d_insertafter,
184 insertbefore = d_insertbefore,
185 ischar = direct.ischar,
186 isdirect = isdirect,
187 isglyph = direct.isglyph,
188 isnextchar = direct.isnextchar,
189 isnextglyph = direct.isnextglyph,
190 isnode = isnode,
191 isnut = isdirect,
192 isprevchar = direct.isprevchar,
193 isprevglyph = direct.isprevglyph,
194 iszeroglue = direct.iszeroglue,
195 isnext = direct.isnext,
196 isprev = direct.isprev,
197 isboth = direct.isboth,
198 issimilarglyph = direct.issimilarglyph,
199 isitalicglyph = direct.isitalicglyph,
200 firstitalicglyph = direct.firstitalicglyph,
201 kerning = direct.kerning,
202 lastnode = direct.lastnode,
203 length = direct.length,
204 ligaturing = direct.ligaturing,
205 makextensible = direct.makextensible,
206 migrate = direct.migrate,
207 mlisttohlist = direct.mlisttohlist,
208 naturalhsize = direct.naturalhsize,
209 naturalwidth = direct.naturalwidth,
210 new = direct.new,
211 newmathglyph = direct.newmathglyph,
212 patchattributes = direct.patchattributes,
213 prependbeforehead = direct.prependbeforehead,
214 protectglyph = direct.protectglyph,
215 protectglyphs = direct.protectglyphs,
216 protectglyphsnone = direct.protectglyphsnone,
217 protrusionskippable = direct.protrusionskippable,
218 rangedimensions = direct.rangedimensions,
219 remove = d_remove_node,
220 removefromlist = direct.removefromlist,
221 repack = direct.repack,
222 reverse = direct.reverse,
223 serialized = direct.serialized,
224 setanchors = direct.setanchors,
225 setattr = direct.setattribute,
226 setattribute = direct.setattribute,
227 setattributelist = direct.setattributelist,
228 setattributes = direct.setattributes,
229 setattrlist = direct.setattributelist,
230 setattrs = direct.setattributes,
231 setboth = direct.setboth,
232 setbottom = direct.setbottom,
233 setbox = direct.setbox,
234 setboxglue = direct.setglue,
235 setchar = direct.setchar,
236 setchardict = direct.setchardict,
237 setchoice = direct.setchoice,
238 setclass = direct.setclass,
239 setdata = direct.setdata,
240 setdegree = direct.setdegree,
241 setdelimiter = direct.setdelimiter,
242 setdenominator = direct.setdenominator,
243 setdepth = direct.setdepth,
244 setdir = direct.setdir,
245 setdirection = direct.setdirection,
246 setdisc = direct.setdisc,
247 setdiscpart = direct.setdiscpart,
248 setdiscretionary = direct.setdisc,
249 setexpansion = direct.setexpansion,
250 setfam = direct.setfam,
251 setfield = direct.setfield,
252 setfont = direct.setfont,
253 setgeometry = direct.setgeometry,
254 setglue = direct.setglue,
255 setglyphdata = direct.setglyphdata,
256 setheight = direct.setheight,
257 setinputfields = direct.setinputfields,
258 setkern = direct.setkern,
259 setlang = direct.setlanguage,
260 setlanguage = direct.setlanguage,
261 setleader = direct.setleader,
262 setleftdelimiter = direct.setleftdelimiter,
263 setlink = d_setlink,
264 setlist = direct.setlist,
265 setmiddledelimiter = direct.setdelimiter,
266 setnext = direct.setnext,
267 setnucleus = direct.setnucleus,
268 setnumerator = direct.setnumerator,
269 setoffsets = direct.setoffsets,
270 setoptions = direct.setoptions,
271 setorientation = direct.setorientation,
272 setpenalty = direct.setpenalty,
273 setpost = direct.setpost,
274 setpre = direct.setpre,
275 setprev = direct.setprev,
276 setprime = direct.setprime,
277 setreplace = direct.setreplace,
278 setrightdelimiter = direct.setrightdelimiter,
279 setruledata = direct.setdata,
280 setscale = direct.setscale or direct.setscales,
281 setscales = direct.setscales,
282 setscript = direct.setscript,
283 setshift = direct.setshift,
284 setslant = direct.setslant,
285 setspeciallist = direct.setspeciallist,
286 setsplit = direct.setsplit,
287 setstate = direct.setstate,
288 setsub = direct.setsub,
289 setsubpre = direct.setsubpre,
290 setsubtype = direct.setsubtype,
291 setsup = direct.setsup,
292 setsuppre = direct.setsuppre,
293 setsurround = direct.setkern,
294 setvalue = direct.setdata,
295 settop = direct.settop,
296 setwhd = direct.setwhd,
297 setwidth = direct.setwidth,
298 setweight = direct.setweight,
299 show = direct.show,
300 slide = d_slide,
301 softenhyphens = direct.softenhyphens,
302 startofpar = direct.startofpar,
303 tail = d_find_tail,
304 takeattr = direct.unsetattribute,
305 tonode = tonode,
306 tonut = tonut,
307 tostring = direct.tostring,
308 traverse = d_traverse,
309 traversechar = direct.traversechar,
310 traversecontent = direct.traversecontent,
311 traverseglyph = direct.traverseglyph,
312 traverseid = direct.traverseid,
313 traverseitalic = direct.traverseitalic,
314 traverseleader = direct.traverseleader,
315 traverselist = direct.traverselist,
316 unprotectglyph = direct.unprotectglyph,
317 unprotectglyphs = direct.unprotectglyphs,
318 unsetattribute = direct.unsetattribute,
319 unsetattributes = direct.unsetattributes,
320 usedlist = direct.usedlist,
321 usesfont = direct.usesfont,
322 verticalbreak = direct.verticalbreak,
323 vpack = direct.vpack,
324 write = direct.write,
325 xscaled = direct.xscaled,
326 yscaled = direct.yscaled,
327}
328
329nodes.nuts = nuts
330
331nodes.isnode = isnode
332nodes.isdirect = isnut
333nodes.isnut = isnut
334
335nodes.tonode = tonode
336nodes.tonut = tonut
337
338function nuts.delete(head,current)
339 return d_remove_node(head,current,true)
340end
341
342function nuts.replace(head,current,new)
343 if not new then
344 head, current, new = false, head, current
345 end
346 local prev, next = d_getboth(current)
347 if prev or next then
348 d_setlink(prev,new,next)
349 end
350 if head then
351 if head == current then
352 head = new
353 end
354 d_flushnode(current)
355 return head, new
356 else
357 d_flushnode(current)
358 return new
359 end
360end
361
362local function countall(stack,flat)
363 local n = 0
364 while stack do
365 local id = d_getid(stack)
366 if not flat and id == hlist_code or id == vlist_code then
367 local list = d_getlist(stack)
368 if list then
369 n = n + 1 + countall(list)
370 else
371 n = n + 1
372 end
373 else
374 n = n + 1
375 end
376 stack = d_getnext(stack)
377 end
378 return n
379end
380
381nuts.countall = countall
382
383function nodes.countall(stack,flat)
384 return countall(tonut(stack),flat)
385end
386
387function nuts.append(head,current,...)
388 for i=1,select("#",...) do
389 head, current = d_insertafter(head,current,(select(i,...)))
390 end
391 return head, current
392end
393
394function nuts.prepend(head,current,...)
395 for i=1,select("#",...) do
396 head, current = d_insertbefore(head,current,(select(i,...)))
397 end
398 return head, current
399end
400
401function nuts.linked(...)
402 local head, last
403 for i=1,select("#",...) do
404 local next = select(i,...)
405 if next then
406 if head then
407 d_setlink(last,next)
408 else
409 head = next
410 end
411 last = d_find_tail(next)
412 end
413 end
414 return head
415end
416
417function nuts.concat(list)
418 local head, tail
419 for i=1,#list do
420 local li = list[i]
421 if li then
422 if head then
423 d_setlink(tail,li)
424 else
425 head = li
426 end
427 tail = d_slide(li)
428 end
429 end
430 return head, tail
431end
432
433function nuts.reference(n)
434 return n or "<none>"
435end
436
437function nuts.vianuts (f) return function(n,...) return tonode(f(tonut (n),...)) end end
438function nuts.vianodes(f) return function(n,...) return tonut (f(tonode(n),...)) end end
439
440nodes.vianuts = nuts.vianuts
441nodes.vianodes = nuts.vianodes
442
443function nodes.insertlistafter(h,c,n)
444 local t = n_tail(n)
445 if c then
446 local cn = n_getnext(c)
447 if cn then
448
449 n_setfield(t,"next",cn)
450 n_setfield(cn,"prev",t)
451 else
452 n_setfield(t,"next",nil)
453 end
454 n_setfield(c,"next",n)
455 n_setfield(n,"prev",c)
456 return h, n
457 end
458 return n, t
459end
460
461function nuts.insertlistafter(h,c,n)
462 local t = d_tail(n)
463 if c then
464 local cn = d_getnext(c)
465 if cn then
466 d_setlink(t,cn)
467 else
468 d_setnext(t)
469 end
470 d_setlink(c,n)
471 return h, n
472 end
473 return n, t
474end
475
476
477
478
479
480local report = logs.reporter("sliding")
481
482local function message(detail,head,current,previous)
483 report("error: %s, current: %s:%s, previous: %s:%s, list: %s, text: %s",
484 detail,
485 nodecodes[d_getid(current)],
486 current,
487 nodecodes[d_getid(previous)],
488 previous,
489 nodes.idstostring(head),
490 nodes.listtoutf(head)
491 )
492 utilities.debugger.showtraceback(report)
493end
494
495local function warn()
496 report()
497 report("warning: the slide tracer is enabled")
498 report()
499 warn = false
500end
501
502local function tracedslide(head)
503 if head then
504 if warn then
505 warn()
506 end
507 local next = d_getnext(head)
508 if next then
509 local prev = head
510 for n in d_traverse(next) do
511 local p = d_getprev(n)
512 if not p then
513 message("unset",head,n,prev)
514
515 elseif p ~= prev then
516 message("wrong",head,n,prev)
517
518 end
519 prev = n
520 end
521 end
522 return d_slide(head)
523 end
524end
525
526local function nestedtracedslide(head,level)
527 if head then
528 if warn then
529 warn()
530 end
531 local id = d_getid(head)
532 local next = d_getnext(head)
533 if next then
534 report("%whead:%s",level or 0,nodecodes[id])
535 local prev = head
536 for n in d_traverse(next) do
537 local p = d_getprev(n)
538 if not p then
539 message("unset",head,n,prev)
540
541 elseif p ~= prev then
542 message("wrong",head,n,prev)
543
544 end
545 prev = n
546 local id = d_getid(n)
547 if id == hlist_code or id == vlist_code then
548 nestedtracedslide(d_getlist(n),(level or 0) + 1)
549 end
550 end
551 elseif id == hlist_code or id == vlist_code then
552 report("%wlist:%s",level or 0,nodecodes[id])
553 nestedtracedslide(d_getlist(head),(level or 0) + 1)
554 end
555
556 end
557end
558
559local function untracedslide(head)
560 if head then
561 if warn then
562 warn()
563 end
564 local next = d_getnext(head)
565 if next then
566 local prev = head
567 for n in d_traverse(next) do
568 local p = d_getprev(n)
569 if not p then
570 return "unset", d_getid(n)
571 elseif p ~= prev then
572 return "wrong", d_getid(n)
573 end
574 prev = n
575 end
576 end
577 return d_slide(head)
578 end
579end
580
581nuts.tracedslide = tracedslide
582nuts.untracedslide = untracedslide
583nuts.nestedtracedslide = nestedtracedslide
584
585
586
587local propertydata = direct.getpropertiestable(true)
588
589local getattr = nuts.getattr
590local setattr = nuts.setattr
591
592nodes.properties = {
593 data = propertydata,
594}
595
596
597
598
599function nuts.getprop(n,k)
600 local p = propertydata[n]
601 if p then
602 if k then
603 return p[k]
604 else
605 return p
606 end
607 end
608end
609
610function nuts.rawprop(n,k)
611 local p = rawget(propertydata,n)
612 if p then
613 if k then
614 return p[k]
615 else
616 return p
617 end
618 end
619end
620
621function nuts.setprop(n,k,v)
622 local p = propertydata[n]
623 if p then
624 p[k] = v
625 else
626 propertydata[n] = { [k] = v }
627 end
628end
629
630function nuts.theprop(n)
631 local p = propertydata[n]
632 if not p then
633 p = { }
634 propertydata[n] = p
635 end
636 return p
637end
638
639
640function nuts.isdone(n,k)
641 local p = propertydata[n]
642 if not p then
643 propertydata[n] = { [k] = true }
644 return false
645 end
646 local v = p[k]
647 if v == nil then
648 propertydata[n] = { [k] = true }
649 return false
650 end
651 return v
652end
653
654function nuts.copy_properties(source,target,what)
655 local newprops = propertydata[source]
656 if not newprops then
657
658 return
659 end
660 if what then
661
662 newprops = rawget(source,what)
663 if newprops then
664 newprops = fastcopy(newprops)
665 local p = rawget(propertydata,target)
666 if p then
667 p[what] = newprops
668 else
669 propertydata[target] = {
670 [what] = newprops,
671 }
672 end
673 end
674 else
675
676 newprops = fastcopy(newprops)
677 propertydata[target] = newprops
678 end
679 return newprops
680end
681 |