diff options
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.lua | 1175 |
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 |