mult-ini.lua /size: 11 Kb    last modification: 2021-10-28 13:50
1
if
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 9
local
format
,
gmatch
,
match
,
find
,
sub
=
string
.
format
,
string
.
gmatch
,
string
.
match
,
string
.
find
,
string
.
sub
10
local
lpegmatch
=
lpeg
.
match
11
local
serialize
,
concat
=
table
.
serialize
,
table
.
concat
12
local
rawget
,
type
,
tonumber
,
next
=
rawget
,
type
,
tonumber
,
next
13 14
local
context
=
context
15
local
commands
=
commands
16
local
implement
=
interfaces
.
implement
17 18
local
allocate
=
utilities
.
storage
.
allocate
19
local
mark
=
utilities
.
storage
.
mark
20
local
prtcatcodes
=
catcodes
.
numbers
.
prtcatcodes
21
local
vrbcatcodes
=
catcodes
.
numbers
.
vrbcatcodes
22
local
contextsprint
=
context
.
sprint
23
local
setmetatableindex
=
table
.
setmetatableindex
24
local
formatters
=
string
.
formatters
25 26
local
report_interface
=
logs
.
reporter
(
"
interface
"
,
"
initialization
"
)
27 28
interfaces
=
interfaces
or
{
}
29
interfaces
.
constants
=
mark
(
interfaces
.
constants
or
{
}
)
30
interfaces
.
variables
=
mark
(
interfaces
.
variables
or
{
}
)
31
interfaces
.
elements
=
mark
(
interfaces
.
elements
or
{
}
)
32
interfaces
.
formats
=
mark
(
interfaces
.
formats
or
{
}
)
33
interfaces
.
translations
=
mark
(
interfaces
.
translations
or
{
}
)
34
interfaces
.
setupstrings
=
mark
(
interfaces
.
setupstrings
or
{
}
)
35
interfaces
.
corenamespaces
=
mark
(
interfaces
.
corenamespaces
or
{
}
)
36
interfaces
.
usednamespaces
=
mark
(
interfaces
.
usednamespaces
or
{
}
)
37 38
local
registerstorage
=
storage
.
register
39
local
sharedstorage
=
storage
.
shared
40 41
local
constants
=
interfaces
.
constants
42
local
variables
=
interfaces
.
variables
43
local
elements
=
interfaces
.
elements
44
local
formats
=
interfaces
.
formats
45
local
translations
=
interfaces
.
translations
46
local
setupstrings
=
interfaces
.
setupstrings
47
local
corenamespaces
=
interfaces
.
corenamespaces
48
local
usednamespaces
=
interfaces
.
usednamespaces
49
local
reporters
=
{
}
-- just an optimization
50 51
registerstorage
(
"
interfaces/constants
"
,
constants
,
"
interfaces.constants
"
)
52
registerstorage
(
"
interfaces/variables
"
,
variables
,
"
interfaces.variables
"
)
53
registerstorage
(
"
interfaces/elements
"
,
elements
,
"
interfaces.elements
"
)
54
registerstorage
(
"
interfaces/formats
"
,
formats
,
"
interfaces.formats
"
)
55
registerstorage
(
"
interfaces/translations
"
,
translations
,
"
interfaces.translations
"
)
56
registerstorage
(
"
interfaces/setupstrings
"
,
setupstrings
,
"
interfaces.setupstrings
"
)
57
registerstorage
(
"
interfaces/corenamespaces
"
,
corenamespaces
,
"
interfaces.corenamespaces
"
)
58
registerstorage
(
"
interfaces/usednamespaces
"
,
usednamespaces
,
"
interfaces.usednamespaces
"
)
59 60
interfaces
.
interfaces
=
{
61
"
cs
"
,
"
de
"
,
"
en
"
,
"
fr
"
,
"
it
"
,
"
nl
"
,
"
ro
"
,
"
pe
"
,
62
}
63 64
sharedstorage
.
currentinterface
=
sharedstorage
.
currentinterface
or
"
en
"
65
sharedstorage
.
currentresponse
=
sharedstorage
.
currentresponse
or
"
en
"
66 67
local
currentinterface
=
sharedstorage
.
currentinterface
68
local
currentresponse
=
sharedstorage
.
currentresponse
69 70
interfaces
.
currentinterface
=
currentinterface
71
interfaces
.
currentresponse
=
currentresponse
72 73
local
complete
=
allocate
(
)
74
interfaces
.
complete
=
complete
75 76
local
function
resolve
(
t
,
k
)
-- one access needed to get loaded (not stored!)
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
)
83
end
84 85
setmetatableindex
(
complete
,
resolve
)
86 87
local
function
valueiskey
(
t
,
k
)
-- will be helper
88
t
[
k
]
=
k
89
return
k
90
end
91 92
setmetatableindex
(
variables
,
valueiskey
)
93
setmetatableindex
(
constants
,
valueiskey
)
94
setmetatableindex
(
elements
,
valueiskey
)
95
setmetatableindex
(
formats
,
valueiskey
)
96
setmetatableindex
(
translations
,
valueiskey
)
97
setmetatableindex
(
setupstrings
,
valueiskey
)
98 99
function
interfaces
.
registernamespace
(
n
,
namespace
)
100
corenamespaces
[
n
]
=
namespace
101
usednamespaces
[
namespace
]
=
n
102
end
103 104
function
interfaces
.
getnamespace
(
n
)
105
return
usednamespaces
[
n
]
.
.
"
>
"
106
end
107 108
if
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 122
end
123 124
local
function
resolve
(
t
,
k
)
125
local
v
=
logs
.
reporter
(
k
)
126
t
[
k
]
=
v
127
return
v
128
end
129 130
setmetatableindex
(
reporters
,
resolve
)
131 132
for
category
,
_
in
next
,
translations
do
133
-- We pre-create reporters for already defined messages
134
-- because otherwise listing is incomplete and we want
135
-- to use that for checking so delaying makes not much
136
-- sense there.
137
local
r
=
reporters
[
category
]
138
end
139 140
-- adding messages
141 142
local
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
-- error
150
else
151
f
[
k
]
=
v
152
end
153
end
154
end
155
end
156 157
function
interfaces
.
settranslation
(
tag
,
values
)
158
add
(
translations
,
tag
,
values
)
159
end
160 161
function
interfaces
.
setformat
(
tag
,
values
)
162
add
(
formats
,
tag
,
values
)
163
end
164 165
local
function
getsetupstring
(
tag
)
166
return
setupstrings
[
tag
]
or
tag
167
end
168 169
interfaces
.
getsetupstring
=
getsetupstring
170 171
-- the old method:
172 173
local
replacer
=
lpeg
.
replacer
{
{
"
--
"
,
"
%%a
"
}
}
174 175
local
function
fulltag
(
category
,
tag
)
176
return
formatters
[
"
%s:%s
"
]
(
category
,
lpegmatch
(
replacer
,
tag
)
)
177
end
178 179
function
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
187
end
188 189
function
interfaces
.
setmessage
(
category
,
tag
,
message
)
190
formats
[
fulltag
(
category
,
tag
)
]
=
lpegmatch
(
replacer
,
message
)
191
end
192 193
function
interfaces
.
getmessage
(
category
,
tag
,
default
)
194
return
formats
[
fulltag
(
category
,
tag
)
]
or
default
or
"
unknown message
"
195
end
196 197
function
interfaces
.
doifelsemessage
(
category
,
tag
)
198
return
rawget
(
formats
,
fulltag
(
category
,
tag
)
)
199
end
200 201
local
splitter
=
lpeg
.
splitat
(
"
,
"
)
202 203
function
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
216
end
217 218
-- till here
219 220
function
interfaces
.
setvariable
(
variable
,
given
)
221
variables
[
given
]
=
variable
222
end
223 224
function
interfaces
.
setconstant
(
constant
,
given
)
225
constants
[
given
]
=
constant
226
end
227 228
function
interfaces
.
setelement
(
element
,
given
)
229
elements
[
given
]
=
element
230
end
231 232
-- the real thing:
233 234
logs
.
setmessenger
(
context
.
verbatim
.
ctxreport
)
235 236
interfaces
.
cachedsetups
=
interfaces
.
cachedsetups
or
{
}
237
interfaces
.
hashedsetups
=
interfaces
.
hashedsetups
or
{
}
238 239
local
cachedsetups
=
interfaces
.
cachedsetups
240
local
hashedsetups
=
interfaces
.
hashedsetups
241 242
storage
.
register
(
"
interfaces/cachedsetups
"
,
cachedsetups
,
"
interfaces.cachedsetups
"
)
243
storage
.
register
(
"
interfaces/hashedsetups
"
,
hashedsetups
,
"
interfaces.hashedsetups
"
)
244 245
function
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
256
end
257 258
function
interfaces
.
interfacedcommand
(
name
)
259
local
command
=
complete
.
commands
[
name
]
260
return
command
and
command
[
currentinterface
]
or
name
261
end
262 263
-- interface
264 265
function
interfaces
.
writestatus
(
category
,
message
)
266
reporters
[
category
]
(
message
)
-- could also be a setmetatablecall
267
end
268 269
function
interfaces
.
message
(
str
)
270
texio
.
write
(
str
)
-- overloaded
271
end
272 273
implement
{
name
=
"
registernamespace
"
,
actions
=
interfaces
.
registernamespace
,
arguments
=
{
"
integer
"
,
"
string
"
}
}
274
implement
{
name
=
"
setinterfaceconstant
"
,
actions
=
interfaces
.
setconstant
,
arguments
=
"
2 strings
"
}
275
implement
{
name
=
"
setinterfacevariable
"
,
actions
=
interfaces
.
setvariable
,
arguments
=
"
2 strings
"
}
276
implement
{
name
=
"
setinterfaceelement
"
,
actions
=
interfaces
.
setelement
,
arguments
=
"
2 strings
"
}
277
implement
{
name
=
"
setinterfacemessage
"
,
actions
=
interfaces
.
setmessage
,
arguments
=
"
3 strings
"
}
278
implement
{
name
=
"
setinterfacemessages
"
,
actions
=
interfaces
.
setmessages
,
arguments
=
"
2 strings
"
}
279
implement
{
name
=
"
showmessage
"
,
actions
=
interfaces
.
showmessage
,
arguments
=
"
3 strings
"
}
280 281
implement
{
282
name
=
"
doifelsemessage
"
,
283
actions
=
{
interfaces
.
doifelsemessage
,
commands
.
doifelse
}
,
284
arguments
=
"
2 strings
"
,
285
}
286 287
implement
{
288
name
=
"
getmessage
"
,
289
actions
=
{
interfaces
.
getmessage
,
context
}
,
290
arguments
=
"
3 strings
"
,
291
}
292 293
implement
{
294
name
=
"
writestatus
"
,
295
overload
=
true
,
296
actions
=
interfaces
.
writestatus
,
297
arguments
=
"
2 strings
"
,
298
}
299 300
implement
{
301
name
=
"
message
"
,
302
overload
=
true
,
303
actions
=
interfaces
.
message
,
304
arguments
=
"
string
"
,
305
}
306 307
local
function
gss
(
s
)
308
contextsprint
(
vrbcatcodes
,
getsetupstring
(
s
)
)
309
end
310 311
implement
{
-- will be overloaded
312
name
=
"
getsetupstring
"
,
313
actions
=
gss
,
314
arguments
=
"
string
"
,
315
}
316 317
implement
{
318
name
=
"
rawsetupstring
"
,
319
actions
=
gss
,
320
arguments
=
"
string
"
,
321
}
322 323 324
local
function
showassignerror
(
namespace
,
key
,
line
)
325
-- if key and key ~= "" and key ~= "," then
326
local
ns
,
instance
=
match
(
namespace
,
"
^(%d+)[^%a]+(%a*)
"
)
327
if
ns
then
328
namespace
=
corenamespaces
[
tonumber
(
ns
)
]
or
ns
329
end
330
-- injected in the stream for timing:
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
-- end
337
end
338 339
implement
{
340
name
=
"
showassignerror
"
,
341
actions
=
showassignerror
,
342
arguments
=
{
"
string
"
,
"
string
"
,
"
integer
"
}
,
343
}
344 345
-- a simple helper
346 347
local
settings_to_hash
=
utilities
.
parsers
.
settings_to_hash
348 349
local
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
356
end
357 358
function
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
367
end
368