mtx-context.lua /size: 66 Kb    last modification: 2021-10-28 13:50
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
mtx-context
'
]
=
{
2
version
=
1
.
001
,
3
comment
=
"
companion to mtxrun.lua
"
,
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
-- todo: more local functions
10
-- todo: pass jobticket/ctxdata table around
11 12
local
type
,
next
,
tostring
,
tonumber
=
type
,
next
,
tostring
,
tonumber
13
local
format
,
gmatch
,
match
,
gsub
,
find
=
string
.
format
,
string
.
gmatch
,
string
.
match
,
string
.
gsub
,
string
.
find
14
local
quote
,
validstring
,
splitstring
=
string
.
quote
,
string
.
valid
,
string
.
split
15
local
sort
,
concat
,
insert
,
sortedhash
,
tohash
=
table
.
sort
,
table
.
concat
,
table
.
insert
,
table
.
sortedhash
,
table
.
tohash
16
local
settings_to_array
=
utilities
.
parsers
.
settings_to_array
17
local
appendtable
=
table
.
append
18
local
lpegpatterns
,
lpegmatch
,
Cs
,
P
=
lpeg
.
patterns
,
lpeg
.
match
,
lpeg
.
Cs
,
lpeg
.
P
19 20
local
getargument
=
environment
.
getargument
or
environment
.
argument
21
local
setargument
=
environment
.
setargument
22 23
local
filejoinname
=
file
.
join
24
local
filebasename
=
file
.
basename
25
local
filenameonly
=
file
.
nameonly
26
local
filepathpart
=
file
.
pathpart
27
local
filesuffix
=
file
.
suffix
28
local
fileaddsuffix
=
file
.
addsuffix
29
local
filenewsuffix
=
file
.
replacesuffix
30
local
removesuffix
=
file
.
removesuffix
31
local
validfile
=
lfs
.
isfile
32
local
removefile
=
os
.
remove
33
local
renamefile
=
os
.
rename
34
local
formatters
=
string
.
formatters
35 36
local
application
=
logs
.
application
{
37
name
=
"
mtx-context
"
,
38
banner
=
"
ConTeXt Process Management 1.04
"
,
39
-- helpinfo = helpinfo, -- table with { category_a = text_1, category_b = text_2 } or helpstring or xml_blob
40
helpinfo
=
"
mtx-context.xml
"
,
41
}
42 43
-- local luatexflags = {
44
-- ["8bit"] = true, -- ignored, input is assumed to be in UTF-8 encoding
45
-- ["default-translate-file"] = true, -- ignored, input is assumed to be in UTF-8 encoding
46
-- ["translate-file"] = true, -- ignored, input is assumed to be in UTF-8 encoding
47
-- ["etex"] = true, -- ignored, the etex extensions are always active
48
-- ["parse-first-line"] = true, -- ignored, enable parsing of the first line of the input file
49
-- ["no-parse-first-line"] = true, -- ignored, disable parsing of the first line of the input file
50
--
51
-- ["credits"] = true, -- display credits and exit
52
-- ["debug-format"] = true, -- enable format debugging
53
-- ["disable-write18"] = true, -- disable \write18{SHELL COMMAND}
54
-- ["draftmode"] = true, -- switch on draft mode (generates no output PDF)
55
-- ["enable-write18"] = true, -- enable \write18{SHELL COMMAND}
56
-- ["file-line-error"] = true, -- enable file:line:error style messages
57
-- ["file-line-error-style"] = true, -- aliases of --file-line-error
58
-- ["no-file-line-error"] = true, -- disable file:line:error style messages
59
-- ["no-file-line-error-style"] = true, -- aliases of --no-file-line-error
60
-- ["fmt"] = true, -- load the format file FORMAT
61
-- ["halt-on-error"] = true, -- stop processing at the first error
62
-- ["help"] = true, -- display help and exit
63
-- ["ini"] = true, -- be iniluatex, for dumping formats
64
-- ["interaction"] = true, -- set interaction mode (STRING=batchmode/nonstopmode/scrollmode/errorstopmode)
65
-- ["jobname"] = true, -- set the job name to STRING
66
-- ["kpathsea-debug"] = true, -- set path searching debugging flags according to the bits of NUMBER
67
-- ["lua"] = true, -- load and execute a lua initialization script
68
-- ["mktex"] = true, -- enable mktexFMT generation (FMT=tex/tfm)
69
-- ["no-mktex"] = true, -- disable mktexFMT generation (FMT=tex/tfm)
70
-- ["nosocket"] = true, -- disable the lua socket library
71
-- ["output-comment"] = true, -- use STRING for DVI file comment instead of date (no effect for PDF)
72
-- ["output-directory"] = true, -- use existing DIR as the directory to write files in
73
-- ["output-format"] = true, -- use FORMAT for job output; FORMAT is 'dvi' or 'pdf'
74
-- ["progname"] = true, -- set the program name to STRING
75
-- ["recorder"] = true, -- enable filename recorder
76
-- ["safer"] = true, -- disable easily exploitable lua commands
77
-- ["shell-escape"] = true, -- enable \write18{SHELL COMMAND}
78
-- ["no-shell-escape"] = true, -- disable \write18{SHELL COMMAND}
79
-- ["shell-restricted"] = true, -- restrict \write18 to a list of commands given in texmf.cnf
80
-- ["nodates"] = true, -- no production dates in pdf file
81
-- ["trailerid"] = true, -- alternative trailer id
82
-- ["synctex"] = true, -- enable synctex
83
-- ["version"] = true, -- display version and exit
84
-- ["luaonly"] = true, -- run a lua file, then exit
85
-- ["luaconly"] = true, -- byte-compile a lua file, then exit
86
-- ["jiton"] = false, -- not supported (makes no sense, slower)
87
-- }
88 89
local
report
=
application
.
report
90 91
scripts
=
scripts
or
{
}
92
scripts
.
context
=
scripts
.
context
or
{
}
93 94
-- for the moment here
95 96
if
jit
then
-- already luajittex
97
setargument
(
"
engine
"
,
"
luajittex
"
)
98
setargument
(
"
jit
"
,
nil
)
99
elseif
getargument
(
"
luatex
"
)
then
-- relaunch luajittex
100
setargument
(
"
engine
"
,
"
luatex
"
)
101
elseif
getargument
(
"
jit
"
)
or
getargument
(
"
luajittex
"
)
then
-- relaunch luajittex
102
-- bonus shortcut, we assume that --jit also indicates the engine
103
-- although --jit and --engine=luajittex are independent
104
setargument
(
"
engine
"
,
"
luajittex
"
)
105
end
106 107
-- -- The way we use stubs will change in a bit in 2019 (mtxrun and context). We also normalize
108
-- -- the platforms to use a similar approach to this.
109 110
local
engine_new
=
filenameonly
(
getargument
(
"
engine
"
)
or
directives
.
value
(
"
system.engine
"
)
)
111
local
engine_old
=
filenameonly
(
environment
.
ownmain
)
or
filenameonly
(
environment
.
ownbin
)
112 113
local
function
restart
(
engine_old
,
engine_new
)
114
local
generate
=
environment
.
arguments
.
generate
and
(
engine_new
=
=
"
luatex
"
or
engine_new
=
=
"
luajittex
"
)
115
local
arguments
=
generate
and
"
--generate
"
or
environment
.
reconstructcommandline
(
)
116
local
ownname
=
filejoinname
(
filepathpart
(
environment
.
ownname
)
,
"
mtxrun.lua
"
)
117
local
command
=
format
(
"
%s --luaonly %q %s --redirected
"
,
engine_new
,
ownname
,
arguments
)
118
report
(
format
(
"
redirect %s -> %s: %s
"
,
engine_old
,
engine_new
,
command
)
)
119
local
result
=
os
.
execute
(
command
)
120
os
.
exit
(
result
=
=
0
and
0
or
1
)
121
end
122 123
-- if getargument("redirected") then
124
-- setargument("engine",engine_old) -- later on we need this
125
-- elseif engine_new == engine_old then
126
-- setargument("engine",engine_new) -- later on we need this
127
-- elseif environment.validengines[engine_new] and engine_new ~= environment.basicengines[engine_old] then
128
-- restart(engine_old,engine_new)
129
-- else
130
-- setargument("engine",engine_new) -- later on we need this
131
-- end
132 133
if
environment
.
validengines
[
engine_new
]
and
engine_new
~
=
environment
.
basicengines
[
engine_old
]
then
134
restart
(
engine_old
,
engine_new
)
135
end
136 137
-- so far
138 139
-- constants
140 141
local
usedfiles
=
{
142
nop
=
"
cont-nop.mkiv
"
,
143
yes
=
"
cont-yes.mkiv
"
,
144
}
145 146
local
usedsuffixes
=
{
147
before
=
{
148
"
tuc
"
149
}
,
150
after
=
{
151
"
pdf
"
,
"
tuc
"
,
"
log
"
152
}
,
153
keep
=
{
154
"
log
"
155
}
,
156
}
157 158
local
formatofinterface
=
{
159
en
=
"
cont-en
"
,
160
uk
=
"
cont-uk
"
,
161
de
=
"
cont-de
"
,
162
fr
=
"
cont-fr
"
,
163
nl
=
"
cont-nl
"
,
164
cs
=
"
cont-cs
"
,
165
it
=
"
cont-it
"
,
166
ro
=
"
cont-ro
"
,
167
pe
=
"
cont-pe
"
,
168
}
169 170
local
defaultformats
=
{
171
"
cont-en
"
,
172
-- "cont-nl",
173
}
174 175
-- purging files (we should have an mkii and mkiv variants)
176 177
local
generic_files
=
{
178
"
texexec.tex
"
,
"
texexec.tui
"
,
"
texexec.tuo
"
,
179
"
texexec.tuc
"
,
"
texexec.tua
"
,
180
"
texexec.ps
"
,
"
texexec.pdf
"
,
"
texexec.dvi
"
,
181
"
cont-opt.tex
"
,
"
cont-opt.bak
"
182
}
183 184
local
obsolete_results
=
{
185
"
dvi
"
,
186
}
187 188
local
temporary_runfiles
=
{
189
"
tui
"
,
-- mkii two pass file
190
"
tua
"
,
-- mkiv obsolete
191
"
tup
"
,
"
ted
"
,
"
tes
"
,
-- texexec
192
"
top
"
,
-- mkii options file
193
"
log
"
,
-- tex log file
194
"
tmp
"
,
-- mkii buffer file
195
"
run
"
,
-- mkii stub
196
"
bck
"
,
-- backup (obsolete)
197
"
rlg
"
,
-- resource log
198
"
ctl
"
,
--
199
"
mpt
"
,
"
mpx
"
,
"
mpd
"
,
"
mpo
"
,
"
mpb
"
,
-- metafun
200
"
prep
"
,
-- context preprocessed
201
"
pgf
"
,
-- tikz
202
"
aux
"
,
"
blg
"
,
-- bibtex
203
}
204 205
local
temporary_suffixes
=
{
206
"
prep
"
,
-- context preprocessed
207
}
208 209
local
synctex_runfiles
=
{
210
"
synctex
"
,
"
synctex.gz
"
,
"
syncctx
"
-- synctex
211
}
212 213
local
persistent_runfiles
=
{
214
"
tuo
"
,
-- mkii two pass file
215
"
tub
"
,
-- mkii buffer file
216
"
top
"
,
-- mkii options file
217
"
tuc
"
,
-- mkiv two pass file
218
"
bbl
"
,
-- bibtex
219
}
220 221
local
special_runfiles
=
{
222
"
%-mpgraph
"
,
"
%-mprun
"
,
"
%-temp%-
"
,
223
}
224 225
local
extra_runfiles
=
{
226
"
^m_k_i_v_.-%.pdf$
"
,
227
"
^l_m_t_x_.-%.pdf$
"
,
228
}
229 230
local
function
purge_file
(
dfile
,
cfile
)
231
if
cfile
and
validfile
(
cfile
)
then
232
if
removefile
(
dfile
)
then
233
return
filebasename
(
dfile
)
234
end
235
elseif
dfile
then
236
if
removefile
(
dfile
)
then
237
return
filebasename
(
dfile
)
238
end
239
end
240
end
241 242
-- process information
243 244
local
ctxrunner
=
{
}
-- namespace will go
245 246
local
ctx_locations
=
{
'
..
'
,
'
../..
'
}
247 248
function
ctxrunner
.
new
(
)
249
return
{
250
ctxname
=
"
"
,
251
jobname
=
"
"
,
252
flags
=
{
}
,
253
}
254
end
255 256
function
ctxrunner
.
checkfile
(
ctxdata
,
ctxname
,
defaultname
)
257 258
if
not
ctxdata
.
jobname
or
ctxdata
.
jobname
=
=
"
"
or
getargument
(
"
noctx
"
)
then
259
return
260
end
261 262
ctxdata
.
ctxname
=
ctxname
or
removesuffix
(
ctxdata
.
jobname
)
or
"
"
263 264
if
ctxdata
.
ctxname
=
=
"
"
then
265
return
266
end
267 268
ctxdata
.
jobname
=
fileaddsuffix
(
ctxdata
.
jobname
,
'
tex
'
)
269
ctxdata
.
ctxname
=
fileaddsuffix
(
ctxdata
.
ctxname
,
'
ctx
'
)
270 271
report
(
"
jobname: %s
"
,
ctxdata
.
jobname
)
272
report
(
"
ctxname: %s
"
,
ctxdata
.
ctxname
)
273 274
-- mtxrun should resolve kpse: and file:
275 276
local
usedname
=
ctxdata
.
ctxname
277
local
found
=
validfile
(
usedname
)
278 279
-- no further test if qualified path
280 281
if
not
found
then
282
for
_
,
path
in
next
,
ctx_locations
do
283
local
fullname
=
filejoinname
(
path
,
ctxdata
.
ctxname
)
284
if
validfile
(
fullname
)
then
285
usedname
=
fullname
286
found
=
true
287
break
288
end
289
end
290
end
291 292
if
not
found
then
293
usedname
=
resolvers
.
findfile
(
ctxdata
.
ctxname
,
"
tex
"
)
294
found
=
usedname
~
=
"
"
295
end
296 297
if
not
found
and
defaultname
and
defaultname
~
=
"
"
and
validfile
(
defaultname
)
then
298
usedname
=
defaultname
299
found
=
true
300
end
301 302
if
not
found
then
303
return
304
end
305 306
local
xmldata
=
xml
.
load
(
usedname
)
307 308
if
not
xmldata
then
309
return
310
else
311
-- test for valid, can be text file
312
end
313 314
local
ctxpaths
=
table
.
append
(
{
'
.
'
,
filepathpart
(
ctxdata
.
ctxname
)
}
,
ctx_locations
)
315 316
xml
.
include
(
xmldata
,
'
ctx:include
'
,
'
name
'
,
ctxpaths
)
317 318
local
flags
=
ctxdata
.
flags
319 320
for
e
in
xml
.
collected
(
xmldata
,
"
/ctx:job/ctx:flags/ctx:flag
"
)
do
321
local
flag
=
xml
.
text
(
e
)
or
"
"
322
local
key
,
value
=
match
(
flag
,
"
^(.-)=(.+)$
"
)
323
if
key
and
value
then
324
flags
[
key
]
=
value
325
else
326
flags
[
flag
]
=
true
327
end
328
end
329 330
end
331 332
function
ctxrunner
.
checkflags
(
ctxdata
)
333
if
ctxdata
then
334
for
k
,
v
in
next
,
ctxdata
.
flags
do
335
if
getargument
(
k
)
=
=
nil
then
336
setargument
(
k
,
v
)
337
end
338
end
339
end
340
end
341 342
-- multipass control
343 344
local
multipass_suffixes
=
{
"
.tuc
"
}
345
local
multipass_nofruns
=
9
-- better for tracing oscillation
346
local
multipass_forcedruns
=
false
347 348
local
function
multipass_hashfiles
(
jobname
)
349
local
hash
=
{
}
350
for
i
=
1
,
#
multipass_suffixes
do
351
local
suffix
=
multipass_suffixes
[
i
]
352
local
full
=
jobname
.
.
suffix
353
hash
[
full
]
=
md5
.
hex
(
io
.
loaddata
(
full
)
or
"
unknown
"
)
354
end
355
return
hash
356
end
357 358
local
function
multipass_changed
(
oldhash
,
newhash
)
359
for
k
,
v
in
next
,
oldhash
do
360
if
v
~
=
newhash
[
k
]
then
361
return
true
362
end
363
end
364
return
false
365
end
366 367
local
f_tempfile_i
=
formatters
[
"
%s-%s-%02d.tmp
"
]
368
local
f_tempfile_s
=
formatters
[
"
%s-%s-keep.%s
"
]
369 370
local
function
backup
(
jobname
,
run
,
kind
,
filename
)
371
if
run
then
372
if
run
=
=
1
then
373
for
i
=
1
,
10
do
374
local
tmpname
=
f_tempfile_i
(
jobname
,
kind
,
i
)
375
if
validfile
(
tmpname
)
then
376
removefile
(
tmpname
)
377
report
(
"
removing %a
"
,
tmpname
)
378
end
379
end
380
end
381
if
validfile
(
filename
)
then
382
local
tmpname
=
f_tempfile
(
jobname
,
kind
,
run
or
1
)
383
report
(
"
copying %a into %a
"
,
filename
,
tmpname
)
384
file
.
copy
(
filename
,
tmpname
)
385
else
386
report
(
"
no file %a, nothing kept
"
,
filename
)
387
end
388
elseif
validfile
(
filename
)
then
389
local
tmpname
=
f_tempfile_s
(
jobname
,
kind
,
kind
)
390
report
(
"
copying %a into %a
"
,
filename
,
tmpname
)
391
file
.
copy
(
filename
,
tmpname
)
392
else
393
report
(
"
no file %a, nothing kept
"
,
filename
)
394
end
395
end
396 397
local
function
multipass_copyluafile
(
jobname
,
run
)
398
local
tuaname
,
tucname
=
jobname
.
.
"
.tua
"
,
jobname
.
.
"
.tuc
"
399
if
validfile
(
tuaname
)
then
400
if
run
then
401
backup
(
jobname
,
run
,
"
tuc
"
,
tucname
)
402
report
(
"
copying %a into %a
"
,
tuaname
,
tucname
)
403
report
(
)
404
end
405
removefile
(
tucname
)
406
renamefile
(
tuaname
,
tucname
)
407
end
408
end
409 410
local
function
multipass_copypdffile
(
jobname
,
run
)
411
if
run
then
412
local
pdfname
=
jobname
.
.
"
.pdf
"
413
if
validfile
(
pdfname
)
then
414
backup
(
jobname
,
false
,
"
pdf
"
,
pdfname
)
415
report
(
)
416
end
417
end
418
end
419 420
local
function
multipass_copylogfile
(
jobname
,
run
)
421
if
run
then
422
local
logname
=
jobname
.
.
"
.log
"
423
if
validfile
(
logname
)
then
424
backup
(
jobname
,
run
,
"
log
"
,
logname
)
425
report
(
)
426
end
427
end
428
end
429 430
--
431 432
local
pattern
=
lpegpatterns
.
utfbom
^
-1
*
(
P
(
"
%%
"
)
+
P
(
"
%
"
)
)
*
Cs
(
(
1
-
lpegpatterns
.
newline
)
^
1
)
433 434
local
prefile
=
nil
435
local
predata
=
nil
436 437
local
function
preamble_analyze
(
filename
)
-- only files on current path
438
filename
=
fileaddsuffix
(
filename
,
"
tex
"
)
-- to be sure
439
if
predata
and
prefile
=
=
filename
then
440
return
predata
441
end
442
prefile
=
filename
443
predata
=
{
}
444
local
line
=
io
.
loadlines
(
prefile
)
445
if
line
then
446
local
preamble
=
lpegmatch
(
pattern
,
line
)
447
if
preamble
then
448
utilities
.
parsers
.
options_to_hash
(
preamble
,
predata
)
449
predata
.
type
=
"
tex
"
450
elseif
find
(
line
,
"
^<?xml
"
)
then
451
predata
.
type
=
"
xml
"
452
end
453
if
predata
.
nofruns
then
454
multipass_nofruns
=
predata
.
nofruns
455
end
456
if
not
predata
.
engine
then
457
predata
.
engine
=
environment
.
basicengines
[
engine_old
]
--'luatex'
458
end
459
if
predata
.
engine
~
=
engine_old
then
-- hack
460
if
environment
.
validengines
[
predata
.
engine
]
and
predata
.
engine
~
=
environment
.
basicengines
[
engine_old
]
then
461
restart
(
engine_old
,
predata
.
engine
)
462
end
463
end
464
end
465
return
predata
466
end
467 468
-- automatically opening and closing pdf files
469 470
local
pdfview
-- delayed
471 472
local
function
pdf_open
(
name
,
method
)
473
statistics
.
starttiming
(
"
pdfview
"
)
474
pdfview
=
pdfview
or
dofile
(
resolvers
.
findfile
(
"
l-pdfview.lua
"
,
"
tex
"
)
)
475
pdfview
.
setmethod
(
method
)
476
report
(
pdfview
.
status
(
)
)
477
local
pdfname
=
filenewsuffix
(
name
,
"
pdf
"
)
478
if
not
lfs
.
isfile
(
pdfname
)
then
479
pdfname
=
name
.
.
"
.pdf
"
-- agressive
480
end
481
pdfview
.
open
(
pdfname
)
482
statistics
.
stoptiming
(
"
pdfview
"
)
483
report
(
"
pdfview overhead: %s seconds
"
,
statistics
.
elapsedtime
(
"
pdfview
"
)
)
484
end
485 486
local
function
pdf_close
(
name
,
method
)
487
statistics
.
starttiming
(
"
pdfview
"
)
488
pdfview
=
pdfview
or
dofile
(
resolvers
.
findfile
(
"
l-pdfview.lua
"
,
"
tex
"
)
)
489
pdfview
.
setmethod
(
method
)
490
local
pdfname
=
filenewsuffix
(
name
,
"
pdf
"
)
491
if
lfs
.
isfile
(
pdfname
)
then
492
pdfview
.
close
(
pdfname
)
493
end
494
pdfname
=
name
.
.
"
.pdf
"
-- agressive
495
pdfview
.
close
(
pdfname
)
496
statistics
.
stoptiming
(
"
pdfview
"
)
497
end
498 499
-- result file handling
500 501
local
function
result_push_purge
(
oldbase
,
newbase
)
502
for
_
,
suffix
in
next
,
usedsuffixes
.
after
do
503
local
oldname
=
fileaddsuffix
(
oldbase
,
suffix
)
504
local
newname
=
fileaddsuffix
(
newbase
,
suffix
)
505
removefile
(
newname
)
506
removefile
(
oldname
)
507
end
508
end
509 510
local
function
result_push_keep
(
oldbase
,
newbase
)
511
for
_
,
suffix
in
next
,
usedsuffixes
.
before
do
512
local
oldname
=
fileaddsuffix
(
oldbase
,
suffix
)
513
local
newname
=
fileaddsuffix
(
newbase
,
suffix
)
514
local
tmpname
=
"
keep-
"
.
.
oldname
515
removefile
(
tmpname
)
516
renamefile
(
oldname
,
tmpname
)
517
removefile
(
oldname
)
518
renamefile
(
newname
,
oldname
)
519
end
520
end
521 522
local
function
result_save_error
(
oldbase
,
newbase
)
523
for
_
,
suffix
in
next
,
usedsuffixes
.
keep
do
524
local
oldname
=
fileaddsuffix
(
oldbase
,
suffix
)
525
local
newname
=
fileaddsuffix
(
newbase
,
suffix
)
526
removefile
(
newname
)
-- to be sure
527
renamefile
(
oldname
,
newname
)
528
end
529
end
530 531
local
function
result_save_purge
(
oldbase
,
newbase
)
532
for
_
,
suffix
in
next
,
usedsuffixes
.
after
do
533
local
oldname
=
fileaddsuffix
(
oldbase
,
suffix
)
534
local
newname
=
fileaddsuffix
(
newbase
,
suffix
)
535
removefile
(
newname
)
-- to be sure
536
renamefile
(
oldname
,
newname
)
537
end
538
end
539 540
local
function
result_save_keep
(
oldbase
,
newbase
)
541
for
_
,
suffix
in
next
,
usedsuffixes
.
after
do
542
local
oldname
=
fileaddsuffix
(
oldbase
,
suffix
)
543
local
newname
=
fileaddsuffix
(
newbase
,
suffix
)
544
local
tmpname
=
"
keep-
"
.
.
oldname
545
removefile
(
newname
)
546
renamefile
(
oldname
,
newname
)
547
renamefile
(
tmpname
,
oldname
)
548
end
549
end
550 551
-- use mtx-plain instead
552 553
local
plain_formats
=
{
554
[
"
plain
"
]
=
"
plain
"
,
555
[
"
luatex-plain
"
]
=
"
luatex-plain
"
,
556
}
557 558
local
function
plain_format
(
plainformat
)
559
return
plainformat
and
plain_formats
[
plainformat
]
560
end
561 562
local
function
run_plain
(
plainformat
,
filename
)
563
local
plainformat
=
plain_formats
[
plainformat
]
564
if
plainformat
then
565
local
command
=
format
(
"
mtxrun --script --texformat=%s plain %s
"
,
plainformat
,
filename
)
566
report
(
"
running command: %s\n\n
"
,
command
)
567
-- todo: load and run
568
local
resultname
=
filenewsuffix
(
filename
,
"
pdf
"
)
569
local
pdfview
=
getargument
(
"
autopdf
"
)
or
getargument
(
"
closepdf
"
)
570
if
pdfview
then
571
pdf_close
(
resultname
,
pdfview
)
572
os
.
execute
(
command
)
-- maybe also a proper runner
573
pdf_open
(
resultname
,
pdfview
)
574
else
575
os
.
execute
(
command
)
-- maybe also a proper runner
576
end
577
end
578
end
579 580
local
function
run_texexec
(
filename
,
a_purge
,
a_purgeall
)
581
if
false
then
582
-- we need to write a top etc too and run mp etc so it's not worth the
583
-- trouble, so it will take a while before the next is finished
584
--
585
-- context --extra=texutil --convert myfile
586
else
587
local
texexec
=
resolvers
.
findfile
(
"
texexec.rb
"
)
or
"
"
588
if
texexec
~
=
"
"
then
589
os
.
setenv
(
"
RUBYOPT
"
,
"
"
)
590
local
options
=
environment
.
reconstructcommandline
(
environment
.
arguments_after
)
591
options
=
gsub
(
options
,
"
--purge
"
,
"
"
)
592
options
=
gsub
(
options
,
"
--purgeall
"
,
"
"
)
593
local
command
=
format
(
"
ruby %s %s
"
,
texexec
,
options
)
594
report
(
"
running command: %s\n\n
"
,
command
)
595
if
a_purge
then
596
os
.
execute
(
command
)
597
scripts
.
context
.
purge_job
(
filename
,
false
,
true
)
598
elseif
a_purgeall
then
599
os
.
execute
(
command
)
600
scripts
.
context
.
purge_job
(
filename
,
true
,
true
)
601
else
602
os
.
execute
(
command
)
-- we can use os.exec but that doesn't give back timing
603
end
604
end
605
end
606
end
607 608
-- executing luatex
609 610
local
function
flags_to_string
(
flags
,
prefix
)
611
-- context flags get prepended by c: ... this will move to the sbx module
612
local
t
=
{
}
613
for
k
,
v
in
table
.
sortedhash
(
flags
)
do
614
if
prefix
then
615
k
=
format
(
"
c:%s
"
,
k
)
616
end
617
if
not
v
or
v
=
=
"
"
or
v
=
=
'
""
'
then
618
-- no need to flag false
619
elseif
v
=
=
true
then
620
t
[
#
t
+
1
]
=
format
(
'
--%s
'
,
k
)
621
elseif
type
(
v
)
=
=
"
string
"
then
622
t
[
#
t
+
1
]
=
format
(
'
--%s=%s
'
,
k
,
quote
(
v
)
)
623
else
624
t
[
#
t
+
1
]
=
format
(
'
--%s=%s
'
,
k
,
tostring
(
v
)
)
625
end
626
end
627
return
concat
(
t
,
"
"
)
628
end
629 630
function
scripts
.
context
.
run
(
ctxdata
,
filename
)
631
--
632
local
verbose
=
false
633
--
634
local
a_nofile
=
getargument
(
"
nofile
"
)
635
local
a_engine
=
getargument
(
"
engine
"
)
636
--
637
local
files
=
environment
.
filenames
or
{
}
638
--
639
local
filelist
,
mainfile
640
--
641
if
filename
then
642
-- the given forced name is processed, the filelist is passed to context
643
mainfile
=
filename
644
filelist
=
{
filename
}
645
-- files = files
646
elseif
a_nofile
then
647
-- the list of given files is processed using the dummy file
648
mainfile
=
usedfiles
.
nop
649
filelist
=
{
usedfiles
.
nop
}
650
-- files = { }
651
elseif
#
files
>
0
then
652
-- the list of given files is processed using the stub file
653
mainfile
=
usedfiles
.
yes
-- this can become "" for luametatex/lmtx
654
filelist
=
files
655
files
=
{
}
656
else
657
return
658
end
659
--
660
local
interface
=
validstring
(
getargument
(
"
interface
"
)
)
or
"
en
"
661
local
formatname
=
formatofinterface
[
interface
]
or
"
cont-en
"
662
local
formatfile
,
663
scriptfile
=
resolvers
.
locateformat
(
formatname
)
-- regular engine !
664
if
not
formatfile
or
not
scriptfile
then
665
report
(
"
warning: no format found, forcing remake (commandline driven)
"
)
666
scripts
.
context
.
make
(
formatname
)
667
formatfile
,
scriptfile
=
resolvers
.
locateformat
(
formatname
)
-- variant
668
end
669
if
formatfile
and
scriptfile
then
670
-- okay
671
elseif
formatname
then
672
report
(
"
error, no format found with name: %s, aborting
"
,
formatname
)
673
return
674
else
675
report
(
"
error, no format found (provide formatname or interface)
"
)
676
return
677
end
678
--
679
local
a_mkii
=
getargument
(
"
mkii
"
)
or
getargument
(
"
pdftex
"
)
or
getargument
(
"
xetex
"
)
680
local
a_purge
=
getargument
(
"
purge
"
)
681
local
a_purgeall
=
getargument
(
"
purgeall
"
)
682
local
a_purgeresult
=
getargument
(
"
purgeresult
"
)
683
local
a_global
=
getargument
(
"
global
"
)
684
local
a_runpath
=
getargument
(
"
runpath
"
)
685
local
a_timing
=
getargument
(
"
timing
"
)
686
local
a_profile
=
getargument
(
"
profile
"
)
687
local
a_batchmode
=
getargument
(
"
batchmode
"
)
688
local
a_nonstopmode
=
getargument
(
"
nonstopmode
"
)
689
local
a_scollmode
=
getargument
(
"
scrollmode
"
)
690
local
a_once
=
getargument
(
"
once
"
)
691
local
a_backend
=
getargument
(
"
backend
"
)
692
local
a_arrange
=
getargument
(
"
arrange
"
)
693
local
a_noarrange
=
getargument
(
"
noarrange
"
)
694
local
a_jithash
=
getargument
(
"
jithash
"
)
695
local
a_permitloadlib
=
getargument
(
"
permitloadlib
"
)
696
local
a_texformat
=
getargument
(
"
texformat
"
)
697
local
a_keeptuc
=
getargument
(
"
keeptuc
"
)
698
local
a_keeplog
=
getargument
(
"
keeplog
"
)
699
local
a_keeppdf
=
getargument
(
"
keeppdf
"
)
700
local
a_export
=
getargument
(
"
export
"
)
701
local
a_nodates
=
getargument
(
"
nodates
"
)
702
local
a_trailerid
=
getargument
(
"
trailerid
"
)
703
local
a_nocompression
=
getargument
(
"
nocompression
"
)
704
--
705
a_batchmode
=
(
a_batchmode
and
"
batchmode
"
)
or
(
a_nonstopmode
and
"
nonstopmode
"
)
or
(
a_scrollmode
and
"
scrollmode
"
)
or
nil
706
--
707
for
i
=
1
,
#
filelist
do
708
--
709
local
filename
=
filelist
[
i
]
710 711
if
filename
=
=
"
"
then
712
report
(
"
warning: bad filename
"
)
713
break
714
end
715 716
local
basename
=
filebasename
(
filename
)
-- use splitter
717
local
pathname
=
filepathpart
(
filename
)
718
--
719
if
filesuffix
(
filename
)
=
=
"
"
then
720
filename
=
fileaddsuffix
(
filename
,
"
tex
"
)
721
end
722
--
723
if
pathname
=
=
"
"
and
not
a_global
and
filename
~
=
usedfiles
.
nop
then
724
filename
=
"
./
"
.
.
filename
725
if
not
validfile
(
filename
)
then
726
report
(
"
warning: no (local) file %a, proceeding
"
,
filename
)
727
end
728
end
729
--
730
local
jobname
=
removesuffix
(
basename
)
731
-- local jobname = removesuffix(filename)
732
local
ctxname
=
ctxdata
and
ctxdata
.
ctxname
733
--
734
local
analysis
=
preamble_analyze
(
filename
)
735
--
736
if
a_mkii
or
analysis
.
engine
=
=
'
pdftex
'
or
analysis
.
engine
=
=
'
xetex
'
then
737
run_texexec
(
filename
,
a_purge
,
a_purgeall
)
738
elseif
plain_format
(
a_texformat
or
analysis
.
texformat
)
then
739
run_plain
(
a_texformat
or
analysis
.
texformat
,
filename
)
740
else
741
if
analysis
.
interface
and
analysis
.
interface
~
=
interface
then
742
formatname
=
formatofinterface
[
analysis
.
interface
]
or
formatname
743
formatfile
,
scriptfile
=
resolvers
.
locateformat
(
formatname
)
744
end
745
--
746
local
runpath
=
a_runpath
or
analysis
.
runpath
747
if
type
(
runpath
)
=
=
"
string
"
and
runpath
~
=
"
"
then
748
runpath
=
resolvers
.
resolve
(
runpath
)
749
local
currentdir
=
dir
.
current
(
)
750
if
not
lfs
.
isdir
(
runpath
)
then
751
if
dir
.
makedirs
(
runpath
)
then
752
report
(
"
runpath %a has been created
"
,
runpath
)
753
else
754
report
(
"
error: runpath %a cannot be created
"
,
runpath
)
755
os
.
exit
(
)
756
end
757
end
758
if
lfs
.
chdir
(
runpath
)
then
759
report
(
"
changing to runpath %a
"
,
runpath
)
760
else
761
report
(
"
error: changing to runpath %a is impossible
"
,
runpath
)
762
os
.
exit
(
)
763
end
764
environment
.
arguments
.
path
=
currentdir
765
environment
.
arguments
.
runpath
=
runpath
766
if
filepathpart
(
filename
)
=
=
"
.
"
then
767
filename
=
filebasename
(
filename
)
768
end
769
end
770
--
771
a_jithash
=
validstring
(
a_jithash
or
analysis
.
jithash
)
or
nil
772
a_permitloadlib
=
a_permitloadlib
or
analysis
.
permitloadlib
or
nil
773
--
774
if
not
formatfile
or
not
scriptfile
then
775
report
(
"
warning: no format found, forcing remake (source driven)
"
)
776
scripts
.
context
.
make
(
formatname
,
a_engine
)
777
formatfile
,
scriptfile
=
resolvers
.
locateformat
(
formatname
)
778
end
779
--
780
local
function
combine
(
key
)
781
local
flag
=
validstring
(
environment
[
key
]
)
782
local
plus
=
analysis
[
key
]
783
if
flag
and
plus
then
784
return
plus
.
.
"
,
"
.
.
flag
-- flag wins
785
else
786
return
flag
or
plus
-- flag wins
787
end
788
end
789
----- a_trackers = analysis.trackers
790
----- a_experiments = analysis.experiments
791
local
directives
=
combine
(
"
directives
"
)
792
local
trackers
=
combine
(
"
trackers
"
)
793
local
experiments
=
combine
(
"
experiments
"
)
794
--
795
if
formatfile
and
scriptfile
then
796
local
suffix
=
validstring
(
getargument
(
"
suffix
"
)
)
797
local
resultname
=
validstring
(
getargument
(
"
result
"
)
)
798
if
not
resultname
or
resultname
=
=
"
"
then
799
resultname
=
validstring
(
analysis
.
result
)
800
end
801
local
resultpath
=
filepathpart
(
resultname
)
802
if
resultpath
~
=
"
"
then
803
resultname
=
nil
804
elseif
suffix
then
805
resultname
=
removesuffix
(
jobname
)
.
.
suffix
806
end
807
local
oldbase
=
"
"
808
local
newbase
=
"
"
809
if
resultname
then
810
oldbase
=
removesuffix
(
jobname
)
811
newbase
=
removesuffix
(
resultname
)
812
if
oldbase
~
=
newbase
then
813
if
a_purgeresult
then
814
result_push_purge
(
oldbase
,
newbase
)
815
else
816
result_push_keep
(
oldbase
,
newbase
)
817
end
818
else
819
resultname
=
nil
820
end
821
end
822
--
823
local
pdfview
=
getargument
(
"
autopdf
"
)
or
getargument
(
"
closepdf
"
)
824
if
pdfview
then
825
pdf_close
(
filename
,
pdfview
)
826
if
resultname
then
827
pdf_close
(
resultname
,
pdfview
)
828
end
829
end
830
--
831
-- we could do this when locating the format and exit from luatex when
832
-- there is a version mismatch .. that way we can use stock luatex
833
-- plus mtxrun to run luajittex instead .. this saves a restart but is
834
-- also cleaner as then mtxrun only has to check for a special return
835
-- code (signaling a make + rerun) .. maybe some day
836
--
837
local
okay
=
statistics
.
checkfmtstatus
(
formatfile
,
a_engine
)
838
if
okay
~
=
true
then
839
report
(
"
warning: %s, forcing remake
"
,
tostring
(
okay
)
)
840
scripts
.
context
.
make
(
formatname
)
841
end
842
--
843
local
oldhash
=
multipass_hashfiles
(
jobname
)
844
local
newhash
=
{
}
845
local
maxnofruns
=
once
and
1
or
multipass_nofruns
846
local
fulljobname
=
validstring
(
filename
)
847
--
848
local
c_flags
=
{
849
directives
=
directives
,
-- gets passed via mtxrun
850
trackers
=
trackers
,
-- gets passed via mtxrun
851
experiments
=
experiments
,
-- gets passed via mtxrun
852
--
853
result
=
validstring
(
resultname
)
,
854
input
=
validstring
(
getargument
(
"
input
"
)
or
filename
)
,
-- alternative input
855
fulljobname
=
fulljobname
,
856
files
=
concat
(
files
,
"
,
"
)
,
857
ctx
=
validstring
(
ctxname
)
,
858
export
=
a_export
and
true
or
nil
,
859
nocompression
=
a_nocompression
and
true
or
nil
,
860
texmfbinpath
=
os
.
selfdir
,
861
}
862
--
863
for
k
,
v
in
next
,
environment
.
arguments
do
864
-- the raw arguments
865
if
c_flags
[
k
]
=
=
nil
then
866
c_flags
[
k
]
=
v
867
end
868
end
869
--
870
-- todo: --output-file=... in luatex
871
--
872
local
usedname
=
jobname
873
local
engine
=
analysis
.
engine
or
"
luametatex
"
874
if
engine
=
=
"
luametatex
"
and
(
mainfile
=
=
usedfiles
.
yes
or
mainfile
=
=
usedfiles
.
nop
)
and
not
getargument
(
"
redirected
"
)
then
875
mainfile
=
"
"
-- we don't need that
876
usedname
=
fulljobname
877
end
878
--
879
--
880
local
l_flags
=
{
881
[
"
interaction
"
]
=
a_batchmode
,
882
-- ["synctex"] = false, -- context has its own way
883
-- ["no-parse-first-line"] = true, -- obsolete
884
-- ["safer"] = a_safer, -- better use --sandbox
885
-- ["no-mktex"] = true,
886
-- ["file-line-error-style"] = true,
887
-- ["fmt"] = formatfile,
888
-- ["lua"] = scriptfile,
889
-- ["jobname"] = jobname,
890
[
"
jobname
"
]
=
usedname
,
891
[
"
jithash
"
]
=
a_jithash
,
892
[
"
permitloadlib
"
]
=
a_permitloadlib
,
893
}
894
--
895
local
directives
=
{
}
896
--
897
if
a_nodates
then
898
directives
[
#
directives
+
1
]
=
format
(
"
backend.date=%s
"
,
type
(
a_nodates
)
=
=
"
string
"
and
a_nodates
or
"
no
"
)
899
end
900
--
901
if
type
(
a_trailerid
)
=
=
"
string
"
then
902
directives
[
#
directives
+
1
]
=
format
(
"
backend.trailerid=%s
"
,
a_trailerid
)
903
end
904
--
905
if
a_profile
then
906
directives
[
#
directives
+
1
]
=
format
(
"
system.profile=%s
"
,
tonumber
(
a_profile
)
or
0
)
907
end
908
--
909
for
i
=
1
,
#
synctex_runfiles
do
910
removefile
(
fileaddsuffix
(
jobname
,
synctex_runfiles
[
i
]
)
)
911
end
912
--
913
if
#
directives
>
0
then
914
c_flags
.
directives
=
concat
(
directives
,
"
,
"
)
915
end
916
--
917
-- kindofrun: 1:first run, 2:successive run, 3:once, 4:last of maxruns
918
--
919
-- can be used to include pages from a previous run, --keeppdf or "% keeppdf" on first-line
920
--
921
multipass_copypdffile
(
jobname
,
a_keeppdf
or
analysis
.
keeppdf
)
922
--
923
for
currentrun
=
1
,
maxnofruns
do
924
--
925
c_flags
.
final
=
false
926
c_flags
.
kindofrun
=
(
a_once
and
3
)
or
(
currentrun
=
=
1
and
1
)
or
(
currentrun
=
=
maxnofruns
and
4
)
or
2
927
c_flags
.
maxnofruns
=
maxnofruns
928
c_flags
.
forcedruns
=
multipass_forcedruns
and
multipass_forcedruns
>
0
and
multipass_forcedruns
or
nil
929
c_flags
.
currentrun
=
currentrun
930
c_flags
.
noarrange
=
a_noarrange
or
a_arrange
or
nil
931
c_flags
.
profile
=
a_profile
and
(
tonumber
(
a_profile
)
or
0
)
or
nil
932
--
933
print
(
"
"
)
-- cleaner, else continuation on same line
934
--
935
local
returncode
=
environment
.
run_format
(
936
formatfile
,
937
scriptfile
,
938
mainfile
,
939
flags_to_string
(
l_flags
)
,
940
flags_to_string
(
c_flags
,
true
)
,
941
verbose
942
)
943
-- todo: remake format when no proper format is found
944
if
not
returncode
then
945
report
(
"
fatal error: no return code
"
)
946
if
resultname
then
947
result_save_error
(
oldbase
,
newbase
)
948
end
949
os
.
exit
(
1
)
950
break
951
elseif
returncode
=
=
0
then
952
multipass_copyluafile
(
jobname
,
a_keeptuc
and
currentrun
)
953
multipass_copylogfile
(
jobname
,
a_keeplog
and
currentrun
)
954
if
not
multipass_forcedruns
then
955
newhash
=
multipass_hashfiles
(
jobname
)
956
if
multipass_changed
(
oldhash
,
newhash
)
then
957
oldhash
=
newhash
958
else
959
break
960
end
961
elseif
currentrun
=
=
multipass_forcedruns
then
962
report
(
"
quitting after force %i runs
"
,
multipass_forcedruns
)
963
break
964
end
965
else
966
report
(
"
fatal error: return code: %s
"
,
returncode
or
"
?
"
)
967
if
resultname
then
968
result_save_error
(
oldbase
,
newbase
)
969
end
970
os
.
exit
(
1
)
-- (returncode)
971
break
972
end
973
--
974
end
975
--
976
if
environment
.
arguments
[
"
ansilog
"
]
then
977
local
logfile
=
filenewsuffix
(
jobname
,
"
log
"
)
978
local
logdata
=
io
.
loaddata
(
logfile
)
or
"
"
979
if
logdata
~
=
"
"
then
980
io
.
savedata
(
logfile
,
(
gsub
(
logdata
,
"
%[.-m
"
,
"
"
)
)
)
981
end
982
end
983
--
984
--
985
-- this will go away after we update luatex
986
--
987
local
syncctx
=
fileaddsuffix
(
jobname
,
"
syncctx
"
)
988
if
validfile
(
syncctx
)
then
989
renamefile
(
syncctx
,
fileaddsuffix
(
jobname
,
"
synctex
"
)
)
990
end
991
--
992
if
a_arrange
then
993
--
994
c_flags
.
final
=
true
995
c_flags
.
kindofrun
=
3
996
c_flags
.
currentrun
=
c_flags
.
currentrun
+
1
997
c_flags
.
noarrange
=
nil
998
--
999
report
(
"
arrange run: %s
"
,
command
)
1000
--
1001
local
returncode
=
environment
.
run_format
(
1002
formatfile
,
1003
scriptfile
,
1004
mainfile
,
1005
flags_to_string
(
l_flags
)
,
1006
flags_to_string
(
c_flags
,
true
)
,
1007
verbose
1008
)
1009
--
1010
if
not
returncode
then
1011
report
(
"
fatal error: no return code, message: %s
"
,
errorstring
or
"
?
"
)
1012
os
.
exit
(
1
)
1013
elseif
returncode
>
0
then
1014
report
(
"
fatal error: return code: %s
"
,
returncode
or
"
?
"
)
1015
os
.
exit
(
returncode
)
1016
end
1017
--
1018
end
1019
--
1020
if
a_purge
then
1021
scripts
.
context
.
purge_job
(
jobname
,
false
,
false
,
fulljobname
)
1022
elseif
a_purgeall
then
1023
scripts
.
context
.
purge_job
(
jobname
,
true
,
false
,
fulljobname
)
1024
end
1025
--
1026
if
resultname
then
1027
if
a_purgeresult
then
1028
-- so, if there is no result then we don't get the old one, but
1029
-- related files (log etc) are still there for tracing purposes
1030
result_save_purge
(
oldbase
,
newbase
)
1031
else
1032
result_save_keep
(
oldbase
,
newbase
)
1033
end
1034
report
(
"
result renamed to: %s
"
,
newbase
)
1035
elseif
resultpath
~
=
"
"
then
1036
report
(
)
1037
report
(
"
results are to be on the running path, not on %a, ignoring --result
"
,
resultpath
)
1038
report
(
)
1039
end
1040
--
1041
-- -- needs checking
1042
--
1043
-- if a_purge then
1044
-- scripts.context.purge_job(resultname)
1045
-- elseif a_purgeall then
1046
-- scripts.context.purge_job(resultname,true)
1047
-- end
1048
--
1049
local
pdfview
=
getargument
(
"
autopdf
"
)
1050
if
pdfview
then
1051
pdf_open
(
resultname
or
jobname
,
pdfview
)
1052
end
1053
--
1054
local
epub
=
analysis
.
epub
1055
if
epub
then
1056
if
type
(
epub
)
=
=
"
string
"
then
1057
local
t
=
settings_to_array
(
epub
)
1058
for
i
=
1
,
#
t
do
1059
t
[
i
]
=
"
--
"
.
.
gsub
(
t
[
i
]
,
"
^%-*
"
,
"
"
)
1060
end
1061
epub
=
concat
(
t
,
"
"
)
1062
else
1063
epub
=
"
--make
"
1064
end
1065
local
command
=
"
mtxrun --script epub
"
.
.
epub
.
.
"
"
.
.
jobname
1066
report
(
)
1067
report
(
"
making epub file:
"
,
command
)
1068
report
(
)
1069
os
.
execute
(
command
)
-- todo: also a runner
1070
end
1071
--
1072
if
a_timing
then
1073
report
(
)
1074
report
(
"
you can process (timing) statistics with:
"
,
jobname
)
1075
report
(
)
1076
report
(
"
context --extra=timing '%s'
"
,
jobname
)
1077
-- report("mtxrun --script timing --xhtml [--launch --remove] '%s'",jobname)
1078
report
(
)
1079
end
1080
else
1081
if
formatname
then
1082
report
(
"
error, no format found with name: %s, skipping
"
,
formatname
)
1083
else
1084
report
(
"
error, no format found (provide formatname or interface)
"
)
1085
end
1086
break
1087
end
1088
end
1089
end
1090
--
1091
end
1092 1093
function
scripts
.
context
.
pipe
(
)
-- still used?
1094
-- context --pipe
1095
-- context --pipe --purge --dummyfile=whatever.tmp
1096
local
interface
=
getargument
(
"
interface
"
)
1097
interface
=
(
type
(
interface
)
=
=
"
string
"
and
interface
)
or
"
en
"
1098
local
formatname
=
formatofinterface
[
interface
]
or
"
cont-en
"
1099
local
formatfile
,
scriptfile
=
resolvers
.
locateformat
(
formatname
)
1100
if
not
formatfile
or
not
scriptfile
then
1101
report
(
"
warning: no format found, forcing remake (commandline driven)
"
)
1102
scripts
.
context
.
make
(
formatname
)
1103
formatfile
,
scriptfile
=
resolvers
.
locateformat
(
formatname
)
1104
end
1105
if
formatfile
and
scriptfile
then
1106
local
okay
=
statistics
.
checkfmtstatus
(
formatfile
)
1107
if
okay
~
=
true
then
1108
report
(
"
warning: %s, forcing remake
"
,
tostring
(
okay
)
)
1109
scripts
.
context
.
make
(
formatname
)
1110
end
1111
local
l_flags
=
{
1112
interaction
=
"
scrollmode
"
,
1113
fmt
=
formatfile
,
1114
lua
=
scriptfile
,
1115
}
1116
local
c_flags
=
{
1117
backend
=
"
pdf
"
,
1118
final
=
false
,
1119
kindofrun
=
3
,
1120
currentrun
=
1
,
1121
}
1122
local
filename
=
getargument
(
"
dummyfile
"
)
or
"
"
1123
if
filename
=
=
"
"
then
1124
filename
=
"
\\relax
"
1125
report
(
"
entering scrollmode, end job with \\end
"
)
1126
else
1127
filename
=
fileaddsuffix
(
filename
,
"
tmp
"
)
1128
io
.
savedata
(
filename
,
"
\\relax
"
)
1129
report
(
"
entering scrollmode using '%s' with optionfile, end job with \\end
"
,
filename
)
1130
end
1131
local
returncode
=
environment
.
run_format
(
1132
formatfile
,
1133
scriptfile
,
1134
filename
,
1135
flags_to_string
(
l_flags
)
,
1136
flags_to_string
(
c_flags
,
true
)
,
1137
verbose
1138
)
1139
if
getargument
(
"
purge
"
)
then
1140
scripts
.
context
.
purge_job
(
filename
)
1141
elseif
getargument
(
"
purgeall
"
)
then
1142
scripts
.
context
.
purge_job
(
filename
,
true
)
1143
removefile
(
filename
)
1144
end
1145
elseif
formatname
then
1146
report
(
"
error, no format found with name: %s, aborting
"
,
formatname
)
1147
else
1148
report
(
"
error, no format found (provide formatname or interface)
"
)
1149
end
1150
end
1151 1152
local
function
make_mkiv_format
(
name
,
engine
)
1153
environment
.
make_format
(
name
)
-- jit is picked up later
1154
end
1155 1156
local
make_mkii_format
1157 1158
do
-- more or less copied from mtx-plain.lua:
1159 1160
local
function
mktexlsr
(
)
1161
if
environment
.
arguments
.
silent
then
1162
local
result
=
os
.
execute
(
"
mktexlsr --quiet > temp.log
"
)
1163
if
result
~
=
0
then
1164
print
(
"
mktexlsr silent run > fatal error
"
)
-- we use a basic print
1165
else
1166
print
(
"
mktexlsr silent run
"
)
-- we use a basic print
1167
end
1168
removefile
(
"
temp.log
"
)
1169
else
1170
report
(
"
running mktexlsr
"
)
1171
os
.
execute
(
"
mktexlsr
"
)
1172
end
1173
end
1174 1175
local
function
engine
(
texengine
,
texformat
)
1176
local
command
=
string
.
format
(
'
%s --ini --etex --8bit %s \\dump
'
,
texengine
,
fileaddsuffix
(
texformat
,
"
mkii
"
)
)
1177
if
environment
.
arguments
.
silent
then
1178
statistics
.
starttiming
(
)
1179
local
command
=
format
(
"
%s > temp.log
"
,
command
)
1180
local
result
=
os
.
execute
(
command
)
1181
local
runtime
=
statistics
.
stoptiming
(
)
1182
if
result
~
=
0
then
1183
print
(
format
(
"
%s silent make > fatal error when making format %q
"
,
texengine
,
texformat
)
)
-- we use a basic print
1184
else
1185
print
(
format
(
"
%s silent make > format %q made in %.3f seconds
"
,
texengine
,
texformat
,
runtime
)
)
-- we use a basic print
1186
end
1187
removefile
(
"
temp.log
"
)
1188
else
1189
report
(
"
running command: %s
"
,
command
)
1190
os
.
execute
(
command
)
1191
end
1192
end
1193 1194
local
function
resultof
(
...
)
1195
local
command
=
string
.
format
(
...
)
1196
report
(
"
running command %a
"
,
command
)
1197
return
string
.
strip
(
os
.
resultof
(
command
)
or
"
"
)
1198
end
1199 1200
local
function
make
(
texengine
,
texformat
)
1201
report
(
"
generating kpse file database
"
)
1202
mktexlsr
(
)
1203
local
fmtpathspec
=
resultof
(
"
kpsewhich --var-value=TEXFORMATS --engine=%s
"
,
texengine
)
1204
if
fmtpathspec
~
=
"
"
then
1205
report
(
"
using path specification %a
"
,
fmtpathspec
)
1206
fmtpathspec
=
resultof
(
'
kpsewhich -expand-braces="%s"
'
,
fmtpathspec
)
1207
end
1208
if
fmtpathspec
~
=
"
"
then
1209
report
(
"
using path expansion %a
"
,
fmtpathspec
)
1210
else
1211
report
(
"
no valid path reported, trying alternative
"
)
1212
fmtpathspec
=
resultof
(
"
kpsewhich --show-path=fmt --engine=%s
"
,
texengine
)
1213
if
fmtpathspec
~
=
"
"
then
1214
report
(
"
using path expansion %a
"
,
fmtpathspec
)
1215
else
1216
report
(
"
no valid path reported, falling back to current path
"
)
1217
fmtpathspec
=
"
.
"
1218
end
1219
end
1220
fmtpathspec
=
string
.
splitlines
(
fmtpathspec
)
[
1
]
or
fmtpathspec
1221
fmtpathspec
=
fmtpathspec
and
file
.
splitpath
(
fmtpathspec
)
1222
local
fmtpath
=
nil
1223
if
fmtpathspec
then
1224
for
i
=
1
,
#
fmtpathspec
do
1225
local
path
=
fmtpathspec
[
i
]
1226
if
path
~
=
"
.
"
then
1227
dir
.
makedirs
(
path
)
1228
if
lfs
.
isdir
(
path
)
and
file
.
is_writable
(
path
)
then
1229
fmtpath
=
path
1230
break
1231
end
1232
end
1233
end
1234
end
1235
if
not
fmtpath
or
fmtpath
=
=
"
"
then
1236
fmtpath
=
"
.
"
1237
else
1238
lfs
.
chdir
(
fmtpath
)
1239
end
1240
engine
(
texengine
,
texformat
)
1241
report
(
"
generating kpse file database
"
)
1242
mktexlsr
(
)
1243
report
(
"
format %a saved on path %a
"
,
texformat
,
fmtpath
)
1244
end
1245 1246
local
function
run
(
texengine
,
texformat
,
filename
)
1247
local
t
=
{
}
1248
for
k
,
v
in
next
,
environment
.
arguments
do
1249
t
[
#
t
+
1
]
=
string
.
format
(
"
--mtx:%s=%s
"
,
k
,
v
)
1250
end
1251
execute
(
'
%s --fmt=%s %s "%s"
'
,
texengine
,
removesuffix
(
texformat
)
,
table
.
concat
(
t
,
"
"
)
,
filename
)
1252
end
1253 1254
make_mkii_format
=
function
(
name
,
engine
)
1255 1256
-- let the binary sort it out
1257 1258
os
.
setenv
(
'
SELFAUTOPARENT
'
,
"
"
)
1259
os
.
setenv
(
'
SELFAUTODIR
'
,
"
"
)
1260
os
.
setenv
(
'
SELFAUTOLOC
'
,
"
"
)
1261
os
.
setenv
(
'
TEXROOT
'
,
"
"
)
1262
os
.
setenv
(
'
TEXOS
'
,
"
"
)
1263
os
.
setenv
(
'
TEXMFOS
'
,
"
"
)
1264
os
.
setenv
(
'
TEXMFCNF
'
,
"
"
)
1265 1266
make
(
engine
,
name
)
1267
end
1268 1269
end
1270 1271
function
scripts
.
context
.
generate
(
)
1272
resolvers
.
renewcache
(
)
1273
trackers
.
enable
(
"
resolvers.locating
"
)
1274
resolvers
.
load
(
)
1275
end
1276 1277
function
scripts
.
context
.
make
(
name
)
1278
if
not
getargument
(
"
fast
"
)
then
-- as in texexec
1279
scripts
.
context
.
generate
(
)
1280
end
1281
local
list
=
(
name
and
{
name
}
)
or
(
environment
.
filenames
[
1
]
and
environment
.
filenames
)
or
defaultformats
1282
local
engine
=
getargument
(
"
engine
"
)
or
(
status
and
status
.
luatex_engine
)
or
"
luatex
"
1283
if
getargument
(
"
jit
"
)
then
1284
engine
=
"
luajittex
"
1285
end
1286
for
i
=
1
,
#
list
do
1287
local
name
=
list
[
i
]
1288
name
=
formatofinterface
[
name
]
or
name
or
"
"
1289
if
name
=
=
"
"
then
1290
-- nothing
1291
elseif
engine
=
=
"
luametatex
"
or
engine
=
=
"
luatex
"
or
engine
=
=
"
luajittex
"
then
1292
make_mkiv_format
(
name
,
engine
)
1293
elseif
engine
=
=
"
pdftex
"
or
engine
=
=
"
xetex
"
then
1294
make_mkii_format
(
name
,
engine
)
1295
end
1296
end
1297
end
1298 1299
function
scripts
.
context
.
ctx
(
)
1300
local
ctxdata
=
ctxrunner
.
new
(
)
1301
ctxdata
.
jobname
=
environment
.
filenames
[
1
]
1302
ctxrunner
.
checkfile
(
ctxdata
,
getargument
(
"
ctx
"
)
)
1303
ctxrunner
.
checkflags
(
ctxdata
)
1304
scripts
.
context
.
run
(
ctxdata
)
1305
end
1306 1307
function
scripts
.
context
.
autoctx
(
)
1308
local
ctxdata
=
nil
1309
local
files
=
environment
.
filenames
1310
local
firstfile
=
#
files
>
0
and
files
[
1
]
1311
if
firstfile
then
1312
local
suffix
=
filesuffix
(
firstfile
)
1313
local
ctxname
=
nil
1314
if
suffix
=
=
"
xml
"
then
1315
local
chunk
=
io
.
loadchunk
(
firstfile
)
-- 1024
1316
if
chunk
then
1317
ctxname
=
match
(
chunk
,
"
<%?context%-directive%s+job%s+ctxfile%s+([^ ]-)%s*?>
"
)
1318
end
1319
elseif
suffix
=
=
"
tex
"
or
suffix
=
=
"
mkiv
"
or
suffix
=
=
"
mkxl
"
then
1320
local
analysis
=
preamble_analyze
(
firstfile
)
1321
ctxname
=
analysis
.
ctxfile
or
analysis
.
ctx
1322
end
1323
if
ctxname
then
1324
ctxdata
=
ctxrunner
.
new
(
)
1325
ctxdata
.
jobname
=
firstfile
1326
ctxrunner
.
checkfile
(
ctxdata
,
ctxname
)
1327
ctxrunner
.
checkflags
(
ctxdata
)
1328
end
1329
end
1330
scripts
.
context
.
run
(
ctxdata
)
1331
end
1332 1333
function
scripts
.
context
.
version
(
)
1334
local
list
=
{
"
context.mkiv
"
,
"
context.mkxl
"
}
1335
for
i
=
1
,
#
list
do
1336
local
base
=
list
[
i
]
1337
local
name
=
resolvers
.
findfile
(
base
)
1338
if
name
~
=
"
"
then
1339
report
(
"
main context file: %s
"
,
name
)
1340
local
data
=
io
.
loaddata
(
name
)
1341
if
data
then
1342
local
version
=
match
(
data
,
"
\\edef\\contextversion{(.-)}
"
)
1343
if
version
then
1344
report
(
"
current version: %s
"
,
version
)
1345
else
1346
report
(
"
context version: unknown, no timestamp found
"
)
1347
end
1348
else
1349
report
(
"
context version: unknown, load error
"
)
1350
end
1351
else
1352
report
(
"
main context file: unknown, %a not found
"
,
base
)
1353
end
1354
end
1355
end
1356 1357
function
scripts
.
context
.
purge_job
(
jobname
,
all
,
mkiitoo
,
fulljobname
)
1358
if
jobname
and
jobname
~
=
"
"
then
1359
jobname
=
filebasename
(
jobname
)
1360
local
filebase
=
removesuffix
(
jobname
)
1361
if
mkiitoo
then
1362
scripts
.
context
.
purge
(
all
,
filebase
,
true
)
-- leading "./"
1363
else
1364
local
deleted
=
{
}
1365
for
i
=
1
,
#
obsolete_results
do
1366
deleted
[
#
deleted
+
1
]
=
purge_file
(
fileaddsuffix
(
filebase
,
obsolete_results
[
i
]
)
,
fileaddsuffix
(
filebase
,
"
pdf
"
)
)
1367
end
1368
for
i
=
1
,
#
temporary_runfiles
do
1369
deleted
[
#
deleted
+
1
]
=
purge_file
(
fileaddsuffix
(
filebase
,
temporary_runfiles
[
i
]
)
)
1370
end
1371
if
fulljobname
and
fulljobname
~
=
jobname
then
1372
for
i
=
1
,
#
temporary_suffixes
do
1373
deleted
[
#
deleted
+
1
]
=
purge_file
(
fileaddsuffix
(
fulljobname
,
temporary_suffixes
[
i
]
,
true
)
)
1374
end
1375
end
1376
if
all
then
1377
for
i
=
1
,
#
persistent_runfiles
do
1378
deleted
[
#
deleted
+
1
]
=
purge_file
(
fileaddsuffix
(
filebase
,
persistent_runfiles
[
i
]
)
)
1379
end
1380
end
1381
if
#
deleted
>
0
then
1382
report
(
"
purged files: %s
"
,
concat
(
deleted
,
"
,
"
)
)
1383
end
1384
end
1385
end
1386
end
1387 1388
function
scripts
.
context
.
purge
(
all
,
pattern
,
mkiitoo
)
1389
local
all
=
all
or
getargument
(
"
all
"
)
1390
local
pattern
=
getargument
(
"
pattern
"
)
or
(
pattern
and
(
pattern
.
.
"
*
"
)
)
or
"
*.*
"
1391
local
files
=
dir
.
glob
(
pattern
)
1392
local
obsolete
=
tohash
(
obsolete_results
)
1393
local
temporary
=
tohash
(
temporary_runfiles
)
1394
local
synctex
=
tohash
(
synctex_runfiles
)
1395
local
persistent
=
tohash
(
persistent_runfiles
)
1396
local
generic
=
tohash
(
generic_files
)
1397
local
deleted
=
{
}
1398
for
i
=
1
,
#
files
do
1399
local
name
=
files
[
i
]
1400
local
suffix
=
filesuffix
(
name
)
1401
local
basename
=
filebasename
(
name
)
1402
if
obsolete
[
suffix
]
or
temporary
[
suffix
]
or
synctex
[
suffix
]
or
persistent
[
suffix
]
or
generic
[
basename
]
then
1403
deleted
[
#
deleted
+
1
]
=
purge_file
(
name
)
1404
elseif
mkiitoo
then
1405
for
i
=
1
,
#
special_runfiles
do
1406
if
find
(
name
,
special_runfiles
[
i
]
)
then
1407
deleted
[
#
deleted
+
1
]
=
purge_file
(
name
)
1408
end
1409
end
1410
end
1411
for
i
=
1
,
#
extra_runfiles
do
1412
if
find
(
basename
,
extra_runfiles
[
i
]
)
then
1413
deleted
[
#
deleted
+
1
]
=
purge_file
(
name
)
1414
end
1415
end
1416
end
1417
if
#
deleted
>
0
then
1418
report
(
"
purged files: %s
"
,
concat
(
deleted
,
"
,
"
)
)
1419
end
1420
end
1421 1422
-- touching files (signals regeneration of formats)
1423 1424
local
newversion
=
false
1425 1426
local
function
touch
(
path
,
name
,
versionpattern
,
kind
,
kindpattern
)
1427
if
path
and
path
~
=
"
"
then
1428
name
=
filejoinname
(
path
,
name
)
1429
else
1430
name
=
resolvers
.
findfile
(
name
)
1431
end
1432
local
olddata
=
io
.
loaddata
(
name
)
1433
if
olddata
then
1434
local
oldkind
=
"
"
1435
local
newkind
=
kind
or
"
"
1436
local
oldversion
=
"
"
1437
local
newdata
1438
newversion
=
newversion
or
os
.
date
(
"
%Y.%m.%d %H:%M
"
)
1439
if
versionpattern
then
1440
newdata
=
gsub
(
olddata
,
versionpattern
,
function
(
pre
,
mid
,
post
)
1441
oldversion
=
mid
1442
return
pre
.
.
newversion
.
.
post
1443
end
)
or
olddata
1444
end
1445
if
kind
and
kindpattern
then
1446
newdata
=
gsub
(
newdata
,
kindpattern
,
function
(
pre
,
mid
,
post
)
1447
oldkind
=
mid
1448
return
pre
.
.
newkind
.
.
post
1449
end
)
or
newdata
1450
end
1451
if
newdata
~
=
"
"
and
(
oldversion
~
=
newversion
or
oldkind
~
=
newkind
or
newdata
~
=
olddata
)
then
1452
local
backup
=
filenewsuffix
(
name
,
"
tmp
"
)
1453
removefile
(
backup
)
1454
renamefile
(
name
,
backup
)
1455
io
.
savedata
(
name
,
newdata
)
1456
return
name
,
oldversion
,
newversion
,
oldkind
,
newkind
1457
end
1458
end
1459
end
1460 1461
local
p_contextkind
=
"
(\\edef\\contextkind%s*{)(.-)(})
"
1462
local
p_contextversion
=
"
(\\edef\\contextversion%s*{)(.-)(})
"
1463
local
p_newcontextversion
=
"
(\\newcontextversion%s*{)(.-)(})
"
1464 1465
local
function
touchfiles
(
suffix
,
kind
,
path
)
1466
local
foundname
,
oldversion
,
newversion
,
oldkind
,
newkind
=
touch
(
path
,
fileaddsuffix
(
"
context
"
,
suffix
)
,
p_contextversion
,
kind
,
p_contextkind
)
1467
if
foundname
then
1468
report
(
"
old version : %s (%s)
"
,
oldversion
,
oldkind
)
1469
report
(
"
new version : %s (%s)
"
,
newversion
,
newkind
)
1470
report
(
"
touched file : %s
"
,
foundname
)
1471
local
foundname
=
touch
(
path
,
fileaddsuffix
(
"
cont-new
"
,
suffix
)
,
p_newcontextversion
)
1472
if
foundname
then
1473
report
(
"
touched file : %s
"
,
foundname
)
1474
end
1475
else
1476
report
(
"
nothing touched
"
)
1477
end
1478
end
1479 1480
local
tobetouched
=
tohash
{
"
mkii
"
,
"
mkiv
"
,
"
mkvi
"
,
"
mkxl
"
,
"
mklx
"
}
1481 1482
function
scripts
.
context
.
touch
(
)
1483
if
getargument
(
"
expert
"
)
then
1484
local
touch
=
getargument
(
"
touch
"
)
1485
local
kind
=
getargument
(
"
kind
"
)
1486
local
path
=
getargument
(
"
basepath
"
)
1487
if
tobetouched
[
touch
]
then
-- mkix mkxi ctix ctxi
1488
touchfiles
(
touch
,
kind
,
path
)
1489
else
1490
for
touch
in
sortedhash
(
tobetouched
)
do
1491
touchfiles
(
touch
,
kind
,
path
)
1492
end
1493
end
1494
else
1495
report
(
"
touching needs --expert
"
)
1496
end
1497
end
1498 1499
function
scripts
.
context
.
pages
(
)
1500
local
filename
=
environment
.
files
[
1
]
1501
if
filename
then
1502
local
u
=
table
.
load
(
fileaddsuffix
(
filename
,
"
tuc
"
)
)
1503
if
u
then
1504
local
p
=
u
.
structures
.
pages
.
collected
1505
local
l
=
u
.
structures
.
lists
.
collected
1506
local
page
=
environment
.
arguments
.
page
1507
local
list
=
environment
.
arguments
.
list
1508
if
type
(
page
)
=
=
"
string
"
then
1509
page
=
settings_to_array
(
page
)
1510
end
1511
if
type
(
list
)
=
=
"
string
"
then
1512
list
=
settings_to_array
(
list
)
1513
end
1514
if
page
or
list
then
1515
if
page
then
1516
for
i
=
1
,
#
page
do
1517
page
[
i
]
=
string
.
topattern
(
page
[
i
]
)
1518
end
1519
for
i
=
1
,
#
p
do
1520
local
pi
=
p
[
i
]
1521
local
m
=
pi
.
marked
1522
if
m
then
1523
local
ml
=
#
m
1524
for
j
=
1
,
#
page
do
1525
local
n
=
page
[
j
]
1526
for
k
=
1
,
ml
do
1527
if
find
(
m
[
k
]
,
n
)
then
1528
report
(
"
page : %04i %s
"
,
i
,
m
[
k
]
)
1529
end
1530
end
1531
end
1532
end
1533
end
1534
end
1535
if
list
then
1536
for
i
=
1
,
#
list
do
1537
list
[
i
]
=
string
.
topattern
(
list
[
i
]
)
1538
end
1539
for
i
=
1
,
#
l
do
1540
local
li
=
l
[
i
]
1541
local
r
=
li
.
references
1542
if
r
then
1543
local
rr
=
r
.
reference
1544
if
rr
then
1545
rr
=
splitstring
(
rr
,
"
,
"
)
1546
local
rrl
=
#
rr
1547
for
j
=
1
,
#
list
do
1548
local
n
=
list
[
j
]
1549
for
k
=
1
,
rrl
do
1550
if
find
(
rr
[
k
]
,
n
)
then
1551
report
(
"
list : %04i %s
"
,
r
.
realpage
,
rr
[
k
]
)
1552
end
1553
end
1554
end
1555
end
1556
end
1557
end
1558
end
1559
else
1560
for
i
=
1
,
#
p
do
1561
local
pi
=
p
[
i
]
1562
local
m
=
pi
.
marked
1563
if
m
then
1564
report
(
"
page : %04i % t
"
,
i
,
m
)
1565
end
1566
end
1567
end
1568
end
1569
end
1570
end
1571 1572
-- modules
1573 1574
local
labels
=
{
"
title
"
,
"
comment
"
,
"
status
"
}
1575
local
cards
=
{
"
*.mkiv
"
,
"
*.mkvi
"
,
"
*.mkix
"
,
"
*.mkxi
"
,
"
*.mkxl
"
,
"
*.mklx
"
,
"
*.tex
"
}
1576
local
valid
=
tohash
{
"
mkiv
"
,
"
mkvi
"
,
"
mkix
"
,
"
mkxi
"
,
"
mkxl
"
,
"
mklx
"
,
"
tex
"
}
1577 1578
function
scripts
.
context
.
modules
(
pattern
)
1579
local
list
=
{
}
1580
local
found
=
resolvers
.
findfile
(
"
context.mkiv
"
)
1581
if
not
pattern
or
pattern
=
=
"
"
then
1582
-- official files in the tree
1583
for
i
=
1
,
#
cards
do
1584
resolvers
.
findwildcardfiles
(
cards
[
i
]
,
list
)
1585
end
1586
-- my dev path
1587
for
i
=
1
,
#
cards
do
1588
dir
.
glob
(
filejoinname
(
filepathpart
(
found
)
,
cards
[
i
]
)
,
list
)
1589
end
1590
else
1591
resolvers
.
findwildcardfiles
(
pattern
,
list
)
1592
dir
.
glob
(
filejoinname
(
filepathpart
(
found
,
pattern
)
)
,
list
)
1593
end
1594
local
done
=
{
}
-- todo : sort
1595
local
none
=
{
x
=
{
}
,
m
=
{
}
,
s
=
{
}
,
t
=
{
}
}
1596
for
i
=
1
,
#
list
do
1597
local
v
=
list
[
i
]
1598
local
base
=
filebasename
(
v
)
1599
if
not
done
[
base
]
then
1600
done
[
base
]
=
true
1601
local
suffix
=
filesuffix
(
base
)
1602
if
valid
[
suffix
]
then
1603
local
prefix
,
rest
=
match
(
base
,
"
^([xmst])%-(.*)
"
)
1604
if
prefix
then
1605
v
=
resolvers
.
findfile
(
base
)
-- so that files on my dev path are seen
1606
local
data
=
io
.
loaddata
(
v
)
or
"
"
1607
data
=
match
(
data
,
"
%% begin info(.-)%% end info
"
)
1608
if
data
then
1609
local
info
=
{
}
1610
for
label
,
text
in
gmatch
(
data
,
"
%% +([^ ]+) *: *(.-)[\n\r]
"
)
do
1611
info
[
label
]
=
text
1612
end
1613
report
(
)
1614
report
(
"
%-7s : %s
"
,
"
module
"
,
base
)
1615
report
(
)
1616
for
i
=
1
,
#
labels
do
1617
local
l
=
labels
[
i
]
1618
if
info
[
l
]
then
1619
report
(
"
%-7s : %s
"
,
l
,
info
[
l
]
)
1620
end
1621
end
1622
report
(
)
1623
else
1624
insert
(
none
[
prefix
]
,
rest
)
1625
end
1626
end
1627
end
1628
end
1629
end
1630 1631
local
function
show
(
k
,
v
)
1632
sort
(
v
)
1633
if
#
v
>
0
then
1634
report
(
)
1635
for
i
=
1
,
#
v
do
1636
report
(
"
%s : %s
"
,
k
,
v
[
i
]
)
1637
end
1638
end
1639
end
1640
for
k
,
v
in
sortedhash
(
none
)
do
1641
show
(
k
,
v
)
1642
end
1643
end
1644 1645
-- extras
1646 1647
function
scripts
.
context
.
extras
(
pattern
)
1648
-- only in base path, i.e. only official ones
1649
if
type
(
pattern
)
~
=
"
string
"
then
1650
pattern
=
"
*
"
1651
end
1652
local
found
=
resolvers
.
findfile
(
"
context.mkiv
"
)
1653
if
found
~
=
"
"
then
1654
pattern
=
filejoinname
(
dir
.
expandname
(
filepathpart
(
found
)
)
,
format
(
"
mtx-context-%s.tex
"
,
pattern
or
"
*
"
)
)
1655
local
list
=
dir
.
glob
(
pattern
)
1656
for
i
=
1
,
#
list
do
1657
local
v
=
list
[
i
]
1658
local
data
=
io
.
loaddata
(
v
)
or
"
"
1659
data
=
match
(
data
,
"
%% begin help(.-)%% end help
"
)
1660
if
data
then
1661
report
(
)
1662
report
(
"
extra: %s (%s)
"
,
(
gsub
(
v
,
"
^.*mtx%-context%-(.-)%.tex$
"
,
"
%1
"
)
)
,
v
)
1663
for
s
in
gmatch
(
data
,
"
%% *(.-)[\n\r]
"
)
do
1664
report
(
s
)
1665
end
1666
report
(
)
1667
end
1668
end
1669
end
1670
end
1671 1672
function
scripts
.
context
.
extra
(
)
1673
local
extra
=
getargument
(
"
extra
"
)
1674
if
type
(
extra
)
~
=
"
string
"
then
1675
scripts
.
context
.
extras
(
)
1676
elseif
getargument
(
"
help
"
)
then
1677
scripts
.
context
.
extras
(
extra
)
1678
else
1679
local
fullextra
=
extra
1680
if
not
find
(
fullextra
,
"
mtx%-context%-
"
)
then
1681
fullextra
=
"
mtx-context-
"
.
.
extra
1682
end
1683
local
foundextra
=
resolvers
.
findfile
(
fullextra
)
1684
if
foundextra
=
=
"
"
then
1685
scripts
.
context
.
extras
(
)
1686
return
1687
else
1688
report
(
"
processing extra: %s
"
,
foundextra
)
1689
end
1690
setargument
(
"
purgeall
"
,
true
)
1691
local
result
=
getargument
(
"
result
"
)
or
"
"
1692
if
result
=
=
"
"
then
1693
setargument
(
"
result
"
,
"
context-extra
"
)
1694
end
1695
scripts
.
context
.
run
(
nil
,
foundextra
)
1696
end
1697
end
1698 1699
-- todo: we need to do a dummy run
1700 1701
local
function
showsetter
(
)
1702
environment
.
files
=
{
resolvers
.
findfile
(
"
mtx-context-setters.tex
"
)
}
1703
multipass_nofruns
=
1
1704
setargument
(
"
purgeall
"
,
true
)
1705
scripts
.
context
.
run
(
)
1706
end
1707 1708
scripts
.
context
.
trackers
=
showsetter
1709
scripts
.
context
.
directives
=
showsetter
1710
scripts
.
context
.
experiments
=
showsetter
1711 1712
function
scripts
.
context
.
logcategories
(
)
1713
environment
.
files
=
{
resolvers
.
findfile
(
"
m-logcategories.mkiv
"
)
}
1714
multipass_nofruns
=
1
1715
setargument
(
"
purgeall
"
,
true
)
1716
scripts
.
context
.
run
(
)
1717
end
1718 1719
function
scripts
.
context
.
timed
(
action
)
1720
statistics
.
timed
(
action
,
true
)
1721
end
1722 1723
-- getting it done
1724 1725
if
getargument
(
"
pdftex
"
)
then
1726
setargument
(
"
engine
"
,
"
pdftex
"
)
1727
elseif
getargument
(
"
xetex
"
)
then
1728
setargument
(
"
engine
"
,
"
xetex
"
)
1729
end
1730 1731
if
getargument
(
"
timedlog
"
)
then
1732
logs
.
settimedlog
(
)
1733
end
1734 1735
if
getargument
(
"
nostats
"
)
then
1736
setargument
(
"
nostatistics
"
,
true
)
1737
setargument
(
"
nostat
"
,
nil
)
1738
end
1739 1740
if
getargument
(
"
batch
"
)
then
1741
setargument
(
"
batchmode
"
,
true
)
1742
setargument
(
"
batch
"
,
nil
)
1743
end
1744 1745
if
getargument
(
"
nonstop
"
)
then
1746
setargument
(
"
nonstopmode
"
,
true
)
1747
setargument
(
"
nonstop
"
,
nil
)
1748
end
1749 1750
do
1751 1752
local
htmlerrorpage
=
getargument
(
"
htmlerrorpage
"
)
1753
if
htmlerrorpage
=
=
"
scite
"
then
1754
directives
.
enable
(
"
system.showerror=scite
"
)
1755
elseif
htmlerrorpage
then
1756
directives
.
enable
(
"
system.showerror
"
)
1757
end
1758 1759
end
1760 1761
do
1762 1763
local
silent
=
getargument
(
"
silent
"
)
1764
if
type
(
silent
)
=
=
"
string
"
then
1765
directives
.
enable
(
format
(
"
logs.blocked={%s}
"
,
silent
)
)
1766
elseif
silent
then
1767
directives
.
enable
(
"
logs.blocked
"
)
1768
end
1769 1770
local
errors
=
getargument
(
"
errors
"
)
1771
if
type
(
errors
)
=
=
"
errors
"
then
1772
directives
.
enable
(
format
(
"
logs.errors={%s}
"
,
silent
)
)
1773
elseif
errors
then
1774
directives
.
enable
(
"
logs.errors
"
)
1775
end
1776 1777
end
1778 1779
if
getargument
(
"
once
"
)
then
1780
multipass_nofruns
=
1
1781
else
1782
if
getargument
(
"
runs
"
)
then
1783
multipass_nofruns
=
tonumber
(
getargument
(
"
runs
"
)
)
or
nil
1784
end
1785
multipass_forcedruns
=
tonumber
(
getargument
(
"
forcedruns
"
)
)
or
nil
1786
end
1787 1788
if
getargument
(
"
run
"
)
then
1789
scripts
.
context
.
timed
(
scripts
.
context
.
autoctx
)
1790
elseif
getargument
(
"
make
"
)
then
1791
scripts
.
context
.
timed
(
function
(
)
scripts
.
context
.
make
(
)
end
)
1792
elseif
getargument
(
"
generate
"
)
then
1793
scripts
.
context
.
timed
(
function
(
)
scripts
.
context
.
generate
(
)
end
)
1794
elseif
getargument
(
"
ctx
"
)
and
not
getargument
(
"
noctx
"
)
then
1795
scripts
.
context
.
timed
(
scripts
.
context
.
ctx
)
1796
elseif
getargument
(
"
version
"
)
then
1797
application
.
identify
(
)
1798
scripts
.
context
.
version
(
)
1799
elseif
getargument
(
"
touch
"
)
then
1800
scripts
.
context
.
touch
(
)
1801
elseif
getargument
(
"
pages
"
)
then
1802
scripts
.
context
.
pages
(
)
1803
elseif
getargument
(
"
expert
"
)
then
1804
application
.
help
(
"
expert
"
,
"
special
"
)
1805
elseif
getargument
(
"
showmodules
"
)
or
getargument
(
"
modules
"
)
then
1806
scripts
.
context
.
modules
(
)
1807
elseif
getargument
(
"
showextras
"
)
or
getargument
(
"
extras
"
)
then
1808
scripts
.
context
.
extras
(
environment
.
filenames
[
1
]
or
getargument
(
"
extras
"
)
)
1809
elseif
getargument
(
"
extra
"
)
then
1810
scripts
.
context
.
extra
(
)
1811
elseif
getargument
(
"
exporthelp
"
)
then
1812
-- application.export(getargument("exporthelp"),environment.filenames[1])
1813
application
.
export
(
)
1814
elseif
getargument
(
"
help
"
)
then
1815
if
environment
.
filenames
[
1
]
=
=
"
extras
"
then
1816
scripts
.
context
.
extras
(
)
1817
else
1818
application
.
help
(
"
basic
"
)
1819
end
1820
elseif
getargument
(
"
showtrackers
"
)
or
getargument
(
"
trackers
"
)
=
=
true
then
1821
scripts
.
context
.
trackers
(
)
1822
elseif
getargument
(
"
showdirectives
"
)
or
getargument
(
"
directives
"
)
=
=
true
then
1823
scripts
.
context
.
directives
(
)
1824
elseif
getargument
(
"
showlogcategories
"
)
then
1825
scripts
.
context
.
logcategories
(
)
1826
elseif
environment
.
filenames
[
1
]
or
getargument
(
"
nofile
"
)
then
1827
scripts
.
context
.
timed
(
scripts
.
context
.
autoctx
)
1828
elseif
getargument
(
"
pipe
"
)
then
1829
scripts
.
context
.
timed
(
scripts
.
context
.
pipe
)
1830
elseif
getargument
(
"
purge
"
)
then
1831
-- only when no filename given, supports --pattern
1832
scripts
.
context
.
purge
(
)
1833
elseif
getargument
(
"
purgeall
"
)
then
1834
-- only when no filename given, supports --pattern
1835
scripts
.
context
.
purge
(
true
,
nil
,
true
)
1836
elseif
getargument
(
"
pattern
"
)
then
1837
environment
.
filenames
=
dir
.
glob
(
getargument
(
"
pattern
"
)
)
1838
scripts
.
context
.
timed
(
scripts
.
context
.
autoctx
)
1839
else
1840
application
.
help
(
"
basic
"
)
1841
end
1842 1843
-- we can wipe a signal file when done
1844 1845
do
1846 1847
if
getargument
(
"
wipebusy
"
)
then
1848
removefile
(
"
context-is-busy.tmp
"
)
1849
end
1850 1851
end
1852