diff options
Diffstat (limited to 'tex/context/base/core-uti.lua')
-rw-r--r-- | tex/context/base/core-uti.lua | 98 |
1 files changed, 93 insertions, 5 deletions
diff --git a/tex/context/base/core-uti.lua b/tex/context/base/core-uti.lua index 00811e528..fc99f67cb 100644 --- a/tex/context/base/core-uti.lua +++ b/tex/context/base/core-uti.lua @@ -6,6 +6,9 @@ if not modules then modules = { } end modules ['core-uti'] = { license = "see context related readme files" } +-- todo: keep track of changes here (hm, track access, and only true when +-- accessed and changed) + --[[ldx-- <p>A utility file has always been part of <l n='context'/> and with the move to <l n='luatex'/> we also moved a lot of multi-pass info @@ -14,9 +17,12 @@ utility file under different setups, we now load a table once. This saves much runtime but at the cost of more memory usage.</p> --ldx]]-- -if not jobs then jobs = { } end -if not job then jobs['main'] = { } end job = jobs['main'] -if not job.variables then job.variables = { } end +local format = string.format + +if not jobs then jobs = { } end +if not job then jobs['main'] = { } end job = jobs['main'] + +jobs.version = 1.01 --[[ldx-- <p>Variables are saved using in the previously defined table and passed @@ -24,6 +30,88 @@ onto <l n='tex'/> using the following method. Of course one can also directly access the variable using a <l n='lua'/> call.</p> --ldx]]-- -function job.initializevariable(cs,value) - tex.sprint("\\xdef\\"..cs.."{"..value.."}") +local savelist, comment = { }, { } + +function job.comment(...) + for _, str in ipairs({...}) do + comment[#comment+1] = str + end +end + +job.comment(format("version: %1.2f",jobs.version)) + +job._save_, job._load_ = { }, { } + +function job.save(filename) + input.starttiming(job._save_) + local f = io.open(filename,'w') + if f then + for _, str in ipairs(comment) do + f:write("-- ",str,"\n") + end + f:write("\n") + for _, list in ipairs(savelist) do + local target, data, finalizer = list[1], list[2], list[4] + if type(finalizer) == "function" then + finalizer() + end + f:write(aux.definetable(target),"\n") + f:write(table.serialize(data,target,true,true),"\n") + end + f:close() + end + input.stoptiming(job._save_) +end + +function job.load(filename) + input.starttiming(job._load_) + local data = io.loaddata(filename) + if data and data ~= "" then + local version = tonumber(data:match("^-- version: ([%d%.]+)")) + if version ~= jobs.version then + logs.report("job","version mismatch with jobfile: %s <> %s", version or "?", jobs.version) + else + loadstring(data)() + for _, list in ipairs(savelist) do + local target, initializer = list[1], list[3] + if type(initializer) == "function" then + initializer(aux.accesstable(target)) + end + end + end + end + input.stoptiming(job._load_) +end + +function job.initialize(loadname,savename) + job.load(loadname) + table.insert(input.stop_actions, function() + if not status.lasterrorstring or status.lasterrorstring == "" then + job.save(savename) + end + end) end + +function job.register(...) -- collected, tobesaved, initializer, finalizer + savelist[#savelist+1] = { ... } +end + +-- as an example we implement variables + +jobvariables = jobvariables or { } +jobvariables.collected = jobvariables.collected or { } +jobvariables.tobesaved = jobvariables.tobesaved or { } + +local function initializer() + for cs, value in pairs(jobvariables.collected) do + tex.sprint(string.format("\\xdef\\%s{%s}",cs,value)) + end +end + +job.register('jobvariables.collected', jobvariables.tobesaved, initializer) + +function jobvariables.save(cs,value) + jobvariables.tobesaved[cs] = value +end + + |