summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/mlib-scn.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/mlib-scn.lua')
-rw-r--r--tex/context/base/mkiv/mlib-scn.lua103
1 files changed, 87 insertions, 16 deletions
diff --git a/tex/context/base/mkiv/mlib-scn.lua b/tex/context/base/mkiv/mlib-scn.lua
index 454f3e281..a7c1924eb 100644
--- a/tex/context/base/mkiv/mlib-scn.lua
+++ b/tex/context/base/mkiv/mlib-scn.lua
@@ -70,6 +70,7 @@ local mppair = mp.pair
local mppath = mp.path
local mptriplet = mp.triplet
local mpquadruple = mp.quadruple
+local mptransform = mp.transform
local mpvalue = mp.value
local report = logs.reporter("metapost")
@@ -89,6 +90,7 @@ local string_code <const> = codes.string
local capsule_code <const> = codes.capsule
local nullary_code <const> = codes.nullary
local tag_code <const> = codes.tag
+local definedmacro_code <const> = codes.definedmacro
local typescanners = nil
local tokenscanners = nil
@@ -140,11 +142,16 @@ scanset = function() -- can be optimized, we now read twice
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
+ [nullary_code] = scanboolean, -- todo
}
typescanners = {
@@ -152,11 +159,11 @@ typescanners = {
[types.numeric] = scannumeric,
[types.string] = scanstring,
[types.boolean] = scanboolean,
- [types.pair] = function() return scanpair (true) end,
- [types.color] = function() return scancolor (true) end,
- [types.cmykcolor] = function() return scancmykcolor(true) end,
- [types.transform] = function() return scantransform(true) end,
- [types.path] = function() return scanpath () end,
+ [types.pair] = scan_pair,
+ [types.color] = scan_color,
+ [types.cmykcolor] = scan_cmykcolor,
+ [types.transform] = scan_transform,
+ [types.path] = scanpath,
}
table.setmetatableindex(tokenscanners,function()
@@ -164,6 +171,8 @@ table.setmetatableindex(tokenscanners,function()
return typescanners[e] or scanexpression
end)
+-- a key like 'color' has code 'declare'
+
local function scanparameters(fenced)
local data = { }
local close = "]"
@@ -175,7 +184,8 @@ local function scanparameters(fenced)
return data
end
while true do
- local s = scansymbol()
+ -- local s = scansymbol()
+ local s = scansymbol(false,false)
if s == close then
break;
elseif s == "," then
@@ -186,7 +196,15 @@ local function scanparameters(fenced)
-- optional equal or :
scantoken()
end
- data[s] = tokenscanners[scantoken(true)]()
+ 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
@@ -204,9 +222,7 @@ local function get_parameters(nested)
return data
end
while true do
- -- a key like 'color' has code 'declare'
- -- print(scansymbol(true),scantoken(true),codes[scantoken(true)])
- local s = scansymbol()
+ local s = scansymbol(false,false)
if s == "]" then
break;
elseif s == "," then
@@ -218,7 +234,7 @@ local function get_parameters(nested)
scantoken()
end
local kind = scantoken(true)
- if kind == leftdelimiter_code or kind == tag_code then
+ 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
@@ -232,7 +248,7 @@ local function get_parameters(nested)
end
local function getparameters()
- local namespace = scanstring()
+ local namespace = scanstring()
-- same as below
local parameters = get_parameters()
local presets = presets[namespace]
@@ -273,7 +289,16 @@ end
local function presetparameters()
local namespace = scanstring()
- presets[namespace] = get_parameters()
+ 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()
@@ -282,13 +307,13 @@ local function collectnames()
while true do
local t = scantoken(true)
-- (1) not really needed
- if t == numeric_code or t == capsule_code then
+ 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 == leftdelimiter_code or t == tag_code then
+ 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
@@ -316,6 +341,8 @@ local function get(v)
return mptriplet(v)
elseif n == 4 then
return mpquadruple(v)
+ elseif n == 6 then
+ return mptransform(v)
end
end
return mpnumeric(0)
@@ -477,6 +504,37 @@ local function getparametercount()
return mpnumeric(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 mpnumeric(n)
+end
+
local validconnectors = {
[".."] = true,
["..."] = true,
@@ -565,6 +623,7 @@ metapost.registerscript("hasparameter", hasparameter)
metapost.registerscript("getparameter", getparameter)
metapost.registerscript("getparameterdefault", getparameterdefault)
metapost.registerscript("getparametercount", getparametercount)
+metapost.registerscript("getmaxparametercount",getmaxparametercount)
metapost.registerscript("getparameterpath", getparameterpath)
metapost.registerscript("getparametertext", getparametertext)
metapost.registerscript("getparameteroption", getparameteroption)
@@ -585,6 +644,18 @@ function metapost.getparameter(list)
return v
end
+function metapost.getparameterset(namespace)
+ return namespaces[namespace]
+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