summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/mlib-run.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mlib-run.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/mlib-run.lua250
1 files changed, 250 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/mlib-run.lua b/Master/texmf-dist/tex/context/base/mlib-run.lua
new file mode 100644
index 00000000000..30cd01c736d
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mlib-run.lua
@@ -0,0 +1,250 @@
+if not modules then modules = { } end modules ['mlib-run'] = {
+ version = 1.001,
+ comment = "companion to mlib-ctx.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files",
+}
+
+--~ cmyk -> done, native
+--~ spot -> done, but needs reworking (simpler)
+--~ multitone ->
+--~ shade -> partly done, todo: cm
+--~ figure -> done
+--~ hyperlink -> low priority, easy
+
+-- new * run
+-- or
+-- new * execute^1 * finish
+
+-- a*[b,c] == b + a * (c-b)
+
+--[[ldx--
+<p>The directional helpers and pen analysis are more or less translated from the
+<l n='c'/> code. It really helps that Taco know that source so well. Taco and I spent
+quite some time on speeding up the <l n='lua'/> and <l n='c'/> code. There is not
+much to gain, especially if on ekeeps in mind that when integrated in <l n='tex'/>
+only a part of the time is spent in <l n='metapost'/>. Of course an integrated
+approach is way faster than an external <l n='metapost'/> and processing time
+nears zero.</p>
+--ldx]]--
+
+local format = string.format
+
+metapost = metapost or { }
+
+local function finder(name, mode, ftype)
+ if mode=="w" then
+ return name
+ elseif input.aux.qualified_path(name) then
+ return name
+ else
+ return input.find_file((texmf and texmf.instance) or instance,name,ftype)
+ end
+end
+
+metapost.finder = finder
+
+--~ statistics = {
+--~ ["hash_size"]=1774,
+--~ ["main_memory"]=50237,
+--~ ["max_in_open"]=5,
+--~ ["param_size"]=4,
+--~ }
+
+metapost.parameters = {
+ hash_size = 100000,
+ main_memory = 2000000,
+ max_in_open = 50,
+ param_size = 100000,
+}
+
+metapost.exectime = metapost.exectime or { } -- hack
+
+function metapost.make(name, target, version)
+ input.starttiming(mplib)
+ target = file.replacesuffix(target or name, "mem")
+ local mpx = mplib.new ( table.merged (
+ metapost.parameters,
+ {
+ ini_version = true,
+ find_file = finder,
+ job_name = file.stripsuffix(target),
+ }
+ ) )
+ if mpx then
+ input.starttiming(metapost.exectime)
+ local result = mpx:execute(format('\\ ; boolean mplib ; mplib := true ; string mp_parent_version ; mp_parent_version := "%s" ; show mp_parent_version ; input %s ; dump ;', version or "unknown", name))
+ input.stoptiming(metapost.exectime)
+ if mpx then
+ mpx:finish()
+ end
+ end
+ input.stoptiming(mplib)
+ return mpx -- mpx = nil will free memory
+end
+
+function metapost.load(name)
+ input.starttiming(mplib)
+ local mpx = mplib.new ( table.merged (
+ metapost.parameters,
+ {
+ mem_name = file.replacesuffix(name,"mem"),
+ find_file = finder,
+ }
+ ) )
+ if mpx then
+ input.starttiming(metapost.exectime)
+ mpx:execute("\\")
+ input.stoptiming(metapost.exectime)
+ end
+ input.stoptiming(mplib)
+ return mpx
+end
+
+function metapost.unload(mpx)
+ input.starttiming(mplib)
+ if mpx then
+ mpx:finish()
+ end
+ input.stoptiming(mplib)
+end
+
+function metapost.checkformat(mpsinput, mpsformat)
+ mpsinput = file.addsuffix(mpsinput or "metafun", "mp")
+ mpsformat = file.stripsuffix(file.basename(mpsformat or texconfig.formatname or tex.formatname or mpsinput))
+ local mpsbase = file.stripsuffix(file.basename(mpsinput))
+ if mpsbase ~= mpsformat then
+ mpsformat = mpsformat .. "-" .. mpsbase
+ end
+ mpsformat = file.addsuffix(mpsformat, "mem")
+ local pth = file.dirname(texconfig.formatname or "")
+ if pth ~= "" then
+ mpsformat = file.join(pth,mpsformat)
+ end
+ local the_version = environment.version or "unset version"
+ if io.exists(mpsformat) then
+ commands.writestatus("mplib", format("loading format: %s, name: %s", mpsinput, mpsformat))
+ local mpx = metapost.load(mpsformat)
+ if mpx then
+ local result = mpx:execute(format("show mp_parent_version ;"))
+ local version = result.log:match(">> *(.-)[\n\r]") or "unknown"
+ version = version:gsub("[\'\"]","")
+ if version ~= the_version then
+ commands.writestatus("mplib", format("version mismatch: %s <> %s", version or "unknown", the_version))
+ else
+ return mpx
+ end
+ end
+ end
+ commands.writestatus("mplib", format("making format: %s, name: %s", mpsinput, mpsformat))
+ metapost.make(mpsinput,mpsformat,the_version) -- somehow return ... fails here
+ if io.exists(mpsformat) then
+ commands.writestatus("mplib", format("loading format: %s, name: %s", mpsinput, mpsformat))
+ return metapost.load(mpsformat)
+ else
+ commands.writestatus("mplib", format("problems with format: %s, name: %s", mpsinput, mpsformat))
+ end
+end
+
+--~ if environment.initex then
+--~ metapost.unload(metapost.checkformat("metafun"))
+--~ end
+
+local mpxformats = {}
+
+function metapost.format(name)
+ local mpx = mpxformats[name]
+ if not mpx then
+ mpx = metapost.checkformat(name)
+ mpxformats[name] = mpx
+ end
+ return mpx
+end
+
+function metapost.reset(mpx)
+ if not mpx then
+ -- nothing
+ elseif type(mpx) == "string" then
+ if mpxformats[mpx] then
+ mpxformats[mpx]:finish()
+ mpxformats[mpx] = nil
+ end
+ else
+ for name=1,#mpxformats do
+ if mpxformats[name] == mpx then
+ mpxformats[name] = nil
+ break
+ end
+ end
+ mpx:finish()
+ end
+end
+
+metapost.showlog = false
+
+function metapost.process(mpx, data, trialrun, flusher, multipass)
+ local converted, result = false, {}
+ if type(mpx) == "string" then
+ mpx = metapost.format(mpx) -- goody
+ end
+ if mpx and data then
+ input.starttiming(metapost)
+ if type(data) == "table" then
+ for i=1,#data do
+ local d = data[i]
+ if d then
+ input.starttiming(metapost.exectime)
+ result = mpx:execute(d)
+ input.stoptiming(metapost.exectime)
+ if not result then
+ metapost.report("mp error", "no result object returned")
+ elseif result.status > 0 then
+ local t, e, l = result.term, result.error, result.log
+ if t then
+ metapost.report("mp terminal",t)
+ end
+ if e then
+ metapost.report("mp error",e)
+ end
+ if not t and not e and l then
+ metapost.report("mp log",l)
+ else
+ metapost.report("mp error","unknown, no error, terminal or log messages")
+ end
+ elseif metapost.showlog then
+ metapost.report("mp info",result.term or "no terminal output")
+ elseif result.fig then
+ converted = metapost.convert(result, trialrun, flusher, multipass)
+ end
+ else
+ metapost.report("mp error", "invalid graphic component " .. i)
+ end
+ end
+ else
+ input.starttiming(metapost.exectime)
+ result = mpx:execute(data)
+ input.stoptiming(metapost.exectime)
+ -- todo: error message
+ if not result then
+ metapost.report("error", "no result object returned")
+ elseif result.status > 0 then
+ metapost.report("error",(result.term or "no-term") .. "\n" .. (result.error or "no-error"))
+ elseif metapost.showlog then
+ metapost.report("info",result.term or "no-term")
+ elseif result.fig then
+ converted = metapost.convert(result, trialrun, flusher, multipass)
+ end
+ end
+ input.stoptiming(metapost)
+ end
+ return converted, result
+end
+
+function metapost.convert(result, trialrun, multipass)
+ metapost.report('Warning','no converter set')
+end
+
+function metapost.report(...)
+ logs.report(...)
+end