core-dat.lua /size: 8817 b    last modification: 2020-07-01 14:35
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
core-dat
'
]
=
{
2
version
=
1
.
001
,
3
comment
=
"
companion to core-dat.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
--[[ldx-- 10<p>This module provides a (multipass) container for arbitrary data. It 11replaces the twopass data mechanism.</p> 12--ldx]]
--
13 14
local
tonumber
,
tostring
,
type
=
tonumber
,
tostring
,
type
15 16
local
context
=
context
17
local
commands
=
commands
18
local
ctx_latelua
=
context
.
latelua
19 20
local
trace_datasets
=
false
trackers
.
register
(
"
job.datasets
"
,
function
(
v
)
trace_datasets
=
v
end
)
21
local
trace_pagestates
=
false
trackers
.
register
(
"
job.pagestates
"
,
function
(
v
)
trace_pagestates
=
v
end
)
22 23
local
report_dataset
=
logs
.
reporter
(
"
dataset
"
)
24
local
report_pagestate
=
logs
.
reporter
(
"
pagestate
"
)
25 26
local
allocate
=
utilities
.
storage
.
allocate
27
local
settings_to_hash
=
utilities
.
parsers
.
settings_to_hash
28 29
local
texgetcount
=
tex
.
getcount
30
local
texsetcount
=
tex
.
setcount
31 32
local
formatters
=
string
.
formatters
33 34
local
v_yes
=
interfaces
.
variables
.
yes
35 36
local
new_latelua
=
nodes
.
pool
.
latelua
37 38
local
implement
=
interfaces
.
implement
39
local
getnamespace
=
interfaces
.
getnamespace
40 41
local
collected
=
allocate
(
)
42
local
tobesaved
=
allocate
(
)
43 44
local
datasets
=
{
45
collected
=
collected
,
46
tobesaved
=
tobesaved
,
47
}
48 49
job
.
datasets
=
datasets
50 51
local
function
initializer
(
)
52
collected
=
datasets
.
collected
53
tobesaved
=
datasets
.
tobesaved
54
end
55 56
job
.
register
(
'
job.datasets.collected
'
,
tobesaved
,
initializer
,
nil
)
57 58
local
sets
=
{
}
59 60
table
.
setmetatableindex
(
tobesaved
,
function
(
t
,
k
)
61
local
v
=
{
}
62
t
[
k
]
=
v
63
return
v
64
end
)
65 66
table
.
setmetatableindex
(
sets
,
function
(
t
,
k
)
67
local
v
=
{
68
index
=
0
,
69
order
=
0
,
70
}
71
t
[
k
]
=
v
72
return
v
73
end
)
74 75
local
function
setdata
(
settings
)
76
local
name
=
settings
.
name
77
local
tag
=
settings
.
tag
78
local
data
=
settings
.
data
79
local
list
=
tobesaved
[
name
]
80
if
settings
.
convert
and
type
(
data
)
=
=
"
string
"
then
81
data
=
settings_to_hash
(
data
)
82
end
83
if
type
(
data
)
~
=
"
table
"
then
84
data
=
{
data
=
data
}
85
end
86
if
not
tag
then
87
tag
=
#
list
+
1
88
else
89
tag
=
tonumber
(
tag
)
or
tag
-- autonumber saves keys
90
end
91
list
[
tag
]
=
data
92
if
settings
.
delay
=
=
v_yes
then
93
local
set
=
sets
[
name
]
94
local
index
=
set
.
index
+
1
95
set
.
index
=
index
96
data
.
index
=
index
97
data
.
order
=
index
98
data
.
realpage
=
texgetcount
(
"
realpageno
"
)
99
if
trace_datasets
then
100
report_dataset
(
"
action %a, name %a, tag %a, index %a
"
,
"
assign delayed
"
,
name
,
tag
,
index
)
101
end
102
elseif
trace_datasets
then
103
report_dataset
(
"
action %a, name %a, tag %a
"
,
"
assign immediate
"
,
name
,
tag
)
104
end
105
return
name
,
tag
,
data
106
end
107 108
datasets
.
setdata
=
setdata
109 110
function
datasets
.
extend
(
name
,
tag
)
111
if
type
(
name
)
=
=
"
table
"
then
112
name
,
tag
=
name
.
name
,
name
.
tag
113
end
114
local
set
=
sets
[
name
]
115
local
order
=
set
.
order
+
1
116
local
realpage
=
texgetcount
(
"
realpageno
"
)
117
set
.
order
=
order
118
local
t
=
tobesaved
[
name
]
[
tag
]
119
t
.
realpage
=
realpage
120
t
.
order
=
order
121
if
trace_datasets
then
122
report_dataset
(
"
action %a, name %a, tag %a, page %a, index %a
"
,
"
flush by order
"
,
name
,
tag
,
t
.
index
or
0
,
order
,
realpage
)
123
end
124
end
125 126
function
datasets
.
getdata
(
name
,
tag
,
key
,
default
)
127
local
t
=
collected
[
name
]
128
if
t
=
=
nil
then
129
if
trace_datasets
then
130
report_dataset
(
"
error: unknown dataset, name %a
"
,
name
)
131
end
132
elseif
type
(
t
)
~
=
"
table
"
then
133
return
t
134
else
135
t
=
t
[
tag
]
or
t
[
tonumber
(
tag
)
]
136
if
not
t
then
137
if
trace_datasets
then
138
report_dataset
(
"
error: unknown dataset, name %a, tag %a
"
,
name
,
tag
)
139
end
140
elseif
key
then
141
return
t
[
key
]
or
default
142
else
143
return
t
144
end
145
end
146
return
default
147
end
148 149
local
function
setdataset
(
settings
)
150
settings
.
convert
=
true
151
local
name
,
tag
=
setdata
(
settings
)
152
if
settings
.
delay
~
=
v_yes
then
153
--
154
else
155
context
(
new_latelua
{
action
=
job
.
datasets
.
extend
,
name
=
name
,
tag
=
tag
}
)
156
end
157
end
158 159
local
function
datasetvariable
(
name
,
tag
,
key
)
160
local
t
=
collected
[
name
]
161
if
t
=
=
nil
then
162
if
trace_datasets
then
163
report_dataset
(
"
error: unknown dataset, name %a, tag %a, not passed to tex
"
,
name
)
-- no tag
164
end
165
elseif
type
(
t
)
~
=
"
table
"
then
166
context
(
tostring
(
t
)
)
167
else
168
t
=
t
and
(
t
[
tag
]
or
t
[
tonumber
(
tag
)
]
)
169
if
not
t
then
170
if
trace_datasets
then
171
report_dataset
(
"
error: unknown dataset, name %a, tag %a, not passed to tex
"
,
name
,
tag
)
172
end
173
elseif
type
(
t
)
=
=
"
table
"
then
174
local
s
=
t
[
key
]
175
if
type
(
s
)
~
=
"
table
"
then
176
context
(
tostring
(
s
)
)
177
elseif
trace_datasets
then
178
report_dataset
(
"
error: unknown dataset, name %a, tag %a, not passed to tex
"
,
name
,
tag
)
179
end
180
end
181
end
182
end
183 184
implement
{
185
name
=
"
setdataset
"
,
186
actions
=
setdataset
,
187
arguments
=
{
188
{
189
{
"
name
"
}
,
190
{
"
tag
"
}
,
191
{
"
delay
"
}
,
192
{
"
data
"
}
,
193
}
194
}
195
}
196 197
implement
{
198
name
=
"
datasetvariable
"
,
199
actions
=
datasetvariable
,
200
arguments
=
"
3 strings
"
,
201
}
202 203
--[[ldx-- 204<p>We also provide an efficient variant for page states.</p> 205--ldx]]
--
206 207
local
collected
=
allocate
(
)
208
local
tobesaved
=
allocate
(
)
209 210
local
pagestates
=
{
211
collected
=
collected
,
212
tobesaved
=
tobesaved
,
213
}
214 215
job
.
pagestates
=
pagestates
216 217
local
function
initializer
(
)
218
collected
=
pagestates
.
collected
219
tobesaved
=
pagestates
.
tobesaved
220
end
221 222
job
.
register
(
'
job.pagestates.collected
'
,
tobesaved
,
initializer
,
nil
)
223 224
table
.
setmetatableindex
(
tobesaved
,
function
(
t
,
k
)
225
local
v
=
{
}
226
t
[
k
]
=
v
227
return
v
228
end
)
229 230
local
function
setstate
(
settings
)
231
local
name
=
settings
.
name
232
local
tag
=
settings
.
tag
233
local
list
=
tobesaved
[
name
]
234
if
not
tag
then
235
tag
=
#
list
+
1
236
else
237
tag
=
tonumber
(
tag
)
or
tag
-- autonumber saves keys
238
end
239
local
realpage
=
texgetcount
(
"
realpageno
"
)
240
local
data
=
realpage
241
list
[
tag
]
=
data
242
if
trace_pagestates
then
243
report_pagestate
(
"
action %a, name %a, tag %a, preset %a
"
,
"
set
"
,
name
,
tag
,
realpage
)
244
end
245
return
name
,
tag
,
data
246
end
247 248
local
function
extend
(
name
,
tag
)
249
local
realpage
=
texgetcount
(
"
realpageno
"
)
250
if
trace_pagestates
then
251
report_pagestate
(
"
action %a, name %a, tag %a, preset %a
"
,
"
synchronize
"
,
name
,
tag
,
realpage
)
252
end
253
tobesaved
[
name
]
[
tag
]
=
realpage
254
end
255 256
local
function
realpage
(
name
,
tag
,
default
)
257
local
t
=
collected
[
name
]
258
if
t
then
259
t
=
t
[
tag
]
or
t
[
tonumber
(
tag
)
]
260
if
t
then
261
return
tonumber
(
t
or
default
)
262
elseif
trace_pagestates
then
263
report_pagestate
(
"
error: unknown dataset, name %a, tag %a
"
,
name
,
tag
)
264
end
265
elseif
trace_pagestates
then
266
report_pagestate
(
"
error: unknown dataset, name %a, tag %a
"
,
name
)
-- nil
267
end
268
return
default
269
end
270 271
local
function
realpageorder
(
name
,
tag
)
272
local
t
=
collected
[
name
]
273
if
t
then
274
local
p
=
t
[
tag
]
275
if
p
then
276
local
n
=
1
277
for
i
=
tag
-1
,
1
,
-1
do
278
if
t
[
i
]
=
=
p
then
279
n
=
n
+
1
280
end
281
end
282
return
n
283
end
284
end
285
return
0
286
end
287 288
pagestates
.
setstate
=
setstate
289
pagestates
.
extend
=
extend
290
pagestates
.
realpage
=
realpage
291
pagestates
.
realpageorder
=
realpageorder
292 293
function
pagestates
.
countervalue
(
name
)
294
return
name
and
texgetcount
(
getnamespace
(
"
pagestatecounter
"
)
.
.
name
)
or
0
295
end
296 297
local
function
setpagestate
(
settings
)
298
local
name
,
tag
=
setstate
(
settings
)
299
-- context(new_latelua(function() extend(name,tag) end))
300
ctx_latelua
(
function
(
)
extend
(
name
,
tag
)
end
)
301
end
302 303
local
function
setpagestaterealpageno
(
name
,
tag
)
304
local
t
=
collected
[
name
]
305
t
=
t
and
(
t
[
tag
]
or
t
[
tonumber
(
tag
)
]
)
306
texsetcount
(
"
realpagestateno
"
,
t
or
texgetcount
(
"
realpageno
"
)
)
307
end
308 309
implement
{
310
name
=
"
setpagestate
"
,
311
actions
=
setpagestate
,
312
arguments
=
{
313
{
314
{
"
name
"
}
,
315
{
"
tag
"
}
,
316
{
"
delay
"
}
,
317
}
318
}
319
}
320 321
implement
{
322
name
=
"
pagestaterealpage
"
,
323
actions
=
{
realpage
,
context
}
,
324
arguments
=
"
2 strings
"
,
325
}
326 327
implement
{
328
name
=
"
setpagestaterealpageno
"
,
329
actions
=
setpagestaterealpageno
,
330
arguments
=
"
2 strings
"
,
331
}
332 333
implement
{
334
name
=
"
pagestaterealpageorder
"
,
335
actions
=
{
realpageorder
,
context
}
,
336
arguments
=
{
"
string
"
,
"
integer
"
}
337
}
338