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
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 . copy_node = node . copy
76nodes . copy_list = node . copy_list
77nodes . delete = node . delete
78nodes . dimensions = node . dimensions
79nodes . rangedimensions = node . rangedimensions
80nodes . end_of_math = node . end_of_math
81nodes . flush = node . flush_node
82nodes . flush_node = node . flush_node
83nodes . flush_list = node . flush_list
84nodes . free = node . free
85nodes . insert_after = node . insert_after
86nodes . insert_before = node . insert_before
87nodes . hpack = node . hpack
88nodes . new = node . new
89nodes . tail = node . tail
90nodes . traverse = node . traverse
91nodes . traverse_id = node . traverse_id
92nodes . traverse_char = node . traverse_char
93nodes . traverse_glyph = node . traverse_glyph
94nodes . traverse_list = node . traverse_list
95nodes . slide = node . slide
96nodes . vpack = node . vpack
97nodes . fields = node . fields
98nodes . is_node = node . is_node
99nodes . setglue = node . setglue
100nodes . uses_font = node . uses_font
101
102nodes . first_glyph = node . first_glyph
103nodes . has_glyph = node . has_glyph or node . first_glyph
104
105nodes . current_attr = node . current_attr
106nodes . has_field = node . has_field
107nodes . last_node = node . last_node
108nodes . usedlist = node . usedlist
109nodes . protrusion_skippable = node . protrusion_skippable
110nodes . check_discretionaries = node . check_discretionaries
111nodes . write = node . write
112nodes . flatten_discretionaries = node . flatten_discretionaries
113
114nodes . count = node . count
115nodes . length = node . length
116
117nodes . has_attribute = node . has_attribute
118nodes . set_attribute = node . set_attribute
119nodes . find_attribute = node . find_attribute
120nodes . unset_attribute = node . unset_attribute
121
122nodes . protect_glyph = node . protect_glyph
123nodes . protect_glyphs = node . protect_glyphs
124nodes . unprotect_glyph = node . unprotect_glyph
125nodes . unprotect_glyphs = node . unprotect_glyphs
126nodes . kerning = node . kerning
127nodes . ligaturing = node . ligaturing
128nodes . hyphenating = node . hyphenating
129nodes . mlist_to_hlist = node . mlist_to_hlist
130
131nodes . effective_glue = node . effective_glue
132nodes . getglue = node . getglue
133nodes . setglue = node . setglue
134nodes . is_zero_glue = node . is_zero_glue
135
136nodes . tonode = function ( n ) return n end
137nodes . tonut = function ( n ) return n end
138
139
140
141
142local n_getfield = node . getfield
143local n_getattr = node . get_attribute
144
145local n_setfield = node . setfield
146local n_setattr = n_setfield
147
148nodes . getfield = n_getfield
149nodes . setfield = n_setfield
150nodes . getattr = n_getattr
151nodes . setattr = n_setattr
152nodes . takeattr = nodes . unset_attribute
153
154local function n_getid ( n ) return n_getfield ( n , " id " ) end
155local function n_getsubtype ( n ) return n_getfield ( n , " subtype " ) end
156
157nodes . getid = n_getid
158nodes . getsubtype = n_getsubtype
159
160local function n_getchar ( n ) return n_getfield ( n , " char " ) end
161local function n_setchar ( n , c ) return n_setfield ( n , " char " , c ) end
162local function n_getfont ( n ) return n_getfield ( n , " font " ) end
163local function n_setfont ( n , f ) return n_setfield ( n , " font " , f ) end
164
165nodes . getchar = n_getchar
166nodes . setchar = n_setchar
167nodes . getfont = n_getfont
168nodes . setfont = n_setfont
169
170local function n_getlist ( n ) return n_getfield ( n , " list " ) end
171local function n_setlist ( n , l ) return n_setfield ( n , " list " , l ) end
172local function n_getleader ( n ) return n_getfield ( n , " leader " ) end
173local function n_setleader ( n , l ) return n_setfield ( n , " leader " , l ) end
174
175nodes . getlist = n_getlist
176nodes . setlist = n_setlist
177nodes . getleader = n_getleader
178nodes . setleader = n_setleader
179
180local function n_getnext ( n ) return n_getfield ( n , " next " ) end
181local function n_setnext ( n , nn ) return n_setfield ( n , " next " , nn ) end
182local function n_getprev ( n ) return n_getfield ( n , " prev " ) end
183local function n_setprev ( n , pp ) return n_setfield ( n , " prev " , pp ) end
184local function n_getboth ( n ) return n_getfield ( n , " prev " ) , n_getfield ( n , " next " ) end
185local function n_setboth ( n , pp , nn ) return n_setfield ( n , " prev " , pp ) , n_setfield ( n , " next " , nn ) end
186
187nodes . getnext = n_getnext
188nodes . setnext = n_setnext
189nodes . getprev = n_getprev
190nodes . setprev = n_setprev
191nodes . getboth = n_getboth
192nodes . setboth = n_setboth
193
194local function n_setlink ( ... )
195
196 local h = nil
197 for i = 1 , select ( " # " , ... ) do
198 local n = select ( i , ... )
199 if not n then
200
201 elseif h then
202 n_setfield ( h , " next " , n )
203 n_setfield ( n , " prev " , h )
204 else
205 h = n
206 end
207 end
208 return h
209end
210
211nodes . setlink = n_setlink
212
213nodes . getbox = node . getbox or tex . getbox
214nodes . setbox = node . setbox or tex . setbox
215
216local n_flush_node = nodes . flush
217local n_copy_node = nodes . copy
218local n_copy_list = nodes . copy_list
219local n_find_tail = nodes . tail
220local n_insert_after = nodes . insert_after
221local n_insert_before = nodes . insert_before
222local n_slide = nodes . slide
223
224local n_remove_node = node . remove
225
226local function remove ( head , current , free_too )
227 local t = current
228 head , current = n_remove_node ( head , current )
229 if not t then
230
231 elseif free_too then
232 n_flush_node ( t )
233 t = nil
234 else
235 n_setboth ( t )
236 end
237 return head , current , t
238end
239
240nodes . remove = remove
241
242function nodes . delete ( head , current )
243 return remove ( head , current , true )
244end
245
246
247
248
249
250
251
252function nodes . replace ( head , current , new )
253 if not new then
254 head , current , new = false , head , current
255
256 end
257 local prev = n_getprev ( current )
258 local next = n_getnext ( current )
259 if next then
260 n_setlink ( new , next )
261 end
262 if prev then
263 n_setlink ( prev , new )
264 end
265 if head then
266 if head = = current then
267 head = new
268 end
269 n_flush_node ( current )
270 return head , new
271 else
272 n_flush_node ( current )
273 return new
274 end
275end
276
277
278
279function nodes . append ( head , current , ... )
280 for i = 1 , select ( " # " , ... ) do
281 head , current = n_insert_after ( head , current , ( select ( i , ... ) ) )
282 end
283 return head , current
284end
285
286function nodes . prepend ( head , current , ... )
287 for i = 1 , select ( " # " , ... ) do
288 head , current = n_insert_before ( head , current , ( select ( i , ... ) ) )
289 end
290 return head , current
291end
292
293function nodes . linked ( ... )
294 local head , last
295 for i = 1 , select ( " # " , ... ) do
296 local next = select ( i , ... )
297 if next then
298 if head then
299 n_setlink ( last , next )
300 else
301 head = next
302 end
303 last = n_find_tail ( next )
304 end
305 end
306 return head
307end
308
309function nodes . concat ( list )
310 local head , tail
311 for i = 1 , # list do
312 local li = list [ i ]
313 if li then
314 if head then
315 n_setlink ( tail , li )
316 else
317 head = li
318 end
319 tail = n_slide ( li )
320 end
321 end
322 return head , tail
323end
324
325function nodes . reference ( n )
326 return n and tonut ( n ) or " <none> "
327end
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
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383local n_remove_node = nodes . remove
384
385metatable . __concat = function ( n1 , n2 )
386 if not n1 then
387 return n2
388 elseif not n2 then
389 return n1
390 elseif n1 = = n2 then
391
392 return n2
393 else
394 local tail = n_find_tail ( n1 )
395 n_setlink ( tail , n2 )
396 return n1
397 end
398end
399
400metatable . __mul = function ( n , multiplier )
401 if type ( multiplier ) ~ = " number " then
402 n , multiplier = multiplier , n
403 end
404 if multiplier < = 1 then
405 return n
406 elseif n_getnext ( n ) then
407 local head
408 for i = 2 , multiplier do
409 local h = n_copy_list ( n )
410 if head then
411 local t = n_find_tail ( h )
412 n_setlink ( t , head )
413 end
414 head = h
415 end
416 local t = n_find_tail ( n )
417 n_setlink ( t , head )
418 else
419 local head
420 for i = 2 , multiplier do
421 local c = n_copy_node ( n )
422 if head then
423 n_setlink ( c , head )
424 end
425 head = c
426 end
427 n_setlink ( n , head )
428 end
429 return n
430end
431
432metatable . __sub = function ( first , second )
433 if type ( second ) = = " number " then
434 local tail = n_find_tail ( first )
435 for i = 1 , second do
436 local prev = n_getprev ( tail )
437 n_flush_node ( tail )
438 if prev then
439 tail = prev
440 else
441 return nil
442 end
443 end
444 if tail then
445 n_setnext ( tail )
446 return first
447 else
448 return nil
449 end
450 else
451
452 local firsttail = n_find_tail ( first )
453 local prev = n_getprev ( firsttail )
454 if prev then
455 local secondtail = n_find_tail ( second )
456 n_setlink ( secondtail , firsttail )
457 n_setlink ( prev , second )
458 return first
459 else
460 local secondtail = n_find_tail ( second )
461 n_setlink ( secondtail , first )
462 return second
463 end
464 end
465end
466
467metatable . __add = function ( first , second )
468 if type ( first ) = = " number " then
469 local head = second
470 for i = 1 , first do
471 local second = n_getnext ( head )
472 n_flush_node ( head )
473 if second then
474 head = second
475 else
476 return nil
477 end
478 end
479 if head then
480 n_setprev ( head )
481 return head
482 else
483 return nil
484 end
485 else
486
487 local next = n_getnext ( first )
488 if next then
489 local secondtail = n_find_tail ( second )
490 n_setlink ( first , second )
491 n_setlink ( secondtail , next )
492 else
493 n_setlink ( first , second )
494 end
495 return first
496 end
497end
498
499metatable . __len = function ( current )
500 local length = 0
501 while current do
502 current = n_getnext ( current )
503 length = length + 1
504 end
505 return length
506end
507
508metatable . __div = function ( list , action )
509 return action ( list ) or list
510end
511
512metatable . __pow = function ( n , multiplier )
513 local tail = n
514 local head = nil
515 if n_getnext ( n ) then
516 if multiplier = = 1 then
517 head = n_copy_list ( n )
518 else
519 for i = 1 , multiplier do
520 local h = n_copy_list ( n )
521 if head then
522 local t = n_find_tail ( h )
523 n_setlink ( t , head )
524 end
525 head = h
526 end
527 end
528 else
529 if multiplier = = 1 then
530 head = n_copy_node ( n )
531 else
532 for i = 2 , multiplier do
533 local c = n_copy_node ( n )
534 if head then
535 n_setlink ( head , c )
536 end
537 head = c
538 end
539 end
540 end
541
542 return head
543end
544
545metatable . __unm = function ( head )
546 local last = head
547 local first = head
548 local current = n_getnext ( head )
549 while current do
550 local next = n_getnext ( current )
551 n_setlink ( current , first )
552 first = current
553 current = next
554 end
555 n_setprev ( first )
556 n_setnext ( last )
557 return first
558end
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582local tonode = nodes . tonode
583local whatsit_code = nodecodes . whatsit
584local getfields = node . fields
585local sort = table . sort
586local whatsitkeys = { }
587local keys = { whatsit = whatsitkeys }
588local messyhack = table . tohash {
589 nodecodes . attributelist ,
590 nodecodes . attribute ,
591 nodecodes . action ,
592}
593
594setmetatableindex ( keys , function ( t , k )
595 local v = ( k = = " attributelist " or k = = nodecodes . attributelist ) and { } or getfields ( k )
596 if messyhack [ k ] then
597 for i = 1 , # v do
598 if v [ i ] = = " subtype " then
599 remove ( v , i )
600 break
601 end
602 end
603 end
604 if v [ 0 ] then v [ # v + 1 ] = " next " v [ 0 ] = nil end
605 if v [ -1 ] then v [ # v + 1 ] = " prev " v [ -1 ] = nil end
606 sort ( v )
607 t [ k ] = v
608 return v
609end )
610
611setmetatableindex ( whatsitkeys , function ( t , k )
612 local v = getfields ( whatsit_code , k )
613 if v [ 0 ] then v [ # v + 1 ] = " next " v [ 0 ] = nil end
614 if v [ -1 ] then v [ # v + 1 ] = " prev " v [ -1 ] = nil end
615 sort ( v )
616 t [ k ] = v
617 return v
618end )
619
620local function nodefields ( n )
621 n = tonode ( n )
622 local id = n . id
623 if id = = whatsit_code then
624 return whatsitkeys [ n . subtype ]
625 else
626 return keys [ id ]
627 end
628end
629
630nodes . keys = keys
631nodes . fields = nodefields
632
633if not nodes . count then
634
635 local type = type
636
637 local direct = node . direct
638 local todirect = direct . tovaliddirect
639 local tonode = direct . tonode
640
641 local count = direct . count
642 local length = direct . length
643 local slide = direct . slide
644
645 function node . count ( id , first , last )
646 return count ( id , first and todirect ( first ) , last and todirect ( last ) or nil )
647 end
648
649 function node . length ( first , last )
650 return length ( first and todirect ( first ) , last and todirect ( last ) or nil )
651 end
652
653 function node . slide ( n )
654 if n then
655 n = slide ( todirect ( n ) )
656 if n then
657 return tonode ( n )
658 end
659 end
660 return nil
661 end
662
663 local hyphenating = direct . hyphenating
664 local ligaturing = direct . ligaturing
665 local kerning = direct . kerning
666
667
668
669 function node . hyphenating ( first , last )
670 if first then
671 local h , t = hyphenating ( todirect ( first ) , last and todirect ( last ) or nil )
672 return h and tonode ( h ) or nil , t and tonode ( t ) or nil , true
673 else
674 return nil , false
675 end
676 end
677
678 function node . ligaturing ( first , last )
679 if first then
680 local h , t = ligaturing ( todirect ( first ) , last and todirect ( last ) or nil )
681 return h and tonode ( h ) or nil , t and tonode ( t ) or nil , true
682 else
683 return nil , false
684 end
685 end
686
687 function node . kerning ( first , last )
688 if first then
689 local h , t = kerning ( todirect ( first ) , last and todirect ( last ) or nil )
690 return h and tonode ( h ) or nil , t and tonode ( t ) or nil , true
691 else
692 return nil , false
693 end
694 end
695
696 local protect_glyph = direct . protect_glyph
697 local unprotect_glyph = direct . unprotect_glyph
698 local protect_glyphs = direct . protect_glyphs
699 local unprotect_glyphs = direct . unprotect_glyphs
700
701 function node . protect_glyphs ( first , last )
702 protect_glyphs ( todirect ( first ) , last and todirect ( last ) or nil )
703 end
704
705 function node . unprotect_glyphs ( first , last )
706 unprotect_glyphs ( todirect ( first ) , last and todirect ( last ) or nil )
707 end
708
709 function node . protect_glyph ( first )
710 protect_glyph ( todirect ( first ) )
711 end
712
713 function node . unprotect_glyph ( first )
714 unprotect_glyph ( todirect ( first ) )
715 end
716
717 local flatten_discretionaries = direct . flatten_discretionaries
718 local check_discretionaries = direct . check_discretionaries
719 local check_discretionary = direct . check_discretionary
720
721 function node . flatten_discretionaries ( first )
722 local h , count = flatten_discretionaries ( todirect ( first ) )
723 return tonode ( h ) , count
724 end
725
726 function node . check_discretionaries ( n )
727 check_discretionaries ( todirect ( n ) )
728 end
729
730 function node . check_discretionary ( n )
731 check_discretionary ( todirect ( n ) )
732 end
733
734 local hpack = direct . hpack
735 local vpack = direct . vpack
736 local list_to_hlist = direct . mlist_to_hlist
737
738 function node . hpack ( head , ... )
739 local h , badness = hpack ( head and todirect ( head ) or nil , ... )
740 return tonode ( h ) , badness
741 end
742
743 function node . vpack ( head , ... )
744 local h , badness = vpack ( head and todirect ( head ) or nil , ... )
745 return tonode ( h ) , badness
746 end
747
748 function node . mlist_to_hlist ( head , ... )
749 return tonode ( mlist_to_hlist ( head and todirect ( head ) or nil , ... ) )
750 end
751
752 local end_of_math = direct . end_of_math
753 local find_attribute = direct . find_attribute
754 local first_glyph = direct . first_glyph
755
756 function node . end_of_math ( n )
757 if n then
758 n = end_of_math ( todirect ( n ) )
759 if n then
760 return tonode ( n )
761 end
762 end
763 return nil
764 end
765
766 function node . find_attribute ( n , a )
767 if n then
768 local v , n = find_attribute ( todirect ( n ) , a )
769 if n then
770 return v , tonode ( n )
771 end
772 end
773 return nil
774 end
775
776 function node . first_glyph ( first , last )
777 local n = first_glyph ( todirect ( first ) , last and todirect ( last ) or nil )
778 return n and tonode ( n ) or nil
779 end
780
781 local dimensions = direct . dimensions
782 local rangedimensions = direct . rangedimensions
783 local effective_glue = direct . effective_glue
784
785 function node . dimensions ( a , b , c , d , e )
786 if type ( a ) = = " userdata " then
787 a = todirect ( a )
788 if type ( b ) = = " userdata " then
789 b = todirect ( b )
790 end
791 return dimensions ( a , b )
792 else
793 d = todirect ( d )
794 if type ( e ) = = " userdata " then
795 e = todirect ( e )
796 end
797 return dimensions ( a , b , c , d , e )
798 end
799 return 0 , 0 , 0
800 end
801
802 function node . rangedimensions ( parent , first , last )
803 return rangedimenensions ( todirect ( parent ) , todirect ( first ) , last and todirect ( last ) )
804 end
805
806 function node . effective_glue ( list , parent )
807 return effective_glue ( list and todirect ( list ) or nil , parent and todirect ( parent ) or nil )
808 end
809
810 local uses_font = direct . uses_font
811 local has_glyph = direct . has_glyph
812 local protrusion_skippable = direct . protrusion_skippable
813 local prepend_prevdepth = direct . prepend_prevdepth
814 local make_extensible = direct . make_extensible
815
816 function node . uses_font ( n , f )
817 return uses_font ( todirect ( n ) , f )
818 end
819
820 function node . has_glyph ( n )
821 return has_glyph ( todirect ( n ) )
822 end
823
824 function node . protrusion_skippable ( n )
825 return protrusion_skippable ( todirect ( n ) )
826 end
827
828 function node . prepend_prevdepth ( n )
829 local n , d = prepend_prevdepth ( todirect ( n ) )
830 return tonode ( n ) , d
831 end
832
833 function node . make_extensible ( ... )
834 local n = make_extensible ( ... )
835 return n and tonode ( n ) or nil
836 end
837
838 local last_node = direct . last_node
839
840 function node . last_node ( )
841 local n = last_node ( )
842 return n and tonode ( n ) or nil
843 end
844
845 local is_zero_glue = direct . is_zero_glue
846 local getglue = direct . getglue
847 local setglue = direct . setglue
848
849 function node . is_zero_glue ( n )
850 return is_zero_glue ( todirect ( n ) )
851 end
852
853 function node . get_glue ( n )
854 return get_glue ( todirect ( n ) )
855 end
856
857 function node . set_glue ( n )
858 return set_glue ( todirect ( n ) )
859 end
860
861end
862 |