summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/mlib-lua.lua
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2018-07-10 16:30:53 +0200
committerContext Git Mirror Bot <phg42.2a@gmail.com>2018-07-10 16:30:53 +0200
commitff693671b6540fa81d2ad7aecdbe786a4df97335 (patch)
tree979066b446d6d47fcec40fa7da9978c31a2bf802 /tex/context/base/mkiv/mlib-lua.lua
parentf58860178fcd1497d52acaa3cb2ceda7531e46ac (diff)
downloadcontext-ff693671b6540fa81d2ad7aecdbe786a4df97335.tar.gz
2018-07-10 16:00:00
Diffstat (limited to 'tex/context/base/mkiv/mlib-lua.lua')
-rw-r--r--tex/context/base/mkiv/mlib-lua.lua1122
1 files changed, 588 insertions, 534 deletions
diff --git a/tex/context/base/mkiv/mlib-lua.lua b/tex/context/base/mkiv/mlib-lua.lua
index 5d0ab1ab6..785d3c947 100644
--- a/tex/context/base/mkiv/mlib-lua.lua
+++ b/tex/context/base/mkiv/mlib-lua.lua
@@ -28,121 +28,16 @@ local trace_enabled = true
local be_tolerant = true directives.register("metapost.lua.tolerant", function(v) be_tolerant = v end)
-mp = mp or { } -- system namespace
-MP = MP or { } -- user namespace
+local get, set, aux = { }, { }, { }
-local buffer = { }
-local n = 0
-local max = 20 -- we reuse upto max
-local nesting = 0
-
-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("%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
-end
-
-local f_code = formatters["%s return mp._f_()"]
-
-local f_integer = formatters["%i"]
-
--- local f_numeric = formatters["%.16f"]
--- local f_pair = formatters["(%.16f,%.16f)"]
--- local f_triplet = formatters["(%.16f,%.16f,%.16f)"]
--- local f_quadruple = formatters["(%.16f,%.16f,%.16f,%.16f)"]
-
-local f_numeric = formatters["%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 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.cleaned = function(s) return lpegmatch(p,s) or s end
+mp = mp or { -- system namespace
+ set = set,
+ get = get,
+ aux = aux,
+}
-mp.print = mpprint
-mp.vprint = mpvprint
+MP = MP or { -- user namespace
+}
-- We had this:
--
@@ -157,238 +52,486 @@ mp.vprint = mpvprint
-- lua.mp("somedefdname","foo")
table.setmetatablecall(mp,function(t,k,...) return t[k](...) end)
+table.setmetatablecall(MP,function(t,k,...) return t[k](...) 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 currentmpx = nil
+ local stack = { }
-function mp.points(i)
- n = n + 1
- buffer[n] = i and f_points(i) or "0pt"
-end
+ 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
-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
+ 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
-function mp.pairpoints(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
+ set.path = function(s,t) return set_path(currentmpx,s,t) end -- not working yet
-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)
+ function metapost.pushscriptrunner(mpx)
+ insert(stack,mpx)
+ currentmpx = mpx
end
-end
-function mp.tripletpoints(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)
+ function metapost.popscriptrunner()
+ currentmpx = remove(stack,mpx)
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
-function mp.quadruplepoints(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
+do
-local function mppath(f2,f6,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 = "--"
+ 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
- local ti = t[1]
- n = n + 1 ;
- if #ti == 6 then
- local tn = t[2] or t[1]
- buffer[n] = f6(ti[1],ti[2],ti[5],ti[6],tn[3],tn[4])
+ 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
- buffer[n] = f2(ti[1],ti[2])
+ result = concat(buffer," ",1,n)
end
- for i=2,tn do
- local ti = t[i]
- n = n + 1 ; buffer[n] = connector
- n = n + 1 ;
- if #ti == 6 and (i < tn or cycle) then
- local tn = t[i+1] or t[1]
- buffer[n] = f6(ti[1],ti[2],ti[5],ti[6],tn[3],tn[4])
- else
- buffer[n] = f2(ti[1],ti[2])
+ if n > max then
+ buffer = { }
+ end
+ n = 0
+ return result
+ end
+ end
+
+ mp._f_ = _f_ -- convenient to have it in a top module
+ aux.flush = _f_
+
+ local f_code = formatters["%s return mp._f_()"]
+
+ local f_integer = formatters["%i"]
+ -- local f_numeric = formatters["%.16f"]
+ -- local f_pair = formatters["(%.16f,%.16f)"]
+ -- local f_triplet = formatters["(%.16f,%.16f,%.16f)"]
+ -- local f_quadruple = formatters["(%.16f,%.16f,%.16f,%.16f)"]
+
+ -- %N
+
+ local f_numeric = formatters["%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
- if cycle then
- n = n + 1 ; buffer[n] = connector
- n = n + 1 ; buffer[n] = "cycle"
+ end
+ end
+
+ 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
-end
-function mp.path(...)
- mppath(f_pair,f_ctrl,...)
-end
+ local function mpboolean(b)
+ n = n + 1
+ buffer[n] = b and "true" or "false"
+ end
-function mp.pathpoints(...)
- mppath(f_pair_pt,f_ctrl_pt,...)
-end
+ local function mpnumeric(f)
+ n = n + 1
+ buffer[n] = f and f_numeric(f) or "0"
+ end
+ local function mpinteger(i)
+ n = n + 1
+ -- buffer[n] = i and f_integer(i) or "0"
+ buffer[n] = i or "0"
+ end
-function mp.pathpoints(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
- local ti = t[1]
- n = n + 1 ;
- if #ti == 6 then
- buffer[n] = f_pair_pt_ctrl(ti[1],ti[2],ti[3],ti[4],ti[5],ti[6])
- else
- buffer[n] = f_pair_pt(ti[1],ti[2])
- end
- for i=2,tn do
- local ti = t[i]
- n = n + 1 ; buffer[n] = connector
+ local function mppoints(i)
+ n = n + 1
+ buffer[n] = i and f_points(i) or "0pt"
+ 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
+
+ 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 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
+
+ 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
+
+ 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 function mp_path(f2,f6,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
+ -- local ti = t[1]
+ -- n = n + 1 ;
+ -- if #ti == 6 then
+ -- local tn = t[2] or t[1]
+ -- buffer[n] = f6(ti[1],ti[2],ti[5],ti[6],tn[3],tn[4])
+ -- else
+ -- buffer[n] = f2(ti[1],ti[2])
+ -- end
+ -- for i=2,tn do
+ -- local ti = t[i]
+ -- n = n + 1 ; buffer[n] = connector
+ -- n = n + 1 ;
+ -- if #ti == 6 and (i < tn or cycle) then
+ -- local tn = t[i+1] or t[1]
+ -- buffer[n] = f6(ti[1],ti[2],ti[5],ti[6],tn[3],tn[4])
+ -- else
+ -- buffer[n] = f2(ti[1],ti[2])
+ -- end
+ -- end
+ -- if cycle then
+ -- n = n + 1 ; buffer[n] = connector
+ -- n = n + 1 ; buffer[n] = "cycle"
+ -- end
+ -- end
+ -- end
+ -- end
+
+ local function mp_path(f2,f6,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
+ local ti = t[1]
n = n + 1 ;
if #ti == 6 then
- buffer[n] = f_pair_pt_ctrl(ti[1],ti[2],ti[3],ti[4],ti[5],ti[6])
+ buffer[n] = f6(ti[1],ti[2],ti[3],ti[4],ti[5],ti[6])
else
- buffer[n] = f_pair_pt(ti[1],ti[2])
+ buffer[n] = f2(ti[1],ti[2])
+ end
+ for i=2,tn do
+ local ti = t[i]
+ n = n + 1 ; buffer[n] = connector
+ n = n + 1 ;
+ if #ti == 6 then
+ buffer[n] = f6(ti[1],ti[2],ti[3],ti[4],ti[5],ti[6])
+ else
+ buffer[n] = f2(ti[1],ti[2])
+ end
+ end
+ if cycle then
+ n = n + 1 ; buffer[n] = connector
+ n = n + 1 ; buffer[n] = "cycle"
end
- end
- if cycle then
- n = n + 1 ; buffer[n] = connector
- n = n + 1 ; buffer[n] = "cycle"
end
end
end
-end
-function mp.size(t)
- n = n + 1
- buffer[n] = type(t) == "table" and f_numeric(#t) or "0"
-end
+ local function mppath(...)
+ mp_path(f_pair,f_pair_ctrl,...)
+ end
-local mpnamedcolor = attributes.colors.mpnamedcolor
+ local function mppathpoints(...)
+ mp_path(f_pair_pt,f_pair_pt_ctrl,...)
+ end
-mp.NamedColor = function(str)
- mpprint(mpnamedcolor(str))
-end
+ local function mpsize(t)
+ n = n + 1
+ buffer[n] = type(t) == "table" and f_numeric(#t) or "0"
+ end
--- experiment: names can change
+ local replacer = lpeg.replacer("@","%%")
+
+ local function mpfprint(fmt,...)
+ n = n + 1
+ if not find(fmt,"%",1,true) then
+ fmt = lpegmatch(replacer,fmt)
+ end
+ buffer[n] = formatters[fmt](...)
+ end
-local datasets = { }
-mp.datasets = datasets
+ 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](s,...) .. '"'
+ buffer[n] = lpegmatch(p,formatters[fmt](s,...))
+ elseif fmt then
+ -- buffer[n] = '"' .. fmt .. '"'
+ buffer[n] = lpegmatch(p,fmt)
+ else
+ -- something is wrong
+ end
+ end
-function datasets.load(tag,filename)
- if not filename then
- tag, filename = file.basename(tag), tag
+ aux.print = mpprint
+ aux.vprint = mpvprint
+ aux.boolean = mpboolean
+ 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
+
+ -- there is no gain in:
+ --
+ -- local cache = table.makeweak()
+ --
+ -- f = cache[code]
+ -- if not f then
+ -- f = loadstring(f_code(code))
+ -- if f then
+ -- cache[code] = f
+ -- elseif be_tolerant then
+ -- f = loadstring(code)
+ -- if f then
+ -- cache[code] = f
+ -- end
+ -- end
+ -- end
+
+ 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 = loadstring(f_code(code))
+ if not f and be_tolerant then
+ f = loadstring(code)
+ end
+ if f then
+ local _buffer_, _n_ = buffer, 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)
+-- print(debug.traceback())
+ else
+ report_luarun("%i: result: %s",nesting,result)
+ end
+ end
+ buffer, n = _buffer_, _n_
+ nesting = nesting - 1
+ return result
+ elseif trace then
+ report_luarun("%i: no result",nesting)
+-- print(debug.traceback())
+ end
+ buffer, n = _buffer_, _n_
+ else
+ report_luarun("%i: no result, invalid code: %s",nesting,code)
+ end
+ nesting = nesting - 1
+ return ""
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
---
+ -- for the moment
-local replacer = lpeg.replacer("@","%%")
+ for k, v in next, aux do mp[k] = v end
-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 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](s,...) .. '"'
- buffer[n] = lpegmatch(p,formatters[fmt](s,...))
- elseif fmt then
- -- buffer[n] = '"' .. fmt .. '"'
- buffer[n] = lpegmatch(p,fmt)
- else
- -- something is wrong
+do
+
+ local mpnamedcolor = attributes.colors.mpnamedcolor
+ local mpprint = aux.print
+
+ mp.mf_named_color = function(str)
+ mpprint(mpnamedcolor(str))
end
-end
-mp.quoted = mpquoted
+end
-function mp.n(t)
+function mp.n(t) -- used ?
return type(t) == "table" and #t or 0
end
-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)
+do
+
+ -- experiment: names can change
+
+ local mppath = aux.mppath
+ local mpsize = aux.mpsize
-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 pattern = whitespace^0 * series
+
+ 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
-function mp.dataset(str)
- return lpegmatch(pattern,str)
end
-- \startluacode
@@ -420,269 +563,183 @@ end
-- endfor ;
-- \stopMPpage
-local runs = 0
-
-function metapost.nofscriptruns()
- return runs
-end
-
--- there is no gain in:
---
--- local cache = table.makeweak()
---
--- f = cache[code]
--- if not f then
--- f = loadstring(f_code(code))
--- if f then
--- cache[code] = f
--- elseif be_tolerant then
--- f = loadstring(code)
--- if f then
--- cache[code] = f
--- end
--- end
--- end
-
-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 = loadstring(f_code(code))
- if not f and be_tolerant then
- f = loadstring(code)
- end
- if f then
- local _buffer_, _n_ = buffer, 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, n = _buffer_, _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
+-- texts:
do
- 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 get_number = get_numeric
+ local mptriplet = mp.triplet
- local set_path = mplib.set_path
+ local bpfactor = number.dimenfactors.bp
+ local textexts = nil
+ local mptriplet = mp.triplet
+ local nbdimensions = nodes.boxes.dimensions
- local currentmpx = nil
- local stack = { }
- local getters = { }
- local setters = { }
-
- getters.numeric = function(s) return get_numeric(currentmpx,s) end
- getters.string = function(s) return get_string (currentmpx,s) end
- getters.boolean = function(s) return get_boolean(currentmpx,s) end
- getters.path = function(s) return get_path (currentmpx,s) end
- getters.number = mp.numeric
-
- setters.path = function(s,t) return set_path(currentmpx,s,t) end
+ function mp.mf_tt_initialize(tt)
+ textexts = tt
+ end
- function metapost.pushscriptrunner(mpx)
- insert(stack,mpx)
- currentmpx = mpx
+ 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)
+ end
end
- function metapost.popscriptrunner()
- currentmpx = remove(stack,mpx)
+ function mp.mf_tb_dimensions(category,name)
+ local w, h, d = nbdimensions(category,name)
+ mptriplet(w*bpfactor,h*bpfactor,d*bpfactor)
end
- mp.get = getters
- mp.set = setters
+ 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
end
--- texts:
+do
-local factor = 65536*(7227/7200)
-local textexts = nil
-local mptriplet = mp.triplet
-local nbdimensions = nodes.boxes.dimensions
+ local mpprint = aux.print
+ local mpvprint = aux.vprint
-function mp.tt_initialize(tt)
- textexts = tt
-end
+ local hashes = { }
--- 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)
+ function mp.newhash()
+ for i=1,#hashes+1 do
+ if not hashes[i] then
+ hashes[i] = { }
+ mpvprint(i)
+ return
+ end
+ end
end
-end
-function mp.tb_dimensions(category,name)
- local w, h, d = nbdimensions(category,name)
- mptriplet(w/factor,h/factor,d/factor)
-end
-
-function mp.report(a,b)
- if b then
- report_message("%s : %s",a,b)
- elseif a then
- report_message("%s : %s","message",a)
+ function mp.disposehash(n)
+ hashes[n] = nil
end
-end
-
---
-local hashes = { }
+ function mp.inhash(n,key)
+ local h = hashes[n]
+ mpprint(h and h[key] and true or false)
+ end
-function mp.newhash()
- for i=1,#hashes+1 do
- if not hashes[i] then
- hashes[i] = { }
- mpprint(i)
- return
+ function mp.tohash(n,key)
+ local h = hashes[n]
+ if h then
+ h[key] = true
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
+do
+
+ local mpprint = aux.print
+ local modes = tex.modes
+ local systemmodes = tex.systemmodes
-function mp.tohash(n,key)
- local h = hashes[n]
- if h then
- h[key] = true
+ function mp.mode(s)
+ mpprint(modes[s] and true or false)
end
-end
-local modes = tex.modes
-local systemmodes = tex.systemmodes
+ function mp.systemmode(s)
+ mpprint(systemmodes[s] and true or false)
+ end
-function mp.mode(s)
- mpprint(modes[s] and true or false)
-end
+ mp.processingmode = mp.mode
-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
+do
-function mp.prefix(str)
- mpquoted(match(str,"^(.-)[%d%[]") or str)
-end
+ local mpprint = aux.print
+ local mpquoted = aux.quoted
+
+ function mp.isarray(str)
+ mpprint(find(str,"%d") and true or false)
+ end
--- function mp.dimension(str)
--- local n = 0
--- for s in gmatch(str,"%[?%-?%d+%]?") do --todo: lpeg
--- n = n + 1
--- end
--- mpprint(n)
--- end
+ function mp.prefix(str)
+ mpquoted(match(str,"^(.-)[%d%[]") or str)
+ end
-mp.dimension = lpeg.counter(P("[") * lpegpatterns.integer * P("]") + lpegpatterns.integer,mpprint)
+ -- function mp.dimension(str)
+ -- local n = 0
+ -- for s in gmatch(str,"%[?%-?%d+%]?") do --todo: lpeg
+ -- n = n + 1
+ -- end
+ -- mpprint(n)
+ -- end
--- 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
+ mp.dimension = lpeg.counter(P("[") * lpegpatterns.integer * P("]") + lpegpatterns.integer,mpprint)
--- 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
+ -- 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
+
+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
+do
+
+ 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 mpprint = mp.print
-local mpquoted = mp.quoted
+ local mpprint = mp.print
+ local mpquoted = mp.quoted
-local factor = number.dimenfactors.bp
+ local bpfactor = number.dimenfactors.bp
--- more helpers
+ -- more helpers
-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
+ function mp.getdimen(k) mpprint (getdimen(k)*bpfactor) end
+ function mp.getcount(k) mpprint (getcount(k)) end
+ function mp.gettoks (k) mpquoted(gettoks (k)) end
--- def foo = lua.mp.foo ... enddef ; % loops due to foo in suffix
+ 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
-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
+ -- 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
+
+end
-- position fun
@@ -796,7 +853,7 @@ do
local mpvprint = mp.vprint
- local stores = { }
+ local stores = { }
function mp.newstore(name)
stores[name] = { }
@@ -826,59 +883,50 @@ end
do
- local mpprint = mp.print
- local texmodes = tex.modes
-
- function mp.processingmode(s)
- mpprint(tostring(texmodes[s]))
- end
-
-end
-
-do
-
-- a bit overkill: just a find(str,"mf_object=") can be enough
- local p1 = P("mf_object=")
- local p2 = lpeg.patterns.eol * p1
- local pattern = (1-p2)^0 * p2 + p1
+ 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)
- mp.boolean(pattern and str ~= "" and lpegmatch(p,str))
+ mpboolean(pattern and str ~= "" and lpegmatch(p,str))
end
end
do
- local mpnumeric = mp.numeric
- local mppair = mp.pair
- local mpgetpath = mp.get.path
+ local mpnumeric = aux.numeric
+ local mppair = aux.pair
+ local mpgetpath = get.path
local p = nil
local n = 0
- function mp.mfun_path_length(name)
- p = mp.get.path(name)
+ local function mf_path_length(name)
+ p = mpgetpath(name)
n = p and #p or 0
mpnumeric(n)
end
- function mp.mfun_path_point(i)
+ local function mf_path_point(i)
if i > 0 and i <= n then
local pi = p[i]
mppair(pi[1],pi[2])
end
end
- function mp.mfun_path_left(i)
+ local function mf_path_left(i)
if i > 0 and i <= n then
local pi = p[i]
mppair(pi[5],pi[6])
end
end
- function mp.mfun_path_right(i)
+ local function mf_path_right(i)
if i > 0 and i <= n then
local pn
if i == 1 then
@@ -890,9 +938,15 @@ do
end
end
- function mp.mfun_path_reset()
+ 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