1if 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
13
14local tonumber , tostring , type = tonumber , tostring , type
15
16local context = context
17local commands = commands
18local ctx_latelua = context . latelua
19
20local trace_datasets = false trackers . register ( " job.datasets " , function ( v ) trace_datasets = v end )
21local trace_pagestates = false trackers . register ( " job.pagestates " , function ( v ) trace_pagestates = v end )
22
23local report_dataset = logs . reporter ( " dataset " )
24local report_pagestate = logs . reporter ( " pagestate " )
25
26local allocate = utilities . storage . allocate
27local settings_to_hash = utilities . parsers . settings_to_hash
28
29local texgetcount = tex . getcount
30local texsetcount = tex . setcount
31
32local formatters = string . formatters
33
34local v_yes = interfaces . variables . yes
35
36local new_latelua = nodes . pool . latelua
37
38local implement = interfaces . implement
39local getnamespace = interfaces . getnamespace
40
41local collected = allocate ( )
42local tobesaved = allocate ( )
43
44local datasets = {
45 collected = collected ,
46 tobesaved = tobesaved ,
47}
48
49job . datasets = datasets
50
51local function initializer ( )
52 collected = datasets . collected
53 tobesaved = datasets . tobesaved
54end
55
56job . register ( ' job.datasets.collected ' , tobesaved , initializer , nil )
57
58local sets = { }
59
60table . setmetatableindex ( tobesaved , function ( t , k )
61 local v = { }
62 t [ k ] = v
63 return v
64end )
65
66table . setmetatableindex ( sets , function ( t , k )
67 local v = {
68 index = 0 ,
69 order = 0 ,
70 }
71 t [ k ] = v
72 return v
73end )
74
75local 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
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
106end
107
108datasets . setdata = setdata
109
110function 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
124end
125
126function 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
147end
148
149local 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
157end
158
159local 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 )
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
182end
183
184implement {
185 name = " setdataset " ,
186 actions = setdataset ,
187 arguments = {
188 {
189 { " name " } ,
190 { " tag " } ,
191 { " delay " } ,
192 { " data " } ,
193 }
194 }
195}
196
197implement {
198 name = " datasetvariable " ,
199 actions = datasetvariable ,
200 arguments = " 3 strings " ,
201}
202
203
206
207local collected = allocate ( )
208local tobesaved = allocate ( )
209
210local pagestates = {
211 collected = collected ,
212 tobesaved = tobesaved ,
213}
214
215job . pagestates = pagestates
216
217local function initializer ( )
218 collected = pagestates . collected
219 tobesaved = pagestates . tobesaved
220end
221
222job . register ( ' job.pagestates.collected ' , tobesaved , initializer , nil )
223
224table . setmetatableindex ( tobesaved , function ( t , k )
225 local v = { }
226 t [ k ] = v
227 return v
228end )
229
230local 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
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
246end
247
248local 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
254end
255
256local 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 )
267 end
268 return default
269end
270
271local 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
286end
287
288pagestates . setstate = setstate
289pagestates . extend = extend
290pagestates . realpage = realpage
291pagestates . realpageorder = realpageorder
292
293function pagestates . countervalue ( name )
294 return name and texgetcount ( getnamespace ( " pagestatecounter " ) . . name ) or 0
295end
296
297local function setpagestate ( settings )
298 local name , tag = setstate ( settings )
299
300 ctx_latelua ( function ( ) extend ( name , tag ) end )
301end
302
303local 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 " ) )
307end
308
309implement {
310 name = " setpagestate " ,
311 actions = setpagestate ,
312 arguments = {
313 {
314 { " name " } ,
315 { " tag " } ,
316 { " delay " } ,
317 }
318 }
319}
320
321implement {
322 name = " pagestaterealpage " ,
323 actions = { realpage , context } ,
324 arguments = " 2 strings " ,
325}
326
327implement {
328 name = " setpagestaterealpageno " ,
329 actions = setpagestaterealpageno ,
330 arguments = " 2 strings " ,
331}
332
333implement {
334 name = " pagestaterealpageorder " ,
335 actions = { realpageorder , context } ,
336 arguments = { " string " , " integer " }
337}
338 |