diff options
Diffstat (limited to 'scripts/context/lua/mtx-context.lua')
-rw-r--r-- | scripts/context/lua/mtx-context.lua | 293 |
1 files changed, 226 insertions, 67 deletions
diff --git a/scripts/context/lua/mtx-context.lua b/scripts/context/lua/mtx-context.lua index 6c444d531..d90da11e0 100644 --- a/scripts/context/lua/mtx-context.lua +++ b/scripts/context/lua/mtx-context.lua @@ -6,8 +6,6 @@ if not modules then modules = { } end modules ['mtx-context'] = { license = "see context related readme files" } -texmf.instance = instance -- we need to get rid of this / maybe current instance in global table - scripts = scripts or { } scripts.context = scripts.context or { } @@ -30,11 +28,11 @@ end function input.locate_format(name) -- move this to core / luat-xxx local barename, fmtname = name:gsub("%.%a+$",""), "" if input.usecache then - local path = file.join(caches.setpath(instance,"formats")) -- maybe platform + local path = file.join(caches.setpath("formats")) -- maybe platform fmtname = file.join(path,barename..".fmt") or "" end if fmtname == "" then - fmtname = input.find_files(instance,barename..".fmt")[1] or "" + fmtname = input.find_files(barename..".fmt")[1] or "" end fmtname = input.clean_path(fmtname) if fmtname ~= "" then @@ -137,7 +135,7 @@ do elseif ctxdata.ctxname then ctlname = file.replacesuffix(ctxdata.ctxname,'ctl') else - input.report(string.format("invalid ctl name %s",ctlname or "?")) + input.report("invalid ctl name: %s",ctlname or "?") return end end @@ -145,7 +143,7 @@ do input.report("nothing prepared, no ctl file saved") os.remove(ctlname) else - input.report(string.format("saving logdata in %s",ctlname)) + input.report("saving logdata in: %s",ctlname) f = io.open(ctlname,'w') if f then f:write("<?xml version='1.0' standalone='yes'?>\n\n") @@ -190,8 +188,8 @@ do ctxdata.jobname = file.addsuffix(ctxdata.jobname,'tex') ctxdata.ctxname = file.addsuffix(ctxdata.ctxname,'ctx') - input.report("jobname:",ctxdata.jobname) - input.report("ctxname:",ctxdata.ctxname) + input.report("jobname: %s",ctxdata.jobname) + input.report("ctxname: %s",ctxdata.ctxname) -- mtxrun should resolve kpse: and file: @@ -238,17 +236,9 @@ do ctxdata.flags = ctxrunner.reflag(ctxdata.flags) for _, message in ipairs(ctxdata.messages) do - -- message ctxdata.justtext(xml.tostring(message)) + input.report("ctx comment: %s", xml.tostring(message)) end - --~ REXML::XPath.each(root,"//ctx:block") do |blk| - --~ if @jobname && blk.attributes['pattern'] then - --~ root.delete(blk) unless @jobname =~ /#{blk.attributes['pattern']}/ - --~ else - --~ root.delete(blk) - --~ end - --~ end - xml.each(ctxdata.xmldata,"ctx:value[@name='job']", function(ek,e,k) e[k] = ctxdata.variables['job'] or "" end) @@ -259,8 +249,8 @@ do commands[ek.at and ek.at['name'] or "unknown"] = ek end) - local suffix = xml.first(ctxdata.xmldata,"/ctx:job/ctx:preprocess/@suffix") or ctxdata.suffix - local runlocal = xml.first(ctxdata.xmldata,"/ctx:job/ctx:preprocess/ctx:processors/@local") + local suffix = xml.filter(ctxdata.xmldata,"/ctx:job/ctx:preprocess/attribute(suffix)") or ctxdata.suffix + local runlocal = xml.filter(ctxdata.xmldata,"/ctx:job/ctx:preprocess/ctx:processors/attribute(local)") runlocal = toboolean(runlocal) @@ -283,6 +273,7 @@ do pattern = ctxrunner.justtext(xml.tostring(pattern)) local oldfiles = dir.glob(pattern) + local pluspath = false if #oldfiles == 0 then -- message: no files match pattern @@ -333,11 +324,12 @@ do end end) -- potential optimization: when mtxrun run internal + command = xml.text(command) command = ctxrunner.justtext(command) -- command is still xml element here - input.report("command",command) - local result = os.spawn(command) + input.report("command: %s",command) + local result = os.spawn(command) or 0 if result > 0 then - input.report("error, return code",result) + input.report("error, return code: %s",result) end if ctxdata.runlocal then oldfile = file.basename(oldfile) @@ -348,7 +340,7 @@ do file.syncmtimes(oldfile,newfile) ctxdata.prepfiles[oldfile] = true else - input.report("error, check target location of new file", newfile) + input.report("error, check target location of new file: %s", newfile) ctxdata.prepfiles[oldfile] = false end else @@ -400,15 +392,13 @@ scripts.context.backends = { dvips = 'dvips' } -function scripts.context.multipass.makeoptionfile(jobname,ctxdata) +function scripts.context.multipass.makeoptionfile(jobname,ctxdata,kindofrun,currentrun,finalrun) -- take jobname from ctx local f = io.open(jobname..".top","w") if f then - local finalrun, kindofrun, currentrun = false, 0, 0 local function someflag(flag) return (ctxdata and ctxdata.flags[flag]) or environment.argument(flag) end ---~ local someflag = environment.argument local function setvalue(flag,format,hash,default) local a = someflag(flag) or default if a and a ~= "" then @@ -445,21 +435,23 @@ function scripts.context.multipass.makeoptionfile(jobname,ctxdata) end setalways("\\unprotect") setvalue('output' , "\\setupoutput[%s]", scripts.context.backends, 'pdftex') - setalways( "\\setupsystem[\\c!n=%s,\\c!m=%s]", kindofrun, currentrun) + setalways( "\\setupsystem[\\c!n=%s,\\c!m=%s]", kindofrun or 0, currentrun or 0) setalways( "\\setupsystem[\\c!type=%s]",os.platform) setfixed ("batchmode" , "\\batchmode") setfixed ("nonstopmode" , "\\nonstopmode") setfixed ("tracefiles" , "\\tracefilestrue") setfixed ("paranoid" , "\\def\\maxreadlevel{1}") setvalues("modefile" , "\\readlocfile{%s}{}{}") + setvalue ("inputfile" , "\\setupsystem[inputfile=%s]") setvalue ("result" , "\\setupsystem[file=%s]") setvalues("path" , "\\usepath[%s]") setfixed ("color" , "\\setupcolors[\\c!state=\\v!start]") - setfixed ("nompmode" , "\\runMPgraphicsfalse") -- obsolete, we assume runtime mp graphics - setfixed ("nomprun" , "\\runMPgraphicsfalse") -- obsolete, we assume runtime mp graphics - setfixed ("automprun" , "\\runMPgraphicsfalse") -- obsolete, we assume runtime mp graphics + -- setfixed ("nompmode" , "\\runMPgraphicsfalse") -- obsolete, we assume runtime mp graphics + -- setfixed ("nomprun" , "\\runMPgraphicsfalse") -- obsolete, we assume runtime mp graphics + -- setfixed ("automprun" , "\\runMPgraphicsfalse") -- obsolete, we assume runtime mp graphics setfixed ("fast" , "\\fastmode\n") setfixed ("silentmode" , "\\silentmode\n") + setfixed ("nostats" , "\\nomkivstatistics\n") setvalue ("separation" , "\\setupcolors[\\c!split=%s]") setvalue ("setuppath" , "\\setupsystem[\\c!directory={%s}]") setfixed ("noarrange" , "\\setuparranging[\\v!disable]") @@ -468,7 +460,7 @@ function scripts.context.multipass.makeoptionfile(jobname,ctxdata) end setvalue ("arguments" , "\\setupenv[%s]") setvalue ("randomseed" , "\\setupsystem[\\c!random=%s]") - setvalues("modes" , "\\enablemode[%s]") +--~ setvalues("modes" , "\\enablemode[%s]") setvalues("mode" , "\\enablemode[%s]") setvalues("filters" , "\\useXMLfilter[%s]") setvalues("usemodules" , "\\usemodule[%s]") @@ -480,8 +472,8 @@ function scripts.context.multipass.makeoptionfile(jobname,ctxdata) setvalues(ctxdata.environments, "\\environment %s ") end -- done - setalways( "\\protect") - setalways( "\\endinput") + setalways("\\protect") + setalways("\\endinput") f:close() end end @@ -509,6 +501,13 @@ scripts.context.xmlsuffixes = table.tohash { "xml", } +scripts.context.beforesuffixes = { + "tuo", "tuc" +} +scripts.context.aftersuffixes = { + "pdf", "tuo", "tuc", "log" +} + function scripts.context.run(ctxdata) local function makestub(format,filename) local stubname = file.replacesuffix(file.basename(filename),'run') @@ -530,9 +529,9 @@ function scripts.context.run(ctxdata) end local files = environment.files if #files > 0 then - input.identify_cnf(instance) - input.load_cnf(instance) - input.expand_variables(instance) + input.identify_cnf() + input.load_cnf() + input.expand_variables() local formatname = "cont-en" local formatfile, scriptfile = input.locate_format(formatname) if formatfile and scriptfile then @@ -542,26 +541,59 @@ function scripts.context.run(ctxdata) if pathname == "" then filename = "./" .. filename end - -- also other stubs - if environment.argument("forcexml") or scripts.context.xmlsuffixes[file.extname(filename) or "?"] then -- mkii - filename = makestub("\\processXMLfilegrouped{%s}",filename) - elseif environment.argument("processxml") then -- mkiv - filename = makestub("\\xmlprocess{%s}",filename) + -- we default to mkiv xml ! + if scripts.context.xmlsuffixes[file.extname(filename) or "?"] or environment.argument("forcexml") then + if environment.argument("mkii") then + filename = makestub("\\processXMLfilegrouped{%s}",filename) + else + filename = makestub("\\xmlprocess{\\xmldocument}{%s}{}",filename) + end + end + -- + -- todo: also other stubs + -- + local resultname, oldbase, newbase = environment.argument("result"), "", "" + if type(resultname) == "string" then + oldbase = file.removesuffix(jobname) + newbase = file.removesuffix(resultname) + if oldbase ~= newbase then + for _, suffix in pairs(scripts.context.beforesuffixes) do + local oldname = file.addsuffix(oldbase,suffix) + local newname = file.addsuffix(newbase,suffix) + os.remove(oldname) + os.rename(newname,oldname) + end + else + resultname = nil + end + else + resultname = nil end -- if environment.argument("autopdf") then os.spawn(string.format('pdfclose --file "%s" 2>&1', file.replacesuffix(filename,"pdf"))) + if resultname then + os.spawn(string.format('pdfclose --file "%s" 2>&1', file.replacesuffix(resultname,"pdf"))) + end end -- local command = "luatex --fmt=" .. string.quote(formatfile) .. " --lua=" .. string.quote(scriptfile) .. " " .. string.quote(filename) local oldhash, newhash = scripts.context.multipass.hashfiles(jobname), { } - scripts.context.multipass.makeoptionfile(jobname,ctxdata) - for i=1, scripts.context.multipass.nofruns do - input.report(string.format("run %s: %s",i,command)) - local returncode = os.spawn(command) - input.report("return code: " .. returncode) - if returncode > 0 then - input.report("fatal error, run aborted") + local once = environment.argument("once") + local maxnofruns = (once and 1) or scripts.context.multipass.nofruns + for i=1,maxnofruns do + -- 1:first run, 2:successive run, 3:once, 4:last of maxruns + local kindofrun = (once and 3) or (i==1 and 1) or (i==maxnofruns and 4) or 2 + scripts.context.multipass.makeoptionfile(jobname,ctxdata,kindofrun,i,false) -- kindofrun, currentrun, final + input.report("run %s: %s",i,command) + local returncode, errorstring = os.spawn(command) + if not returncode then + input.report("fatal error, message: %s",errorstring or "?") + os.exit(1) + break + elseif returncode > 0 then + input.report("fatal error, code: %s",returncode or "?") + os.exit(returncode) break else scripts.context.multipass.copyluafile(jobname) @@ -575,25 +607,63 @@ function scripts.context.run(ctxdata) end end -- - -- todo: result + -- todo: extra arrange run + -- + if environment.argument("purge") then + scripts.context.purge_job(filename) + elseif environment.argument("purgeall") then + scripts.context.purge_job(filename,true) + end -- + if resultname then + for _, suffix in pairs(scripts.context.aftersuffixes) do + local oldname = file.addsuffix(oldbase,suffix) + local newname = file.addsuffix(newbase,suffix) + os.remove(newname) + os.rename(oldname,newname) + end + input.report("result renamed to: %s",newbase) + end if environment.argument("autopdf") then - os.spawn(string.format('pdfopen --file "%s" 2>&1', file.replacesuffix(filename,"pdf"))) + if resultname then + os.spawn(string.format('pdfopen --file "%s" 2>&1', file.replacesuffix(resultname,"pdf"))) + else + os.spawn(string.format('pdfopen --file "%s" 2>&1', file.replacesuffix(filename,"pdf"))) + end end -- end else input.verbose = true - input.report("error", "no format found with name " .. formatname) + input.report("error, no format found with name: %s",formatname) end end end +local fallback = { + en = "cont-en", + uk = "cont-uk", + de = "cont-de", + fr = "cont-fr", + nl = "cont-nl", + cz = "cont-cz", + it = "cont-it", + ro = "cont-ro", +} + +local defaults = { + "cont-en", + "cont-nl", + "mptopdf", + "plain" +} + function scripts.context.make() - local list = (environment.files[1] and environment.files) or { "cont-en", "cont-nl", "mptopdf" } + local list = (environment.files[1] and environment.files) or defaults for _, name in ipairs(list) do + name = fallback[name] or name local command = "luatools --make --compile " .. name - input.report("running command: " .. command) + input.report("running command: %s",command) os.spawn(command) end end @@ -601,7 +671,7 @@ end function scripts.context.generate() -- hack, should also be a shared function local command = "luatools --generate " - input.report("running command: " .. command) + input.report("running command: %s",command) os.spawn(command) end @@ -613,14 +683,14 @@ function scripts.context.ctx() end function scripts.context.version() - local name = input.find_file(instance,"context.tex") + local name = input.find_file("context.tex") if name ~= "" then - input.report(string.format("main context file: %s",name)) + input.report("main context file: %s",name) local data = io.loaddata(name) if data then local version = data:match("\\edef\\contextversion{(.-)}") if version then - input.report(string.format("current version : %s",version)) + input.report("current version: %s",version) else input.report("context version: unknown, no timestamp found") end @@ -632,10 +702,87 @@ function scripts.context.version() end end +local generic_files = { + "texexec.tex", "texexec.tui", "texexec.tuo", + "texexec.tuc", "texexec.tua", + "texexec.ps", "texexec.pdf", "texexec.dvi", + "cont-opt.tex", "cont-opt.bak" +} + +local obsolete_results = { + "dvi", +} + +local temporary_runfiles = { + "tui", "tua", "tup", "ted", "tes", "top", + "log", "tmp", "run", "bck", "rlg", + "mpt", "mpx", "mpd", "mpo", "mpb", + "ctl", +} + +local persistent_runfiles = { + "tuo", "tub", "top", "tuc" +} + +local function purge_file(dfile,cfile) + if cfile and lfs.isfile(cfile) then + if os.remove(dfile) then + return file.basename(dfile) + end + else + if os.remove(dfile) then + return file.basename(dfile) + end + end +end + +function scripts.context.purge_job(jobname,all) + local filebase = file.removesuffix(jobname) + local deleted = { } + for _, suffix in ipairs(obsolete_results) do + deleted[#deleted+1] = purge_file(filebase.."."..suffix,filebase..".pdf") + end + for _, suffix in ipairs(temporary_runfiles) do + deleted[#deleted+1] = purge_file(filebase.."."..suffix) + end + if all then + for _, suffix in ipairs(persistent_runfiles) do + deleted[#deleted+1] = purge_file(filebase.."."..suffix) + end + end + if #deleted > 0 then + input.report("purged files: %s", table.join(deleted,", ")) + end +end + +function scripts.context.purge(all) + local all = all or environment.argument("all") + local pattern = environment.argument("pattern") or "*.*" + local files = dir.glob(pattern) + local obsolete = table.tohash(obsolete_results) + local temporary = table.tohash(temporary_runfiles) + local persistent = table.tohash(persistent_runfiles) + local generic = table.tohash(generic_files) + local deleted = { } + for _, name in ipairs(files) do + local suffix = file.extname(name) + local basename = file.basename(name) + if obsolete[suffix] or temporary[suffix] or persistent[suffix] or generic[basename] then + deleted[#deleted+1] = purge_file(name) + end + end + if #deleted > 0 then + input.report("purged files: %s", table.join(deleted,", ")) + end +end + +--~ purge_for_files("test",true) +--~ purge_all_files() + function scripts.context.touch() if environment.argument("expert") then local function touch(name,pattern) - local name = input.find_file(instance,name) + local name = input.find_file(name) local olddata = io.loaddata(name) if olddata then local oldversion, newversion = "", os.date("%Y.%M.%d %H:%m") @@ -656,12 +803,12 @@ function scripts.context.touch() end local done, oldversion, newversion, foundname = touch("context.tex", "(\\edef\\contextversion{)(.-)(})") if done then - input.report(string.format("old version : %s", oldversion)) - input.report(string.format("new version : %s", newversion)) - input.report(string.format("touched file: %s", foundname)) + input.report("old version : %s", oldversion) + input.report("new version : %s", newversion) + input.report("touched file: %s", foundname) local ok, _, _, foundname = touch("cont-new.tex", "(\\newcontextversion{)(.-)(})") if ok then - input.report(string.format("touched file: %s", foundname)) + input.report("touched file: %s", foundname) end end end @@ -671,18 +818,22 @@ function scripts.context.timed(action) input.starttiming(scripts.context) action() input.stoptiming(scripts.context) - input.report("total runtime: " .. input.elapsedtime(scripts.context)) + input.report("total runtime: %s",input.elapsedtime(scripts.context)) end banner = banner .. " | context tools " messages.help = [[ --run process (one or more) files (default action) ---make create context formats formats +--make create context formats --generate generate file database etc. --ctx=name use ctx file --version report installed context version ---autopdf open pdf file afterwards +--forcexml force xml stub (optional flag: --mkii) +--autopdf close pdf file in viewer and start pdf viewer afterwards +--once only one run +--purge(all) purge files (--pattern=...) +--result=name rename result to given name --expert expert options ]] @@ -703,18 +854,26 @@ if environment.argument("run") then scripts.context.timed(scripts.context.run) elseif environment.argument("make") then scripts.context.timed(scripts.context.make) +elseif environment.argument("generate") then + scripts.context.timed(scripts.context.generate) elseif environment.argument("ctx") then scripts.context.timed(scripts.context.ctx) elseif environment.argument("version") then scripts.context.version() elseif environment.argument("touch") then scripts.context.touch() -elseif environment.argument("help") then - input.help(banner,messages.help) elseif environment.argument("expert") then input.help(banner,messages.expert) +elseif environment.argument("help") then + input.help(banner,messages.help) elseif environment.files[1] then scripts.context.timed(scripts.context.run) +elseif environment.argument("purge") then + -- only when no filename given, supports --pattern + scripts.context.purge() +elseif environment.argument("purgeall") then + -- only when no filename given, supports --pattern + scripts.context.purge(true) else input.help(banner,messages.help) end |