diff options
author | Hans Hagen <pragma@wxs.nl> | 2020-11-23 19:48:34 +0100 |
---|---|---|
committer | Context Git Mirror Bot <phg@phi-gamma.net> | 2020-11-23 19:48:34 +0100 |
commit | 18499e46a49b8ccf4346686d1cf626ada33935b8 (patch) | |
tree | bd0ae7b601b323e20954c10c07598637d9403e00 /tex/context/base/mkiv/mlib-scn.lmt | |
parent | 4b089e589d39346a66a27d04f9857fe16e4b7b41 (diff) | |
download | context-18499e46a49b8ccf4346686d1cf626ada33935b8.tar.gz |
2020-11-23 18:39:00
Diffstat (limited to 'tex/context/base/mkiv/mlib-scn.lmt')
-rw-r--r-- | tex/context/base/mkiv/mlib-scn.lmt | 780 |
1 files changed, 0 insertions, 780 deletions
diff --git a/tex/context/base/mkiv/mlib-scn.lmt b/tex/context/base/mkiv/mlib-scn.lmt deleted file mode 100644 index ff1cff0e3..000000000 --- a/tex/context/base/mkiv/mlib-scn.lmt +++ /dev/null @@ -1,780 +0,0 @@ -if not modules then modules = { } end modules ['mlib-scn'] = { - version = 1.001, - comment = "companion to mlib-ctx.mkiv", - author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright = "PRAGMA ADE / ConTeXt Development Team", - license = "see context related readme files", -} - --- Very experimental, for Alan and me. - --- for i = 1 upto 32000 : % 0.062 --- ts := 5mm / 20; --- endfor ; --- --- for i = 1 upto 32000 : % 0.219 --- ts := (getparameter "axis" "sy") / 20; --- endfor ; --- --- for i = 1 upto 32000 : % 0.266 --- ts := (getparameterx "axis" "sy") / 20; --- endfor ; --- --- pushparameters "axis"; --- for i = 1 upto 32000 : % 0.250 --- ts := (getparameterx "sy") / 20; --- endfor ; --- popparameters; - -local type, next, rawget, getmetatable = type, next, rawget, getmetatable -local byte, gmatch = string.byte, string.gmatch -local insert, remove = table.insert, table.remove - -local mplib = mplib -local metapost = metapost - -local codes = mplib.getcodes() -local types = mplib.gettypes() - -table.hashed(codes) -table.hashed(types) - -metapost.codes = codes -metapost.types = types - -local setmetatableindex = table.setmetatableindex - -local scanners = mp.scan -local injectors = mp.inject - -local scannext = scanners.next -local scanexpression = scanners.expression -local scantoken = scanners.token -local scansymbol = scanners.symbol -local scannumeric = scanners.numeric -local scannumber = scanners.number -local scaninteger = scanners.integer -local scanboolean = scanners.boolean -local scanstring = scanners.string -local scanpair = scanners.pair -local scancolor = scanners.color -local scancmykcolor = scanners.cmykcolor -local scantransform = scanners.transform -local scanpath = scanners.path -local scanpen = scanners.pen - -local mpprint = mp.print -local injectnumeric = injectors.numeric -local injectstring = injectors.string -local injectboolean = injectors.boolean -local injectpair = injectors.pair -local injecttriplet = injectors.color -local injectquadruple = injectors.cmykcolor -local injecttransform = injectors.transform -local injectpath = injectors.path - -local report = logs.reporter("metapost") - -local semicolon_code = codes.semicolon -local equals_code = codes.equals -local comma_code = codes.comma -local colon_code = codes.colon -local leftbrace_code = codes.leftbrace -local rightbrace_code = codes.rightbrace -local leftbracket_code = codes.leftbracket -local rightbracket_code = codes.rightbracket -local leftdelimiter_code = codes.leftdelimiter -local rightdelimiter_code = codes.rightdelimiter -local numeric_code = codes.numeric -local string_code = codes.string -local capsule_code = codes.capsule -local nullary_code = codes.nullary -local tag_code = codes.tag -local definedmacro_code = codes.definedmacro - -local typescanners = nil -local tokenscanners = nil -local scanset = nil -local scanparameters = nil - -scanset = function() -- can be optimized, we now read twice - scantoken() - if scantoken(true) == rightbrace_code then - scantoken() - return { } - else - local l = { } - local i = 0 - while true do - i = i + 1 - local s = scansymbol(true) - if s == "{" then - l[i] = scanset() - elseif s == "[" then - local d = { } - scansymbol() - while true do - local s = scansymbol() - if s == "]" then - break; - elseif s == "," then - -- continue - else - local t = scantoken(true) - if t == equals_code or t == colon_code then - scantoken() - end - d[s] = tokenscanners[scantoken(true)]() - end - end - l[i] = d - else - local e = scanexpression(true) - l[i] = (typescanners[e] or scanexpression)() - end - if scantoken() == rightbrace_code then - break - else - -- whatever - end - end - return l - end -end - -local function scan_pair () return scanpair (true) end -local function scan_color () return scancolor (true) end -local function scan_cmykcolor() return scancmykcolor(true) end -local function scan_transform() return scantransform(true) end - -tokenscanners = { - [leftbrace_code] = scanset, - [numeric_code] = scannumeric, - [string_code] = scanstring, - [nullary_code] = scanboolean, -- todo -} - -typescanners = { - [types.known] = scannumeric, - [types.numeric] = scannumeric, - [types.string] = scanstring, - [types.boolean] = scanboolean, - [types.pair] = scan_pair, - [types.color] = scan_color, - [types.cmykcolor] = scan_cmykcolor, - [types.transform] = scan_transform, - [types.path] = scanpath, - [types.pen] = scanpen, -} - -table.setmetatableindex(tokenscanners,function() - local e = scanexpression(true) - return typescanners[e] or scanexpression -end) - --- a key like 'color' has code 'declare' - -local function scanparameters(fenced) - local data = { } - local close = "]" - if not fenced then - close = ";" - elseif scansymbol(true) == "[" then - scansymbol() - else - return data - end - while true do - -- local s = scansymbol() - local s = scansymbol(false,false) - if s == close then - break; - elseif s == "," then - -- continue - else - local t = scantoken(true) - if t == equals_code or t == colon_code then - -- optional equal or : - scantoken() - end - local kind = scantoken(true) - if kind == leftdelimiter_code or kind == tag_code or kind == capsule_code then - kind = scanexpression(true) - data[s] = (typescanners[kind] or scanexpression)() - elseif kind == leftbracket_code then - data[s] = get_parameters(true) - else - data[s] = tokenscanners[kind]() - end - end - end - return data -end - -local namespaces = { } -local presets = { } -local passed = { } - -local function get_parameters(nested) - local data = { } - if nested or scansymbol(true) == "[" then - scansymbol() - else - return data - end - while true do - local s = scansymbol(false,false) - if s == "]" then - break; - elseif s == "," then - -- continue - else - local t = scantoken(true) - if t == equals_code or t == colon_code then - -- optional equal or : - scantoken() - end - local kind = scantoken(true) - if kind == leftdelimiter_code or kind == tag_code or kind == capsule_code then - kind = scanexpression(true) - data[s] = (typescanners[kind] or scanexpression)() - elseif kind == leftbracket_code then - data[s] = get_parameters(true) - else - data[s] = tokenscanners[kind]() - end - end - end - return data -end - -local function getparameters() - local namespace = scanstring() - -- same as below - local parameters = get_parameters() - local presets = presets[namespace] - local passed = passed[namespace] - if passed then - if presets then - setmetatableindex(passed,presets) - end - setmetatableindex(parameters,passed) - elseif presets then - setmetatableindex(parameters,presets) - end - namespaces[namespace] = parameters - -- -end - -local function applyparameters() - local saved = namespaces - local namespace = scanstring() - local action = scanstring() -- before we scan the parameters - -- same as above - local parameters = get_parameters() - local presets = presets[namespace] - local passed = passed[namespace] - if passed then - if presets then - setmetatableindex(passed,presets) - end - setmetatableindex(parameters,passed) - elseif presets then - setmetatableindex(parameters,presets) - end - namespaces[namespace] = parameters - -- till here - mpprint(action) - namespaces = saved -end - -local function presetparameters() - local namespace = scanstring() - local parent = nil - local t = scantoken(true) - if t == string_code then - parent = presets[scanstring()] - end - local p = get_parameters() - if parent then - setmetatableindex(p,parent) - end - presets[namespace] = p -end - -local function collectnames() - local l = { } -- can be reused but then we can't nest - local n = 0 - while true do - local t = scantoken(true) - -- (1) not really needed - if t == numeric_code then - n = n + 1 l[n] = scaninteger(1) - elseif t == string_code then - n = n + 1 l[n] = scanstring(1) - elseif t == nullary_code then - n = n + 1 l[n] = scanboolean(1) - elseif t == leftbracket_code then - scantoken() -- leftbacket - n = n + 1 l[n] = scaninteger(1) - scantoken() -- rightbacket - elseif t == leftdelimiter_code or t == tag_code or t == capsule_code then - t = scanexpression(true) - n = n + 1 l[n] = (typescanners[t] or scanexpression)() - else - break - end - end - return l, n -end - -local function get(v) - local t = type(v) - if t == "number" then - return injectnumeric(v) - elseif t == "boolean" then - return injectboolean(v) - elseif t == "string" then - return injectstring(v) - elseif t == "table" then - local n = #v - if type(v[1]) == "table" then - return injectpath(v) - elseif n == 2 then - return injectpair(v) - elseif n == 3 then - return injecttriplet(v) - elseif n == 4 then - return injectquadruple(v) - elseif n == 6 then - return injecttransform(v) - end - end - return injectnumeric(0) -end - -local stack = { } - -local function pushparameters() - local l, n = collectnames() - insert(stack,namespaces) - for i=1,n do - local n = namespaces[l[i]] - if type(n) == "table" then - namespaces = n - else - break - end - end -end - -local function popparameters() - local n = remove(stack) - if n then - namespaces = n - else - report("stack error") - end -end - --- todo: - -local function getparameter() - local list, n = collectnames() - local v = namespaces - for i=1,n do - local l = list[i] - local vl = v[l] - if vl == nil then - if type(l) == "number" then - vl = v[1] - if vl == nil then - return injectnumeric(0) - end - else - return injectnumeric(0) - end - end - v = vl - end - if v == nil then - return injectnumeric(0) - else - return get(v) - end -end - -local function hasparameter() - local list, n = collectnames() - local v = namespaces - for i=1,n do - local l = list[i] - local vl = rawget(v,l) - if vl == nil then - if type(l) == "number" then - vl = rawget(v,1) - if vl == nil then - return injectboolean(false) - end - else - return injectboolean(false) - end - end - v = vl - end - if v == nil then - return injectboolean(false) - else - return injectboolean(true) - end -end - -local function hasoption() - local list, n = collectnames() - if n > 1 then - local v = namespaces - if n > 2 then - for i=1,n-1 do - local l = list[i] - local vl = v[l] - if vl == nil then - return injectboolean(false) - end - v = vl - end - else - v = v[list[1]] - end - if type(v) == "string" then - -- no caching .. slow anyway - local o = list[n] - if v == o then - return injectboolean(true) - end - for vv in gmatch(v,"[^%s,]+") do - for oo in gmatch(o,"[^%s,]+") do - if vv == oo then - return injectboolean(true) - end - end - end - end - end - return injectboolean(false) -end - -local function getparameterdefault() - local list, n = collectnames() - local v = namespaces - if n == 1 then - local l = list[1] - local vl = v[l] - if vl == nil then - -- maybe backtrack - local top = stack[#stack] - if top then - vl = top[l] - end - end - if vl == nil then - return injectnumeric(0) - else - return get(vl) - end - else - for i=1,n-1 do - local l = list[i] - local vl = v[l] - if vl == nil then - if type(l) == "number" then - vl = v[1] - if vl == nil then - return get(list[n]) - end - else - local last = list[n] - if last == "*" then - -- so, only when not pushed - local m = getmetatable(namespaces[list[1]]) - if n then - m = m.__index -- can also be a _m_ - end - if m then - local v = m - for i=2,n-1 do - local l = list[i] - local vl = v[l] - if vl == nil then - return injectnumeric(0) - end - v = vl - end - if v == nil then - return injectnumeric(0) - else - return get(v) - end - end - return injectnumeric(0) - else - return get(last) - end - end - end - v = vl - end - if v == nil then - return get(list[n]) - else - return get(v) - end - end -end - -local function getparametercount() - local list, n = collectnames() - local v = namespaces - for i=1,n do - v = v[list[i]] - if not v then - break - end - end - return injectnumeric(type(v) == "table" and #v or 0) -end - -local function getmaxparametercount() - local list, n = collectnames() - local v = namespaces - for i=1,n do - v = v[list[i]] - if not v then - break - end - end - local n = 0 - if type(v) == "table" then - local v1 = v[1] - if type(v1) == "table" then - n = #v1 - for i=2,#v do - local vi = v[i] - if type(vi) == "table" then - local vn = #vi - if vn > n then - n = vn - end - else - break; - end - end - end - - end - return injectnumeric(n) -end - -local validconnectors = { - [".."] = true, - ["..."] = true, - ["--"] = true, -} - -local function getparameterpath() - local list, n = collectnames() - local close = list[n] - if type(close) == "boolean" then - n = n - 1 - else - close = false - end - local connector = list[n] - if type(connector) == "string" and validconnectors[connector] then - n = n - 1 - else - connector = "--" - end - local v = namespaces - for i=1,n do - v = v[list[i]] - if not v then - break - end - end - if type(v) == "table" then - return injectpath(v,connector,close) - else - return injectpair(0,0) - end -end - -local function getparameterpen() - local list, n = collectnames() - local v = namespaces - for i=1,n do - v = v[list[i]] - if not v then - break - end - end - if type(v) == "table" then - return injectpath(v,"..",true) - else - return injectpair(0,0) - end -end - -local function getparametertext() - local list, n = collectnames() - local strut = list[n] - if type(strut) == "boolean" then - n = n - 1 - else - strut = false - end - local v = namespaces - for i=1,n do - v = v[list[i]] - if not v then - break - end - end - if type(v) == "string" then - return injectstring("\\strut " .. v) - else - return injectstring("") - end -end - --- local function getparameteroption() --- local list, n = collectnames() --- local last = list[n] --- if type(last) == "string" then --- n = n - 1 --- else --- return false --- end --- local v = namespaces --- for i=1,n do --- v = v[list[i]] --- if not v then --- break --- end --- end --- if type(v) == "string" and v ~= "" then --- for s in gmatch(v,"[^ ,]+") do --- if s == last then --- return true --- end --- end --- end --- return false --- end - -function metapost.scanparameters() --- scantoken() -- we scan the semicolon - return get_parameters() -end - -metapost.registerscript("getparameters", getparameters) -metapost.registerscript("applyparameters", applyparameters) -metapost.registerscript("presetparameters", presetparameters) -metapost.registerscript("hasparameter", hasparameter) -metapost.registerscript("hasoption", hasoption) -metapost.registerscript("getparameter", getparameter) -metapost.registerscript("getparameterdefault", getparameterdefault) -metapost.registerscript("getparametercount", getparametercount) -metapost.registerscript("getmaxparametercount",getmaxparametercount) -metapost.registerscript("getparameterpath", getparameterpath) -metapost.registerscript("getparameterpen", getparameterpen) -metapost.registerscript("getparametertext", getparametertext) ---------.registerscript("getparameteroption", getparameteroption) -metapost.registerscript("pushparameters", pushparameters) -metapost.registerscript("popparameters", popparameters) - -function metapost.getparameter(list) - local n = #list - local v = namespaces - for i=1,n do - local l = list[i] - local vl = v[l] - if vl == nil then - return - end - v = vl - end - return v -end - -function metapost.getparameterset(namespace) - return namespace and namespaces[namespace] or namespaces -end - -function metapost.setparameterset(namespace,t) - namespaces[namespace] = t -end - --- goodies - -metapost.registerscript("definecolor", function() - scantoken() -- we scan the semicolon - local s = get_parameters() - attributes.colors.defineprocesscolordirect(s) -end) - --- tex scanners - -local scanners = tokens.scanners -local scanhash = scanners.hash -local scanstring = scanners.string -local scanvalue = scanners.value -local scaninteger = scanners.integer -local scanboolean = scanners.boolean -local scanfloat = scanners.float -local scandimension = scanners.dimension - -local definitions = { } - -local bpfactor = number.dimenfactors.bp -local comma = byte(",") -local close = byte("]") - -local scanrest = function() return scanvalue(comma,close) or "" end -local scandimension = function() return scandimension() * bpfactor end - -local scanners = { - ["integer"] = scaninteger, - ["number"] = scanfloat, - ["numeric"] = scanfloat, - ["boolean"] = scanboolean, - ["string"] = scanrest, - ["dimension"] = scandimension, -} - -interfaces.implement { - name = "lmt_parameters_define", - arguments = "string", - actions = function(namespace) - local d = scanhash() - for k, v in next, d do - d[k] = scanners[v] or scanrest - end - definitions[namespace] = d - end, -} - -interfaces.implement { - name = "lmt_parameters_preset", - arguments = "string", - actions = function(namespace) - passed[namespace] = scanhash(definitions[namespace]) - end, -} - -interfaces.implement { - name = "lmt_parameters_reset", - arguments = "string", - actions = function(namespace) - passed[namespace] = nil - end, -} |