1if not modules then modules = { } end modules ['luat-fmt'] = {
2 version = 1.001,
3 comment = "companion to mtxrun",
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
10
11
12
13
14
15
16
17
18
19
20
21
22
23local format = string.format
24local concat = table.concat
25local quoted = string.quoted
26local luasuffixes = utilities.lua.suffixes
27
28local report_format = logs.reporter("resolvers","formats")
29
30local function primaryflags(arguments)
31 local flags = { }
32 if arguments.silent then
33 flags[#flags+1] = "--interaction=batchmode"
34 end
35 return concat(flags," ")
36end
37
38local function secondaryflags(arguments)
39 local trackers = arguments.trackers
40 local directives = arguments.directives
41 local flags = { }
42 if trackers and trackers ~= "" then
43 flags[#flags+1] = "--c:trackers=" .. quoted(trackers)
44 end
45 if directives and directives ~= "" then
46 flags[#flags+1] = "--c:directives=" .. quoted(directives)
47 end
48 if arguments.silent then
49 flags[#flags+1] = "--c:silent"
50 end
51 if arguments.errors then
52 flags[#flags+1] = "--c:errors"
53 end
54 if arguments.ansi then
55 flags[#flags+1] = "--c:ansi"
56 end
57 if arguments.ansilog then
58 flags[#flags+1] = "--c:ansilog"
59 end
60 if arguments.strip then
61 flags[#flags+1] = "--c:strip"
62 end
63 if arguments.lmtx then
64 flags[#flags+1] = "--c:lmtx"
65 end
66 return concat(flags," ")
67end
68
69
70
71
72local template = [[--ini %primaryflags% --socket --shell-escape --lua=%luafile% %texfile% %secondaryflags% %redirect%]]
73
74local checkers = {
75 primaryflags = "verbose",
76 secondaryflags = "verbose",
77 luafile = "readable",
78 texfile = "readable",
79 redirect = "string",
80 binarypath = "string",
81}
82
83local runners = {
84 luametatex = sandbox.registerrunner {
85 name = "make luametatex format",
86 program = "luametatex",
87 template = template,
88 checkers = checkers,
89 reporter = report_format,
90 },
91 luatex = sandbox.registerrunner {
92 name = "make luatex format",
93 program = "luatex",
94 template = template,
95 checkers = checkers,
96 reporter = report_format,
97 },
98 luajittex = sandbox.registerrunner {
99 name = "make luajittex format",
100 program = "luajittex",
101 template = template,
102 checkers = checkers,
103 reporter = report_format,
104 },
105}
106
107local stubfiles = {
108 luametatex = "luat-cod.lmt",
109 luatex = "luat-cod.lua",
110 luajittex = "luat-cod.lua",
111}
112
113local suffixes = {
114 luametatex = "mkxl",
115 luatex = "mkiv",
116 luajittex = "mkiv",
117}
118
119local function validbinarypath()
120
121 if not environment.arguments.nobinarypath then
122 local path = environment.ownpath or file.dirname(environment.ownname)
123 if path and path ~= "" then
124 path = dir.expandname(path)
125 if path ~= "" and lfs.isdir(path) then
126 return path
127 end
128 end
129 end
130end
131
132local function fatalerror(startupdir,...)
133 report_format(...)
134 lfs.chdir(startupdir)
135end
136
137function environment.make_format(formatname)
138 local arguments = environment.arguments
139 local engine = environment.ownmain or "luatex"
140 local silent = arguments.silent
141 local errors = arguments.errors
142 local runner = runners[engine]
143 local startupdir = dir.current()
144 if not runner then
145 return fatalerror(startupdir,"the format %a cannot be generated, no runner available for engine %a",name,engine)
146 end
147
148
149 local luasourcename = stubfiles[engine]
150 if not luasourcename then
151 return fatalerror(startupdir,"no lua stub file specified for %a",engine)
152 end
153 local texsourcename = file.addsuffix(formatname,suffixes[engine])
154 local fulltexsourcename = resolvers.findfile(texsourcename,"tex") or ""
155 if fulltexsourcename == "" then
156 return fatalerror(startupdir,"no tex source file with name %a (mkiv or tex)",formatname)
157 end
158
159
160 local fulltexsourcename = dir.expandname(fulltexsourcename)
161 local texsourcepath = file.dirname(fulltexsourcename)
162 if lfs.isfile(fulltexsourcename) then
163 report_format("using tex source file %a",fulltexsourcename)
164 else
165 return fatalerror(startupdir,"no accessible tex source file with name %a",fulltexsourcename)
166 end
167
168
169
170 local fullluasourcename = dir.expandname(file.join(texsourcepath,luasourcename) or "")
171 if lfs.isfile(fullluasourcename) then
172 report_format("using lua stub file %a",fullluasourcename)
173 else
174 return fatalerror(startupdir,"no accessible lua stub file with name %a",fulltexsourcename)
175 end
176
177
178 local validformatpath = caches.getwritablepath("formats",engine) or ""
179 if validformatpath == "" then
180 return fatalerror(startupdir,"invalid format path, insufficient write access")
181 end
182
183
184 local binarypath = validbinarypath()
185 report_format("changing to format path %a",validformatpath)
186
187
188 if not lfs.chdir(validformatpath) then
189 return fatalerror(startupdir,"unable to change to format path %a",validformatpath)
190 end
191
192
193 local primaryflags = primaryflags(arguments)
194 local secondaryflags = secondaryflags(arguments)
195 local specification = {
196 binarypath = binarypath,
197 primaryflags = primaryflags,
198 secondaryflags = secondaryflags,
199 luafile = quoted(fullluasourcename),
200 texfile = quoted(fulltexsourcename),
201 }
202 if silent then
203 specification.redirect = "> temp.log"
204 end
205 statistics.starttiming("format")
206 local result = runner(specification)
207 statistics.stoptiming("format")
208 if silent then
209 os.remove("temp.log")
210 end
211
212 report_format()
213 if binarypath and binarypath ~= "" then
214 report_format("binary path : %s",binarypath or "?")
215 end
216 report_format("format path : %s",validformatpath)
217 report_format("luatex engine : %s",engine)
218 report_format("lua startup file : %s",fullluasourcename)
219 if primaryflags ~= "" then
220 report_format("primary flags : %s",primaryflags)
221 end
222 if secondaryflags ~= "" then
223 report_format("secondary flags : %s",secondaryflags)
224 end
225 report_format("context file : %s",fulltexsourcename)
226 report_format("run time : %.3f seconds",statistics.elapsed("format"))
227 report_format("return value : %s",result == 0 and "okay" or "error")
228 report_format()
229
230 lfs.chdir(startupdir)
231end
232
233local template = [[%primaryflags% --socket --shell-escape --fmt=%fmtfile% --lua=%luafile% %texfile% %secondaryflags%]]
234
235local checkers = {
236 primaryflags = "verbose",
237 secondaryflags = "verbose",
238 fmtfile = "readable",
239 luafile = "readable",
240 texfile = "readable",
241}
242
243local runners = {
244 luatex = sandbox.registerrunner {
245 name = "run luatex format",
246 program = "luatex",
247 template = template,
248 checkers = checkers,
249 reporter = report_format,
250 },
251 luametatex = sandbox.registerrunner {
252 name = "run luametatex format",
253 program = "luametatex",
254 template = template,
255 checkers = checkers,
256 reporter = report_format,
257 },
258 luajittex = sandbox.registerrunner {
259 name = "run luajittex format",
260 program = "luajittex",
261 template = template,
262 checkers = checkers,
263 reporter = report_format,
264 },
265}
266
267function environment.run_format(formatname,scriptname,filename,primaryflags,secondaryflags,verbose)
268 local engine = environment.ownmain or "luatex"
269 if not formatname or formatname == "" then
270 report_format("missing format name")
271 return
272 end
273 if not scriptname or scriptname == "" then
274 report_format("missing script name")
275 return
276 end
277 if not lfs.isfile(formatname) or not lfs.isfile(scriptname) then
278 formatname, scriptname = resolvers.locateformat(formatname)
279 end
280 if not formatname or formatname == "" then
281 report_format("invalid format name")
282 return
283 end
284 if not scriptname or scriptname == "" then
285 report_format("invalid script name")
286 return
287 end
288 local runner = runners[engine]
289 if not runner then
290 report_format("format %a cannot be run, no runner available for engine %a",file.nameonly(name),engine)
291 return
292 end
293 if not filename then
294 filename ""
295 end
296 local binarypath = validbinarypath()
297 local specification = {
298 binarypath = binarypath,
299 primaryflags = primaryflags or "",
300 secondaryflags = secondaryflags or "",
301 fmtfile = quoted(formatname),
302 luafile = quoted(scriptname),
303 texfile = filename ~= "" and quoted(filename) or "",
304 }
305 statistics.starttiming("make format")
306 local result = runner(specification)
307 statistics.stoptiming("make format")
308 if verbose then
309 report_format()
310 if binarypath and binarypath ~= "" then
311 report_format("binary path : %s",binarypath)
312 end
313 report_format("luatex engine : %s",engine)
314 report_format("lua startup file : %s",scriptname)
315 report_format("tex format file : %s",formatname)
316 if filename ~= "" then
317 report_format("tex input file : %s",filename)
318 end
319 if primaryflags ~= "" then
320 report_format("primary flags : %s",primaryflags)
321 end
322 if secondaryflags ~= "" then
323 report_format("secondary flags : %s",secondaryflags)
324 end
325 report_format("run time : %0.3f seconds",statistics.elapsed("make format"))
326 report_format("return value : %s",result == 0 and "okay" or "error")
327 report_format()
328 end
329 return result
330end
331 |