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