mlib-ctx.lua /size: 11 Kb    last modification: 2021-10-28 13:50
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
mlib-ctx
'
]
=
{
2
version
=
1
.
001
,
3
comment
=
"
companion to mlib-ctx.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
type
,
tostring
=
type
,
tostring
10
local
format
,
concat
=
string
.
format
,
table
.
concat
11
local
settings_to_hash
=
utilities
.
parsers
.
settings_to_hash
12
local
formatters
=
string
.
formatters
13 14
local
report_metapost
=
logs
.
reporter
(
"
metapost
"
)
15
local
status_metapost
=
logs
.
messenger
(
"
metapost
"
)
16 17
local
starttiming
=
statistics
.
starttiming
18
local
stoptiming
=
statistics
.
stoptiming
19 20
local
trace_graphic
=
false
21 22
trackers
.
register
(
"
metapost.graphics
"
,
23
function
(
v
)
trace_graphic
=
v
end
24
)
;
25 26
local
mplib
=
mplib
27 28
metapost
=
metapost
or
{
}
29
local
metapost
=
metapost
30
local
context
=
context
31 32
local
setters
=
tokens
.
setters
33
local
setmacro
=
setters
.
macro
34
local
implement
=
interfaces
.
implement
35 36
local
v_no
=
interfaces
.
variables
.
no
37 38
local
extensiondata
=
metapost
.
extensiondata
or
storage
.
allocate
{
}
39
metapost
.
extensiondata
=
extensiondata
40 41
storage
.
register
(
"
metapost/extensiondata
"
,
extensiondata
,
"
metapost.extensiondata
"
)
42 43
function
metapost
.
setextensions
(
instances
,
data
)
44
if
data
and
data
~
=
"
"
then
45
extensiondata
[
#
extensiondata
+
1
]
=
{
46
usedinall
=
not
instances
or
instances
=
=
"
"
,
47
instances
=
settings_to_hash
(
instances
or
"
"
)
,
48
extensions
=
data
,
49
}
50
end
51
end
52 53
function
metapost
.
getextensions
(
instance
,
state
)
54
if
state
and
state
=
=
v_no
then
55
return
"
"
56
else
57
local
t
=
{
}
58
for
i
=
1
,
#
extensiondata
do
59
local
e
=
extensiondata
[
i
]
60
local
status
=
e
.
instances
[
instance
]
61
if
(
status
~
=
true
)
and
(
e
.
usedinall
or
status
)
then
62
t
[
#
t
+
1
]
=
e
.
extensions
63
e
.
instances
[
instance
]
=
true
64
end
65
end
66
return
concat
(
t
,
"
"
)
67
end
68
end
69 70
implement
{
71
name
=
"
setmpextensions
"
,
72
actions
=
metapost
.
setextensions
,
73
arguments
=
"
2 strings
"
,
74
}
75 76
implement
{
77
name
=
"
getmpextensions
"
,
78
actions
=
{
metapost
.
getextensions
,
context
}
,
79
arguments
=
"
string
"
80
}
81 82
local
patterns
=
{
83
CONTEXTLMTXMODE
>
0
and
"
meta-imp-%s.mkxl
"
or
"
"
,
84
"
meta-imp-%s.mkiv
"
,
85
"
meta-imp-%s.tex
"
,
86
-- obsolete:
87
"
meta-%s.mkiv
"
,
88
"
meta-%s.tex
"
89
}
90 91
local
function
action
(
name
,
foundname
)
92
commands
.
loadlibrary
(
name
,
foundname
,
false
)
93
status_metapost
(
"
library %a is loaded
"
,
name
)
94
end
95 96
local
function
failure
(
name
)
97
report_metapost
(
"
library %a is unknown or invalid
"
,
name
)
98
end
99 100
implement
{
101
name
=
"
useMPlibrary
"
,
102
arguments
=
"
string
"
,
103
actions
=
function
(
name
)
104
resolvers
.
uselibrary
{
105
name
=
name
,
106
patterns
=
patterns
,
107
action
=
action
,
108
failure
=
failure
,
109
onlyonce
=
true
,
110
}
111
end
112
}
113 114
-- metapost.variables = { } -- to be stacked
115 116
implement
{
117
name
=
"
mprunvar
"
,
118
arguments
=
"
string
"
,
119
actions
=
function
(
name
)
120
local
value
=
metapost
.
variables
[
name
]
121
if
value
~
=
nil
then
122
local
tvalue
=
type
(
value
)
123
if
tvalue
=
=
"
table
"
then
124
context
(
concat
(
value
,
"
"
)
)
125
elseif
tvalue
=
=
"
number
"
or
tvalue
=
=
"
boolean
"
then
126
context
(
tostring
(
value
)
)
127
elseif
tvalue
=
=
"
string
"
then
128
context
(
value
)
129
end
130
end
131
end
132
}
133 134
implement
{
135
name
=
"
mpruntab
"
,
136
arguments
=
{
"
string
"
,
"
integer
"
}
,
137
actions
=
function
(
name
,
n
)
138
local
value
=
metapost
.
variables
[
name
]
139
if
value
~
=
nil
then
140
local
tvalue
=
type
(
value
)
141
if
tvalue
=
=
"
table
"
then
142
context
(
value
[
n
]
)
143
elseif
tvalue
=
=
"
number
"
or
tvalue
=
=
"
boolean
"
then
144
context
(
tostring
(
value
)
)
145
elseif
tvalue
=
=
"
string
"
then
146
context
(
value
)
147
end
148
end
149
end
150
}
151 152
implement
{
153
name
=
"
mprunset
"
,
154
arguments
=
"
2 strings
"
,
155
actions
=
function
(
name
,
connector
)
156
local
value
=
metapost
.
variables
[
name
]
157
if
value
~
=
nil
then
158
local
tvalue
=
type
(
value
)
159
if
tvalue
=
=
"
table
"
then
160
context
(
concat
(
value
,
connector
)
)
161
elseif
tvalue
=
=
"
number
"
or
tvalue
=
=
"
boolean
"
then
162
context
(
tostring
(
value
)
)
163
elseif
tvalue
=
=
"
string
"
then
164
context
(
value
)
165
end
166
end
167
end
168
}
169 170
-- we need to move more from pps to here as pps is the plugin .. the order is a mess
171
-- or just move the scanners to pps
172 173
function
metapost
.
graphic
(
specification
)
174
metapost
.
pushformat
(
specification
)
175
metapost
.
graphic_base_pass
(
specification
)
176
metapost
.
popformat
(
)
177
end
178 179
function
metapost
.
startgraphic
(
t
)
180
if
not
t
then
181
t
=
{
}
182
end
183
if
not
t
.
instance
then
184
t
.
instance
=
metapost
.
defaultinstance
185
end
186
if
not
t
.
format
then
187
t
.
format
=
metapost
.
defaultformat
188
end
189
if
not
t
.
method
then
190
t
.
method
=
metapost
.
defaultmethod
191
end
192
t
.
data
=
{
}
193
return
t
194
end
195 196
function
metapost
.
stopgraphic
(
t
)
197
if
t
then
198
t
.
data
=
concat
(
t
.
data
or
{
}
,
"
\n
"
)
199
if
trace_graphic
then
200
report_metapost
(
"
\n
"
.
.
t
.
data
.
.
"
\n
"
)
201
end
202
metapost
.
graphic
(
t
)
203
end
204
end
205 206
function
metapost
.
tographic
(
t
,
f
,
s
,
...
)
207
local
d
=
t
.
data
208
d
[
#
d
+
1
]
=
s
and
formatters
[
f
]
(
s
,
...
)
or
f
209
end
210 211
implement
{
212
name
=
"
mpgraphic
"
,
213
actions
=
metapost
.
graphic
,
214
arguments
=
{
215
{
216
{
"
instance
"
}
,
217
{
"
format
"
}
,
218
{
"
data
"
}
,
219
{
"
initializations
"
}
,
220
{
"
extensions
"
}
,
221
{
"
inclusions
"
}
,
222
{
"
definitions
"
}
,
223
{
"
figure
"
}
,
224
{
"
method
"
}
,
225
{
"
namespace
"
}
,
226
}
227
}
228
}
229 230
implement
{
231
name
=
"
mpsetoutercolor
"
,
232
actions
=
function
(
...
)
metapost
.
setoutercolor
(
...
)
end
,
-- not yet implemented
233
arguments
=
{
"
integer
"
,
"
integer
"
,
"
integer
"
,
"
integer
"
}
234
}
235 236
implement
{
237
name
=
"
mpflushreset
"
,
238
actions
=
function
(
)
metapost
.
flushreset
(
)
end
-- not yet implemented
239
}
240 241
implement
{
242
name
=
"
mpflushliteral
"
,
243
actions
=
function
(
str
)
metapost
.
flushliteral
(
str
)
end
,
-- not yet implemented
244
arguments
=
"
string
"
,
245
}
246 247
-- this has to become a codeinjection
248 249
function
metapost
.
getclippath
(
specification
)
-- why not a special instance for this
250
local
mpx
=
metapost
.
pushformat
(
specification
)
251
local
data
=
specification
.
data
or
"
"
252
if
mpx
and
data
~
=
"
"
then
253
starttiming
(
metapost
)
254
starttiming
(
metapost
.
exectime
)
255
local
result
=
mpx
:
execute
(
format
(
"
%s;%s;beginfig(1);%s;%s;endfig;
"
,
256
specification
.
extensions
or
"
"
,
257
specification
.
inclusions
or
"
"
,
258
specification
.
initializations
or
"
"
,
259
data
260
)
)
261
stoptiming
(
metapost
.
exectime
)
262
if
result
.
status
>
0
then
263
report_metapost
(
"
%s: %s
"
,
result
.
status
,
result
.
error
or
result
.
term
or
result
.
log
)
264
result
=
nil
265
else
266
result
=
metapost
.
filterclippath
(
result
)
267
end
268
stoptiming
(
metapost
)
269
metapost
.
popformat
(
)
270
return
result
271
else
272
metapost
.
popformat
(
)
273
end
274
end
275 276
function
metapost
.
filterclippath
(
result
)
277
if
result
then
278
local
figures
=
result
.
fig
279
if
figures
and
#
figures
>
0
then
280
local
figure
=
figures
[
1
]
281
local
objects
=
figure
:
objects
(
)
282
if
objects
then
283
local
lastclippath
284
for
o
=
1
,
#
objects
do
285
local
object
=
objects
[
o
]
286
if
object
.
type
=
=
"
start_clip
"
then
287
lastclippath
=
object
.
path
288
end
289
end
290
return
lastclippath
291
end
292
end
293
end
294
end
295 296
function
metapost
.
theclippath
(
...
)
297
local
result
=
metapost
.
getclippath
(
...
)
298
if
result
then
-- we could just print the table
299
return
concat
(
metapost
.
flushnormalpath
(
result
)
,
"
"
)
300
else
301
return
"
"
302
end
303
end
304 305
implement
{
306
name
=
"
mpsetclippath
"
,
307
actions
=
function
(
specification
)
308
local
p
=
specification
.
data
and
metapost
.
theclippath
(
specification
)
309
if
not
p
or
p
=
=
"
"
then
310
local
b
=
number
.
dimenfactors
.
bp
311
local
w
=
b
*
(
specification
.
width
or
0
)
312
local
h
=
b
*
(
specification
.
height
or
0
)
313
p
=
formatters
[
"
0 0 m %.6N 0 l %.6N %.6N l 0 %.6N l
"
]
(
w
,
w
,
h
,
h
)
314
end
315
setmacro
(
"
MPclippath
"
,
p
,
"
global
"
)
316
end
,
317
arguments
=
{
318
{
319
{
"
instance
"
}
,
320
{
"
format
"
}
,
321
{
"
data
"
}
,
322
{
"
initializations
"
}
,
323
{
"
useextensions
"
}
,
324
{
"
inclusions
"
}
,
325
{
"
method
"
}
,
326
{
"
namespace
"
}
,
327
{
"
width
"
,
"
dimension
"
}
,
328
{
"
height
"
,
"
dimension
"
}
,
329
}
,
330
}
331
}
332 333
statistics
.
register
(
"
metapost
"
,
function
(
)
334
local
n
=
metapost
.
nofruns
335
if
n
and
n
>
0
then
336
local
elapsedtime
=
statistics
.
elapsedtime
337
local
elapsed
=
statistics
.
elapsed
338
local
runs
,
stats
=
metapost
.
nofscriptruns
(
)
339
local
instances
,
340
memory
=
metapost
.
getstatistics
(
true
)
341
return
format
(
"
%s seconds, loading: %s, execution: %s, n: %s, average: %s, instances: %i, luacalls: %s, memory: %0.3f M
"
,
342
elapsedtime
(
metapost
)
,
elapsedtime
(
mplib
)
,
elapsedtime
(
metapost
.
exectime
)
,
n
,
343
elapsedtime
(
(
elapsed
(
metapost
)
+
elapsed
(
mplib
)
+
elapsed
(
metapost
.
exectime
)
)
/
n
)
,
344
instances
,
stats
and
stats
or
runs
,
memory
/
(
1024
*
1024
)
)
345
else
346
return
nil
347
end
348
end
)
349 350
-- only used in graphictexts
351 352
metapost
.
tex
=
metapost
.
tex
or
{
}
353
local
mptex
=
metapost
.
tex
354 355
local
environments
=
{
}
356 357
function
mptex
.
set
(
str
)
358
environments
[
#
environments
+
1
]
=
str
359
end
360 361
function
mptex
.
setfrombuffer
(
name
)
362
environments
[
#
environments
+
1
]
=
buffers
.
getcontent
(
name
)
363
end
364 365
function
mptex
.
get
(
)
366
return
concat
(
environments
,
"
\n
"
)
367
end
368 369
function
mptex
.
reset
(
)
370
environments
=
{
}
371
end
372 373
implement
{
374
name
=
"
mppushvariables
"
,
375
actions
=
metapost
.
pushvariables
,
376
}
377 378
implement
{
379
name
=
"
mppopvariables
"
,
380
actions
=
metapost
.
popvariables
,
381
}
382 383
implement
{
384
name
=
"
mptexset
"
,
385
arguments
=
"
string
"
,
386
actions
=
mptex
.
set
387
}
388 389
implement
{
390
name
=
"
mptexsetfrombuffer
"
,
391
arguments
=
"
string
"
,
392
actions
=
mptex
.
setfrombuffer
393
}
394 395
implement
{
396
name
=
"
mptexget
"
,
397
actions
=
{
mptex
.
get
,
context
}
398
}
399 400
implement
{
401
name
=
"
mptexreset
"
,
402
actions
=
mptex
.
reset
403
}
404 405
-- moved from mlib-lua:
406 407
mp
=
mp
or
{
-- system namespace
408
set
=
{
}
,
409
get
=
{
}
,
410
aux
=
{
}
,
411
scan
=
{
}
,
412
skip
=
{
}
,
413
inject
=
{
}
,
414
}
415 416
MP
=
MP
or
{
}
-- user namespace
417 418
-- We had this:
419
--
420
-- table.setmetatablecall(mp,function(t,k) mpprint(k) end)
421
--
422
-- but the next one is more interesting because we cannot use calls like:
423
--
424
-- lua.mp.somedefdname("foo")
425
--
426
-- which is due to expansion of somedefdname during suffix creation. So:
427
--
428
-- lua.mp("somedefdname","foo")
429 430
table
.
setmetatablecall
(
mp
,
function
(
t
,
k
,
...
)
return
t
[
k
]
(
...
)
end
)
431
table
.
setmetatablecall
(
MP
,
function
(
t
,
k
,
...
)
return
t
[
k
]
(
...
)
end
)
432