1if not modules then modules = { } end modules [ ' cldf-int ' ] = {
2 version = 1 . 001 ,
3 comment = " companion to mult-clm.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
14local format , byte = string . format , string . byte
15local insert , remove , concat = table . insert , table . remove , table . concat
16local unpack , type = unpack or table . unpack , type
17
18local catcodenumbers = catcodes . numbers
19
20local ctxcatcodes = catcodenumbers . ctxcatcodes
21local vrbcatcodes = catcodenumbers . vrbcatcodes
22
23local context = context
24local contextsprint = context . sprint
25
26local trace_define = false trackers . register ( " context.define " , function ( v ) trace_define = v end )
27
28interfaces = interfaces or { }
29local implement = interfaces . implement
30local estart = interfaces . elements . start
31local estop = interfaces . elements . stop
32
33if CONTEXTLMTXMODE > 0 then
34
35 local scanners = tokens . scanners
36 local shortcuts = tokens . shortcuts
37
38 local scanpeek = scanners . peek
39 local scankey = scanners . key
40 local scanvalue = scanners . value
41 local scanskip = scanners . skip
42
43 local open = byte ( ' [ ' )
44 local close = byte ( ' ] ' )
45 local equal = byte ( ' = ' )
46 local comma = byte ( ' , ' )
47
48 function scanhash ( scanners )
49 if scanpeek ( ) = = open then
50 local data = { }
51 scanskip ( )
52 while true do
53 local c = scanpeek ( )
54 if c = = comma then
55 scanskip ( )
56 elseif c = = close then
57 scanskip ( )
58 break
59 else
60 local key = scankey ( equal )
61 if key then
62 if scanpeek ( ) = = equal then
63 scanskip ( )
64 if scanners then
65 local scanner = scanners [ key ]
66 if scanner then
67 data [ key ] = scanner ( )
68 else
69 data [ key ] = scanvalue ( comma , close ) or " "
70 end
71 else
72 data [ key ] = scanvalue ( comma , close ) or " "
73 end
74 else
75 break
76 end
77 else
78 break
79 end
80 end
81 end
82 return data
83 end
84 end
85
86 function scanarray ( )
87 if scanpeek ( ) = = open then
88 local data = { }
89 local d = 0
90 scanskip ( )
91 while true do
92 local c = scanpeek ( )
93 if c = = comma then
94 scanskip ( )
95 elseif c = = close then
96 scanskip ( )
97 break
98 else
99 local v = scanvalue ( comma , close ) or " "
100 d = d + 1
101 data [ d ] = v
102 end
103 end
104 return data
105 end
106 end
107
108 shortcuts . scanhash = scanhash
109 shortcuts . scanarray = scanarray
110
111 scanners . hash = scanhash
112 scanners . array = scanarray
113
114 local function remap ( arguments )
115
116 if type ( arguments ) = = " table " then
117 for i = 1 , # arguments do
118 local a = arguments [ i ]
119 if type ( a ) = = " table " then
120 local t = a [ 2 ]
121 arguments [ i ] = t = = " list " and " array " or t
122 end
123 end
124 return arguments
125 end
126 end
127
128 function interfaces . definecommand ( name , specification )
129 if type ( name ) = = " table " then
130 specification = name
131 name = specification . name
132 end
133 if name and specification then
134 local environment = specification . environment
135 local arguments = remap ( specification . arguments )
136 if environment then
137 local starter = specification . starter
138 local stopper = specification . stopper
139 if starter and stopper then
140 implement {
141 name = estart . . name ,
142 arguments = arguments ,
143 public = true ,
144 protected = true ,
145 actions = starter ,
146 }
147 implement {
148 name = estop . . name ,
149 public = true ,
150 protected = true ,
151 actions = stopper ,
152 }
153 else
154
155 end
156 end
157 if not environment or environment = = " both " then
158 local macro = specification . macro
159 if macro then
160 implement {
161 name = name ,
162 arguments = arguments ,
163 public = true ,
164 protected = true ,
165 actions = macro ,
166 }
167 else
168
169 end
170 end
171 else
172
173 end
174 end
175
176
177else
178
179 _clmh_ = utilities . parsers . settings_to_hash
180 _clma_ = utilities . parsers . settings_to_array
181
182 local starters , stoppers , macros , stack = { } , { } , { } , { }
183
184 local checkers = {
185 [ 0 ] = " " ,
186 " \\dosingleempty " ,
187 " \\dodoubleempty " ,
188 " \\dotripleempty " ,
189 " \\doquadrupleempty " ,
190 " \\doquintupleempty " ,
191 " \\dosixtupleempty " ,
192 }
193
194 function _clmm_ ( name , ... )
195 macros [ name ] ( ... )
196 end
197
198 function _clmb_ ( name , ... )
199 local sn = stack [ name ]
200 insert ( sn , { ... } )
201 starters [ name ] ( ... )
202 end
203
204 function _clme_ ( name )
205 local sn = stack [ name ]
206 local sv = remove ( sn )
207 if sv then
208 stoppers [ name ] ( unpack ( sv ) )
209 else
210
211 end
212 end
213
214 _clmn_ = tonumber
215
216 local estart = interfaces . elements . start
217 local estop = interfaces . elements . stop
218
219
220
221 function interfaces . definecommand ( name , specification )
222 if type ( name ) = = " table " then
223 specification = name
224 name = specification . name
225 end
226 if name and specification then
227 local arguments = specification . arguments
228 local na = ( arguments and # arguments ) or 0
229 local environment = specification . environment
230 if na = = 0 then
231 if environment then
232 contextsprint ( ctxcatcodes , " \\setuvalue{ " , estart , name , " }{\\ctxlua{_clmb_(' " , name , " ')}} " )
233 contextsprint ( ctxcatcodes , " \\setuvalue{ " , estop , name , " }{\\ctxlua{_clme_(' " , name , " ')}} " )
234 end
235 if not environment or environment = = " both " then
236 contextsprint ( ctxcatcodes , " \\setuvalue{ " , name , " }{\\ctxlua{_clmm_(' " , name , " ')}} " )
237 end
238 else
239
240 stack [ name ] = { }
241 local opt = 0
242 local done = false
243 local snippets = { }
244 local mkivdo = " \\mkivdo " . . name
245 snippets [ # snippets + 1 ] = " \\def "
246 snippets [ # snippets + 1 ] = mkivdo
247 for i = 1 , na do
248 local a = arguments [ i ]
249 local variant = a [ 1 ]
250 if variant = = " option " then
251 snippets [ # snippets + 1 ] = " [# "
252 snippets [ # snippets + 1 ] = i
253 snippets [ # snippets + 1 ] = " ] "
254 if not done then
255 opt = opt + 1
256 end
257 else
258 done = true
259 snippets [ # snippets + 1 ] = " # "
260 snippets [ # snippets + 1 ] = i
261 end
262 end
263 if environment then
264 snippets [ # snippets + 1 ] = " {\\ctxlua{_clmb_(' "
265 snippets [ # snippets + 1 ] = name
266 snippets [ # snippets + 1 ] = " ' "
267 else
268 snippets [ # snippets + 1 ] = " {\\ctxlua{_clmm_(' "
269 snippets [ # snippets + 1 ] = name
270 snippets [ # snippets + 1 ] = " ' "
271 end
272 for i = 1 , na do
273 local a = arguments [ i ]
274 local variant = a [ 2 ]
275 if variant = = " list " then
276 snippets [ # snippets + 1 ] = " ,_clma_([==[# "
277 snippets [ # snippets + 1 ] = i
278 snippets [ # snippets + 1 ] = " ]==]) "
279 elseif variant = = " hash " then
280 snippets [ # snippets + 1 ] = " ,_clmh_([==[# "
281 snippets [ # snippets + 1 ] = i
282 snippets [ # snippets + 1 ] = " ]==]) "
283 elseif variant = = " number " then
284 snippets [ # snippets + 1 ] = " ,_clmn_([==[# "
285 snippets [ # snippets + 1 ] = i
286 snippets [ # snippets + 1 ] = " ]==]) "
287 else
288 snippets [ # snippets + 1 ] = " ,[==[# "
289 snippets [ # snippets + 1 ] = i
290 snippets [ # snippets + 1 ] = " ]==] "
291 end
292 end
293 snippets [ # snippets + 1 ] = " )}} "
294 contextsprint ( ctxcatcodes , unpack ( snippets ) )
295 if environment then
296
297 contextsprint ( ctxcatcodes , " \\setuvalue{ " , estart , name , " }{ " , checkers [ opt ] , mkivdo , " } " )
298 contextsprint ( ctxcatcodes , " \\setuvalue{ " , estop , name , " }{\\ctxlua{_clme_(' " , name , " ')}} " )
299 end
300 if not environment or environment = = " both " then
301 contextsprint ( ctxcatcodes , " \\setuvalue{ " , name , " }{ " , checkers [ opt ] , mkivdo , " } " )
302 end
303 end
304 if environment then
305 starters [ name ] = specification . starter
306 stoppers [ name ] = specification . stopper
307 else
308 macros [ name ] = specification . macro
309 end
310 end
311 end
312
313end
314
315function interfaces . tolist ( t )
316 if t then
317 local r = { }
318 for i = 1 , # t do
319 r [ i ] = t [ i ]
320 end
321 local n = # r
322 for k , v in table . sortedhash ( t ) do
323 if type ( k ) ~ = " number " then
324 n = n + 1
325 r [ n ] = k . . " = " . . v
326 end
327 end
328 return concat ( r , " , " )
329 else
330 return " "
331 end
332end
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
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399 |