1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
|
if not modules then modules = { } end modules ['luat-fmt'] = {
version = 1.001,
comment = "companion to mtxrun",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
license = "see context related readme files"
}
local format = string.format
local concat = table.concat
local quoted = string.quoted
local luasuffixes = utilities.lua.suffixes
local report_format = logs.reporter("resolvers","formats")
local function primaryflags()
local arguments = environment.arguments
local flags = { }
if arguments.silent then
flags[#flags+1] = "--interaction=batchmode"
end
if arguments.jit then
flags[#flags+1] = "--jiton"
end
return concat(flags," ")
end
local function secondaryflags()
local arguments = environment.arguments
local trackers = arguments.trackers
local directives = arguments.directives
local flags = { }
if trackers and trackers ~= "" then
flags[#flags+1] = "--c:trackers=" .. quoted(trackers)
end
if directives and directives ~= "" then
flags[#flags+1] = "--c:directives=" .. quoted(directives)
end
if arguments.silent then
flags[#flags+1] = "--c:silent"
end
if arguments.errors then
flags[#flags+1] = "--c:errors"
end
if arguments.jit then
flags[#flags+1] = "--c:jiton"
end
if arguments.ansi then
flags[#flags+1] = "--c:ansi"
end
return concat(flags," ")
end
-- The silent option is Taco. It's a bit of a hack because we cannot yet mess
-- with directives. In fact, I could probably clean up the maker a bit by now.
local template = [[--ini %primaryflags% --lua=%luafile% %texfile% %secondaryflags% %dump% %redirect%]]
local checkers = {
primaryflags = "string",
secondaryflags = "string",
luafile = "readable", -- "cache"
texfile = "readable", -- "cache"
redirect = "string",
dump = "string",
}
local runners = {
luatex = sandbox.registerrunner {
name = "make luatex format",
program = "luatex",
template = template,
checkers = checkers,
reporter = report_format,
},
luajittex = sandbox.registerrunner {
name = "make luajittex format",
program = "luajittex",
template = template,
checkers = checkers,
reporter = report_format,
},
}
function environment.make_format(name,arguments)
local engine = environment.ownmain or "luatex"
local silent = environment.arguments.silent
local errors = environment.arguments.errors
-- change to format path (early as we need expanded paths)
local olddir = dir.current()
local path = caches.getwritablepath("formats",engine) or "" -- maybe platform
if path ~= "" then
lfs.chdir(path)
end
report_format("using format path %a",dir.current())
-- check source file
local texsourcename = file.addsuffix(name,"mkiv")
local fulltexsourcename = resolvers.findfile(texsourcename,"tex") or ""
if fulltexsourcename == "" then
texsourcename = file.addsuffix(name,"tex")
fulltexsourcename = resolvers.findfile(texsourcename,"tex") or ""
end
if fulltexsourcename == "" then
report_format("no tex source file with name %a (mkiv or tex)",name)
lfs.chdir(olddir)
return
else
report_format("using tex source file %a",fulltexsourcename)
end
local texsourcepath = dir.expandname(file.dirname(fulltexsourcename)) -- really needed
-- check specification
local specificationname = file.replacesuffix(fulltexsourcename,"lus")
local fullspecificationname = resolvers.findfile(specificationname,"tex") or ""
if fullspecificationname == "" then
specificationname = file.join(texsourcepath,"context.lus")
fullspecificationname = resolvers.findfile(specificationname,"tex") or ""
end
if fullspecificationname == "" then
report_format("unknown stub specification %a",specificationname)
lfs.chdir(olddir)
return
end
local specificationpath = file.dirname(fullspecificationname)
-- load specification
local usedluastub = nil
local usedlualibs = dofile(fullspecificationname)
if type(usedlualibs) == "string" then
usedluastub = file.join(file.dirname(fullspecificationname),usedlualibs)
elseif type(usedlualibs) == "table" then
report_format("using stub specification %a",fullspecificationname)
local texbasename = file.basename(name)
local luastubname = file.addsuffix(texbasename,luasuffixes.lua)
local lucstubname = file.addsuffix(texbasename,luasuffixes.luc)
-- pack libraries in stub
report_format("creating initialization file %a",luastubname)
utilities.merger.selfcreate(usedlualibs,specificationpath,luastubname)
-- compile stub file (does not save that much as we don't use this stub at startup any more)
if utilities.lua.compile(luastubname,lucstubname) and lfs.isfile(lucstubname) then
report_format("using compiled initialization file %a",lucstubname)
usedluastub = lucstubname
else
report_format("using uncompiled initialization file %a",luastubname)
usedluastub = luastubname
end
else
report_format("invalid stub specification %a",fullspecificationname)
lfs.chdir(olddir)
return
end
-- generate format
local specification = {
primaryflags = primaryflags(),
secondaryflags = secondaryflags(),
luafile = quoted(usedluastub),
texfile = quoted(fulltexsourcename),
dump = os.platform == "unix" and "\\\\dump" or "\\dump",
}
local runner = runners[engine]
if not runner then
report_format("format %a cannot be generated, no runner available for engine %a",name,engine)
elseif silent then
statistics.starttiming()
specification.redirect = "> temp.log"
local result = runner(specification)
local runtime = statistics.stoptiming()
if result ~= 0 then
print(format("%s silent make > fatal error when making format %q",engine,name)) -- we use a basic print
else
print(format("%s silent make > format %q made in %.3f seconds",engine,name,runtime)) -- we use a basic print
end
os.remove("temp.log")
else
runner(specification)
end
-- remove related mem files
local pattern = file.removesuffix(file.basename(usedluastub)).."-*.mem"
-- report_format("removing related mplib format with pattern %a", pattern)
local mp = dir.glob(pattern)
if mp then
for i=1,#mp do
local name = mp[i]
report_format("removing related mplib format %a", file.basename(name))
os.remove(name)
end
end
lfs.chdir(olddir)
end
local template = [[%flags% --fmt=%fmtfile% --lua=%luafile% %texfile% %more%]]
local checkers = {
flags = "string",
more = "string",
fmtfile = "readable", -- "cache"
luafile = "readable", -- "cache"
texfile = "readable", -- "cache"
}
local runners = {
luatex = sandbox.registerrunner {
name = "run luatex format",
program = "luatex",
template = template,
checkers = checkers,
reporter = report_format,
},
luajittex = sandbox.registerrunner {
name = "run luajittex format",
program = "luajittex",
template = template,
checkers = checkers,
reporter = report_format,
},
}
function environment.run_format(name,data,more)
if name and name ~= "" then
local engine = environment.ownmain or "luatex"
local barename = file.removesuffix(name)
local fmtname = caches.getfirstreadablefile(file.addsuffix(barename,"fmt"),"formats",engine)
if fmtname == "" then
fmtname = resolvers.findfile(file.addsuffix(barename,"fmt")) or ""
end
fmtname = resolvers.cleanpath(fmtname)
if fmtname == "" then
report_format("no format with name %a",name)
else
local barename = file.removesuffix(name) -- expanded name
local luaname = file.addsuffix(barename,"luc")
if not lfs.isfile(luaname) then
luaname = file.addsuffix(barename,"lua")
end
if not lfs.isfile(luaname) then
report_format("using format name %a",fmtname)
report_format("no luc/lua file with name %a",barename)
else
local runner = runners[engine]
if not runner then
report_format("format %a cannot be run, no runner available for engine %a",name,engine)
else
runner {
flags = primaryflags(),
fmtfile = quoted(barename),
luafile = quoted(luaname),
texfile = quoted(data),
more = more,
}
end
end
end
end
end
|