summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/mkxl/mlib-mpf.lmt
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkxl/mlib-mpf.lmt')
-rw-r--r--Master/texmf-dist/tex/context/base/mkxl/mlib-mpf.lmt542
1 files changed, 94 insertions, 448 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkxl/mlib-mpf.lmt b/Master/texmf-dist/tex/context/base/mkxl/mlib-mpf.lmt
index f24d7fde09c..34b2d079536 100644
--- a/Master/texmf-dist/tex/context/base/mkxl/mlib-mpf.lmt
+++ b/Master/texmf-dist/tex/context/base/mkxl/mlib-mpf.lmt
@@ -9,7 +9,7 @@ if not modules then modules = { } end modules ['mlib-mpf'] = {
-- moved from mlib-lua:
local type, tostring, tonumber, select, loadstring = type, tostring, tonumber, select, loadstring
-local find, match, gsub, gmatch = string.find, string.match, string.gsub, string.gmatch
+local find, gsub = string.find, string.gsub
local concat = table.concat
local formatters = string.formatters
@@ -31,8 +31,6 @@ local set = mp.set
local get = mp.get
local aux = mp.aux
local scan = mp.scan
-local skip = mp.skip
-local inject = mp.inject
do
@@ -41,7 +39,7 @@ do
local f_integer = formatters["%i"]
local f_numeric = formatters["%F"]
- -- no %n as that can produce -e notation and that is not so nice for scaled butmaybe we
+ -- no %n as that can produce -e notation and that is not so nice for scaled but maybe we
-- should then switch between ... i.e. make a push/pop for the formatters here ... not now.
local f_integer = formatters["%i"]
@@ -77,22 +75,38 @@ do
local runscripts = { }
local runnames = { }
+ local runmodes = { }
local nofscripts = 0
- function metapost.registerscript(name,f)
+ local function registerscript(name,mode,f)
nofscripts = nofscripts + 1
+ if not f then
+ f = mode
+ mode = "buffered"
+ end
if f then
runscripts[nofscripts] = f
runnames[name] = nofscripts
else
runscripts[nofscripts] = name
end
+ runmodes[nofscripts] = mode
if trace_script then
- report_script("registering script %a as %i",name,nofscripts)
+ report_script("registering %s script %a as %i",mode,name,nofscripts)
end
return nofscripts
end
+ metapost.registerscript = registerscript
+
+ function metapost.registerdirect(name,f)
+ registerscript(name,"direct",f)
+ end
+
+ function metapost.registertokens(name,f)
+ registerscript(name,"tokens",f)
+ end
+
function metapost.scriptindex(name)
local index = runnames[name] or 0
if trace_script then
@@ -111,30 +125,8 @@ do
local buffer = gbuffer
local n = 0
- local function mpdirect1(a)
- n = n + 1 buffer[n] = a
- end
- local function mpdirect2(a,b)
- n = n + 1 buffer[n] = a
- n = n + 1 buffer[n] = b
- end
- local function mpdirect3(a,b,c)
- n = n + 1 buffer[n] = a
- n = n + 1 buffer[n] = b
- n = n + 1 buffer[n] = c
- end
- local function mpdirect4(a,b,c,d)
- n = n + 1 buffer[n] = a
- n = n + 1 buffer[n] = b
- n = n + 1 buffer[n] = c
- n = n + 1 buffer[n] = d
- end
- local function mpdirect5(a,b,c,d,e)
+ local function mpdirect(a)
n = n + 1 buffer[n] = a
- n = n + 1 buffer[n] = b
- n = n + 1 buffer[n] = c
- n = n + 1 buffer[n] = d
- n = n + 1 buffer[n] = e
end
local function mpflush(separator)
@@ -142,6 +134,25 @@ do
n = 1
end
+ function metapost.getbuffer()
+ local b = { }
+ for i=1,n do
+ b[i] = buffer
+ end
+ return b, n
+ end
+
+ function metapost.setbuffer(b, s)
+ n = 0
+ for i=1,(s or #b) do
+ local bi = b[i]
+ if bi then
+ n = n + 1
+ buffer[n] = tostring(bi)
+ end
+ end
+ end
+
function metapost.runscript(code)
nesting = nesting + 1
runs = runs + 1
@@ -157,6 +168,26 @@ do
elseif trace_luarun then
report_luarun("%i: index: %i",nesting,code)
end
+ local m = runmodes[code]
+ if m == "direct" then
+ result = f()
+ if trace_luarun then
+ report_luarun("%i: direct: %a",nesting,type(result))
+ end
+ nesting = nesting - 1
+ return result, true -- string and tables as string and objects
+ elseif m == "tokens" then
+ result = f()
+ if trace_luarun then
+ report_luarun("%i: tokens: %a",nesting,type(result))
+ end
+ nesting = nesting - 1
+ return result -- string and tables as text to be scanned
+ else
+ if trace_luarun then
+ report_luarun("%i: no mode",nesting)
+ end
+ end
else
if trace_luarun then
report_luarun("%i: code: %s",nesting,code)
@@ -263,7 +294,7 @@ do
-- writers
- local function mpp(value)
+ local function rawmpp(value)
n = n + 1
local t = type(value)
if t == "number" then
@@ -284,13 +315,13 @@ do
local function mpprint(first,second,...)
if second == nil then
if first ~= nil then
- mpp(first)
+ rawmpp(first)
end
else
for i=1,select("#",first,second,...) do
local value = (select(i,first,second,...))
if value ~= nil then
- mpp(value)
+ rawmpp(value)
end
end
end
@@ -368,7 +399,7 @@ do
if type(x) == "table" then
buffer[n] = f_pair(x[1],x[2])
else
- buffer[n] = f_pair(x,y)
+ buffer[n] = f_pair(x,y or x)
end
end
@@ -377,7 +408,7 @@ do
if type(x) == "table" then
buffer[n] = f_pair_pt(x[1],x[2])
else
- buffer[n] = f_pair_pt(x,y)
+ buffer[n] = f_pair_pt(x,y or x)
end
end
@@ -569,11 +600,7 @@ do
end
end
- aux.direct = mpdirect1
- aux.direct1 = mpdirect1
- aux.direct2 = mpdirect2
- aux.direct3 = mpdirect3
- aux.direct4 = mpdirect4
+ aux.direct = mpdirect
aux.flush = mpflush
aux.print = mpprint
@@ -669,12 +696,29 @@ do
for k, v in next, aux do mp[k] = v end
+ -- mp.print = table.setmetatablecall(aux, function(t,...)
+ -- mpprint(...)
+ -- end)
+
+ mp.print = table.setmetatablecall(aux, function(t,first,second,...)
+ if second == nil then
+ if first ~= nil then
+ rawmpp(first)
+ end
+ else
+ for i=1,select("#",first,second,...) do
+ local value = (select(i,first,second,...))
+ if value ~= nil then
+ rawmpp(value)
+ end
+ end
+ end
+ end)
+
end
do
- -- Another experimental feature:
-
local mpnumeric = mp.numeric
local scanstring = scan.string
local scriptindex = metapost.scriptindex
@@ -687,32 +731,8 @@ do
-- once bootstrapped ... (needs pushed mpx instances)
- metapost.registerscript("scriptindex",function()
- local name = scanstring()
- local index = scriptindex(name)
- -- report_script("method %i, name %a, index %i",2,name,index)
- mpnumeric(index)
- end)
-
-end
-
--- the next will move to mlib-lmp.lua
-
-do
-
- local mpnamedcolor = attributes.colors.mpnamedcolor
- local mpprint = aux.print
- local scanstring = scan.string
-
- mp.mf_named_color = function(str)
- mpprint(mpnamedcolor(str))
- end
-
- -- todo: we can inject but currently we always get a string back so then
- -- we need to deal with it upstream in the color module ... not now
-
- metapost.registerscript("namedcolor",function()
- mpprint(mpnamedcolor(scanstring()))
+ metapost.registerdirect("scriptindex",function()
+ return scriptindex(scanstring())
end)
end
@@ -806,388 +826,14 @@ end
-- texts:
-do
-
- local mptriplet = mp.triplet
-
- local bpfactor = number.dimenfactors.bp
- local textexts = nil
- local mptriplet = mp.triplet
- local nbdimensions = nodes.boxes.dimensions
-
- function mp.mf_tt_initialize(tt)
- textexts = tt
- 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)
- 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)
- end
- end
-
-end
-
-do
-
- local mpprint = aux.print
- local modes = tex.modes
- local systemmodes = tex.systemmodes
-
- function mp.mode(s)
- mpprint(modes[s] and true or false)
- end
-
- function mp.systemmode(s)
- mpprint(systemmodes[s] and true or false)
- end
-
- mp.processingmode = mp.mode
-
-end
-
--- for alan's nodes:
-
-do
-
- local mpprint = aux.print
- local mpquoted = aux.quoted
-
- function mp.isarray(str)
- mpprint(find(str,"%d") and true or false)
- end
-
- function mp.prefix(str)
- mpquoted(match(str,"^(.-)[%d%[]") or str)
- 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
-
-end
-
-do
-
- local scanstring = scan.string
- local scannumeric = scan.numeric
- local skiptoken = skip.token
-
- local injectstring = inject.string
- local injectnumeric = inject.numeric
-
- local registerscript = metapost.registerscript
-
- local comma_code = metapost.codes.comma
-
- local getmacro = tokens.getters.macro
- local setmacro = tokens.setters.macro
-
- 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 bpfactor = number.dimenfactors.bp
-
- -- more helpers
-
- registerscript("getmacro", function() injectstring (getmacro(scanstring())) end)
- registerscript("getdimen", function() injectnumeric(getdimen(scanstring())*bpfactor) end)
- registerscript("getcount", function() injectnumeric(getcount(scanstring())) end)
- registerscript("gettoks", function() injectstring (gettoks (scanstring())) end)
-
- registerscript("setmacro", function() setmacro(scanstring(),scanstring()) end)
- registerscript("setdimen", function() setdimen(scanstring(),scannumeric()/bpfactor) end)
- registerscript("setcount", function() setcount(scanstring(),scannumeric()) end)
- registerscript("settoks", function() settoks (scanstring(),scanstring()) end)
-
- registerscript("setglobalmacro", function() setmacro(scanstring(),scanstring(),"global") end)
- registerscript("setglobaldimen", function() setdimen("global",scanstring(),scannumeric()/bpfactor) end)
- registerscript("setglobalcount", function() setcount("global",scanstring(),scannumeric()) end)
- registerscript("setglobaltoks", function() settoks ("global",scanstring(),scanstring()) end)
-
-
- local utfnum = utf.byte
- local utflen = utf.len
- local utfsub = utf.sub
-
- registerscript("utfnum", function()
- injectnumeric(utfnum(scanstring()))
- end)
-
- registerscript("utflen", function()
- injectnumeric(utflen(scanstring()))
- end)
-
- registerscript("utfsub", function() -- we have an optional third argument so we explicitly scan a text argument
- injectstring(utfsub(scanstring(),skiptoken(comma_code) and scannumeric(),skiptoken(comma_code) and scannumeric()))
- end)
-
-end
-
--- position fun
-
-do
-
- local mpprint = mp.print
- local mpfprint = mp.fprint
- local mpquoted = mp.quoted
- local jobpositions = job.positions
- local getwhd = jobpositions.whd
- local getxy = jobpositions.xy
- local getposition = jobpositions.position
- local getpage = jobpositions.page
- local getregion = jobpositions.region
- local getmacro = tokens.getters.macro
-
- function mp.positionpath(name)
- local w, h, d = getwhd(name)
- if w then
- mpfprint("((%p,%p)--(%p,%p)--(%p,%p)--(%p,%p)--cycle)",0,-d,w,-d,w,h,0,h)
- else
- mpprint("(origin--cycle)")
- end
- end
-
- function mp.positioncurve(name)
- local w, h, d = getwhd(name)
- if w then
- mpfprint("((%p,%p)..(%p,%p)..(%p,%p)..(%p,%p)..cycle)",0,-d,w,-d,w,h,0,h)
- else
- mpprint("(origin--cycle)")
- end
- end
-
- function mp.positionbox(name)
- local p, x, y, w, h, d = getposition(name)
- if p then
- mpfprint("((%p,%p)--(%p,%p)--(%p,%p)--(%p,%p)--cycle)",x,y-d,x+w,y-d,x+w,y+h,x,y+h)
- else
- mpprint("(%p,%p)",x,y)
- end
- end
-
- function mp.positionxy(name)
- local x, y = getxy(name)
- if x then
- mpfprint("(%p,%p)",x,y)
- else
- mpprint("origin")
- end
- end
-
- function mp.positionpage(name)
- mpfprint("%i",getpage(name) or 0)
- end
-
- function mp.positionregion(name)
- local r = getregion(name)
- if r then
- mpquoted(r)
- else
- mpquoted("unknown")
- end
- end
-
- function mp.positionwhd(name)
- local w, h, d = getwhd(name)
- if w then
- mpfprint("(%p,%p,%p)",w,h,d)
- else
- mpprint("(0,0,0)")
- end
- end
-
- function mp.positionpxy(name)
- local p, x, y = getposition(name)
- if p then
- mpfprint("(%p,%p,%p)",p,x,y)
- else
- mpprint("(0,0,0)")
- end
- end
-
- function mp.positionanchor()
- mpquoted(getmacro("MPanchorid"))
- end
-
-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
-
- local injectpair = inject.pair
- local scanstring = scan.string
-
- metapost.registerscript("textextanchor", function()
- local x, y = match(scanstring(),"tx_anchor=(%S+) (%S+)") -- todo: make an lpeg
- if x and y then
- x = tonumber(x)
- y = tonumber(y)
- end
- injectpair(x or 0,y or 0)
- end)
-
-end
-
-do
-
- local mpprint = mp.print
- local mpquoted = mp.quoted
- local getmacro = tokens.getters.macro
-
- function mp.texvar(name)
- mpprint(getmacro(metapost.namespace .. name))
- end
-
- function mp.texstr(name)
- mpquoted(getmacro(metapost.namespace .. name))
- end
-
-end
-
-do
-
- local mpprint = aux.print
- local mpvprint = aux.vprint
-
- local hashes = { }
-
- 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
- end
-
- function mp.disposehash(n)
- if tonumber(n) then
- hashes[n] = false
- else
- hashes[n] = nil
- end
- end
-
- function mp.inhash(n,key)
- local h = hashes[n]
- mpvprint(h and h[key] and true or false)
- 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
+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("message : %s",a)
end
-
- function mp.fromhash(n,key)
- local h = hashes[n]
- mpvprint(h and h[key] or false)
- end
-
- interfaces.implement {
- name = "MPfromhash",
- 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
- end
- }
-
-end
-
-do
-
- -- a bit overkill: just a find(str,"mf_object=") can be enough
- --
- -- todo : share with mlib-pps.lua metapost,isobject
-
- 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))
- end
-
end
function mp.flatten(t)