diff options
Diffstat (limited to 'tex/context/base/core-ctx.lua')
-rw-r--r-- | tex/context/base/core-ctx.lua | 331 |
1 files changed, 46 insertions, 285 deletions
diff --git a/tex/context/base/core-ctx.lua b/tex/context/base/core-ctx.lua index 0dfb21ce9..e6fb7bb5f 100644 --- a/tex/context/base/core-ctx.lua +++ b/tex/context/base/core-ctx.lua @@ -6,290 +6,72 @@ if not modules then modules = { } end modules ['core-ctx'] = { license = "see context related readme files" } ---[[ -Job control files aka ctx files are rather old and date from the mkii times. -They were handled in texexec and mtx-context and deals with modes, modules, -environments and preprocessing in projects where one such file drives the -processing of lots of files without the need to provide command line -arguments. - -In mkiv this concept was of course supported as well. The first implementation -of mtx-context took much of the approach of texexec, but by now we have gotten -rid of the option file (for passing modes, modules and environments), the stubs -(for directly processing cld and xml) as well as the preprocessing component -of the ctx files. Special helper features, like typesetting listings, were -already moved to the extras (a direct side effect of the ability to pass along -command line arguments.) All this made mtx-context more simple than its ancestor -texexec. - -Because some of the modes might affect the mtx-context end, the ctx file is -still loaded there but only for getting the modes. The file is loaded again -during the run but as loading and basic processing takes less than a -millisecond it's not that much of a burden. ---]] - --- the ctxrunner tabel might either become private or move to the job namespace --- which also affects the loading order - local trace_prepfiles = false trackers.register("system.prepfiles", function(v) trace_prepfiles = v end) -local gsub, find, match, validstring = string.gsub, string.find, string.match, string.valid -local concat = table.concat -local xmltext = xml.text - local report_prepfiles = logs.reporter("system","prepfiles") commands = commands or { } local commands = commands -ctxrunner = ctxrunner or { } - -ctxrunner.prepfiles = utilities.storage.allocate() - -local function dontpreparefile(t,k) - return k -- we only store when we have a prepper -end - -table.setmetatableindex(ctxrunner.prepfiles,dontpreparefile) - -local function filtered(str,method) -- in resolvers? - str = tostring(str) - if method == 'name' then str = file.nameonly(str) - elseif method == 'path' then str = file.dirname(str) - elseif method == 'suffix' then str = file.suffix(str) - elseif method == 'nosuffix' then str = file.removesuffix(str) - elseif method == 'nopath' then str = file.basename(str) - elseif method == 'base' then str = file.basename(str) --- elseif method == 'full' then --- elseif method == 'complete' then --- elseif method == 'expand' then -- str = file.expandpath(str) - end - return (gsub(str,"\\","/")) -end - --- local function substitute(e,str) --- local attributes = e.at --- if str and attributes then --- if attributes['method'] then --- str = filtered(str,attributes['method']) --- end --- if str == "" and attributes['default'] then --- str = attributes['default'] --- end --- end --- return str --- end - -local function substitute(str) - return str -end - -local function justtext(str) - str = xml.unescaped(tostring(str)) - str = xml.cleansed(str) - str = gsub(str,"\\+",'/') - str = gsub(str,"%s+",' ') - return str -end - -function ctxrunner.load(ctxname) - - local xmldata = xml.load(ctxname) - - local jobname = tex.jobname -- todo - - local variables = { job = jobname } - local commands = { } - local flags = { } - local paths = { } -- todo - local treatments = { } - local suffix = "prep" - - xml.include(xmldata,'ctx:include','name', {'.', file.dirname(ctxname), "..", "../.." }) - - for e in xml.collected(xmldata,"/ctx:job/ctx:flags/ctx:flag") do - local flag = xmltext(e) - local key, value = match(flag,"^(.-)=(.+)$") - if key and value then - environment.setargument(key,value) - else - environment.setargument(flag,true) - end - end - - -- add to document.options.ctxfile[...] - - local ctxfile = document.options.ctxfile - - local modes = ctxfile.modes - local modules = ctxfile.modules - local environments = ctxfile.environments - - for e in xml.collected(xmldata,"/ctx:job/ctx:process/ctx:resources/ctx:mode") do - modes[#modes+1] = xmltext(e) - -- context.enablemode { xmltext(e) } - end - - for e in xml.collected(xmldata,"/ctx:job/ctx:process/ctx:resources/ctx:module") do - modules[#modules+1] = xmltext(e) - -- context.module { xmltext(e) } - end - - for e in xml.collected(xmldata,"/ctx:job/ctx:process/ctx:resources/ctx:environment") do - environments[#environments+1] = xmltext(e) - -- context.environment { xmltext(e) } - end - - for e in xml.collected(xmldata,"ctx:message") do - report_prepfiles("ctx comment: %s", xmltext(e)) - end - - for r, d, k in xml.elements(xmldata,"ctx:value[@name='job']") do - d[k] = variables['job'] or "" - end - - for e in xml.collected(xmldata,"/ctx:job/ctx:preprocess/ctx:processors/ctx:processor") do - commands[e.at and e.at['name'] or "unknown"] = e - end - - local suffix = xml.filter(xmldata,"xml:///ctx:job/ctx:preprocess/attribute('suffix')") -- or ... - local runlocal = xml.filter(xmldata,"xml:///ctx:job/ctx:preprocess/ctx:processors/attribute('local')") - - runlocal = toboolean(runlocal) - - -- todo: only collect, then plug into file handler - - local inputfile = validstring(environment.arguments.input) or jobname - - variables.old = inputfile - - for files in xml.collected(xmldata,"/ctx:job/ctx:preprocess/ctx:files") do - for pattern in xml.collected(files,"ctx:file") do - local preprocessor = pattern.at['processor'] or "" - for r, d, k in xml.elements(pattern,"/ctx:old") do - d[k] = jobname - end - for r, d, k in xml.elements(pattern,"/ctx:value[@name='old'") do - d[k] = jobname - end - pattern =justtext(xml.tostring(pattern)) - if preprocessor and preprocessor ~= "" and pattern and pattern ~= "" then - local noftreatments = #treatments + 1 - local findpattern = string.topattern(pattern) - local preprocessors = utilities.parsers.settings_to_array(preprocessor) - treatments[noftreatments] = { - pattern = findpattern, - preprocessors = preprocessors, - } - report_prepfiles("step: %s, pattern: %q, preprocessor: %q",noftreatments,findpattern,concat(preprocessors," ")) - end - end - end - - local function needstreatment(oldfile) - for i=1,#treatments do - local treatment = treatments[i] - local pattern = treatment.pattern - if find(oldfile,pattern) then - return treatment - end - end - end - - local preparefile = #treatments > 0 and function(prepfiles,filename) - - local treatment = needstreatment(filename) - if treatment then - local oldfile = filename - -- newfile = oldfile .. "." .. suffix - newfile = oldfile .. ".prep" - if runlocal then - newfile = file.basename(newfile) - end - - if file.needsupdating(oldfile,newfile) then - local preprocessors = treatment.preprocessors - local runners = { } - for i=1,#preprocessors do - local preprocessor = preprocessors[i] - local command = commands[preprocessor] - if command then - command = xml.copy(command) - local suf = command.at and command.at['suffix'] or suffix - if suf then - newfile = oldfile .. "." .. suf - end - if runlocal then - newfile = file.basename(newfile) - end - for r, d, k in xml.elements(command,"ctx:old") do - d[k] = substitute(oldfile) - end - for r, d, k in xml.elements(command,"ctx:new") do - d[k] = substitute(newfile) - end - variables.old = oldfile - variables.new = newfile - for r, d, k in xml.elements(command,"ctx:value") do - local ek = d[k] - local ekat = ek.at and ek.at['name'] - if ekat then - d[k] = substitute(variables[ekat] or "") - end - end - command = xml.content(command) - runners[#runners+1] = justtext(command) - oldfile = newfile - if runlocal then - oldfile = file.basename(oldfile) - end - end - end - -- for tracing we have collected commands first - for i=1,#runners do - report_prepfiles("step %i: %s",i,runners[i]) +local list, suffix, islocal, found = { }, "prep", false, false + +function commands.loadctxpreplist() + local ctlname = file.replacesuffix(tex.jobname,"ctl") + if lfs.isfile(ctlname) then + local x = xml.load(ctlname) + if x then + islocal = xml.found(x,"ctx:preplist[@local=='yes']") +--~ if trace_prepfiles then + if islocal then + report_prepfiles("loading ctx log file (local)") -- todo: m!system + else + report_prepfiles("loading ctx log file (specified)") -- todo: m!system end - -- - for i=1,#runners do - local command = runners[i] - report_prepfiles("command: %s",command) - local result = os.spawn(command) or 0 - -- if result > 0 then - -- report_prepfiles("error, return code: %s",result) - -- end +--~ end + for e in xml.collected(x,"ctx:prepfile") do + local name = xml.text(e) + if islocal then + name = file.basename(name) end - if lfs.isfile(newfile) then - file.syncmtimes(filename,newfile) - report_prepfiles("%q is converted to %q",filename,newfile) - else - report_prepfiles("%q is not converted to %q",filename,newfile) - newfile = filename + local done = e.at['done'] or 'no' + if trace_prepfiles then + report_prepfiles("registering %s -> %s",done) end - elseif lfs.isfile(newfile) then - report_prepfiles("%q is already converted to %q",filename,newfile) - else - -- report_prepfiles("%q is not converted to %q",filename,newfile) - newfile = filename + found = true + list[name] = done -- 'yes' or 'no' end - else - newfile = filename end - prepfiles[filename] = newfile - - return newfile - end +end - table.setmetatableindex(ctxrunner.prepfiles,preparefile or dontpreparefile) - - -- we need to deal with the input filename as it has already be resolved +-- -- -- +local function found(name) -- used in resolve + local prepname = name .. "." .. suffix + if list[name] and lfs.isfile(prepname) then + if trace_prepfiles then + report_prepfiles("preprocessing: using %s",prepname) + end + return prepname + end + return false end local function resolve(name) -- used a few times later on - return ctxrunner.prepfiles[file.collapsepath(name)] or false + local filename = file.collapsepath(name) + local prepname = islocal and found(file.basename(name)) + if prepname then + return prepname + end + prepname = found(filename) + if prepname then + return prepname + end + return false end +--~ support.doiffileexistelse(name) + local processfile = commands.processfile local doifinputfileelse = commands.doifinputfileelse @@ -312,24 +94,3 @@ end function commands.preparedfile(name) return resolve(name) or name end - -function commands.getctxfile() - local ctxfile = document.arguments.ctx or "" - if ctxfile ~= "" then - ctxrunner.load(ctxfile) -- do we need to locate it? - end -end - -function ctxrunner.resolve(name) -- used a few times later on - return ctxrunner.prepfiles[file.collapsepath(name)] or name -end - --- ctxrunner.load("t:/sources/core-ctx.ctx") --- --- context(ctxrunner.prepfiles["one-a.xml"]) context.par() --- context(ctxrunner.prepfiles["one-b.xml"]) context.par() --- context(ctxrunner.prepfiles["two-c.xml"]) context.par() --- context(ctxrunner.prepfiles["two-d.xml"]) context.par() --- context(ctxrunner.prepfiles["all-x.xml"]) context.par() --- --- inspect(ctxrunner.prepfiles) |