node-aux.lua /size: 25 Kb    last modification: 2020-07-01 14:35
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
node-aux
'
]
=
{
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
-- todo: n1 .. n2 : __concat metatable
10 11
local
type
,
tostring
=
type
,
tostring
12 13
local
nodes
=
nodes
14
local
context
=
context
15 16
local
utfvalues
=
utf
.
values
17 18
local
nodecodes
=
nodes
.
nodecodes
19 20
local
glyph_code
=
nodecodes
.
glyph
21
local
hlist_code
=
nodecodes
.
hlist
22
local
vlist_code
=
nodecodes
.
vlist
23
local
attributelist_code
=
nodecodes
.
attributelist
-- temporary
24
local
localpar_code
=
nodecodes
.
localpar
25
local
ligatureglyph_code
=
nodes
.
glyphcodes
.
ligature
26 27
local
nuts
=
nodes
.
nuts
28
local
tonut
=
nuts
.
tonut
29
local
tonode
=
nuts
.
tonode
30
local
vianuts
=
nuts
.
vianuts
31 32
local
getbox
=
nuts
.
getbox
33
local
getnext
=
nuts
.
getnext
34
local
getid
=
nuts
.
getid
35
local
getsubtype
=
nuts
.
getsubtype
36
local
getlist
=
nuts
.
getlist
37
local
getattr
=
nuts
.
getattr
38
local
getboth
=
nuts
.
getboth
39
local
getprev
=
nuts
.
getprev
40
local
getwidth
=
nuts
.
getwidth
41
local
setwidth
=
nuts
.
setwidth
42
local
getboxglue
=
nuts
.
getboxglue
43
local
setboxglue
=
nuts
.
setboxglue
44 45
local
setfield
=
nuts
.
setfield
46
local
setattr
=
nuts
.
setattr
47
local
setlink
=
nuts
.
setlink
48
local
setlist
=
nuts
.
setlist
49
local
setnext
=
nuts
.
setnext
50
local
setprev
=
nuts
.
setprev
51
local
setcomponents
=
nuts
.
setcomponents
52
local
setattrlist
=
nuts
.
setattrlist
53 54
local
traversers
=
nuts
.
traversers
55
local
nextnode
=
traversers
.
node
56
local
nextglyph
=
traversers
.
glyph
57 58
local
flush_node
=
nuts
.
flush
59
local
flush_list
=
nuts
.
flush_list
60
local
hpack_nodes
=
nuts
.
hpack
61
local
unset_attribute
=
nuts
.
unset_attribute
62
local
first_glyph
=
nuts
.
first_glyph
63
local
copy_node
=
nuts
.
copy
64
local
find_tail
=
nuts
.
tail
65
local
getbox
=
nuts
.
getbox
66
local
count
=
nuts
.
count
67
local
isglyph
=
nuts
.
isglyph
68 69
local
nodepool
=
nuts
.
pool
70
local
new_glue
=
nodepool
.
glue
71
local
new_glyph
=
nodepool
.
glyph
72 73
local
unsetvalue
=
attributes
.
unsetvalue
74 75
local
current_font
=
font
.
current
76 77
local
texsetbox
=
tex
.
setbox
78 79
local
report_error
=
logs
.
reporter
(
"
node-aux:error
"
)
80 81
-- At some point we figured that copying before using was the safest bet
82
-- when dealing with boxes at the tex end. This is because tex also needs
83
-- to manage the grouping (i.e. savestack). However, there is an easy
84
-- solution that keeps the tex end happy as tex.setbox deals with this. The
85
-- overhead of one temporary list node is neglectable.
86
--
87
-- function tex.takebox(id)
88
-- local box = tex.getbox(id)
89
-- if box then
90
-- local copy = node.copy(box)
91
-- local list = box.list
92
-- copy.list = list
93
-- box.list = nil
94
-- tex.setbox(id,nil)
95
-- return copy
96
-- end
97
-- end
98 99
local
function
takebox
(
id
)
100
local
box
=
getbox
(
id
)
101
if
box
then
102
local
list
=
getlist
(
box
)
103
setlist
(
box
,
nil
)
104
local
copy
=
copy_node
(
box
)
105
if
list
then
106
setlist
(
copy
,
list
)
107
end
108
texsetbox
(
id
,
false
)
109
return
copy
110
end
111
end
112 113
function
nodes
.
takebox
(
id
)
114
local
b
=
takebox
(
id
)
115
if
b
then
116
return
tonode
(
b
)
117
end
118
end
119 120
local
splitbox
=
tex
.
splitbox
121
nodes
.
splitbox
=
splitbox
122 123
function
nuts
.
splitbox
(
id
,
height
)
124
return
tonut
(
splitbox
(
id
,
height
)
)
125
end
126 127
-- function nodes.takelist(n)
128
-- -- when we need it
129
-- end
130 131
function
nuts
.
takelist
(
n
)
132
local
l
=
getlist
(
n
)
133
setlist
(
n
)
134
flush_node
(
n
)
135
return
l
136
end
137 138
nuts
.
takebox
=
takebox
139
tex
.
takebox
=
nodes
.
takebox
-- sometimes more clear
140 141
-- so far
142 143
local
function
repackhlist
(
list
,
...
)
144
local
temp
,
b
=
hpack_nodes
(
list
,
...
)
145
list
=
getlist
(
temp
)
146
setlist
(
temp
)
147
flush_node
(
temp
)
148
return
list
,
b
149
end
150 151
nuts
.
repackhlist
=
repackhlist
152 153
function
nodes
.
repackhlist
(
list
,
...
)
154
local
list
,
b
=
repackhlist
(
tonut
(
list
)
,
...
)
155
return
tonode
(
list
)
,
b
156
end
157 158
local
function
set_attributes
(
head
,
attr
,
value
)
159
for
n
,
id
in
nextnode
,
head
do
160
setattr
(
n
,
attr
,
value
)
161
if
id
=
=
hlist_node
or
id
=
=
vlist_node
then
162
set_attributes
(
getlist
(
n
)
,
attr
,
value
)
163
end
164
end
165
end
166 167
local
function
set_unset_attributes
(
head
,
attr
,
value
)
168
for
n
,
id
in
nextnode
,
head
do
169
if
not
getattr
(
n
,
attr
)
then
170
setattr
(
n
,
attr
,
value
)
171
end
172
if
id
=
=
hlist_code
or
id
=
=
vlist_code
then
173
set_unset_attributes
(
getlist
(
n
)
,
attr
,
value
)
174
end
175
end
176
end
177 178
local
function
unset_attributes
(
head
,
attr
)
179
for
n
,
id
in
nextnode
,
head
do
180
setattr
(
n
,
attr
,
unsetvalue
)
181
if
id
=
=
hlist_code
or
id
=
=
vlist_code
then
182
unset_attributes
(
getlist
(
n
)
,
attr
)
183
end
184
end
185
end
186 187
-- for old times sake
188 189
nuts
.
setattribute
=
nuts
.
setattr
nodes
.
setattribute
=
nodes
.
setattr
190
nuts
.
getattribute
=
nuts
.
getattr
nodes
.
getattribute
=
nodes
.
getattr
191
nuts
.
unsetattribute
=
nuts
.
unset_attribute
nodes
.
unsetattribute
=
nodes
.
unset_attribute
192
nuts
.
has_attribute
=
nuts
.
has_attribute
nodes
.
has_attribute
=
nodes
.
has_attribute
193
nuts
.
firstglyph
=
nuts
.
first_glyph
nodes
.
firstglyph
=
nodes
.
first_glyph
194 195
nuts
.
setattributes
=
set_attributes
nodes
.
setattributes
=
vianuts
(
set_attributes
)
196
nuts
.
setunsetattributes
=
set_unset_attributes
nodes
.
setunsetattributes
=
vianuts
(
set_unset_attributes
)
197
nuts
.
unsetattributes
=
unset_attributes
nodes
.
unsetattributes
=
vianuts
(
unset_attributes
)
198 199
function
nuts
.
firstcharacter
(
n
,
untagged
)
-- tagged == subtype > 255
200
if
untagged
then
201
return
first_glyph
(
n
)
202
else
203
for
g
in
nextglyph
,
n
do
204
return
g
205
end
206
end
207
end
208 209
local
function
firstcharinbox
(
n
)
210
local
l
=
getlist
(
getbox
(
n
)
)
211
if
l
then
212
for
g
,
c
in
nextglyph
,
l
do
213
return
c
214
end
215
end
216
return
0
217
end
218 219
nuts
.
firstcharinbox
=
firstcharinbox
220
nodes
.
firstcharinbox
=
firstcharinbox
-- hm, ok ?
221
nodes
.
firstcharacter
=
vianuts
(
firstcharacter
)
222 223
interfaces
.
implement
{
224
name
=
"
buildtextaccent
"
,
225
arguments
=
"
integer
"
,
226
actions
=
function
(
n
)
-- Is this crap really used? Or was it an experiment?
227
local
char
=
firstcharinbox
(
n
)
228
if
char
>
0
then
229
-- context.accent(false,char)
230
context
(
[[
\accent%s\relax
]]
,
char
)
231
end
232
end
233
}
234 235
-- this depends on fonts, so we have a funny dependency ... will be
236
-- sorted out .. we could make tonodes a plugin into this
237 238
local
function
tonodes
(
str
,
fnt
,
attr
)
-- (str,template_glyph) -- moved from blob-ini
239
if
not
str
or
str
=
=
"
"
then
240
return
241
end
242
local
head
,
tail
,
space
,
fnt
,
template
=
nil
,
nil
,
nil
,
nil
,
nil
243
if
not
fnt
then
244
fnt
=
current_font
(
)
245
elseif
type
(
fnt
)
~
=
"
number
"
and
getid
(
fnt
)
=
=
glyph_code
then
-- so it has to be a real node
246
fnt
,
template
=
nil
,
tonut
(
fnt
)
247
end
248
for
s
in
utfvalues
(
str
)
do
249
local
n
250
if
s
=
=
32
then
251
if
space
then
252
n
=
copy_node
(
space
)
253
elseif
fonts
then
-- depedency
254
local
parameters
=
fonts
.
hashes
.
identifiers
[
fnt
]
.
parameters
255
space
=
new_glue
(
parameters
.
space
,
parameters
.
space_stretch
,
parameters
.
space_shrink
)
256
n
=
space
257
end
258
elseif
template
then
259
n
=
copy_node
(
template
)
260
setvalue
(
n
,
"
char
"
,
s
)
261
else
262
n
=
new_glyph
(
fnt
,
s
)
263
end
264
if
attr
then
-- normally false when template
265
setattrlist
(
n
,
attr
)
266
end
267
if
head
then
268
setlink
(
tail
,
n
)
269
else
270
head
=
n
271
end
272
tail
=
n
273
end
274
return
head
,
tail
275
end
276 277
nuts
.
tonodes
=
tonodes
278 279
nodes
.
tonodes
=
function
(
str
,
fnt
,
attr
)
280
local
head
,
tail
=
tonodes
(
str
,
fnt
,
attr
)
281
return
tonode
(
head
)
,
tonode
(
tail
)
282
end
283 284
local
function
link
(
list
,
currentfont
,
currentattr
,
head
,
tail
)
-- an oldie, might be replaced
285
for
i
=
1
,
#
list
do
286
local
n
=
list
[
i
]
287
if
n
then
288
local
tn
=
type
(
n
)
289
if
tn
=
=
"
string
"
then
290
if
#
tn
>
0
then
291
if
not
currentfont
then
292
currentfont
=
current_font
(
)
293
end
294
local
h
,
t
=
tonodes
(
n
,
currentfont
,
currentattr
)
295
if
not
h
then
296
-- skip
297
elseif
not
head
then
298
head
,
tail
=
h
,
t
299
else
300
setnext
(
tail
,
h
)
301
setprev
(
h
,
t
)
302
tail
=
t
303
end
304
end
305
elseif
tn
=
=
"
table
"
then
306
if
#
tn
>
0
then
307
if
not
currentfont
then
308
currentfont
=
current_font
(
)
309
end
310
head
,
tail
=
link
(
n
,
currentfont
,
currentattr
,
head
,
tail
)
311
end
312
elseif
not
head
then
313
head
=
n
314
tail
=
find_tail
(
n
)
315
elseif
getid
(
n
)
=
=
attributelist_code
then
316
-- weird case
317
report_error
(
"
weird node type in list at index %s:
"
,
i
)
318
for
i
=
1
,
#
list
do
319
local
l
=
list
[
i
]
320
report_error
(
"
%3i: %s %S
"
,
i
,
getid
(
l
)
=
=
attributelist_code
and
"
!
"
or
"
>
"
,
l
)
321
end
322
os
.
exit
(
)
323
else
324
setlink
(
tail
,
n
)
325
if
getnext
(
n
)
then
326
tail
=
find_tail
(
n
)
327
else
328
tail
=
n
329
end
330
end
331
else
332
-- permitting nil is convenient
333
end
334
end
335
return
head
,
tail
336
end
337 338
nuts
.
link
=
link
339 340
nodes
.
link
=
function
(
list
,
currentfont
,
currentattr
,
head
,
tail
)
341
local
head
,
tail
=
link
(
list
,
currentfont
,
currentattr
,
tonut
(
head
)
,
tonut
(
tail
)
)
342
return
tonode
(
head
)
,
tonode
(
tail
)
343
end
344 345
local
function
locate
(
start
,
wantedid
,
wantedsubtype
)
346
for
n
,
id
,
subtype
in
nextnode
,
start
do
347
if
id
=
=
wantedid
then
348
if
not
wantedsubtype
or
subtype
=
=
wantedsubtype
then
349
return
n
350
end
351
elseif
id
=
=
hlist_code
or
id
=
=
vlist_code
then
352
local
found
=
locate
(
getlist
(
n
)
,
wantedid
,
wantedsubtype
)
353
if
found
then
354
return
found
355
end
356
end
357
end
358
end
359 360
nuts
.
locate
=
locate
361 362
function
nodes
.
locate
(
start
,
wantedid
,
wantedsubtype
)
363
local
found
=
locate
(
tonut
(
start
)
,
wantedid
,
wantedsubtype
)
364
return
found
and
tonode
(
found
)
365
end
366 367
local
function
rehpack
(
n
,
width
)
368
local
head
=
getlist
(
n
)
369
local
size
=
width
or
getwidth
(
n
)
370
local
temp
=
hpack_nodes
(
head
,
size
,
"
exactly
"
)
371
setwidth
(
n
,
size
)
372
local
set
,
order
,
sign
=
getboxglue
(
temp
)
373
setboxglue
(
n
,
set
,
order
,
sign
)
374
setlist
(
temp
)
375
flush_node
(
temp
)
376
return
n
377
end
378 379
nuts
.
rehpack
=
rehpack
380 381
function
nodes
.
rehpack
(
n
,
...
)
382
rehpack
(
tonut
(
n
)
,
...
)
383
end
384 385
if
CONTEXTLMTXMODE
>
0
then
386 387
local
fastcopy
=
table
.
fastcopy
388
local
getprop
=
nuts
.
getprop
389
local
setprop
=
nuts
.
setprop
390 391
local
function
set_components
(
base
,
list
)
392
local
t
=
{
}
393
local
n
=
0
394
while
list
do
395
local
char
=
isglyph
(
list
)
396
if
char
then
397
n
=
n
+
1
398
t
[
n
]
=
char
399
end
400
list
=
getnext
(
list
)
401
end
402
setprop
(
base
,
"
components
"
,
n
>
0
and
t
or
false
)
403
end
404 405
local
function
get_components
(
base
)
406
return
getprop
(
base
,
"
components
"
)
407
end
408 409
local
function
copy_no_components
(
base
)
410
local
copy
=
copy_node
(
base
)
411
setprop
(
copy
,
"
components
"
,
false
)
-- no metatable lookup!
412
return
copy
413
end
414 415
local
function
copy_only_glyphs
(
base
)
416
local
t
=
getprop
(
base
,
"
components
"
)
-- also metatable
417
if
t
then
418
return
fastcopy
(
t
)
419
end
420
end
421 422
local
function
do_count
(
t
,
marks
)
423
local
n
=
0
424
if
t
then
425
for
i
=
1
,
#
t
do
426
local
c
=
t
[
i
]
427
if
type
(
c
)
=
=
"
table
"
then
428
n
=
n
+
do_count
(
t
,
marks
)
429
elseif
not
marks
[
c
]
then
430
n
=
n
+
1
431
else
432
--marks don't count
433
end
434
end
435
end
436
return
n
437
end
438 439
-- start is a mark and we need to keep that one
440 441
local
done
=
false
442 443
local
function
count_components
(
base
,
marks
)
444
local
char
=
isglyph
(
base
)
445
if
char
then
446
if
getsubtype
(
base
)
=
=
ligatureglyph_code
then
447
if
not
done
then
448
logs
.
report
(
"
fonts
"
,
"
!
"
)
449
logs
.
report
(
"
fonts
"
,
"
! check count_components with mkiv !
"
)
450
logs
.
report
(
"
fonts
"
,
"
!
"
)
451
done
=
true
452
end
453
local
t
=
getprop
(
base
,
"
components
"
)
454
if
t
then
455
return
do_count
(
t
,
marks
)
456
end
457
elseif
not
marks
[
char
]
then
458
return
1
459
end
460
end
461
return
0
462
end
463 464
nuts
.
set_components
=
set_components
465
nuts
.
get_components
=
get_components
466
nuts
.
copy_only_glyphs
=
copy_only_glyphs
467
nuts
.
copy_no_components
=
copy_no_components
468
nuts
.
count_components
=
count_components
469 470
else
471 472
local
get_components
=
node
.
direct
.
getcomponents
473
local
set_components
=
node
.
direct
.
setcomponents
474 475
local
function
copy_no_components
(
g
,
copyinjection
)
476
local
components
=
get_components
(
g
)
477
if
components
then
478
set_components
(
g
)
479
local
n
=
copy_node
(
g
)
480
if
copyinjection
then
481
copyinjection
(
n
,
g
)
482
end
483
set_components
(
g
,
components
)
484
-- maybe also upgrade the subtype but we don't use it anyway
485
return
n
486
else
487
local
n
=
copy_node
(
g
)
488
if
copyinjection
then
489
copyinjection
(
n
,
g
)
490
end
491
return
n
492
end
493
end
494 495
local
function
copy_only_glyphs
(
current
)
496
local
head
=
nil
497
local
previous
=
nil
498
for
n
in
nextglyph
,
current
do
499
n
=
copy_node
(
n
)
500
if
head
then
501
setlink
(
previous
,
n
)
502
else
503
head
=
n
504
end
505
previous
=
n
506
end
507
return
head
508
end
509 510
-- start is a mark and we need to keep that one
511 512
local
function
count_components
(
start
,
marks
)
513
local
char
=
isglyph
(
start
)
514
if
char
then
515
if
getsubtype
(
start
)
=
=
ligatureglyph_code
then
516
local
n
=
0
517
local
components
=
get_components
(
start
)
518
while
components
do
519
n
=
n
+
count_components
(
components
,
marks
)
520
components
=
getnext
(
components
)
521
end
522
return
n
523
elseif
not
marks
[
char
]
then
524
return
1
525
end
526
end
527
return
0
528
end
529 530
nuts
.
set_components
=
set_components
531
nuts
.
get_components
=
get_components
532
nuts
.
copy_only_glyphs
=
copy_only_glyphs
533
nuts
.
copy_no_components
=
copy_no_components
534
nuts
.
count_components
=
count_components
535 536
end
537 538
nuts
.
setcomponents
=
function
(
)
report_error
(
"
unsupported: %a
"
,
"
setcomponents
"
)
end
539
nuts
.
getcomponents
=
function
(
)
report_error
(
"
unsupported: %a
"
,
"
getcomponents
"
)
end
540 541
do
542 543
local
localparcodes
=
nodes
.
localparcodes
544
local
hmodepar_code
=
localparcodes
.
vmode_par
545
local
vmodepar_code
=
localparcodes
.
hmode_par
546 547
local
getnest
=
tex
.
getnest
548
local
getsubtype
=
nuts
.
getsubtype
549 550
function
nuts
.
setparproperty
(
action
,
...
)
551
local
tail
=
tonut
(
getnest
(
)
.
tail
)
552
while
tail
do
553
if
getid
(
tail
)
=
=
localpar_code
then
554
local
s
=
getsubtype
(
tail
)
555
if
s
=
=
hmodepar_code
or
s
=
=
vmodepar_code
then
556
return
action
(
tail
,
...
)
557
else
558
-- something is wrong here
559
end
560
end
561
tail
=
getprev
(
tail
)
562
end
563
end
564 565
local
getsubtype
=
nodes
.
getsubtype
566 567
function
nodes
.
start_of_par
(
n
)
568
local
s
=
getsubtype
(
n
)
569
return
s
=
=
hmodepar_code
or
s
=
=
vmodepar_code
570
end
571 572
end
573 574
-- Currently only in luametatex ... experimental anyway .. if it doesn't end
575
-- up in luatex I'll move this to a different module.
576 577
do
578 579
local
nextnode
=
traversers
.
glue
580
local
findfail
=
nuts
.
tail
581 582
local
getid
=
nuts
.
getid
583
local
getsubtype
=
nuts
.
getsubtype
584
local
getlist
=
nuts
.
getlist
585
local
getwidth
=
nuts
.
getwidth
586 587
local
direct
=
node
.
direct
588 589
local
nodecodes
=
nodes
.
nodecodes
590
local
skipcodes
=
nodes
.
skipcodes
591 592
local
hlist_code
=
nodecodes
.
hlist
593
local
line_code
=
nodecodes
.
line
594 595
local
leftskip_code
=
skipcodes
.
leftskip
596
local
rightskip_code
=
skipcodes
.
rightskip
597
local
lefthangskip_code
=
skipcodes
.
lefthangskip
598
local
righthangskip_code
=
skipcodes
.
righthangskip
599
local
indentskip_code
=
skipcodes
.
indentskip
600
local
parfillskip_code
=
skipcodes
.
parfillskip
601 602
local
find_node
=
direct
.
find_node
or
function
(
h
,
t
,
s
)
603
if
h
then
604
if
s
then
605
for
node
,
subtype
in
traversers
[
t
]
do
606
if
s
=
=
subtype
then
607
return
current
608
end
609
end
610
else
611
for
node
,
subtype
in
traversers
[
t
]
do
612
return
current
,
subtype
613
end
614
end
615
end
616
end
617 618
nuts
.
find_node
=
find_node
619 620
nodes
.
getnormalizeline
=
node
.
getnormalizeline
or
function
(
)
return
0
end
621
nodes
.
setnormalizeline
=
node
.
setnormalizeline
or
function
(
)
end
622 623
nuts
.
getnormalizedline
=
direct
.
getnormalizedline
or
function
(
h
)
624
if
getid
(
h
)
=
=
hlist_code
and
getsubtype
(
h
)
=
=
line_code
then
625
local
ls
,
rs
=
0
,
0
626
local
lh
,
rh
=
0
,
0
627
local
is
,
ps
=
0
,
0
628
local
h
=
getlist
(
h
)
629
local
t
=
findtail
(
h
)
630
for
n
,
subtype
in
nextglue
,
h
do
631
if
subtype
=
=
leftskip_code
then
ls
=
getwidth
(
n
)
632
elseif
subtype
=
=
rightskip_code
then
rs
=
getwidth
(
n
)
633
elseif
subtype
=
=
lefthangskip_code
then
lh
=
getwidth
(
n
)
634
elseif
subtype
=
=
righthangskip_code
then
rh
=
getwidth
(
n
)
635
elseif
subtype
=
=
indentskip_code
then
is
=
getwidth
(
n
)
636
elseif
subtype
=
=
parfillskip_code
then
ps
=
getwidth
(
n
)
637
end
638
end
639
return
ls
,
rs
,
lh
,
rh
,
is
,
ps
,
h
,
t
640
end
641
end
642 643
end
644 645
if
not
nodes
.
count
then
646 647
local
type
=
type
648 649
local
direct
=
node
.
direct
650
local
todirect
=
direct
.
tovaliddirect
651
local
tonode
=
direct
.
tonode
652 653
local
count
=
direct
.
count
654
local
length
=
direct
.
length
655
local
slide
=
direct
.
slide
656 657
function
node
.
count
(
id
,
first
,
last
)
658
return
count
(
id
,
first
and
todirect
(
first
)
,
last
and
todirect
(
last
)
or
nil
)
659
end
660 661
function
node
.
length
(
first
,
last
)
662
return
length
(
first
and
todirect
(
first
)
,
last
and
todirect
(
last
)
or
nil
)
663
end
664 665
function
node
.
slide
(
n
)
666
if
n
then
667
n
=
slide
(
todirect
(
n
)
)
668
if
n
then
669
return
tonode
(
n
)
670
end
671
end
672
return
nil
673
end
674 675
local
hyphenating
=
direct
.
hyphenating
676
local
ligaturing
=
direct
.
ligaturing
677
local
kerning
=
direct
.
kerning
678 679
-- kind of inconsistent
680 681
function
node
.
hyphenating
(
first
,
last
)
682
if
first
then
683
local
h
,
t
=
hyphenating
(
todirect
(
first
)
,
last
and
todirect
(
last
)
or
nil
)
684
return
h
and
tonode
(
h
)
or
nil
,
t
and
tonode
(
t
)
or
nil
,
true
685
else
686
return
nil
,
false
687
end
688
end
689 690
function
node
.
ligaturing
(
first
,
last
)
691
if
first
then
692
local
h
,
t
=
ligaturing
(
todirect
(
first
)
,
last
and
todirect
(
last
)
or
nil
)
693
return
h
and
tonode
(
h
)
or
nil
,
t
and
tonode
(
t
)
or
nil
,
true
694
else
695
return
nil
,
false
696
end
697
end
698 699
function
node
.
kerning
(
first
,
last
)
700
if
first
then
701
local
h
,
t
=
kerning
(
todirect
(
first
)
,
last
and
todirect
(
last
)
or
nil
)
702
return
h
and
tonode
(
h
)
or
nil
,
t
and
tonode
(
t
)
or
nil
,
true
703
else
704
return
nil
,
false
705
end
706
end
707 708
local
protect_glyph
=
direct
.
protect_glyph
709
local
unprotect_glyph
=
direct
.
unprotect_glyph
710
local
protect_glyphs
=
direct
.
protect_glyphs
711
local
unprotect_glyphs
=
direct
.
unprotect_glyphs
712 713
function
node
.
protect_glyphs
(
first
,
last
)
714
protect_glyphs
(
todirect
(
first
)
,
last
and
todirect
(
last
)
or
nil
)
715
end
716 717
function
node
.
unprotect_glyphs
(
first
,
last
)
718
unprotect_glyphs
(
todirect
(
first
)
,
last
and
todirect
(
last
)
or
nil
)
719
end
720 721
function
node
.
protect_glyph
(
first
)
722
protect_glyph
(
todirect
(
first
)
)
723
end
724 725
function
node
.
unprotect_glyph
(
first
)
726
unprotect_glyph
(
todirect
(
first
)
)
727
end
728 729
local
flatten_discretionaries
=
direct
.
flatten_discretionaries
730
local
check_discretionaries
=
direct
.
check_discretionaries
731
local
check_discretionary
=
direct
.
check_discretionary
732 733
function
node
.
flatten_discretionaries
(
first
)
734
local
h
,
count
=
flatten_discretionaries
(
todirect
(
first
)
)
735
return
tonode
(
h
)
,
count
736
end
737 738
function
node
.
check_discretionaries
(
n
)
739
check_discretionaries
(
todirect
(
n
)
)
740
end
741 742
function
node
.
check_discretionary
(
n
)
743
check_discretionary
(
todirect
(
n
)
)
744
end
745 746
local
hpack
=
direct
.
hpack
747
local
vpack
=
direct
.
vpack
748
local
list_to_hlist
=
direct
.
mlist_to_hlist
749 750
function
node
.
hpack
(
head
,
...
)
751
local
h
,
badness
=
hpack
(
head
and
todirect
(
head
)
or
nil
,
...
)
752
return
tonode
(
h
)
,
badness
753
end
754 755
function
node
.
vpack
(
head
,
...
)
756
local
h
,
badness
=
vpack
(
head
and
todirect
(
head
)
or
nil
,
...
)
757
return
tonode
(
h
)
,
badness
758
end
759 760
function
node
.
mlist_to_hlist
(
head
,
...
)
761
return
tonode
(
mlist_to_hlist
(
head
and
todirect
(
head
)
or
nil
,
...
)
)
762
end
763 764
local
end_of_math
=
direct
.
end_of_math
765
local
find_attribute
=
direct
.
find_attribute
766
local
first_glyph
=
direct
.
first_glyph
767 768
function
node
.
end_of_math
(
n
)
769
if
n
then
770
n
=
end_of_math
(
todirect
(
n
)
)
771
if
n
then
772
return
tonode
(
n
)
773
end
774
end
775
return
nil
776
end
777 778
function
node
.
find_attribute
(
n
,
a
)
779
if
n
then
780
local
v
,
n
=
find_attribute
(
todirect
(
n
)
,
a
)
781
if
n
then
782
return
v
,
tonode
(
n
)
783
end
784
end
785
return
nil
786
end
787 788
function
node
.
first_glyph
(
first
,
last
)
789
local
n
=
first_glyph
(
todirect
(
first
)
,
last
and
todirect
(
last
)
or
nil
)
790
return
n
and
tonode
(
n
)
or
nil
791
end
792 793
local
dimensions
=
direct
.
dimensions
794
local
rangedimensions
=
direct
.
rangedimensions
795
local
effective_glue
=
direct
.
effective_glue
796 797
function
node
.
dimensions
(
a
,
b
,
c
,
d
,
e
)
798
if
type
(
a
)
=
=
"
userdata
"
then
799
a
=
todirect
(
a
)
800
if
type
(
b
)
=
=
"
userdata
"
then
801
b
=
todirect
(
b
)
802
end
803
return
dimensions
(
a
,
b
)
804
else
805
d
=
todirect
(
d
)
806
if
type
(
e
)
=
=
"
userdata
"
then
807
e
=
todirect
(
e
)
808
end
809
return
dimensions
(
a
,
b
,
c
,
d
,
e
)
810
end
811
return
0
,
0
,
0
812
end
813 814
function
node
.
rangedimensions
(
parent
,
first
,
last
)
815
return
rangedimenensions
(
todirect
(
parent
)
,
todirect
(
first
)
,
last
and
todirect
(
last
)
)
816
end
817 818
function
node
.
effective_glue
(
list
,
parent
)
819
return
effective_glue
(
list
and
todirect
(
list
)
or
nil
,
parent
and
todirect
(
parent
)
or
nil
)
820
end
821 822
local
uses_font
=
direct
.
uses_font
823
local
has_glyph
=
direct
.
has_glyph
824
local
protrusion_skippable
=
direct
.
protrusion_skippable
825
local
prepend_prevdepth
=
direct
.
prepend_prevdepth
826
local
make_extensible
=
direct
.
make_extensible
827 828
function
node
.
uses_font
(
n
,
f
)
829
return
uses_font
(
todirect
(
n
)
,
f
)
830
end
831 832
function
node
.
has_glyph
(
n
)
833
return
has_glyph
(
todirect
(
n
)
)
834
end
835 836
function
node
.
protrusion_skippable
(
n
)
837
return
protrusion_skippable
(
todirect
(
n
)
)
838
end
839 840
function
node
.
prepend_prevdepth
(
n
)
841
local
n
,
d
=
prepend_prevdepth
(
todirect
(
n
)
)
842
return
tonode
(
n
)
,
d
843
end
844 845
function
node
.
make_extensible
(
...
)
846
local
n
=
make_extensible
(
...
)
847
return
n
and
tonode
(
n
)
or
nil
848
end
849 850
local
last_node
=
direct
.
last_node
851 852
function
node
.
last_node
(
)
853
local
n
=
last_node
(
)
854
return
n
and
tonode
(
n
)
or
nil
855
end
856 857
local
is_zero_glue
=
direct
.
is_zero_glue
858
local
getglue
=
direct
.
getglue
859
local
setglue
=
direct
.
setglue
860 861
function
node
.
is_zero_glue
(
n
)
862
return
is_zero_glue
(
todirect
(
n
)
)
863
end
864 865
function
node
.
get_glue
(
n
)
866
return
get_glue
(
todirect
(
n
)
)
867
end
868 869
function
node
.
set_glue
(
n
)
870
return
set_glue
(
todirect
(
n
)
)
871
end
872 873
end
874