summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/mkxl/mlib-ctx.lmt
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkxl/mlib-ctx.lmt')
-rw-r--r--Master/texmf-dist/tex/context/base/mkxl/mlib-ctx.lmt420
1 files changed, 420 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkxl/mlib-ctx.lmt b/Master/texmf-dist/tex/context/base/mkxl/mlib-ctx.lmt
new file mode 100644
index 00000000000..2569a6066b2
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkxl/mlib-ctx.lmt
@@ -0,0 +1,420 @@
+if not modules then modules = { } end modules ['mlib-ctx'] = {
+ version = 1.001,
+ comment = "companion to mlib-ctx.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files",
+}
+
+local type, tostring = type, tostring
+local format, concat = string.format, table.concat
+local settings_to_hash = utilities.parsers.settings_to_hash
+local formatters = string.formatters
+
+local report_metapost = logs.reporter ("metapost")
+local status_metapost = logs.messenger("metapost")
+
+local starttiming = statistics.starttiming
+local stoptiming = statistics.stoptiming
+
+local trace_graphic = false
+
+trackers.register("metapost.graphics",
+ function(v) trace_graphic = v end
+);
+
+local mplib = mplib
+
+metapost = metapost or { }
+local metapost = metapost
+local context = context
+
+local setters = tokens.setters
+local setmacro = setters.macro
+local implement = interfaces.implement
+
+local v_no = interfaces.variables.no
+
+local extensiondata = metapost.extensiondata or storage.allocate { }
+metapost.extensiondata = extensiondata
+
+storage.register("metapost/extensiondata",extensiondata,"metapost.extensiondata")
+
+function metapost.setextensions(instances,data)
+ if data and data ~= "" then
+ extensiondata[#extensiondata+1] = {
+ usedinall = not instances or instances == "",
+ instances = settings_to_hash(instances or ""),
+ extensions = data,
+ }
+ end
+end
+
+function metapost.getextensions(instance,state)
+ if state and state == v_no then
+ return ""
+ else
+ local t = { }
+ for i=1,#extensiondata do
+ local e = extensiondata[i]
+ local status = e.instances[instance]
+ if (status ~= true) and (e.usedinall or status) then
+ t[#t+1] = e.extensions
+ e.instances[instance] = true
+ end
+ end
+ return concat(t," ")
+ end
+end
+
+implement {
+ name = "setmpextensions",
+ actions = metapost.setextensions,
+ arguments = "2 strings",
+}
+
+implement {
+ name = "getmpextensions",
+ actions = { metapost.getextensions, context } ,
+ arguments = "string"
+}
+
+local patterns = {
+ "meta-imp-%s.mkxl",
+ "meta-imp-%s.mkiv",
+ "meta-imp-%s.tex",
+ -- obsolete:
+ "meta-%s.mkiv",
+ "meta-%s.tex"
+}
+
+local function action(name,foundname)
+ commands.loadlibrary(name,foundname,false)
+ status_metapost("library %a is loaded",name)
+end
+
+local function failure(name)
+ report_metapost("library %a is unknown or invalid",name)
+end
+
+implement {
+ name = "useMPlibrary",
+ arguments = "string",
+ actions = function(name)
+ resolvers.uselibrary {
+ name = name,
+ patterns = patterns,
+ action = action,
+ failure = failure,
+ onlyonce = true,
+ }
+ end
+}
+
+-- metapost.variables = { } -- to be stacked
+
+implement {
+ name = "mprunvar",
+ arguments = "string",
+ actions = function(name)
+ local value = metapost.variables[name]
+ if value ~= nil then
+ local tvalue = type(value)
+ if tvalue == "table" then
+ context(concat(value," "))
+ elseif tvalue == "number" or tvalue == "boolean" then
+ context(tostring(value))
+ elseif tvalue == "string" then
+ context(value)
+ end
+ end
+ end
+}
+
+implement {
+ name = "mpruntab",
+ arguments = { "string", "integer" },
+ actions = function(name,n)
+ local value = metapost.variables[name]
+ if value ~= nil then
+ local tvalue = type(value)
+ if tvalue == "table" then
+ context(value[n])
+ elseif tvalue == "number" or tvalue == "boolean" then
+ context(tostring(value))
+ elseif tvalue == "string" then
+ context(value)
+ end
+ end
+ end
+}
+
+implement {
+ name = "mprunset",
+ arguments = "2 strings",
+ actions = function(name,connector)
+ local value = metapost.variables[name]
+ if value ~= nil then
+ local tvalue = type(value)
+ if tvalue == "table" then
+ context(concat(value,connector))
+ elseif tvalue == "number" or tvalue == "boolean" then
+ context(tostring(value))
+ elseif tvalue == "string" then
+ context(value)
+ end
+ end
+ end
+}
+
+-- we need to move more from pps to here as pps is the plugin .. the order is a mess
+-- or just move the scanners to pps
+
+function metapost.graphic(specification)
+ metapost.pushformat(specification)
+ metapost.graphic_base_pass(specification)
+ metapost.popformat()
+end
+
+function metapost.startgraphic(t)
+ if not t then
+ t = { }
+ end
+ if not t.instance then
+ t.instance = metapost.defaultinstance
+ end
+ if not t.format then
+ t.format = metapost.defaultformat
+ end
+ if not t.method then
+ t.method = metapost.defaultmethod
+ end
+ t.data = { }
+ return t
+end
+
+function metapost.stopgraphic(t)
+ if t then
+ t.data = concat(t.data or { },"\n")
+ if trace_graphic then
+ report_metapost("\n"..t.data.."\n")
+ end
+ metapost.graphic(t)
+ end
+end
+
+function metapost.tographic(t,f,s,...)
+ local d = t.data
+ d[#d+1] = s and formatters[f](s,...) or f
+end
+
+implement {
+ name = "mpgraphic",
+ actions = metapost.graphic,
+ arguments = {
+ {
+ { "instance" },
+ { "format" },
+ { "data" },
+ { "initializations" },
+ { "extensions" },
+ { "inclusions" },
+ { "definitions" },
+ { "figure" },
+ { "method" },
+ { "namespace" },
+ }
+ }
+}
+
+implement {
+ name = "mpsetoutercolor",
+ actions = function(...) metapost.setoutercolor(...) end, -- not yet implemented
+ arguments = { "integer", "integer", "integer", "integer" }
+}
+
+-- this has to become a codeinjection
+
+function metapost.getclippath(specification) -- why not a special instance for this
+ local mpx = metapost.pushformat(specification)
+ local data = specification.data or ""
+ if mpx and data ~= "" then
+ starttiming(metapost)
+ starttiming(metapost.exectime)
+ local result = mpx:execute ( format ( "%s;%s;beginfig(1);%s;%s;endfig;",
+ specification.extensions or "",
+ specification.inclusions or "",
+ specification.initializations or "",
+ data
+ ) )
+ stoptiming(metapost.exectime)
+ if result.status > 0 then
+ report_metapost("%s: %s", result.status, result.error or result.term or result.log)
+ result = nil
+ else
+ result = metapost.filterclippath(result)
+ end
+ stoptiming(metapost)
+ metapost.popformat()
+ return result
+ else
+ metapost.popformat()
+ end
+end
+
+function metapost.filterclippath(result)
+ if result then
+ local figures = result.fig
+ if figures and #figures > 0 then
+ local figure = figures[1]
+ local objects = figure:objects()
+ if objects then
+ local lastclippath
+ for o=1,#objects do
+ local object = objects[o]
+ if object.type == "start_clip" then
+ lastclippath = object.path
+ end
+ end
+ return lastclippath
+ end
+ end
+ end
+end
+
+function metapost.theclippath(...)
+ local result = metapost.getclippath(...)
+ if result then -- we could just print the table
+ return concat(metapost.flushnormalpath(result)," ")
+ else
+ return ""
+ end
+end
+
+implement {
+ name = "mpsetclippath",
+ actions = function(specification)
+ local p = specification.data and metapost.theclippath(specification)
+ if not p or p == "" then
+ local b = number.dimenfactors.bp
+ local w = b * (specification.width or 0)
+ local h = b * (specification.height or 0)
+ p = formatters["0 0 m %.6N 0 l %.6N %.6N l 0 %.6N l"](w,w,h,h)
+ end
+ setmacro("MPclippath",p,"global")
+ end,
+ arguments = {
+ {
+ { "instance" },
+ { "format" },
+ { "data" },
+ { "initializations" },
+ { "useextensions" },
+ { "inclusions" },
+ { "method" },
+ { "namespace" },
+ { "width", "dimension" },
+ { "height", "dimension" },
+ },
+ }
+}
+
+statistics.register("metapost", function()
+ local n = metapost.nofruns
+ if n and n > 0 then
+ local elapsedtime = statistics.elapsedtime
+ local elapsed = statistics.elapsed
+ local runs, stats = metapost.nofscriptruns()
+ local instances,
+ memory = metapost.getstatistics(true)
+ return format("%s seconds, loading: %s, execution: %s, n: %s, average: %s, instances: %i, luacalls: %s, memory: %0.3f M",
+ elapsedtime(metapost), elapsedtime(mplib), elapsedtime(metapost.exectime), n,
+ elapsedtime((elapsed(metapost) + elapsed(mplib) + elapsed(metapost.exectime)) / n),
+ instances, stats and stats or runs, memory/(1024*1024))
+ else
+ return nil
+ end
+end)
+
+-- only used in graphictexts
+
+metapost.tex = metapost.tex or { }
+local mptex = metapost.tex
+
+local environments = { }
+
+function mptex.set(str)
+ environments[#environments+1] = str
+end
+
+function mptex.setfrombuffer(name)
+ environments[#environments+1] = buffers.getcontent(name)
+end
+
+function mptex.get()
+ return concat(environments,"\n")
+end
+
+function mptex.reset()
+ environments = { }
+end
+
+implement {
+ name = "mppushvariables",
+ actions = metapost.pushvariables,
+}
+
+implement {
+ name = "mppopvariables",
+ actions = metapost.popvariables,
+}
+
+implement {
+ name = "mptexset",
+ arguments = "string",
+ actions = mptex.set
+}
+
+implement {
+ name = "mptexsetfrombuffer",
+ arguments = "string",
+ actions = mptex.setfrombuffer
+}
+
+implement {
+ name = "mptexget",
+ actions = { mptex.get, context }
+}
+
+implement {
+ name = "mptexreset",
+ actions = mptex.reset
+}
+
+-- moved from mlib-lua:
+
+mp = mp or { -- system namespace
+ set = { },
+ get = { },
+ aux = { },
+ scan = { },
+ skip = { },
+ inject = { },
+}
+
+MP = MP or { } -- user namespace
+
+-- We had this:
+--
+-- table.setmetatablecall(mp,function(t,k) mpprint(k) end)
+--
+-- but the next one is more interesting because we cannot use calls like:
+--
+-- lua.mp.somedefdname("foo")
+--
+-- which is due to expansion of somedefdname during suffix creation. So:
+--
+-- lua.mp("somedefdname","foo")
+
+table.setmetatablecall(mp,function(t,k,...) return t[k](...) end)
+table.setmetatablecall(MP,function(t,k,...) return t[k](...) end)