summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/mkiv/mlib-lua.lua
diff options
context:
space:
mode:
authorNorbert Preining <preining@logic.at>2019-02-24 15:12:57 +0000
committerNorbert Preining <preining@logic.at>2019-02-24 15:12:57 +0000
commit1314fbe93790c501dc436a5cf99f106b9e5c0f63 (patch)
tree04dc7734c8be8ffe385d41f4388826ef5857b6f9 /Master/texmf-dist/tex/context/base/mkiv/mlib-lua.lua
parenteb80ce7b34f59896a1dfee5ca422495394d6677f (diff)
Revert "ConTeXt version 2019.02.22 19:35"
This reverts commit 5c6357cdb820b4f628d036ba7b2248f221d50c0b. git-svn-id: svn://tug.org/texlive/trunk@50112 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkiv/mlib-lua.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/mkiv/mlib-lua.lua1175
1 files changed, 431 insertions, 744 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/mlib-lua.lua b/Master/texmf-dist/tex/context/base/mkiv/mlib-lua.lua
index d7c2a0fc3f2..19e731b8569 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/mlib-lua.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/mlib-lua.lua
@@ -10,11 +10,11 @@ if not modules then modules = { } end modules ['mlib-lua'] = {
-- maybe we need mplib.model, but how with instances
-local type, tostring, tonumber, select, loadstring = type, tostring, tonumber, select, loadstring
+local type, tostring, select, loadstring = type, tostring, select, loadstring
local find, match, gsub, gmatch = string.find, string.match, string.gsub, string.gmatch
-local concat, insert, remove = table.concat, table.insert, table.remove
local formatters = string.formatters
+local concat = table.concat
local lpegmatch = lpeg.match
local lpegpatterns = lpeg.patterns
@@ -26,18 +26,105 @@ local report_message = logs.reporter("metapost")
local trace_luarun = false trackers.register("metapost.lua",function(v) trace_luarun = v end)
local trace_enabled = true
-local be_tolerant = true directives.register("metapost.lua.tolerant", function(v) be_tolerant = v end)
+local be_tolerant = true directives.register("metapost.lua.tolerant",function(v) be_tolerant = v end)
-local get, set, aux = { }, { }, { }
+mp = mp or { } -- system namespace
+MP = MP or { } -- user namespace
-mp = mp or { -- system namespace
- set = set,
- get = get,
- aux = aux,
-}
+local buffer, n, max = { }, 0, 10 -- we reuse upto max
-MP = MP or { -- user namespace
-}
+function mp._f_()
+ if trace_enabled and trace_luarun then
+ local result = concat(buffer," ",1,n)
+ if n > max then
+ buffer = { }
+ end
+ n = 0
+ report_luarun("data: %s",result)
+ return result
+ else
+ if n == 0 then
+ return ""
+ end
+ local result
+ if n == 1 then
+ result = buffer[1]
+ else
+ result = concat(buffer," ",1,n)
+ end
+ if n > max then
+ buffer = { }
+ end
+ n = 0
+ return result
+ end
+end
+
+local f_code = formatters["%s return mp._f_()"]
+
+local f_numeric = formatters["%.16f"]
+local f_integer = formatters["%i"]
+local f_pair = formatters["(%.16f,%.16f)"]
+local f_triplet = formatters["(%.16f,%.16f,%.16f)"]
+local f_quadruple = formatters["(%.16f,%.16f,%.16f,%.16f)"]
+
+local function mpprint(...) -- we can optimize for n=1
+ for i=1,select("#",...) do
+ local value = select(i,...)
+ if value ~= nil then
+ n = n + 1
+ local t = type(value)
+ if t == "number" then
+ buffer[n] = f_numeric(value)
+ elseif t == "string" then
+ buffer[n] = value
+ elseif t == "table" then
+ buffer[n] = "(" .. concat(value,",") .. ")"
+ else -- boolean or whatever
+ buffer[n] = tostring(value)
+ end
+ end
+ end
+end
+
+local r = P('%') / "percent"
+ + P('"') / "dquote"
+ + P('\n') / "crlf"
+ -- + P(' ') / "space"
+local a = Cc("&")
+local q = Cc('"')
+local p = Cs(q * (r * a)^-1 * (a * r * (P(-1) + a) + P(1))^0 * q)
+
+local function mpvprint(...) -- variable print
+ for i=1,select("#",...) do
+ local value = select(i,...)
+ if value ~= nil then
+ n = n + 1
+ local t = type(value)
+ if t == "number" then
+ buffer[n] = f_numeric(value)
+ elseif t == "string" then
+ buffer[n] = lpegmatch(p,value)
+ elseif t == "table" then
+ local m = #t
+ if m == 2 then
+ buffer[n] = f_pair(unpack(t))
+ elseif m == 3 then
+ buffer[n] = f_triplet(unpack(t))
+ elseif m == 4 then
+ buffer[n] = f_quadruple(unpack(t))
+ else -- error
+ buffer[n] = ""
+ end
+ else -- boolean or whatever
+ buffer[n] = tostring(value)
+ end
+ end
+ end
+end
+
+mp.print = mpprint
+mp.vprint = mpvprint
-- We had this:
--
@@ -52,540 +139,150 @@ MP = MP or { -- user namespace
-- lua.mp("somedefdname","foo")
table.setmetatablecall(mp,function(t,k,...) return t[k](...) end)
-table.setmetatablecall(MP,function(t,k,...) return t[k](...) end)
-
-do
-
- local currentmpx = nil
- local stack = { }
-
- local get_numeric = mplib.get_numeric
- local get_string = mplib.get_string
- local get_boolean = mplib.get_boolean
- local get_path = mplib.get_path
- local set_path = mplib.set_path
-
- get.numeric = function(s) return get_numeric(currentmpx,s) end
- get.string = function(s) return get_string (currentmpx,s) end
- get.boolean = function(s) return get_boolean(currentmpx,s) end
- get.path = function(s) return get_path (currentmpx,s) end
- get.number = function(s) return get_numeric(currentmpx,s) end
-
- set.path = function(s,t) return set_path(currentmpx,s,t) end -- not working yet
-
- function metapost.pushscriptrunner(mpx)
- insert(stack,mpx)
- currentmpx = mpx
- end
- function metapost.popscriptrunner()
- currentmpx = remove(stack,mpx)
- end
+function mp.boolean(b)
+ n = n + 1
+ buffer[n] = b and "true" or "false"
+end
+function mp.numeric(f)
+ n = n + 1
+ buffer[n] = f and f_numeric(f) or "0"
end
-do
+function mp.integer(i)
+ n = n + 1
+ -- buffer[n] = i and f_integer(i) or "0"
+ buffer[n] = i or "0"
+end
- local buffer = { }
- local n = 0
- local max = 20 -- we reuse upto max
- local nesting = 0
- local runs = 0
-
- local function _f_()
- if trace_enabled and trace_luarun then
- local result = concat(buffer," ",1,n)
- if n > max then
- buffer = { }
- end
- n = 0
- report_luarun("%i: data: %s",nesting,result)
- return result
- else
- if n == 0 then
- return ""
- end
- local result
- if n == 1 then
- result = buffer[1]
- else
- result = concat(buffer," ",1,n)
- end
- if n > max then
- buffer = { }
- end
- n = 0
- return result
- end
+function mp.pair(x,y)
+ n = n + 1
+ if type(x) == "table" then
+ buffer[n] = f_pair(x[1],x[2])
+ else
+ buffer[n] = f_pair(x,y)
end
+end
- mp._f_ = _f_ -- convenient to have it in a top module
- aux.flush = _f_
-
- ----- f_code = formatters["%s return mp._f_()"]
-
- local f_integer = formatters["%i"]
-
- local f_numeric = formatters["%n"] -- maybe %N
- local f_pair = formatters["(%n,%n)"]
- local f_ctrl = formatters["(%n,%n) .. controls (%n,%n) and (%n,%n)"]
- local f_triplet = formatters["(%n,%n,%n)"]
- local f_quadruple = formatters["(%n,%n,%n,%n)"]
-
- local f_points = formatters["%p"]
- local f_pair_pt = formatters["(%p,%p)"]
- local f_ctrl_pt = formatters["(%p,%p) .. controls (%p,%p) and (%p,%p)"]
- local f_triplet_pt = formatters["(%p,%p,%p)"]
- local f_quadruple_pt = formatters["(%p,%p,%p,%p)"]
-
- local r = P('%') / "percent"
- + P('"') / "dquote"
- + P('\n') / "crlf"
- -- + P(' ') / "space"
- local a = Cc("&")
- local q = Cc('"')
- local p = Cs(q * (r * a)^-1 * (a * r * (P(-1) + a) + P(1))^0 * q)
-
- mp.cleaned = function(s) return lpegmatch(p,s) or s end
-
- -- local function mpprint(...) -- we can optimize for n=1
- -- for i=1,select("#",...) do
- -- local value = (select(i,...))
- -- if value ~= nil then
- -- n = n + 1
- -- local t = type(value)
- -- if t == "number" then
- -- buffer[n] = f_numeric(value)
- -- elseif t == "string" then
- -- buffer[n] = value
- -- elseif t == "table" then
- -- buffer[n] = "(" .. concat(value,",") .. ")"
- -- else -- boolean or whatever
- -- buffer[n] = tostring(value)
- -- end
- -- end
- -- end
- -- end
-
- local function mpp(value)
- n = n + 1
- local t = type(value)
- if t == "number" then
- buffer[n] = f_numeric(value)
- elseif t == "string" then
- buffer[n] = value
- elseif t == "table" then
- buffer[n] = "(" .. concat(value,",") .. ")"
- else -- boolean or whatever
- buffer[n] = tostring(value)
- end
+function mp.triplet(x,y,z)
+ n = n + 1
+ if type(x) == "table" then
+ buffer[n] = f_triplet(x[1],x[2],x[3])
+ else
+ buffer[n] = f_triplet(x,y,z)
end
+end
- local function mpprint(first,second,...)
- if second == nil then
- if first ~= nil then
- mpp(first)
- end
- else
- for i=1,select("#",first,second,...) do
- local value = (select(i,first,second,...))
- if value ~= nil then
- mpp(value)
- end
- end
- end
+function mp.quadruple(w,x,y,z)
+ n = n + 1
+ if type(w) == "table" then
+ buffer[n] = f_quadruple(w[1],w[2],w[3],w[4])
+ else
+ buffer[n] = f_quadruple(w,x,y,z)
end
+end
- local function mpp(value)
- n = n + 1
- local t = type(value)
- if t == "number" then
- buffer[n] = f_numeric(value)
- elseif t == "string" then
- buffer[n] = lpegmatch(p,value)
- elseif t == "table" then
- if #t > 4 then
- buffer[n] = ""
- else
- buffer[n] = "(" .. concat(value,",") .. ")"
+function mp.path(t,connector,cycle)
+ if type(t) == "table" then
+ local tn = #t
+ if tn > 0 then
+ if connector == true then
+ connector = "--"
+ cycle = true
+ elseif not connector then
+ connector = "--"
end
- else -- boolean or whatever
- buffer[n] = tostring(value)
- end
- end
-
- local function mpvprint(first,second,...) -- variable print
- if second == nil then
- if first ~= nil then
- mpp(first)
+ local ti = t[1]
+ n = n + 1 ; buffer[n] = f_pair(ti[1],ti[2])
+ for i=2,tn do
+ local ti = t[i]
+ n = n + 1 ; buffer[n] = connector
+ n = n + 1 ; buffer[n] = f_pair(ti[1],ti[2])
end
- else
- for i=1,select("#",first,second,...) do
- local value = (select(i,first,second,...))
- if value ~= nil then
- mpp(value)
- end
+ if cycle then
+ n = n + 1 ; buffer[n] = connector
+ n = n + 1 ; buffer[n] = "cycle"
end
end
end
+end
- local function mpstring(value)
- n = n + 1
- buffer[n] = lpegmatch(p,value)
- end
-
- local function mpboolean(b)
- n = n + 1
- buffer[n] = b and "true" or "false"
- end
-
- local function mpnumeric(f)
- n = n + 1
- if not f or f == 0 then
- buffer[n] = "0"
- else
- buffer[n] = f_numeric(f)
- end
- end
-
- local function mpinteger(i)
- n = n + 1
- -- buffer[n] = i and f_integer(i) or "0"
- buffer[n] = i or "0"
- end
-
- local function mppoints(i)
- n = n + 1
- if not i or i == 0 then
- buffer[n] = "0pt"
- else
- buffer[n] = f_points(i)
- end
- end
-
- local function mppair(x,y)
- n = n + 1
- if type(x) == "table" then
- buffer[n] = f_pair(x[1],x[2])
- else
- buffer[n] = f_pair(x,y)
- end
- end
-
- local function mppairpoints(x,y)
- n = n + 1
- if type(x) == "table" then
- buffer[n] = f_pair_pt(x[1],x[2])
- else
- buffer[n] = f_pair_pt(x,y)
- end
- end
+function mp.size(t)
+ n = n + 1
+ buffer[n] = type(t) == "table" and f_numeric(#t) or "0"
+end
- local function mptriplet(x,y,z)
- n = n + 1
- if type(x) == "table" then
- buffer[n] = f_triplet(x[1],x[2],x[3])
- else
- buffer[n] = f_triplet(x,y,z)
- end
- end
+local mpnamedcolor = attributes.colors.mpnamedcolor
- local function mptripletpoints(x,y,z)
- n = n + 1
- if type(x) == "table" then
- buffer[n] = f_triplet_pt(x[1],x[2],x[3])
- else
- buffer[n] = f_triplet_pt(x,y,z)
- end
- end
+mp.NamedColor = function(str)
+ mpprint(mpnamedcolor(str))
+end
- local function mpquadruple(w,x,y,z)
- n = n + 1
- if type(w) == "table" then
- buffer[n] = f_quadruple(w[1],w[2],w[3],w[4])
- else
- buffer[n] = f_quadruple(w,x,y,z)
- end
- end
+-- experiment: names can change
- local function mpquadruplepoints(w,x,y,z)
- n = n + 1
- if type(w) == "table" then
- buffer[n] = f_quadruple_pt(w[1],w[2],w[3],w[4])
- else
- buffer[n] = f_quadruple_pt(w,x,y,z)
- end
- end
+local datasets = { }
+mp.datasets = datasets
- -- we have three kind of connectors:
- --
- -- .. ... -- (true)
-
- local function mp_path(f2,f6,t,connector,cycle)
- if type(t) == "table" then
- local tn = #t
- if tn == 1 then
- local t1 = t[1]
- n = n + 1 ; buffer[n] = f2(t1[1],t1[2])
- elseif tn > 0 then
- if connector == true or connector == nil then
- connector = ".."
- elseif connector == false then
- connector = "--"
- end
- if cycle == nil then
- cycle = t.cycle
- if cycle == nil then
- cycle = true
- end
- end
- local six = connector == ".." -- otherwise we use whatever gets asked for
- local controls = connector -- whatever
- local a = t[1]
- local b = t[2]
- n = n + 1
- if six and #a == 6 and #b == 6 then
- buffer[n] = f6(a[1],a[2],a[5],a[6],b[3],b[4])
- controls = ".."
- else
- buffer[n] = f2(a[1],a[2])
- controls = connector
- end
- for i=2,tn-1 do
- a = b
- b = t[i+1]
- n = n + 1
- buffer[n] = connector
- n = n + 1
- if six and #a == 6 and #b == 6 then
- buffer[n] = f6(a[1],a[2],a[5],a[6],b[3],b[4])
- controls = ".."
- else
- buffer[n] = f2(a[1],a[2])
- controls = connector
- end
- end
- n = n + 1
- buffer[n] = connector
- a = b
- b = t[1]
- n = n + 1
- if cycle then
- if six and #a == 6 and #b == 6 then
- buffer[n] = f6(a[1],a[2],a[5],a[6],b[3],b[4])
- controls = ".."
- else
- buffer[n] = f2(a[1],a[2])
- controls = connector
- end
- n = n + 1
- buffer[n] = connector
- n = n + 1
- buffer[n] = "cycle"
- else
- buffer[n] = f2(a[1],a[2])
- end
- end
- end
+function datasets.load(tag,filename)
+ if not filename then
+ tag, filename = file.basename(tag), tag
end
+ local data = mp.dataset(io.loaddata(filename) or "")
+ datasets[tag] = {
+ Data = data,
+ Line = function(n) mp.path(data[n or 1]) end,
+ Size = function() mp.size(data) end,
+ }
+end
- local function mppath(...)
- mp_path(f_pair,f_ctrl,...)
- end
+--
- local function mppathpoints(...)
- mp_path(f_pair_pt,f_ctrl_pt,...)
- end
+local replacer = lpeg.replacer("@","%%")
- local function mpsize(t)
- n = n + 1
- buffer[n] = type(t) == "table" and f_numeric(#t) or "0"
+function mp.fprint(fmt,...)
+ n = n + 1
+ if not find(fmt,"%",1,true) then
+ fmt = lpegmatch(replacer,fmt)
end
+ buffer[n] = formatters[fmt](...)
+end
- local replacer = lpeg.replacer("@","%%")
-
- local function mpfprint(fmt,...)
- n = n + 1
+local function mpquoted(fmt,s,...)
+ n = n + 1
+ if s then
if not find(fmt,"%",1,true) then
fmt = lpegmatch(replacer,fmt)
end
- buffer[n] = formatters[fmt](...)
+ -- buffer[n] = '"' .. formatters[fmt](s,...) .. '"'
+ buffer[n] = lpegmatch(p,formatters[fmt](s,...))
+ elseif fmt then
+ -- buffer[n] = '"' .. fmt .. '"'
+ buffer[n] = lpegmatch(p,fmt)
+ else
+ -- something is wrong
end
-
- local function mpquoted(fmt,s,...)
- if s then
- n = n + 1
- if not find(fmt,"%",1,true) then
- fmt = lpegmatch(replacer,fmt)
- end
- -- buffer[n] = '"' .. formatters[fmt](s,...) .. '"'
- buffer[n] = lpegmatch(p,formatters[fmt](s,...))
- elseif fmt then
- n = n + 1
- -- buffer[n] = '"' .. fmt .. '"'
- buffer[n] = lpegmatch(p,fmt)
- else
- -- something is wrong
- end
- end
-
- aux.print = mpprint
- aux.vprint = mpvprint
- aux.boolean = mpboolean
- aux.string = mpstring
- aux.numeric = mpnumeric
- aux.number = mpnumeric
- aux.integer = mpinteger
- aux.points = mppoints
- aux.pair = mppair
- aux.pairpoints = mppairpoints
- aux.triplet = mptriplet
- aux.tripletpoints = mptripletpoints
- aux.quadruple = mpquadruple
- aux.quadruplepoints = mpquadruplepoints
- aux.path = mppath
- aux.pathpoints = mppathpoints
- aux.size = mpsize
- aux.fprint = mpfprint
- aux.quoted = mpquoted
-
- -- we need access to the variables
-
- function metapost.nofscriptruns()
- return runs
- end
-
- -- sometimes we gain (e.g. .5 sec on the sync test)
-
- local cache = table.makeweak()
-
- function metapost.runscript(code)
- nesting = nesting + 1
- local trace = trace_enabled and trace_luarun
- if trace then
- report_luarun("%i: code: %s",nesting,code)
- end
- runs = runs + 1
- local f = cache[code]
- if not f then
- f = loadstring(code .. " return mp._f_()")
- if f then
- cache[code] = f
- elseif be_tolerant then
- f = loadstring(code)
- if f then
- cache[code] = f
- end
- end
- end
- if f then
- local _buffer_ = buffer
- local _n_ = n
- buffer = { }
- n = 0
- local result = f()
- if result then
- local t = type(result)
- if t == "number" then
- result = f_numeric(result)
- elseif t ~= "string" then
- result = tostring(result)
- end
- if trace then
- if #result == 0 then
- report_luarun("%i: no result",nesting)
- else
- report_luarun("%i: result: %s",nesting,result)
- end
- end
- buffer = _buffer_
- n = _n_
- nesting = nesting - 1
- return result
- elseif trace then
- report_luarun("%i: no result",nesting)
- end
- buffer, n = _buffer_, _n_
- else
- report_luarun("%i: no result, invalid code: %s",nesting,code)
- end
- nesting = nesting - 1
- return ""
- end
-
- -- for the moment
-
- for k, v in next, aux do mp[k] = v end
-
end
-do
-
- local mpnamedcolor = attributes.colors.mpnamedcolor
- local mpprint = aux.print
+mp.quoted = mpquoted
- mp.mf_named_color = function(str)
- mpprint(mpnamedcolor(str))
- end
-
-end
-
-function mp.n(t) -- used ?
+function mp.n(t)
return type(t) == "table" and #t or 0
end
-do
-
- -- experiment: names can change
-
- local mppath = aux.path
- local mpsize = aux.size
-
- local whitespace = lpegpatterns.whitespace
- local newline = lpegpatterns.newline
- local setsep = newline^2
- local comment = (S("#%") + P("--")) * (1-newline)^0 * (whitespace - setsep)^0
- local value = (1-whitespace)^1 / tonumber
- local entry = Ct( value * whitespace * value)
- local set = Ct((entry * (whitespace-setsep)^0 * comment^0)^1)
- local series = Ct((set * whitespace^0)^1)
-
- local pattern = whitespace^0 * series
+local whitespace = lpegpatterns.whitespace
+local newline = lpegpatterns.newline
+local setsep = newline^2
+local comment = (S("#%") + P("--")) * (1-newline)^0 * (whitespace - setsep)^0
+local value = (1-whitespace)^1 / tonumber
+local entry = Ct( value * whitespace * value)
+local set = Ct((entry * (whitespace-setsep)^0 * comment^0)^1)
+local series = Ct((set * whitespace^0)^1)
- local datasets = { }
- mp.datasets = datasets
-
- function mp.dataset(str)
- return lpegmatch(pattern,str)
- end
-
- function datasets.load(tag,filename)
- if not filename then
- tag, filename = file.basename(tag), tag
- end
- local data = lpegmatch(pattern,io.loaddata(filename) or "")
- datasets[tag] = {
- data = data,
- line = function(n) mppath(data[n or 1]) end,
- size = function() mpsize(data) end,
- }
- end
-
- table.setmetatablecall(datasets,function(t,k,f,...)
- local d = datasets[k]
- local t = type(d)
- if t == "table" then
- d = d[f]
- if type(d) == "function" then
- d(...)
- else
- mpvprint(...)
- end
- elseif t == "function" then
- d(f,...)
- end
- end)
+local pattern = whitespace^0 * series
+function mp.dataset(str)
+ return lpegmatch(pattern,str)
end
-- \startluacode
@@ -617,157 +314,255 @@ end
-- endfor ;
-- \stopMPpage
--- texts:
-
-do
-
- local mptriplet = mp.triplet
-
- local bpfactor = number.dimenfactors.bp
- local textexts = nil
- local mptriplet = mp.triplet
- local nbdimensions = nodes.boxes.dimensions
+local cache, n = { }, 0 -- todo: when > n then reset cache or make weak
- function mp.mf_tt_initialize(tt)
- textexts = tt
+function metapost.runscript(code)
+ local trace = trace_enabled and trace_luarun
+ if trace then
+ report_luarun("code: %s",code)
end
-
- function mp.mf_tt_dimensions(n)
- local box = textexts and textexts[n]
- if box then
- -- could be made faster with nuts but not critical
- mptriplet(box.width*bpfactor,box.height*bpfactor,box.depth*bpfactor)
- else
- mptriplet(0,0,0)
+ local f
+ if n > 100 then
+ cache = nil -- forget about caching
+ f = loadstring(f_code(code))
+ if not f and be_tolerant then
+ f = loadstring(code)
+ end
+ else
+ f = cache[code]
+ if not f then
+ f = loadstring(f_code(code))
+ if f then
+ n = n + 1
+ cache[code] = f
+ elseif be_tolerant then
+ f = loadstring(code)
+ if f then
+ n = n + 1
+ cache[code] = f
+ end
+ end
end
end
-
- function mp.mf_tb_dimensions(category,name)
- local w, h, d = nbdimensions(category,name)
- mptriplet(w*bpfactor,h*bpfactor,d*bpfactor)
- end
-
- function mp.report(a,b,c,...)
- if c then
- report_message("%s : %s",a,formatters[(gsub(b,"@","%%"))](c,...))
- elseif b then
- report_message("%s : %s",a,b)
- elseif a then
- report_message("%s : %s","message",a)
+ if f then
+ local result = f()
+ if result then
+ local t = type(result)
+ if t == "number" then
+ result = f_numeric(result)
+ elseif t ~= "string" then
+ result = tostring(result)
+ end
+ if trace then
+ report_luarun("result: %s",result)
+ end
+ return result
+ elseif trace then
+ report_luarun("no result")
end
+ else
+ report_luarun("no result, invalid code: %s",code)
end
+ return ""
+end
+-- function metapost.initializescriptrunner(mpx)
+-- mp.numeric = function(s) return mpx:get_numeric(s) end
+-- mp.string = function(s) return mpx:get_string (s) end
+-- mp.boolean = function(s) return mpx:get_boolean(s) end
+-- mp.number = mp.numeric
+-- end
+
+local get_numeric = mplib.get_numeric
+local get_string = mplib.get_string
+local get_boolean = mplib.get_boolean
+local get_number = get_numeric
+
+-- function metapost.initializescriptrunner(mpx)
+-- mp.numeric = function(s) return get_numeric(mpx,s) end
+-- mp.string = function(s) return get_string (mpx,s) end
+-- mp.boolean = function(s) return get_boolean(mpx,s) end
+-- mp.number = mp.numeric
+-- end
+
+local currentmpx = nil
+
+local get = { }
+mp.get = get
+
+get.numeric = function(s) return get_numeric(currentmpx,s) end
+get.string = function(s) return get_string (currentmpx,s) end
+get.boolean = function(s) return get_boolean(currentmpx,s) end
+get.number = mp.numeric
+
+function metapost.initializescriptrunner(mpx,trialrun)
+ currentmpx = mpx
+ if trace_luarun then
+ report_luarun("type of run: %s", trialrun and "trial" or "final")
+ end
+ -- trace_enabled = not trialrun blocks too much
end
-do
+-- texts:
- local mpprint = aux.print
- local modes = tex.modes
- local systemmodes = tex.systemmodes
+local factor = 65536*(7227/7200)
+local textexts = nil
+local mptriplet = mp.triplet
+local nbdimensions = nodes.boxes.dimensions
- function mp.mode(s)
- mpprint(modes[s] and true or false)
- end
+function mp.tt_initialize(tt)
+ textexts = tt
+end
- function mp.systemmode(s)
- mpprint(systemmodes[s] and true or false)
+-- function mp.tt_wd(n)
+-- local box = textexts and textexts[n]
+-- mpprint(box and box.width/factor or 0)
+-- end
+-- function mp.tt_ht(n)
+-- local box = textexts and textexts[n]
+-- mpprint(box and box.height/factor or 0)
+-- end
+-- function mp.tt_dp(n)
+-- local box = textexts and textexts[n]
+-- mpprint(box and box.depth/factor or 0)
+-- end
+
+function mp.tt_dimensions(n)
+ local box = textexts and textexts[n]
+ if box then
+ -- could be made faster with nuts but not critical
+ mptriplet(box.width/factor,box.height/factor,box.depth/factor)
+ else
+ mptriplet(0,0,0)
end
+end
- mp.processingmode = mp.mode
-
+function mp.tb_dimensions(category,name)
+ local w, h, d = nbdimensions(category,name)
+ mptriplet(w/factor,h/factor,d/factor)
end
--- for alan's nodes:
+function mp.report(a,b)
+ if b then
+ report_message("%s : %s",a,b)
+ elseif a then
+ report_message("%s : %s","message",a)
+ end
+end
-do
+--
- local mpprint = aux.print
- local mpquoted = aux.quoted
+local hashes = { }
- function mp.isarray(str)
- mpprint(find(str,"%d") and true or false)
+function mp.newhash()
+ for i=1,#hashes+1 do
+ if not hashes[i] then
+ hashes[i] = { }
+ mpprint(i)
+ return
+ end
end
+end
+
+function mp.disposehash(n)
+ hashes[n] = nil
+end
+
+function mp.inhash(n,key)
+ local h = hashes[n]
+ mpprint(h and h[key] and true or false)
+end
- function mp.prefix(str)
- mpquoted(match(str,"^(.-)[%d%[]") or str)
+function mp.tohash(n,key)
+ local h = hashes[n]
+ if h then
+ h[key] = true
end
+end
- -- function mp.dimension(str)
- -- local n = 0
- -- for s in gmatch(str,"%[?%-?%d+%]?") do --todo: lpeg
- -- n = n + 1
- -- end
- -- mpprint(n)
- -- end
-
- mp.dimension = lpeg.counter(P("[") * lpegpatterns.integer * P("]") + lpegpatterns.integer,mpprint)
-
- -- faster and okay as we don't have many variables but probably only
- -- basename makes sense and even then it's not called that often
-
- -- local hash = table.setmetatableindex(function(t,k)
- -- local v = find(k,"%d") and true or false
- -- t[k] = v
- -- return v
- -- end)
- --
- -- function mp.isarray(str)
- -- mpprint(hash[str])
- -- end
- --
- -- local hash = table.setmetatableindex(function(t,k)
- -- local v = '"' .. (match(k,"^(.-)%d") or k) .. '"'
- -- t[k] = v
- -- return v
- -- end)
- --
- -- function mp.prefix(str)
- -- mpprint(hash[str])
- -- end
+local modes = tex.modes
+local systemmodes = tex.systemmodes
+function mp.mode(s)
+ mpprint(modes[s] and true or false)
end
-do
+function mp.systemmode(s)
+ mpprint(systemmodes[s] and true or false)
+end
+
+-- for alan's nodes:
+
+function mp.isarray(str)
+ mpprint(find(str,"%d") and true or false)
+end
+
+function mp.prefix(str)
+ mpquoted(match(str,"^(.-)[%d%[]") or str)
+end
- local getmacro = tex.getmacro
- local getdimen = tex.getdimen
- local getcount = tex.getcount
- local gettoks = tex.gettoks
- local setmacro = tex.setmacro
- local setdimen = tex.setdimen
- local setcount = tex.setcount
- local settoks = tex.settoks
+-- function mp.dimension(str)
+-- local n = 0
+-- for s in gmatch(str,"%[?%-?%d+%]?") do --todo: lpeg
+-- n = n + 1
+-- end
+-- mpprint(n)
+-- end
- local mpprint = mp.print
- local mpquoted = mp.quoted
+mp.dimension = lpeg.counter(P("[") * lpegpatterns.integer * P("]") + lpegpatterns.integer,mpprint)
- local bpfactor = number.dimenfactors.bp
+-- faster and okay as we don't have many variables but probably only
+-- basename makes sense and even then it's not called that often
- -- more helpers
+-- local hash = table.setmetatableindex(function(t,k)
+-- local v = find(k,"%d") and true or false
+-- t[k] = v
+-- return v
+-- end)
+--
+-- function mp.isarray(str)
+-- mpprint(hash[str])
+-- end
+--
+-- local hash = table.setmetatableindex(function(t,k)
+-- local v = '"' .. (match(k,"^(.-)%d") or k) .. '"'
+-- t[k] = v
+-- return v
+-- end)
+--
+-- function mp.prefix(str)
+-- mpprint(hash[str])
+-- end
- local function getmacro(k) mpprint (getmacro(k)) end
- local function getdimen(k) mpprint (getdimen(k)*bpfactor) end
- local function getcount(k) mpprint (getcount(k)) end
- local function gettoks (k) mpquoted(gettoks (k)) end
+local getdimen = tex.getdimen
+local getcount = tex.getcount
+local gettoks = tex.gettoks
+local setdimen = tex.setdimen
+local setcount = tex.setcount
+local settoks = tex.settoks
- local function setmacro(k,v) setmacro(k,v) end
- local function setdimen(k,v) setdimen(k,v/bpfactor) end
- local function setcount(k,v) setcount(k,v) end
- local function settoks (k,v) settoks (k,v) end
+local mpprint = mp.print
+local mpquoted = mp.quoted
- -- def foo = lua.mp.foo ... enddef ; % loops due to foo in suffix
+local factor = number.dimenfactors.bp
- mp._get_macro_ = getmacro mp.getmacro = getmacro
- mp._get_dimen_ = getdimen mp.getdimen = getdimen
- mp._get_count_ = getcount mp.getcount = getcount
- mp._get_toks_ = gettoks mp.gettoks = gettoks
+-- more helpers
- mp._set_macro_ = setmacro mp.setmacro = setmacro
- mp._set_dimen_ = setdimen mp.setdimen = setdimen
- mp._set_count_ = setcount mp.setcount = setcount
- mp._set_toks_ = settoks mp.settoks = settoks
+function mp.getdimen(k) mpprint (getdimen(k)*factor) end
+function mp.getcount(k) mpprint (getcount(k)) end
+function mp.gettoks (k) mpquoted(gettoks (k)) end
+function mp.setdimen(k,v) setdimen(k,v/factor) end
+function mp.setcount(k,v) setcount(k,v) end
+function mp.settoks (k,v) settoks (k,v) end
-end
+-- def foo = lua.mp.foo ... enddef ; % loops due to foo in suffix
+
+mp._get_dimen_ = mp.getdimen
+mp._get_count_ = mp.getcount
+mp._get_toks_ = mp.gettoks
+mp._set_dimen_ = mp.setdimen
+mp._set_count_ = mp.setcount
+mp._set_toks_ = mp.settoks
-- position fun
@@ -863,21 +658,6 @@ end
do
- local mppair = mp.pair
-
- function mp.textextanchor(s)
- local x, y = match(s,"tx_anchor=(%S+) (%S+)") -- todo: make an lpeg
- if x and y then
- x = tonumber(x)
- y = tonumber(y)
- end
- mppair(x or 0,y or 0)
- end
-
-end
-
-do
-
local mprint = mp.print
local qprint = mp.quoted
local getmacro = tokens.getters.macro
@@ -894,65 +674,31 @@ end
do
- local mpprint = aux.print
- local mpvprint = aux.vprint
+ local mpvprint = mp.vprint
- local hashes = { }
+ local stores = { }
- function mp.newhash(name)
- if name then
- hashes[name] = { }
- else
- for i=1,#hashes+1 do
- if not hashes[i] then
- hashes[i] = { }
- mpvprint(i)
- return
- end
- end
- end
+ function mp.newstore(name)
+ stores[name] = { }
end
- function mp.disposehash(n)
- if tonumber(n) then
- hashes[n] = false
- else
- hashes[n] = nil
- end
+ function mp.disposestore(name)
+ stores[name] = nil
end
- function mp.inhash(n,key)
- local h = hashes[n]
- mpvprint(h and h[key] and true or false)
+ function mp.tostore(name,key,value)
+ stores[name][key] = value
end
- function mp.tohash(n,key,value)
- local h = hashes[n]
- if h then
- if value == nil then
- h[key] = true
- else
- h[key] = value
- end
- end
- end
-
- function mp.fromhash(n,key)
- local h = hashes[n]
- mpvprint(h and h[key] or false)
+ function mp.fromstore(name,key)
+ mpvprint(stores[name][key]) -- type specific
end
interfaces.implement {
- name = "MPfromhash",
+ name = "getMPstored",
arguments = "2 strings",
actions = function(name,key)
- local h = hashes[name] or hashes[tonumber(name)]
- if h then
- local v = h[key] or h[tonumber(key)]
- if v then
- context(v)
- end
- end
+ context(stores[name][key])
end
}
@@ -960,70 +706,11 @@ end
do
- -- a bit overkill: just a find(str,"mf_object=") can be enough
+ local mpprint = mp.print
+ local texmodes = tex.modes
- local mpboolean = aux.boolean
-
- local p1 = P("mf_object=")
- local p2 = lpegpatterns.eol * p1
- local pattern = (1-p2)^0 * p2 + p1
-
- function mp.isobject(str)
- mpboolean(pattern and str ~= "" and lpegmatch(pattern,str))
+ function mp.processingmode(s)
+ mpprint(tostring(texmodes[s]))
end
end
-
-do
-
- local mpnumeric = aux.numeric
- local mppair = aux.pair
- local mpgetpath = get.path
-
- local p = nil
- local n = 0
-
- local function mf_path_length(name)
- p = mpgetpath(name)
- n = p and #p or 0
- mpnumeric(n)
- end
-
- local function mf_path_point(i)
- if i > 0 and i <= n then
- local pi = p[i]
- mppair(pi[1],pi[2])
- end
- end
-
- local function mf_path_left(i)
- if i > 0 and i <= n then
- local pi = p[i]
- mppair(pi[5],pi[6])
- end
- end
-
- local function mf_path_right(i)
- if i > 0 and i <= n then
- local pn
- if i == 1 then
- pn = p[2] or p[1]
- else
- pn = p[i+1] or p[1]
- end
- mppair(pn[3],pn[4])
- end
- end
-
- local function mf_path_reset()
- p = nil
- n = 0
- end
-
- mp.mf_path_length = mf_path_length mp.pathlength = mf_path_length
- mp.mf_path_point = mf_path_point mp.pathpoint = mf_path_point
- mp.mf_path_left = mf_path_left mp.pathleft = mf_path_left
- mp.mf_path_right = mf_path_right mp.pathright = mf_path_right
- mp.mf_path_reset = mf_path_reset mp.pathreset = mf_path_reset
-
-end