summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/file-job.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/file-job.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/file-job.lua515
1 files changed, 413 insertions, 102 deletions
diff --git a/Master/texmf-dist/tex/context/base/file-job.lua b/Master/texmf-dist/tex/context/base/file-job.lua
index 992e4b7ec70..ea4623d7724 100644
--- a/Master/texmf-dist/tex/context/base/file-job.lua
+++ b/Master/texmf-dist/tex/context/base/file-job.lua
@@ -9,8 +9,11 @@ if not modules then modules = { } end modules ['file-job'] = {
-- in retrospect dealing it's not that bad to deal with the nesting
-- and push/poppign at the tex end
-local format, gsub, match = string.format, string.gsub, string.match
+local gsub, match, find = string.gsub, string.match, string.find
local insert, remove, concat = table.insert, table.remove, table.concat
+local validstring = string.valid
+local sortedhash = table.sortedhash
+local formatters = string.formatters
local commands, resolvers, context = commands, resolvers, context
@@ -18,25 +21,40 @@ local trace_jobfiles = false trackers.register("system.jobfiles", function(v)
local report_jobfiles = logs.reporter("system","jobfiles")
-local texsetcount = tex.setcount
-local elements = interfaces.elements
-local variables = interfaces.variables
-local logsnewline = logs.newline
-local logspushtarget = logs.pushtarget
-local logspoptarget = logs.poptarget
-
-local v_outer = variables.outer
-local v_text = variables.text
-local v_project = variables.project
-local v_environment = variables.environment
-local v_product = variables.product
-local v_component = variables.component
-local c_prefix = variables.prefix
+local texsetcount = tex.setcount
+local elements = interfaces.elements
+local constants = interfaces.constants
+local variables = interfaces.variables
+local logsnewline = logs.newline
+local logspushtarget = logs.pushtarget
+local logspoptarget = logs.poptarget
+local settings_to_array = utilities.parsers.settings_to_array
+local allocate = utilities.storage.allocate
+
+local nameonly = file.nameonly
+local suffixonly = file.suffix
+local basename = file.basename
+local addsuffix = file.addsuffix
+local removesuffix = file.removesuffix
+local dirname = file.dirname
+local joinpath = file.join
+local is_qualified_path = file.is_qualified_path
+
+local cleanpath = resolvers.cleanpath
+local inputstack = resolvers.inputstack
+
+local v_outer = variables.outer
+local v_text = variables.text
+local v_project = variables.project
+local v_environment = variables.environment
+local v_product = variables.product
+local v_component = variables.component
+local c_prefix = variables.prefix
-- main code .. there is some overlap .. here we have loc://
local function findctxfile(name) -- loc ? any ?
- if file.is_qualified_path(name) then -- maybe when no suffix do some test for tex
+ if is_qualified_path(name) then -- maybe when no suffix do some test for tex
return name
elseif not url.hasscheme(name) then
return resolvers.finders.byscheme("loc",name) or ""
@@ -59,7 +77,7 @@ function commands.doifinputfileelse(name)
end
function commands.locatefilepath(name)
- context(file.dirname(findctxfile(name)))
+ context(dirname(findctxfile(name)))
end
function commands.usepath(paths)
@@ -74,39 +92,24 @@ function commands.allinputpaths()
context(concat(resolvers.instance.extra_paths or { },","))
end
+function commands.setdocumentfilenames()
+ environment.initializefilenames()
+end
+
function commands.usezipfile(name,tree)
if tree and tree ~= "" then
- resolvers.usezipfile(format("zip:///%s?tree=%s",name,tree))
+ resolvers.usezipfile(formatters["zip:///%s?tree=%s"](name,tree))
else
- resolvers.usezipfile(format("zip:///%s",name))
+ resolvers.usezipfile(formatters["zip:///%s"](name))
end
end
-local report_system = logs.reporter("system","options")
-local report_options = logs.reporter("used options")
-
-function commands.copyfiletolog(name)
- local f = io.open(name)
- if f then
- logspushtarget("logfile")
- logsnewline()
- report_system("start used options")
- logsnewline()
- for line in f:lines() do
- report_options(line)
- end
- logsnewline()
- report_system("stop used options")
- logsnewline()
- logspoptarget()
- f:close()
- end
-end
+local report_system = logs.reporter("system")
-- moved from tex to lua:
local texpatterns = { "%s.mkvi", "%s.mkiv", "%s.tex" }
-local luapatterns = { "%s.luc", "%s.lua" }
+local luapatterns = { "%s" .. utilities.lua.suffixes.luc, "%s.lua" }
local cldpatterns = { "%s.cld" }
local xmlpatterns = { "%s.xml" }
@@ -141,7 +144,7 @@ end
local function startprocessing(name,notext)
if not notext then
- -- report_system("begin file %s at line %s",name,status.linenumber or 0)
+ -- report_system("begin file %a at line %a",name,status.linenumber or 0)
context.dostarttextfile(name)
end
end
@@ -149,14 +152,14 @@ end
local function stopprocessing(notext)
if not notext then
context.dostoptextfile()
- -- report_system("end file %s at line %s",name,status.linenumber or 0)
+ -- report_system("end file %a at line %a",name,status.linenumber or 0)
end
end
--
local action = function(name,foundname) input(foundname) end
-local failure = function(name,foundname) end
+local failure = function(name,foundname) report_jobfiles("unknown %s file %a","tex",name) end
local function usetexfile(name,onlyonce,notext)
startprocessing(name,notext)
@@ -171,7 +174,7 @@ local function usetexfile(name,onlyonce,notext)
end
local action = function(name,foundname) dofile(foundname) end
-local failure = function(name,foundname) end
+local failure = function(name,foundname) report_jobfiles("unknown %s file %a","lua",name) end
local function useluafile(name,onlyonce,notext)
uselibrary {
@@ -184,7 +187,7 @@ local function useluafile(name,onlyonce,notext)
end
local action = function(name,foundname) dofile(foundname) end
-local failure = function(name,foundname) end
+local failure = function(name,foundname) report_jobfiles("unknown %s file %a","cld",name) end
local function usecldfile(name,onlyonce,notext)
startprocessing(name,notext)
@@ -199,7 +202,7 @@ local function usecldfile(name,onlyonce,notext)
end
local action = function(name,foundname) context.xmlprocess(foundname,"main","") end
-local failure = function(name,foundname) end
+local failure = function(name,foundname) report_jobfiles("unknown %s file %a","xml",name) end
local function usexmlfile(name,onlyonce,notext)
startprocessing(name,notext)
@@ -232,7 +235,7 @@ local suffixes = {
local function useanyfile(name,onlyonce)
local s = suffixes[file.suffix(name)]
if s then
- s(file.removesuffix(name),onlyonce)
+ s(removesuffix(name),onlyonce)
else
usetexfile(name,onlyonce) -- e.g. ctx file
--~ resolvers.readfilename(name)
@@ -244,14 +247,12 @@ commands.useanyfile = useanyfile
function resolvers.jobs.usefile(name,onlyonce,notext)
local s = suffixes[file.suffix(name)]
if s then
- s(file.removesuffix(name),onlyonce,notext)
+ s(removesuffix(name),onlyonce,notext)
end
end
-- document structure
-local report_system = logs.reporter("system")
-
local textlevel = 0 -- inaccessible for user, we need to define counter textlevel at the tex end
local function dummyfunction() end
@@ -361,8 +362,8 @@ local stacks = {
--
-local report_system = logs.reporter("system","structure")
-local report_structure = logs.reporter("used structure")
+local report_structures = logs.reporter("system","structure")
+local report_structure = logs.reporter("used structure")
local function pushtree(what,name)
local t = { }
@@ -387,20 +388,18 @@ local function log_tree(top,depth)
end
end
-local function logtree()
+luatex.registerstopactions(function()
logspushtarget("logfile")
logsnewline()
- report_system("start used structure")
+ report_structures("start used structure")
logsnewline()
root.name = environment.jobname
log_tree(root,"")
logsnewline()
- report_system("stop used structure")
+ report_structures("stop used structure")
logsnewline()
logspoptarget()
-end
-
-luatex.registerstopactions(logtree)
+end)
job.structure = job.structure or { }
job.structure.collected = job.structure.collected or { }
@@ -429,48 +428,52 @@ job.register('job.structure.collected',root,initialize)
-- component: small unit, either or not components itself
-- product : combination of components
+local context_processfilemany = context.processfilemany
+local context_processfileonce = context.processfileonce
+local context_processfilenone = context.processfilenone
+
local processors = utilities.storage.allocate {
-- [v_outer] = {
- -- [v_text] = { "many", context.processfilemany },
- -- [v_project] = { "once", context.processfileonce },
- -- [v_environment] = { "once", context.processfileonce },
- -- [v_product] = { "many", context.processfileonce },
- -- [v_component] = { "many", context.processfilemany },
+ -- [v_text] = { "many", context_processfilemany },
+ -- [v_project] = { "once", context_processfileonce },
+ -- [v_environment] = { "once", context_processfileonce },
+ -- [v_product] = { "once", context_processfileonce },
+ -- [v_component] = { "many", context_processfilemany },
-- },
[v_text] = {
- [v_text] = { "many", context.processfilemany },
- [v_project] = { "none", context.processfileonce }, -- none
- [v_environment] = { "once", context.processfileonce }, -- once
- [v_product] = { "none", context.processfileonce }, -- none
- [v_component] = { "many", context.processfilemany }, -- many
+ [v_text] = { "many", context_processfilemany },
+ [v_project] = { "once", context_processfileonce }, -- dubious
+ [v_environment] = { "once", context_processfileonce },
+ [v_product] = { "many", context_processfilemany }, -- dubious
+ [v_component] = { "many", context_processfilemany },
},
[v_project] = {
- [v_text] = { "many", context.processfilemany },
- [v_project] = { "none", context.processfilenone }, -- none
- [v_environment] = { "once", context.processfileonce }, -- once
- [v_product] = { "once", context.processfilenone }, -- once
- [v_component] = { "none", context.processfilenone }, -- many *
+ [v_text] = { "many", context_processfilemany },
+ [v_project] = { "none", context_processfilenone },
+ [v_environment] = { "once", context_processfileonce },
+ [v_product] = { "none", context_processfilenone },
+ [v_component] = { "none", context_processfilenone },
},
[v_environment] = {
- [v_text] = { "many", context.processfilemany },
- [v_project] = { "none", context.processfilenone }, -- none
- [v_environment] = { "once", context.processfileonce }, -- once
- [v_product] = { "none", context.processfilenone }, -- none
- [v_component] = { "none", context.processfilenone }, -- none
+ [v_text] = { "many", context_processfilemany },
+ [v_project] = { "none", context_processfilenone },
+ [v_environment] = { "once", context_processfileonce },
+ [v_product] = { "none", context_processfilenone },
+ [v_component] = { "none", context_processfilenone },
},
[v_product] = {
- [v_text] = { "many", context.processfilemany },
- [v_project] = { "once", context.processfileonce }, -- once
- [v_environment] = { "once", context.processfileonce }, -- once
- [v_product] = { "none", context.processfilemany }, -- none
- [v_component] = { "many", context.processfilemany }, -- many
+ [v_text] = { "many", context_processfilemany },
+ [v_project] = { "once", context_processfileonce },
+ [v_environment] = { "once", context_processfileonce },
+ [v_product] = { "many", context_processfilemany },
+ [v_component] = { "many", context_processfilemany },
},
[v_component] = {
- [v_text] = { "many", context.processfilemany },
- [v_project] = { "once", context.processfileonce }, -- once
- [v_environment] = { "once", context.processfileonce }, -- once
- [v_product] = { "none", context.processfilenone }, -- none
- [v_component] = { "many", context.processfilemany }, -- many
+ [v_text] = { "many", context_processfilemany },
+ [v_project] = { "once", context_processfileonce },
+ [v_environment] = { "once", context_processfileonce },
+ [v_product] = { "none", context_processfilenone },
+ [v_component] = { "many", context_processfilemany },
}
}
@@ -531,6 +534,9 @@ local tolerant = false -- too messy, mkii user with the wrong sructure should ad
local function process(what,name)
local depth = #typestack
local process
+ --
+ name = resolvers.resolve(name)
+ --
-- if not tolerant then
-- okay, would be best but not compatible with mkii
process = processors[currenttype][what]
@@ -553,11 +559,11 @@ local function process(what,name)
local method = process[1]
if method == "none" then
if trace_jobfiles then
- report_jobfiles("%s : %s : ignoring %s '%s' in %s '%s'",depth,method,what,name,currenttype,topofstack(currenttype))
+ report_jobfiles("%s : %s : %s %s %a in %s %a",depth,method,"ignoring",what,name,currenttype,topofstack(currenttype))
end
elseif method == "once" and done[name] then
if trace_jobfiles then
- report_jobfiles("%s : %s : skipping %s '%s' in %s '%s'",depth,method,what,name,currenttype,topofstack(currenttype))
+ report_jobfiles("%s : %s : %s %s %a in %s %a",depth,method,"skipping",what,name,currenttype,topofstack(currenttype))
end
else
-- keep in mind that we also handle "once" at the file level
@@ -566,7 +572,7 @@ local function process(what,name)
local before = start[what]
local after = stop [what]
if trace_jobfiles then
- report_jobfiles("%s : %s : processing %s '%s' in %s '%s'",depth,method,what,name,currenttype,topofstack(currenttype))
+ report_jobfiles("%s : %s : %s %s %a in %s %a",depth,method,"processing",what,name,currenttype,topofstack(currenttype))
end
if before then
before()
@@ -578,7 +584,7 @@ local function process(what,name)
end
else
if trace_jobfiles then
- report_jobfiles("%s : ? : ignoring %s '%s' in %s '%s'",depth,what,name,currenttype,topofstack(currenttype))
+ report_jobfiles("%s : %s : %s %s %a in %s %a",depth,"none","ignoring",what,name,currenttype,topofstack(currenttype))
end
end
end
@@ -610,7 +616,7 @@ local function gotonextlevel(what,name) -- todo: something with suffix name
insert(typestack,currenttype)
insert(pathstack,currentpath)
currenttype = what
- currentpath = file.dirname(name)
+ currentpath = dirname(name)
pushtree(what,name)
if start[what] then
start[what]()
@@ -629,10 +635,17 @@ local function gotopreviouslevel(what)
context.signalendofinput(what)
end
-function commands.startproject (name) gotonextlevel(v_project, name) end
-function commands.startproduct (name) gotonextlevel(v_product, name) end
-function commands.startcomponent (name) gotonextlevel(v_component, name) end
-function commands.startenvironment(name) gotonextlevel(v_environment,name) end
+local function autoname(name)
+ if name == "*" then
+ name = nameonly(inputstack[#inputstack] or name)
+ end
+ return name
+end
+
+function commands.startproject (name) gotonextlevel(v_project, autoname(name)) end
+function commands.startproduct (name) gotonextlevel(v_product, autoname(name)) end
+function commands.startcomponent (name) gotonextlevel(v_component, autoname(name)) end
+function commands.startenvironment(name) gotonextlevel(v_environment,autoname(name)) end
function commands.stopproject () gotopreviouslevel(v_project ) end
function commands.stopproduct () gotopreviouslevel(v_product ) end
@@ -664,7 +677,7 @@ local function convertexamodes(str)
local data = xml.text(e)
local mode = match(label,"^mode:(.+)$")
if mode then
- context.enablemode { format("%s:%s",mode,data) }
+ context.enablemode { formatters["%s:%s"](mode,data) }
end
context.setvariable("exa:variables",label,(gsub(data,"([{}])","\\%1")))
end
@@ -673,13 +686,311 @@ end
function commands.loadexamodes(filename)
if not filename or filename == "" then
- filename = file.removesuffix(tex.jobname)
+ filename = removesuffix(tex.jobname)
end
- filename = resolvers.findfile(file.addsuffix(filename,'ctm')) or ""
+ filename = resolvers.findfile(addsuffix(filename,'ctm')) or ""
if filename ~= "" then
- report_examodes("loading %s",filename) -- todo: message system
+ report_examodes("loading %a",filename) -- todo: message system
convertexamodes(io.loaddata(filename))
else
- report_examodes("no mode file %s",filename) -- todo: message system
+ report_examodes("no mode file %a",filename) -- todo: message system
+ end
+end
+
+-- changed in mtx-context
+-- code moved from luat-ini
+
+-- todo: locals when mtx-context is changed
+
+document = document or {
+ arguments = allocate(),
+ files = allocate(),
+ variables = allocate(), -- for templates
+ options = {
+ commandline = {
+ environments = allocate(),
+ modules = allocate(),
+ modes = allocate(),
+ },
+ ctxfile = {
+ environments = allocate(),
+ modules = allocate(),
+ modes = allocate(),
+ },
+ },
+}
+
+function document.setargument(key,value)
+ document.arguments[key] = value
+end
+
+function document.setdefaultargument(key,default)
+ local v = document.arguments[key]
+ if v == nil or v == "" then
+ document.arguments[key] = default
+ end
+end
+
+function document.setfilename(i,name)
+ if name then
+ document.files[tonumber(i)] = name
+ else
+ document.files[#document.files+1] = tostring(i)
+ end
+end
+
+function document.getargument(key,default) -- commands
+ local v = document.arguments[key]
+ if type(v) == "boolean" then
+ v = (v and "yes") or "no"
+ document.arguments[key] = v
+ end
+ context(v or default or "")
+end
+
+function document.getfilename(i) -- commands
+ context(document.files[tonumber(i)] or "")
+end
+
+function commands.getcommandline() -- has to happen at the tex end in order to expand
+
+ -- the document[arguments|files] tables are copies
+
+ local arguments = document.arguments
+ local files = document.files
+ local options = document.options
+
+ for k, v in next, environment.arguments do
+ k = gsub(k,"^c:","") -- already done, but better be safe than sorry
+ if arguments[k] == nil then
+ arguments[k] = v
+ end
+ end
+
+ -- in the new mtx=context approach we always pass a stub file so we need to
+ -- to trick the files table which actually only has one entry in a tex job
+
+ if arguments.timing then
+ context.usemodule("timing")
+ end
+
+ if arguments.batchmode then
+ context.batchmode(false)
+ end
+
+ if arguments.nonstopmode then
+ context.nonstopmode(false)
+ end
+
+ if arguments.nostatistics then
+ directives.enable("system.nostatistics")
+ end
+
+ if arguments.paranoid then
+ context.setvalue("maxreadlevel",1)
+ end
+
+ if validstring(arguments.path) then
+ context.usepath { arguments.path }
+ end
+
+ local inputfile = validstring(arguments.input)
+
+ if inputfile and dirname(inputfile) == "." and lfs.isfile(inputfile) then
+ -- nicer in checks
+ inputfile = basename(inputfile)
+ end
+
+ local kindofrun = arguments.kindofrun
+ local currentrun = arguments.maxnofruns
+ local maxnofruns = arguments.currentrun
+
+ context.setupsystem {
+ [constants.directory] = validstring(arguments.setuppath),
+ [constants.inputfile] = inputfile,
+ [constants.file] = validstring(arguments.result),
+ [constants.random] = validstring(arguments.randomseed),
+ -- old:
+ [constants.n] = validstring(kindofrun),
+ [constants.m] = validstring(currentrun),
+ }
+
+ environment.kindofrun = tonumber(kindofrun) or 0
+ environment.maxnofruns = tonumber(maxnofruns) or 0
+ environment.currentrun = tonumber(currentrun) or 0
+
+ if validstring(arguments.arguments) then
+ context.setupenv { arguments.arguments }
+ end
+
+ if arguments.once then
+ directives.enable("system.runonce")
+ end
+
+ if arguments.noarrange then
+ context.setuparranging { variables.disable }
+ end
+
+ --
+
+ local commandline = options.commandline
+
+ commandline.environments = table.append(commandline.environments,settings_to_array(validstring(arguments.environment)))
+ commandline.modules = table.append(commandline.modules, settings_to_array(validstring(arguments.usemodule)))
+ commandline.modes = table.append(commandline.modes, settings_to_array(validstring(arguments.mode)))
+
+ --
+
+ if #files == 0 then
+ local list = settings_to_array(validstring(arguments.files))
+ if list and #list > 0 then
+ files = list
+ end
+ end
+
+ if #files == 0 then
+ files = { validstring(arguments.input) }
+ end
+
+ --
+
+ document.arguments = arguments
+ document.files = files
+
+end
+
+-- commandline wins over ctxfile
+
+local function apply(list,action)
+ if list then
+ for i=1,#list do
+ action { list[i] }
+ end
+ end
+end
+
+function commands.setdocumentmodes() -- was setup: *runtime:modes
+ apply(document.options.ctxfile .modes,context.enablemode)
+ apply(document.options.commandline.modes,context.enablemode)
+end
+
+function commands.setdocumentmodules() -- was setup: *runtime:modules
+ apply(document.options.ctxfile .modules,context.usemodule)
+ apply(document.options.commandline.modules,context.usemodule)
+end
+
+function commands.setdocumentenvironments() -- was setup: *runtime:environments
+ apply(document.options.ctxfile .environments,context.environment)
+ apply(document.options.commandline.environments,context.environment)
+end
+
+local report_files = logs.reporter("system","files")
+local report_options = logs.reporter("system","options")
+local report_file = logs.reporter("used file")
+local report_option = logs.reporter("used option")
+
+luatex.registerstopactions(function()
+ local foundintrees = resolvers.instance.foundintrees
+ if #foundintrees > 0 then
+ logspushtarget("logfile")
+ logsnewline()
+ report_files("start used files")
+ logsnewline()
+ for i=1,#foundintrees do
+ report_file("%4i: % T",i,foundintrees[i])
+ end
+ logsnewline()
+ report_files("stop used files")
+ logsnewline()
+ logspoptarget()
+ end
+end)
+
+luatex.registerstopactions(function()
+ local files = document.files -- or environment.files
+ local arguments = document.arguments -- or environment.arguments
+ --
+ logspushtarget("logfile")
+ logsnewline()
+ report_options("start commandline options")
+ logsnewline()
+ for argument, value in sortedhash(arguments) do
+ report_option("%s=%A",argument,value)
+ end
+ logsnewline()
+ report_options("stop commandline options")
+ logsnewline()
+ report_options("start commandline files")
+ logsnewline()
+ for i=1,#files do
+ report_file("% 4i: %s",i,files[i])
+ end
+ logsnewline()
+ report_options("stop commandline files")
+ logsnewline()
+ logspoptarget()
+end)
+
+if environment.initex then
+
+ local report_storage = logs.reporter("system","storage")
+ local report_table = logs.reporter("stored table")
+ local report_module = logs.reporter("stored module")
+ local report_attribute = logs.reporter("stored attribute")
+ local report_catcodetable = logs.reporter("stored catcodetable")
+ local report_corenamespace = logs.reporter("stored corenamespace")
+
+ luatex.registerstopactions(function()
+ logspushtarget("logfile")
+ logsnewline()
+ report_storage("start stored tables")
+ logsnewline()
+ for k,v in sortedhash(storage.data) do
+ report_table("%03i %s",k,v[1])
+ end
+ logsnewline()
+ report_storage("stop stored tables")
+ logsnewline()
+ report_storage("start stored modules")
+ logsnewline()
+ for k,v in sortedhash(lua.bytedata) do
+ report_module("%03i %s %s",k,v[2],v[1])
+ end
+ logsnewline()
+ report_storage("stop stored modules")
+ logsnewline()
+ report_storage("start stored attributes")
+ logsnewline()
+ for k,v in sortedhash(attributes.names) do
+ report_attribute("%03i %s",k,v)
+ end
+ logsnewline()
+ report_storage("stop stored attributes")
+ logsnewline()
+ report_storage("start stored catcodetables")
+ logsnewline()
+ for k,v in sortedhash(catcodes.names) do
+ report_catcodetable("%03i % t",k,v)
+ end
+ logsnewline()
+ report_storage("stop stored catcodetables")
+ logsnewline()
+ report_storage("start stored corenamespaces")
+ for k,v in sortedhash(interfaces.corenamespaces) do
+ report_corenamespace("%03i %s",k,v)
+ end
+ logsnewline()
+ report_storage("stop stored corenamespaces")
+ logsnewline()
+ logspoptarget()
+ end)
+
+end
+
+function commands.doifelsecontinuewithfile(inpname)
+ local continue = addsuffix(inpname,"tex") == addsuffix(environment.inputfilename,"tex")
+ if continue then
+ report_system("continuing input file %a",inpname)
end
+ commands.doifelse(continue)
end