mlib-run.lua /size: 20 Kb    last modification: 2021-10-28 13:50
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
mlib-run
'
]
=
{
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
-- cmyk -> done, native
10
-- spot -> done, but needs reworking (simpler)
11
-- multitone ->
12
-- shade -> partly done, todo: cm
13
-- figure -> done
14
-- hyperlink -> low priority, easy
15 16
-- new * run
17
-- or
18
-- new * execute^1 * finish
19 20
-- a*[b,c] == b + a * (c-b)
21 22
--[[ldx-- 23<p>The directional helpers and pen analysis are more or less translated from the 24<l n='c'/> code. It really helps that Taco know that source so well. Taco and I spent 25quite some time on speeding up the <l n='lua'/> and <l n='c'/> code. There is not 26much to gain, especially if one keeps in mind that when integrated in <l n='tex'/> 27only a part of the time is spent in <l n='metapost'/>. Of course an integrated 28approach is way faster than an external <l n='metapost'/> and processing time 29nears zero.</p> 30--ldx]]
--
31 32
local
type
,
tostring
,
tonumber
,
next
=
type
,
tostring
,
tonumber
,
next
33
local
find
,
striplines
=
string
.
find
,
utilities
.
strings
.
striplines
34
local
concat
,
insert
,
remove
=
table
.
concat
,
table
.
insert
,
table
.
remove
35 36
local
emptystring
=
string
.
is_empty
37 38
local
trace_graphics
=
false
trackers
.
register
(
"
metapost.graphics
"
,
function
(
v
)
trace_graphics
=
v
end
)
39
local
trace_tracingall
=
false
trackers
.
register
(
"
metapost.tracingall
"
,
function
(
v
)
trace_tracingall
=
v
end
)
40 41
local
report_metapost
=
logs
.
reporter
(
"
metapost
"
)
42
local
texerrormessage
=
logs
.
texerrormessage
43 44
local
starttiming
=
statistics
.
starttiming
45
local
stoptiming
=
statistics
.
stoptiming
46 47
local
formatters
=
string
.
formatters
48 49
local
mplib
=
mplib
50
metapost
=
metapost
or
{
}
51
local
metapost
=
metapost
52 53
metapost
.
showlog
=
false
54
metapost
.
lastlog
=
"
"
55
metapost
.
texerrors
=
false
56
metapost
.
exectime
=
metapost
.
exectime
or
{
}
-- hack
57
metapost
.
nofruns
=
0
58 59
local
mpxformats
=
{
}
60
local
nofformats
=
0
61
local
mpxpreambles
=
{
}
62
local
mpxterminals
=
{
}
63
local
mpxextradata
=
{
}
64 65
-- The flatten hack is needed because the library currently barks on \n\n and the
66
-- collapse because mp cannot handle snippets due to grouping issues.
67 68
-- todo: pass tables to executempx instead of preparing beforehand,
69
-- as it's more efficient for the terminal
70 71
local
function
flatten
(
source
,
target
)
72
for
i
=
1
,
#
source
do
73
local
d
=
source
[
i
]
74
if
type
(
d
)
=
=
"
table
"
then
75
flatten
(
d
,
target
)
76
elseif
d
and
d
~
=
"
"
then
77
target
[
#
target
+
1
]
=
d
78
end
79
end
80
return
target
81
end
82 83
local
function
prepareddata
(
data
)
84
if
data
and
data
~
=
"
"
then
85
if
type
(
data
)
=
=
"
table
"
then
86
data
=
flatten
(
data
,
{
}
)
87
data
=
#
data
>
1
and
concat
(
data
,
"
\n
"
)
or
data
[
1
]
88
end
89
return
data
90
end
91
end
92 93
local
function
executempx
(
mpx
,
data
)
94
local
terminal
=
mpxterminals
[
mpx
]
95
if
terminal
then
96
terminal
.
writer
(
data
)
97
data
=
"
"
98
elseif
type
(
data
)
=
=
"
table
"
then
99
data
=
prepareddata
(
data
,
collapse
)
100
end
101
metapost
.
nofruns
=
metapost
.
nofruns
+
1
102
return
mpx
:
execute
(
data
)
103
end
104 105
directives
.
register
(
"
mplib.texerrors
"
,
function
(
v
)
metapost
.
texerrors
=
v
end
)
106
trackers
.
register
(
"
metapost.showlog
"
,
function
(
v
)
metapost
.
showlog
=
v
end
)
107 108
function
metapost
.
resetlastlog
(
)
109
metapost
.
lastlog
=
"
"
110
end
111 112
local
new_instance
=
mplib
.
new
113
local
find_file
=
mplib
.
finder
114 115
function
metapost
.
reporterror
(
result
)
116
if
not
result
then
117
report_metapost
(
"
error: no result object returned
"
)
118
return
true
119
elseif
result
.
status
=
=
0
then
120
return
false
121
elseif
mplib
.
realtimelogging
then
122
return
false
-- we already reported
123
else
124
local
t
=
result
.
term
125
local
e
=
result
.
error
126
local
l
=
result
.
log
127
local
report
=
metapost
.
texerrors
and
texerrormessage
or
report_metapost
128
if
t
and
t
~
=
"
"
then
129
report
(
"
mp error: %s
"
,
striplines
(
t
)
)
130
end
131
if
e
=
=
"
"
or
e
=
=
"
no-error
"
then
132
e
=
nil
133
end
134
if
e
then
135
report
(
"
mp error: %s
"
,
striplines
(
e
)
)
136
end
137
if
not
t
and
not
e
and
l
then
138
metapost
.
lastlog
=
metapost
.
lastlog
.
.
"
\n
"
.
.
l
139
report_metapost
(
"
log: %s
"
,
l
)
140
else
141
report_metapost
(
"
error: unknown, no error, terminal or log messages
"
)
142
end
143
return
true
144
end
145
end
146 147
local
f_preamble
=
formatters
[
[[
148 boolean mplib ; mplib := true ; 149 let dump = endinput ; 150 input "%s" ; 151 randomseed:=%s; 152
]]
]
153 154
local
methods
=
{
155
double
=
"
double
"
,
156
scaled
=
"
scaled
"
,
157
-- binary = "binary",
158
binary
=
"
double
"
,
159
decimal
=
"
decimal
"
,
160
default
=
"
scaled
"
,
161
}
162 163
function
metapost
.
runscript
(
code
)
164
return
"
"
165
end
166 167
function
metapost
.
scripterror
(
str
)
168
report_metapost
(
"
script error: %s
"
,
str
)
169
end
170 171
-- todo: random_seed
172 173
local
seed
=
nil
174 175
function
metapost
.
load
(
name
,
method
)
176
starttiming
(
mplib
)
177
if
not
seed
then
178
seed
=
job
.
getrandomseed
(
)
179
if
seed
<
=
1
then
180
seed
=
seed
%
1000
181
elseif
seed
>
4095
then
182
seed
=
seed
%
4096
183
end
184
end
185
method
=
method
and
methods
[
method
]
or
"
scaled
"
186
local
mpx
,
terminal
=
new_instance
{
187
ini_version
=
true
,
188
math_mode
=
method
,
189
run_script
=
metapost
.
runscript
,
190
script_error
=
metapost
.
scripterror
,
191
make_text
=
metapost
.
maketext
,
192
extensions
=
1
,
193
-- random_seed = seed,
194
utf8_mode
=
true
,
195
text_mode
=
true
,
196
}
197
report_metapost
(
"
initializing number mode %a
"
,
method
)
198
local
result
199
if
not
mpx
then
200
result
=
{
status
=
99
,
error
=
"
out of memory
"
}
201
else
202
mpxterminals
[
mpx
]
=
terminal
203
-- pushing permits advanced features
204
metapost
.
pushscriptrunner
(
mpx
)
205
result
=
executempx
(
mpx
,
f_preamble
(
file
.
addsuffix
(
name
,
"
mp
"
)
,
seed
)
)
206
metapost
.
popscriptrunner
(
)
207
end
208
stoptiming
(
mplib
)
209
metapost
.
reporterror
(
result
)
210
return
mpx
,
result
211
end
212 213
function
metapost
.
checkformat
(
mpsinput
,
method
)
214
local
mpsinput
=
mpsinput
or
"
metafun
"
215
local
foundfile
=
"
"
216
if
file
.
suffix
(
mpsinput
)
~
=
"
"
then
217
foundfile
=
find_file
(
mpsinput
)
or
"
"
218
end
219
-- if foundfile == "" then
220
-- foundfile = find_file(file.replacesuffix(mpsinput,"mpvi")) or ""
221
-- end
222
if
CONTEXTLMTXMODE
>
0
and
foundfile
=
=
"
"
then
223
foundfile
=
find_file
(
file
.
replacesuffix
(
mpsinput
,
"
mpxl
"
)
)
or
"
"
224
end
225
if
foundfile
=
=
"
"
then
226
foundfile
=
find_file
(
file
.
replacesuffix
(
mpsinput
,
"
mpiv
"
)
)
or
"
"
227
end
228
if
foundfile
=
=
"
"
then
229
foundfile
=
find_file
(
file
.
replacesuffix
(
mpsinput
,
"
mp
"
)
)
or
"
"
230
end
231
if
foundfile
=
=
"
"
then
232
report_metapost
(
"
loading %a fails, format not found
"
,
mpsinput
)
233
else
234
report_metapost
(
"
loading %a as %a using method %a
"
,
mpsinput
,
foundfile
,
method
or
"
default
"
)
235
local
mpx
,
result
=
metapost
.
load
(
foundfile
,
method
)
236
if
mpx
then
237
return
mpx
238
else
239
report_metapost
(
"
error in loading %a
"
,
mpsinput
)
240
metapost
.
reporterror
(
result
)
241
end
242
end
243
end
244 245
function
metapost
.
unload
(
mpx
)
246
starttiming
(
mplib
)
247
if
mpx
then
248
mpx
:
finish
(
)
249
end
250
stoptiming
(
mplib
)
251
end
252 253
metapost
.
defaultformat
=
"
metafun
"
254
metapost
.
defaultinstance
=
"
metafun
"
255
metapost
.
defaultmethod
=
"
default
"
256 257
function
metapost
.
getextradata
(
mpx
)
258
return
mpxextradata
[
mpx
]
259
end
260 261
function
metapost
.
pushformat
(
specification
,
f
,
m
)
-- was: instance, name, method
262
if
type
(
specification
)
~
=
"
table
"
then
263
specification
=
{
264
instance
=
specification
,
265
format
=
f
,
266
method
=
m
,
267
}
268
end
269
local
instance
=
specification
.
instance
270
local
format
=
specification
.
format
271
local
method
=
specification
.
method
272
local
definitions
=
specification
.
definitions
273
local
extensions
=
specification
.
extensions
274
local
preamble
=
nil
275
if
not
instance
or
instance
=
=
"
"
then
276
instance
=
metapost
.
defaultinstance
277
specification
.
instance
=
instance
278
end
279
if
not
format
or
format
=
=
"
"
then
280
format
=
metapost
.
defaultformat
281
specification
.
format
=
format
282
end
283
if
not
method
or
method
=
=
"
"
then
284
method
=
metapost
.
defaultmethod
285
specification
.
method
=
method
286
end
287
if
definitions
and
definitions
~
=
"
"
then
288
preamble
=
definitions
289
end
290
if
extensions
and
extensions
~
=
"
"
then
291
if
preamble
then
292
preamble
=
preamble
.
.
"
\n
"
.
.
extensions
293
else
294
preamble
=
extensions
295
end
296
end
297
nofformats
=
nofformats
+
1
298
local
usedinstance
=
instance
.
.
"
:
"
.
.
nofformats
299
local
mpx
=
mpxformats
[
usedinstance
]
300
local
mpp
=
mpxpreambles
[
instance
]
or
"
"
301
-- report_metapost("push instance %a (%S)",usedinstance,mpx)
302
if
preamble
then
303
preamble
=
prepareddata
(
preamble
)
304
mpp
=
mpp
.
.
"
\n
"
.
.
preamble
305
mpxpreambles
[
instance
]
=
mpp
306
end
307
if
not
mpx
then
308
report_metapost
(
"
initializing instance %a using format %a and method %a
"
,
usedinstance
,
format
,
method
)
309
mpx
=
metapost
.
checkformat
(
format
,
method
)
310
mpxformats
[
usedinstance
]
=
mpx
311
mpxextradata
[
mpx
]
=
{
}
312
if
mpp
~
=
"
"
then
313
preamble
=
mpp
314
end
315
end
316
if
preamble
then
317
executempx
(
mpx
,
preamble
)
318
end
319
specification
.
mpx
=
mpx
320
return
mpx
321
end
322 323
-- luatex.wrapup(function()
324
-- for k, mpx in next, mpxformats do
325
-- mpx:finish()
326
-- end
327
-- end)
328 329
function
metapost
.
popformat
(
)
330
nofformats
=
nofformats
-
1
331
end
332 333
function
metapost
.
reset
(
mpx
)
334
if
not
mpx
then
335
-- nothing
336
elseif
type
(
mpx
)
=
=
"
string
"
then
337
if
mpxformats
[
mpx
]
then
338
local
instance
=
mpxformats
[
mpx
]
339
instance
:
finish
(
)
340
mpxterminals
[
mpx
]
=
nil
341
mpxextradata
[
mpx
]
=
nil
342
mpxformats
[
mpx
]
=
nil
343
end
344
else
345
for
name
,
instance
in
next
,
mpxformats
do
346
if
instance
=
=
mpx
then
347
mpx
:
finish
(
)
348
mpxterminals
[
mpx
]
=
nil
349
mpxextradata
[
mpx
]
=
nil
350
mpxformats
[
mpx
]
=
nil
351
break
352
end
353
end
354
end
355
end
356 357
local
mp_tra
=
{
}
358
local
mp_tag
=
0
359 360
-- key/values
361 362
do
363 364
local
stack
,
top
=
{
}
,
nil
365 366
function
metapost
.
setvariable
(
k
,
v
)
367
if
top
then
368
top
[
k
]
=
v
369
else
370
metapost
.
variables
[
k
]
=
v
371
end
372
end
373 374
function
metapost
.
pushvariable
(
k
)
375
local
t
=
{
}
376
if
top
then
377
insert
(
stack
,
top
)
378
top
[
k
]
=
t
379
else
380
metapost
.
variables
[
k
]
=
t
381
end
382
top
=
t
383
end
384 385
function
metapost
.
popvariable
(
)
386
top
=
remove
(
stack
)
387
end
388 389
local
stack
=
{
}
390 391
function
metapost
.
pushvariables
(
)
392
insert
(
stack
,
metapost
.
variables
)
393
metapost
.
variables
=
{
}
394
end
395 396
function
metapost
.
popvariables
(
)
397
metapost
.
variables
=
remove
(
stack
)
or
metapost
.
variables
398
end
399 400
end
401 402 403
if
not
metapost
.
process
then
404 405
function
metapost
.
process
(
specification
)
406
metapost
.
run
(
specification
)
407
end
408 409
end
410 411
-- run, process, convert and flush all work with a specification with the
412
-- following (often optional) fields
413
--
414
-- mpx string or mp object
415
-- data string or table of strings
416
-- flusher table with flush methods
417
-- askedfig string ("all" etc) or number
418
-- incontext boolean
419
-- plugmode boolean
420 421
local
function
makebeginbanner
(
specification
)
422
return
formatters
[
"
%% begin graphic: n=%s\n\n
"
]
(
metapost
.
n
)
423
end
424 425
local
function
makeendbanner
(
specification
)
426
return
"
\n% end graphic\n\n
"
427
end
428 429
function
metapost
.
run
(
specification
)
430
local
mpx
=
specification
.
mpx
431
local
data
=
specification
.
data
432
local
converted
=
false
433
local
result
=
{
}
434
local
mpxdone
=
type
(
mpx
)
=
=
"
string
"
435
if
mpxdone
then
436
mpx
=
metapost
.
pushformat
{
instance
=
mpx
,
format
=
mpx
}
437
end
438
if
mpx
and
data
then
439
local
tra
=
nil
440
starttiming
(
metapost
)
-- why not at the outer level ...
441
metapost
.
variables
=
{
}
-- todo also push / pop
442
metapost
.
pushscriptrunner
(
mpx
)
443
if
trace_graphics
then
444
tra
=
mp_tra
[
mpx
]
445
if
not
tra
then
446
mp_tag
=
mp_tag
+
1
447
local
jobname
=
tex
.
jobname
448
tra
=
{
449
inp
=
io
.
open
(
formatters
[
"
%s-mplib-run-%03i.mp
"
]
(
jobname
,
mp_tag
)
,
"
w
"
)
,
450
log
=
io
.
open
(
formatters
[
"
%s-mplib-run-%03i.log
"
]
(
jobname
,
mp_tag
)
,
"
w
"
)
,
451
}
452
mp_tra
[
mpx
]
=
tra
453
end
454
local
banner
=
makebeginbanner
(
specification
)
455
tra
.
inp
:
write
(
banner
)
456
tra
.
log
:
write
(
banner
)
457
end
458
local
function
process
(
d
,
i
)
459
if
d
then
460
if
trace_graphics
then
461
if
i
then
462
tra
.
inp
:
write
(
formatters
[
"
\n%% begin snippet %s\n
"
]
(
i
)
)
463
end
464
if
type
(
d
)
=
=
"
table
"
then
465
for
i
=
1
,
#
d
do
466
tra
.
inp
:
write
(
d
[
i
]
)
467
end
468
else
469
tra
.
inp
:
write
(
d
)
470
end
471
if
i
then
472
tra
.
inp
:
write
(
formatters
[
"
\n%% end snippet %s\n
"
]
(
i
)
)
473
end
474
end
475
starttiming
(
metapost
.
exectime
)
476
result
=
executempx
(
mpx
,
d
)
477
stoptiming
(
metapost
.
exectime
)
478
if
trace_graphics
and
result
then
479
local
str
=
result
.
log
or
result
.
error
480
if
str
and
str
~
=
"
"
then
481
tra
.
log
:
write
(
str
)
482
end
483
end
484
if
not
metapost
.
reporterror
(
result
)
then
485
if
metapost
.
showlog
then
486
-- make function and overload in lmtx
487
local
str
=
result
.
term
~
=
"
"
and
result
.
term
or
"
no terminal output
"
488
if
not
emptystring
(
str
)
then
489
metapost
.
lastlog
=
metapost
.
lastlog
.
.
"
\n
"
.
.
str
490
report_metapost
(
"
log: %s
"
,
str
)
491
end
492
end
493
if
result
.
fig
then
494
converted
=
metapost
.
convert
(
specification
,
result
)
495
end
496
end
497
elseif
i
then
498
report_metapost
(
"
error: invalid graphic component %s
"
,
i
)
499
else
500
report_metapost
(
"
error: invalid graphic
"
)
501
end
502
end
503 504
-- local data = prepareddata(data)
505
if
type
(
data
)
=
=
"
table
"
then
506
if
trace_tracingall
then
507
executempx
(
mpx
,
"
tracingall;
"
)
508
end
509
process
(
data
)
510
-- for i=1,#data do
511
-- process(data[i],i)
512
-- end
513
else
514
if
trace_tracingall
then
515
data
=
"
tracingall;
"
.
.
data
516
end
517
process
(
data
)
518
end
519
if
trace_graphics
then
520
local
banner
=
makeendbanner
(
specification
)
521
tra
.
inp
:
write
(
banner
)
522
tra
.
log
:
write
(
banner
)
523
end
524
stoptiming
(
metapost
)
525
metapost
.
popscriptrunner
(
mpx
)
526
end
527
if
mpxdone
then
528
metapost
.
popformat
(
)
529
end
530
return
converted
,
result
531
end
532 533
if
not
metapost
.
convert
then
534 535
function
metapost
.
convert
(
)
536
report_metapost
(
'
warning: no converter set
'
)
537
end
538 539
end
540 541
-- This will be redone as we no longer output svg of ps!
542 543
-- function metapost.directrun(formatname,filename,outputformat,astable,mpdata)
544
-- local fullname = file.addsuffix(filename,"mp")
545
-- local data = mpdata or io.loaddata(fullname)
546
-- if outputformat ~= "svg" then
547
-- outputformat = "mps"
548
-- end
549
-- if not data then
550
-- report_metapost("unknown file %a",filename)
551
-- else
552
-- local mpx = metapost.checkformat(formatname)
553
-- if not mpx then
554
-- report_metapost("unknown format %a",formatname)
555
-- else
556
-- report_metapost("processing %a",(mpdata and (filename or "data")) or fullname)
557
-- local result = executempx(mpx,data)
558
-- if not result then
559
-- report_metapost("error: no result object returned")
560
-- elseif result.status > 0 then
561
-- report_metapost("error: %s",(result.term or "no-term") .. "\n" .. (result.error or "no-error"))
562
-- else
563
-- if metapost.showlog then
564
-- metapost.lastlog = metapost.lastlog .. "\n" .. result.term
565
-- report_metapost("info: %s",result.term or "no-term")
566
-- end
567
-- local figures = result.fig
568
-- if figures then
569
-- local sorted = table.sortedkeys(figures)
570
-- if astable then
571
-- local result = { }
572
-- report_metapost("storing %s figures in table",#sorted)
573
-- for k=1,#sorted do
574
-- local v = sorted[k]
575
-- if outputformat == "mps" then
576
-- result[v] = figures[v]:postscript()
577
-- else
578
-- result[v] = figures[v]:svg() -- (3) for prologues
579
-- end
580
-- end
581
-- return result
582
-- else
583
-- local basename = file.removesuffix(file.basename(filename))
584
-- for k=1,#sorted do
585
-- local v = sorted[k]
586
-- local output
587
-- if outputformat == "mps" then
588
-- output = figures[v]:postscript()
589
-- else
590
-- output = figures[v]:svg() -- (3) for prologues
591
-- end
592
-- local outname = formatters["%s-%s.%s"](basename,v,outputformat)
593
-- report_metapost("saving %s bytes in %a",#output,outname)
594
-- io.savedata(outname,output)
595
-- end
596
-- return #sorted
597
-- end
598
-- end
599
-- end
600
-- end
601
-- end
602
-- end
603 604
function
metapost
.
directrun
(
formatname
,
filename
,
outputformat
,
astable
,
mpdata
)
605
report_metapost
(
"
producing postscript and svg is no longer supported
"
)
606
end
607 608
do
609 610
local
result
=
{
}
611
local
width
=
0
612
local
height
=
0
613
local
depth
=
0
614
local
bbox
=
{
0
,
0
,
0
,
0
}
615 616
local
flusher
=
{
617
startfigure
=
function
(
n
,
llx
,
lly
,
urx
,
ury
)
618
result
=
{
}
619
width
=
urx
-
llx
620
height
=
ury
621
depth
=
-
lly
622
bbox
=
{
llx
,
lly
,
urx
,
ury
}
623
end
,
624
flushfigure
=
function
(
t
)
625
local
r
=
#
result
626
for
i
=
1
,
#
t
do
627
r
=
r
+
1
628
result
[
r
]
=
t
[
i
]
629
end
630
end
,
631
stopfigure
=
function
(
)
632
end
,
633
}
634 635
-- make table variant:
636 637
function
metapost
.
simple
(
instance
,
code
,
useextensions
,
dontwrap
)
638
-- can we pickup the instance ?
639
local
mpx
=
metapost
.
pushformat
{
640
instance
=
instance
or
"
simplefun
"
,
641
format
=
"
metafun
"
,
-- or: minifun
642
method
=
"
double
"
,
643
}
644
metapost
.
process
{
645
mpx
=
mpx
,
646
flusher
=
flusher
,
647
askedfig
=
1
,
648
useplugins
=
useextensions
,
649
data
=
dontwrap
and
{
code
}
or
{
"
beginfig(1);
"
,
code
,
"
endfig;
"
}
,
650
incontext
=
false
,
651
}
652
metapost
.
popformat
(
)
653
if
result
then
654
local
stream
=
concat
(
result
,
"
"
)
655
result
=
{
}
-- nil -- cleanup .. weird, we can have a dangling q
656
return
stream
,
width
,
height
,
depth
,
bbox
657
else
658
return
"
"
,
0
,
0
,
0
,
{
0
,
0
,
0
,
0
}
659
end
660
end
661 662
end
663 664
local
getstatistics
=
mplib
.
getstatistics
or
mplib
.
statistics
665 666
function
metapost
.
getstatistics
(
memonly
)
667
if
memonly
then
668
local
n
,
m
=
0
,
0
669
for
name
,
mpx
in
next
,
mpxformats
do
670
n
=
n
+
1
671
m
=
m
+
getstatistics
(
mpx
)
.
memory
672
end
673
return
n
,
m
674
else
675
local
t
=
{
}
676
for
name
,
mpx
in
next
,
mpxformats
do
677
t
[
name
]
=
getstatistics
(
mpx
)
678
end
679
return
t
680
end
681
end
682