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 if arguments.ansilog then flags[#flags+1] = "--c:ansilog" end if arguments.strip then flags[#flags+1] = "--c:strip" end if arguments.lmtx then flags[#flags+1] = "--c:lmtx" end return concat(flags," ") end -- The silent option is for 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, }, luametatex = sandbox.registerrunner { name = "make luametatex format", program = "luametatex", 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 = "" local fulltexsourcename = "" if engine == "luametatex" then texsourcename = file.addsuffix(name,"mkxl") fulltexsourcename = resolvers.findfile(texsourcename,"tex") or "" end if fulltexsourcename == "" then texsourcename = file.addsuffix(name,"mkiv") fulltexsourcename = resolvers.findfile(texsourcename,"tex") or "" end 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