node-ser.lua /size: 8441 b    last modification: 2020-07-01 14:35
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
node-ser
'
]
=
{
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
-- beware, some field names will change in a next releases
10
-- of luatex; this is pretty old code that needs an overhaul
11 12
local
type
,
tostring
=
type
,
tostring
13
local
concat
,
tohash
,
sortedkeys
,
printtable
,
serialize
=
table
.
concat
,
table
.
tohash
,
table
.
sortedkeys
,
table
.
print
,
table
.
serialize
14
local
formatters
,
format
,
rep
=
string
.
formatters
,
string
.
format
,
string
.
rep
15 16
local
allocate
=
utilities
.
storage
.
allocate
17 18
local
context
=
context
19
local
nodes
=
nodes
20
local
node
=
node
21 22
local
traverse
=
nodes
.
traverse
23
local
is_node
=
nodes
.
is_node
24 25
local
nodecodes
=
nodes
.
nodecodes
26
local
subtcodes
=
nodes
.
codes
27
local
getfields
=
nodes
.
fields
28 29
local
tonode
=
nodes
.
tonode
30
local
tonut
=
nodes
.
tonut
31 32
local
hlist_code
=
nodecodes
.
hlist
33
local
vlist_code
=
nodecodes
.
vlist
34 35
----- utfchar = utf.char
36
local
f_char
=
formatters
[
"
%U
"
]
37
local
f_attr
=
formatters
[
"
<%i>
"
]
38
----- fontchars = { } table.setmetatableindex(fontchars,function(t,k) fontchars = fonts.hashes.characters return fontchars[k] end)
39 40
----- f_char = utilities.strings.chkuni -- formatters["%!chkuni!"]
41 42
-- this needs checking with the latest state of affairs:
43 44
local
expand
=
allocate
(
tohash
{
45
-- text:
46
"
list
"
,
-- list_ptr & ins_ptr & adjust_ptr
47
"
pre
"
,
--
48
"
post
"
,
--
49
"
replace
"
,
-- nobreak
50
"
top_skip
"
,
--
51
"
attr
"
,
--
52
"
components
"
,
-- lig_ptr
53
"
box_left
"
,
--
54
"
box_right
"
,
--
55
"
glyph
"
,
-- margin_char
56
"
leader
"
,
-- leader_ptr
57
"
action
"
,
-- action_ptr
58
"
value
"
,
-- user_defined nodes with subtype 'a' en 'n'
59
"
head
"
,
60
-- math:
61
"
nucleus
"
,
62
"
sup
"
,
63
"
sub
"
,
64
"
list
"
,
65
"
num
"
,
66
"
denom
"
,
67
"
left
"
,
68
"
right
"
,
69
"
display
"
,
70
"
text
"
,
71
"
script
"
,
72
"
scriptscript
"
,
73
"
delim
"
,
74
"
degree
"
,
75
"
accent
"
,
76
"
bot_accent
"
,
77
}
)
78 79
-- page_insert: "height", "last_ins_ptr", "best_ins_ptr"
80
-- split_insert: "height", "last_ins_ptr", "best_ins_ptr", "broken_ptr", "broken_ins"
81 82
local
ignore
=
allocate
(
tohash
{
83
"
page_insert
"
,
84
"
split_insert
"
,
85
"
ref_count
"
,
86
}
)
87 88
local
dimension
=
allocate
(
tohash
{
89
"
width
"
,
"
height
"
,
"
depth
"
,
"
shift
"
,
90
"
stretch
"
,
"
shrink
"
,
91
"
xoffset
"
,
"
yoffset
"
,
92
"
surround
"
,
93
"
kern
"
,
94
"
box_left_width
"
,
"
box_right_width
"
95
}
)
96 97
-- flat : don't use next, but indexes
98
-- verbose : also add type
99
-- todo : speed up
100 101
nodes
.
dimensionfields
=
dimension
102
nodes
.
listablefields
=
expand
103
nodes
.
ignorablefields
=
ignore
104 105
-- not ok yet:
106 107
local
function
astable
(
n
,
sparse
)
-- not yet ok, might get obsolete anyway
108
n
=
tonode
(
n
)
109
local
f
=
getfields
(
n
)
110
local
t
=
{
}
111
for
i
=
1
,
#
f
do
112
local
v
=
f
[
i
]
113
local
d
=
n
[
v
]
114
if
d
then
115
if
ignore
[
v
]
or
v
=
=
"
id
"
then
116
-- skip
117
elseif
expand
[
v
]
then
-- or: type(n[v]) ~= "string" or type(n[v]) ~= "number" or type(n[v]) ~= "table"
118
t
[
v
]
=
"
<list>
"
119
elseif
sparse
then
120
if
(
type
(
d
)
=
=
"
number
"
and
d
~
=
0
)
or
(
type
(
d
)
=
=
"
string
"
and
d
~
=
"
"
)
then
121
t
[
v
]
=
d
122
end
123
else
124
t
[
v
]
=
d
125
end
126
end
127
end
128
t
.
type
=
nodecodes
[
n
.
id
]
129
return
t
130
end
131 132
nodes
.
astable
=
astable
133 134
setinspector
(
"
node
"
,
function
(
v
)
if
is_node
(
v
)
then
printtable
(
astable
(
v
)
,
tostring
(
v
)
)
return
true
end
end
)
135 136
-- under construction:
137 138
local
function
totable
(
n
,
flat
,
verbose
,
noattributes
)
-- nicest: n,true,true,true
139
local
function
to_table
(
n
,
flat
,
verbose
,
noattributes
)
-- no need to pass
140
local
f
=
getfields
(
n
)
141
local
tt
=
{
}
142
for
k
=
1
,
#
f
do
143
local
v
=
f
[
k
]
144
local
nv
=
v
and
n
[
v
]
145
if
nv
then
146
if
ignore
[
v
]
then
147
-- skip
148
elseif
noattributes
and
v
=
=
"
attr
"
then
149
tt
[
v
]
=
f_attr
(
tonut
(
nv
)
)
150
-- skip
151
elseif
v
=
=
"
prev
"
then
152
tt
[
v
]
=
"
<node>
"
153
elseif
expand
[
v
]
then
154
if
type
(
nv
)
=
=
"
number
"
or
type
(
nv
)
=
=
"
string
"
then
155
tt
[
v
]
=
nv
156
else
157
tt
[
v
]
=
totable
(
nv
,
flat
,
verbose
,
noattributes
)
158
end
159
elseif
type
(
nv
)
=
=
"
table
"
then
160
tt
[
v
]
=
nv
-- totable(nv,flat,verbose) -- data
161
else
162
tt
[
v
]
=
nv
163
end
164
end
165
end
166
if
verbose
then
167
local
subtype
=
tt
.
subtype
168
local
id
=
tt
.
id
169
local
nodename
=
nodecodes
[
id
]
170
tt
.
id
=
nodename
171
local
subtypes
=
subtcodes
[
nodename
]
172
if
subtypes
then
173
tt
.
subtype
=
subtypes
[
subtype
]
174
elseif
subtype
=
=
0
then
175
tt
.
subtype
=
nil
176
else
177
-- we need a table
178
end
179
if
tt
.
char
then
180
tt
.
char
=
f_char
(
tt
.
char
)
181
end
182
if
tt
.
small_char
then
183
tt
.
small_char
=
f_char
(
tt
.
small_char
)
184
end
185
if
tt
.
large_char
then
186
tt
.
large_char
=
f_char
(
tt
.
large_char
)
187
end
188
end
189
return
tt
190
end
191
if
n
then
192
if
flat
then
193
local
t
,
tn
=
{
}
,
0
194
while
n
do
195
tn
=
tn
+
1
196
local
nt
=
to_table
(
n
,
flat
,
verbose
,
noattributes
)
197
t
[
tn
]
=
nt
198
nt
.
next
=
nil
199
nt
.
prev
=
nil
200
n
=
n
.
next
201
end
202
return
t
203
else
204
local
t
=
to_table
(
n
,
flat
,
verbose
,
noattributes
)
205
local
n
=
n
.
next
206
if
n
then
207
t
.
next
=
totable
(
n
,
flat
,
verbose
,
noattributes
)
208
end
209
return
t
210
end
211
else
212
return
{
}
213
end
214
end
215 216
nodes
.
totable
=
function
(
n
,
...
)
return
totable
(
tonode
(
n
)
,
...
)
end
217
nodes
.
totree
=
function
(
n
)
return
totable
(
tonode
(
n
)
,
true
,
true
,
true
)
end
-- no attributes, todo: attributes in k,v list
218 219
local
function
key
(
k
)
220
return
(
(
type
(
k
)
=
=
"
number
"
)
and
"
[
"
.
.
k
.
.
"
]
"
)
or
k
221
end
222 223
function
nodes
.
serialize
(
root
,
flat
,
verbose
,
noattributes
,
name
)
224
return
serialize
(
totable
(
tonode
(
root
)
,
flat
,
verbose
,
noattributes
)
,
name
)
225
end
226 227
function
nodes
.
serializebox
(
n
,
flat
,
verbose
,
noattributes
,
name
)
228
return
serialize
(
totable
(
tex
.
box
[
n
]
,
flat
,
verbose
,
noattributes
)
,
name
)
229
end
230 231
function
nodes
.
visualizebox
(
n
,
flat
,
verbose
,
noattributes
,
name
)
232
context
.
tocontext
(
totable
(
tex
.
box
[
n
]
,
flat
,
verbose
,
noattributes
)
,
name
)
233
end
234 235
function
nodes
.
list
(
head
,
n
)
-- name might change to nodes.type -- to be checked .. will move to module anyway
236
head
=
tonode
(
head
)
237
if
not
n
then
238
context
.
starttyping
(
true
)
239
end
240
while
head
do
241
local
id
=
head
.
id
242
context
(
rep
(
"
"
,
n
or
0
)
.
.
tostring
(
head
)
.
.
"
\n
"
)
243
if
id
=
=
hlist_code
or
id
=
=
vlist_code
then
244
nodes
.
list
(
head
.
list
,
(
n
or
0
)
+
1
)
245
end
246
head
=
head
.
next
247
end
248
if
not
n
then
249
context
.
stoptyping
(
true
)
250
end
251
end
252 253
function
nodes
.
print
(
head
,
n
)
254
head
=
tonode
(
head
)
255
while
head
do
256
local
id
=
head
.
id
257
logs
.
writer
(
string
.
formatters
[
"
%w%S
"
]
,
n
or
0
,
head
)
258
if
id
=
=
hlist_code
or
id
=
=
vlist_code
then
259
nodes
.
print
(
head
.
list
,
(
n
or
0
)
+
1
)
260
end
261
head
=
head
.
next
262
end
263
end
264 265
-- quick hack, nicer is to have a proper expand per node type
266
-- already prepared
267 268
local
function
apply
(
n
,
action
)
269
while
n
do
270
action
(
n
)
271
local
id
=
n
.
id
272
if
id
=
=
hlist_code
or
id
=
=
vlist_code
then
273
apply
(
n
.
list
,
action
)
274
end
275
n
=
n
.
next
276
end
277
end
278 279
nodes
.
apply
=
apply
280 281
local
nuts
=
nodes
.
nuts
282
local
getid
=
nuts
.
getid
283
local
getlist
=
nuts
.
getlist
284
local
getnext
=
nuts
.
getnext
285 286
local
function
apply
(
n
,
action
)
287
while
n
do
288
action
(
n
)
289
local
id
=
getid
(
n
)
290
if
id
=
=
hlist_code
or
id
=
=
vlist_code
then
291
local
list
=
getlist
(
n
,
action
)
292
if
list
then
293
apply
(
list
,
action
)
294
end
295
end
296
n
=
getnext
(
n
)
297
end
298
end
299 300
nuts
.
apply
=
apply
301