1if not modules then modules = { } end modules [ ' mult-ini ' ] = {
2 version = 1 . 001 ,
3 comment = " companion to mult-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
9local format , gmatch , match , find , sub = string . format , string . gmatch , string . match , string . find , string . sub
10local lpegmatch = lpeg . match
11local serialize , concat = table . serialize , table . concat
12local rawget , type , tonumber , next = rawget , type , tonumber , next
13
14local context = context
15local commands = commands
16local implement = interfaces . implement
17
18local allocate = utilities . storage . allocate
19local mark = utilities . storage . mark
20local prtcatcodes = catcodes . numbers . prtcatcodes
21local vrbcatcodes = catcodes . numbers . vrbcatcodes
22local contextsprint = context . sprint
23local setmetatableindex = table . setmetatableindex
24local formatters = string . formatters
25
26local report_interface = logs . reporter ( " interface " , " initialization " )
27
28interfaces = interfaces or { }
29interfaces . constants = mark ( interfaces . constants or { } )
30interfaces . variables = mark ( interfaces . variables or { } )
31interfaces . elements = mark ( interfaces . elements or { } )
32interfaces . formats = mark ( interfaces . formats or { } )
33interfaces . translations = mark ( interfaces . translations or { } )
34interfaces . setupstrings = mark ( interfaces . setupstrings or { } )
35interfaces . corenamespaces = mark ( interfaces . corenamespaces or { } )
36interfaces . usednamespaces = mark ( interfaces . usednamespaces or { } )
37
38local registerstorage = storage . register
39local sharedstorage = storage . shared
40
41local constants = interfaces . constants
42local variables = interfaces . variables
43local elements = interfaces . elements
44local formats = interfaces . formats
45local translations = interfaces . translations
46local setupstrings = interfaces . setupstrings
47local corenamespaces = interfaces . corenamespaces
48local usednamespaces = interfaces . usednamespaces
49local reporters = { }
50
51registerstorage ( " interfaces/constants " , constants , " interfaces.constants " )
52registerstorage ( " interfaces/variables " , variables , " interfaces.variables " )
53registerstorage ( " interfaces/elements " , elements , " interfaces.elements " )
54registerstorage ( " interfaces/formats " , formats , " interfaces.formats " )
55registerstorage ( " interfaces/translations " , translations , " interfaces.translations " )
56registerstorage ( " interfaces/setupstrings " , setupstrings , " interfaces.setupstrings " )
57registerstorage ( " interfaces/corenamespaces " , corenamespaces , " interfaces.corenamespaces " )
58registerstorage ( " interfaces/usednamespaces " , usednamespaces , " interfaces.usednamespaces " )
59
60interfaces . interfaces = {
61 " cs " , " de " , " en " , " fr " , " it " , " nl " , " ro " , " pe " ,
62}
63
64sharedstorage . currentinterface = sharedstorage . currentinterface or " en "
65sharedstorage . currentresponse = sharedstorage . currentresponse or " en "
66
67local currentinterface = sharedstorage . currentinterface
68local currentresponse = sharedstorage . currentresponse
69
70interfaces . currentinterface = currentinterface
71interfaces . currentresponse = currentresponse
72
73local complete = allocate ( )
74interfaces . complete = complete
75
76local function resolve ( t , k )
77 report_interface ( " loading interface definitions from 'mult-def.lua' " )
78 complete = dofile ( resolvers . findfile ( " mult-def.lua " ) )
79 report_interface ( " loading interface messages from 'mult-mes.lua' " )
80 complete . messages = dofile ( resolvers . findfile ( " mult-mes.lua " ) )
81 interfaces . complete = complete
82 return rawget ( complete , k )
83end
84
85setmetatableindex ( complete , resolve )
86
87local function valueiskey ( t , k )
88 t [ k ] = k
89 return k
90end
91
92setmetatableindex ( variables , valueiskey )
93setmetatableindex ( constants , valueiskey )
94setmetatableindex ( elements , valueiskey )
95setmetatableindex ( formats , valueiskey )
96setmetatableindex ( translations , valueiskey )
97setmetatableindex ( setupstrings , valueiskey )
98
99function interfaces . registernamespace ( n , namespace )
100 corenamespaces [ n ] = namespace
101 usednamespaces [ namespace ] = n
102end
103
104function interfaces . getnamespace ( n )
105 return usednamespaces [ n ] . . " > "
106end
107
108if documentdata then
109
110 local prefix , getmacro
111
112 function documentdata . variable ( name )
113 if not prefix then
114 prefix = usednamespaces . variables . . " >document: "
115 end
116 if not getmacro then
117 getmacro = tokens . getters . macro
118 end
119 return getmacro ( prefix . . name )
120 end
121
122end
123
124local function resolve ( t , k )
125 local v = logs . reporter ( k )
126 t [ k ] = v
127 return v
128end
129
130setmetatableindex ( reporters , resolve )
131
132for category , _ in next , translations do
133
134
135
136
137 local r = reporters [ category ]
138end
139
140
141
142local function add ( target , tag , values )
143 local t = target [ tag ]
144 if not f then
145 target [ tag ] = values
146 else
147 for k , v in next , values do
148 if f [ k ] then
149
150 else
151 f [ k ] = v
152 end
153 end
154 end
155end
156
157function interfaces . settranslation ( tag , values )
158 add ( translations , tag , values )
159end
160
161function interfaces . setformat ( tag , values )
162 add ( formats , tag , values )
163end
164
165local function getsetupstring ( tag )
166 return setupstrings [ tag ] or tag
167end
168
169interfaces . getsetupstring = getsetupstring
170
171
172
173local replacer = lpeg . replacer { { " -- " , " %%a " } }
174
175local function fulltag ( category , tag )
176 return formatters [ " %s:%s " ] ( category , lpegmatch ( replacer , tag ) )
177end
178
179function interfaces . setmessages ( category , str )
180 for tag , message in gmatch ( str , " (%S+) *: *(.-) *[\n\r] " ) do
181 if tag = = " title " then
182 translations [ tag ] = translations [ tag ] or tag
183 else
184 formats [ fulltag ( category , tag ) ] = lpegmatch ( replacer , message )
185 end
186 end
187end
188
189function interfaces . setmessage ( category , tag , message )
190 formats [ fulltag ( category , tag ) ] = lpegmatch ( replacer , message )
191end
192
193function interfaces . getmessage ( category , tag , default )
194 return formats [ fulltag ( category , tag ) ] or default or " unknown message "
195end
196
197function interfaces . doifelsemessage ( category , tag )
198 return rawget ( formats , fulltag ( category , tag ) )
199end
200
201local splitter = lpeg . splitat ( " , " )
202
203function interfaces . showmessage ( category , tag , arguments )
204 local r = reporters [ category ]
205 local f = formats [ fulltag ( category , tag ) ]
206 local t = type ( arguments )
207 if t = = " string " and # arguments > 0 then
208 r ( f , lpegmatch ( splitter , arguments ) )
209 elseif t = = " table " then
210 r ( f , unpack ( arguments ) )
211 elseif arguments then
212 r ( f , arguments )
213 else
214 r ( f )
215 end
216end
217
218
219
220function interfaces . setvariable ( variable , given )
221 variables [ given ] = variable
222end
223
224function interfaces . setconstant ( constant , given )
225 constants [ given ] = constant
226end
227
228function interfaces . setelement ( element , given )
229 elements [ given ] = element
230end
231
232
233
234logs . setmessenger ( context . verbatim . ctxreport )
235
236interfaces . cachedsetups = interfaces . cachedsetups or { }
237interfaces . hashedsetups = interfaces . hashedsetups or { }
238
239local cachedsetups = interfaces . cachedsetups
240local hashedsetups = interfaces . hashedsetups
241
242storage . register ( " interfaces/cachedsetups " , cachedsetups , " interfaces.cachedsetups " )
243storage . register ( " interfaces/hashedsetups " , hashedsetups , " interfaces.hashedsetups " )
244
245function interfaces . cachesetup ( t )
246 local hash = serialize ( t )
247 local done = hashedsetups [ hash ]
248 if done then
249 return cachedsetups [ done ]
250 else
251 done = # cachedsetups + 1
252 cachedsetups [ done ] = t
253 hashedsetups [ hash ] = done
254 return t
255 end
256end
257
258function interfaces . interfacedcommand ( name )
259 local command = complete . commands [ name ]
260 return command and command [ currentinterface ] or name
261end
262
263
264
265function interfaces . writestatus ( category , message )
266 reporters [ category ] ( message )
267end
268
269function interfaces . message ( str )
270 texio . write ( str )
271end
272
273implement { name = " registernamespace " , actions = interfaces . registernamespace , arguments = { " integer " , " string " } }
274implement { name = " setinterfaceconstant " , actions = interfaces . setconstant , arguments = " 2 strings " }
275implement { name = " setinterfacevariable " , actions = interfaces . setvariable , arguments = " 2 strings " }
276implement { name = " setinterfaceelement " , actions = interfaces . setelement , arguments = " 2 strings " }
277implement { name = " setinterfacemessage " , actions = interfaces . setmessage , arguments = " 3 strings " }
278implement { name = " setinterfacemessages " , actions = interfaces . setmessages , arguments = " 2 strings " }
279implement { name = " showmessage " , actions = interfaces . showmessage , arguments = " 3 strings " }
280
281implement {
282 name = " doifelsemessage " ,
283 actions = { interfaces . doifelsemessage , commands . doifelse } ,
284 arguments = " 2 strings " ,
285}
286
287implement {
288 name = " getmessage " ,
289 actions = { interfaces . getmessage , context } ,
290 arguments = " 3 strings " ,
291}
292
293implement {
294 name = " writestatus " ,
295 overload = true ,
296 actions = interfaces . writestatus ,
297 arguments = " 2 strings " ,
298}
299
300implement {
301 name = " message " ,
302 overload = true ,
303 actions = interfaces . message ,
304 arguments = " string " ,
305}
306
307local function gss ( s )
308 contextsprint ( vrbcatcodes , getsetupstring ( s ) )
309end
310
311implement {
312 name = " getsetupstring " ,
313 actions = gss ,
314 arguments = " string " ,
315}
316
317implement {
318 name = " rawsetupstring " ,
319 actions = gss ,
320 arguments = " string " ,
321}
322
323
324local function showassignerror ( namespace , key , line )
325
326 local ns , instance = match ( namespace , " ^(%d+)[^%a]+(%a*) " )
327 if ns then
328 namespace = corenamespaces [ tonumber ( ns ) ] or ns
329 end
330
331 if instance and instance ~ = " " then
332 context . writestatus ( " setup " , formatters [ " error in line %a, namespace %a, instance %a, key %a " ] ( line , namespace , instance , key ) )
333 else
334 context . writestatus ( " setup " , formatters [ " error in line %a, namespace %a, key %a " ] ( line , namespace , key ) )
335 end
336
337end
338
339implement {
340 name = " showassignerror " ,
341 actions = showassignerror ,
342 arguments = { " string " , " string " , " integer " } ,
343}
344
345
346
347local settings_to_hash = utilities . parsers . settings_to_hash
348
349local makesparse = function ( t )
350 for k , v in next , t do
351 if not v or v = = " " then
352 t [ k ] = nil
353 end
354 end
355 return t
356end
357
358function interfaces . checkedspecification ( specification )
359 local kind = type ( specification )
360 if kind = = " table " then
361 return makesparse ( specification )
362 elseif kind = = " string " and specification ~ = " " then
363 return makesparse ( settings_to_hash ( specification ) )
364 else
365 return { }
366 end
367end
368 |