summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/cldf-lmt.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/cldf-lmt.lua')
-rw-r--r--tex/context/base/mkiv/cldf-lmt.lua399
1 files changed, 399 insertions, 0 deletions
diff --git a/tex/context/base/mkiv/cldf-lmt.lua b/tex/context/base/mkiv/cldf-lmt.lua
new file mode 100644
index 000000000..74ba5c224
--- /dev/null
+++ b/tex/context/base/mkiv/cldf-lmt.lua
@@ -0,0 +1,399 @@
+if not modules then modules = { } end modules ['cldf-lmt'] = {
+ version = 1.001,
+ comment = "companion to toks-scn.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local random = math.random
+local randomseed = math.randomseed
+local round = math.round
+local abs = math.abs
+
+local scanners = tokens.scanners
+local scanword = scanners.word
+local scanstring = scanners.string
+local scanboolean = scanners.boolean
+local scandimen = scanners.dimen
+local scanfloat = scanners.float
+local scancount = scanners.integer
+local scaninteger = scanners.luainteger
+local scancardinal = scanners.luacardinal
+local scannumber = scanners.luanumber
+local scanargument = scanners.argument
+local scantoken = scanners.token
+local getindex = token.get_index
+local texsetdimen = tex.setdimen
+
+local values = tokens.values
+local none_code = values.none
+local integer_code = values.integer
+local cardinal_code = values.cardinal
+local dimension_code = values.dimension
+local skip_code = values.skip
+local boolean_code = values.boolean
+local float_code = values.float
+
+local context = context
+
+local floats = { }
+local integers = { }
+local cardinals = { }
+local numbers = { }
+
+-- variables --
+
+interfaces.implement {
+ name = "luafloat",
+ public = true,
+ value = true,
+ actions = function(b)
+ local n = scanword()
+ if b then
+ context("%.99g",floats[n] or 0)
+ else
+ floats[n] = scannumber(true)
+ -- floats[n] = scanfloat(true)
+ end
+ end,
+}
+
+interfaces.implement {
+ name = "luainteger",
+ public = true,
+ value = true,
+ actions = function(b)
+ local n = scanword()
+ if b then
+ context("%i",integers[n] or 0)
+ else
+ integers[n] = scaninteger(true)
+ end
+ end,
+}
+
+interfaces.implement {
+ name = "luacount",
+ public = true,
+ value = true,
+ actions = function(b)
+ local n = scanword()
+ if b then
+ return integer_code, integers[n] or 0
+ else
+ integers[n] = scancount(true)
+ end
+ end,
+}
+
+interfaces.implement {
+ name = "luadimen",
+ public = true,
+ value = true,
+ actions = function(b)
+ local n = scanword()
+ if b then
+ return dimension_code, integers[n] or 0
+ else
+ integers[n] = scandimen(false,false,true)
+ end
+ end,
+}
+
+interfaces.implement {
+ name = "luacardinal",
+ public = true,
+ value = true,
+ actions = function(b)
+ local n = scanword()
+ if b then
+ context("%d",cardinals[n] or 0)
+ else
+ cardinals[n] = scancardinal(true)
+ end
+ end,
+}
+
+interfaces.implement {
+ name = "luanumber",
+ public = true,
+ value = true,
+ actions = function(b)
+ local n = scanword()
+ if b then
+ context("%d",floats[n] or integers[n] or cardinals[n] or 0)
+ else
+ -- floats[n] = scanfloat(true)
+ floats[n] = scannumber(true)
+ end
+ end,
+}
+
+interfaces.implement {
+ name = "luarandom",
+ public = true,
+ value = true,
+ actions = function(b)
+ if b then
+ return integer_code, random(scaninteger(),scaninteger())
+ else
+ randomseed(scaninteger(true))
+ end
+ end,
+}
+
+interfaces.floats = floats
+interfaces.integers = integers
+interfaces.cardinals = cardinals
+
+interfaces.numbers = table.setmetatableindex(function(t,k)
+ return floats[k] or integers[k] or cardinals[k]
+end)
+
+-- arrays --
+
+local arrays = { }
+
+interfaces.arrays = arrays
+
+local newindex = lua.newindex
+
+interfaces.implement {
+ name = "newarray",
+ public = true,
+ protected = true,
+ arguments = { {
+ { "name", "string" },
+ { "nx", "integer" },
+ { "ny", "integer" },
+ { "type", "string" },
+ } },
+ actions = function(t)
+ local name = t.name
+ if t.name then
+ local nx = t.nx
+ local ny = t.ny
+ local ty = t.type or "integer"
+ local df = nil
+ if ty == "integer" or ty == "float" or ty == "dimension" then
+ df = 0
+ elseif ty == "boolean" then
+ df = false
+ else
+ ty = nil
+ end
+ if nx and ty ~= nil then
+ local data
+ if ny then
+ data = newindex(t.ny)
+ for i=1,ny do
+ data[i] = newindex(nx,df)
+ end
+ else
+ data = newindex(nx,df)
+ end
+ arrays[name] = data
+ data.nx = nx
+ data.ny = ny
+ data.type = ty
+ if ty == "integer" then
+ data.scanner = scancount
+ elseif ty == "boolean" then
+ data.scanner = scanboolean
+ elseif ty == "dimension" then
+ data.scanner = scandimen
+ elseif ty == "float" then
+ data.scanner = scanfloat
+ end
+ if ty == "integer" then
+ data.code = integer_code
+ elseif ty == "boolean" then
+ data.code = boolean_code
+ elseif ty == "dimension" then
+ data.code = dimension_code
+ elseif ty == "float" then
+ data.code = float_code
+ end
+ end
+ end
+ end,
+}
+
+interfaces.implement {
+ name = "arrayvalue",
+ public = true,
+ value = true,
+ actions = function(b)
+ local name = scanstring()
+ if name then
+ local a = arrays[name]
+ if a then
+ local nx = a.nx
+ local ny = a.ny
+ local d = a
+ if ny then
+ d = d[scaninteger()]
+ end
+ local x = scaninteger()
+ if b then
+ local code = a.code
+ if code == float_code then
+ context("%.99g",d[x])
+ else
+ return code, d[x]
+ end
+ else
+ d[x] = a.scanner()
+ end
+ end
+ end
+ end,
+}
+
+
+interfaces.implement {
+ name = "arrayequals",
+ public = true,
+ value = true,
+ actions = function(b)
+ local name = scanstring()
+ if name then
+ local a = arrays[name]
+ if a then
+ local nx = a.nx
+ local ny = a.ny
+ local d = a
+ if ny then
+ d = d[scaninteger()]
+ end
+ local x = scaninteger()
+ if b then
+ return boolean_code, a.scanner() == d[x]
+ end
+ end
+ end
+ end,
+}
+
+interfaces.implement {
+ name = "arraycompare",
+ public = true,
+ value = true,
+ actions = function(b)
+ local name = scanstring()
+ if name then
+ local a = arrays[name]
+ if a then
+ local nx = a.nx
+ local ny = a.ny
+ local d = a
+ if ny then
+ d = d[scaninteger()]
+ end
+ local x = scaninteger()
+ if b then
+ local v = a.scanner()
+ local d = d[x]
+ if d < v then
+ return integer_code, 0
+ elseif d == v then
+ return integer_code, 1
+ else
+ return integer_code, 2
+ end
+ end
+ end
+ end
+ end,
+}
+
+interfaces.implement {
+ name = "showarray",
+ public = true,
+ protected = true,
+ actions = function()
+ local name = scanstring()
+ if name then
+ inspect(arrays[name])
+ end
+ end,
+}
+
+-- expressions --
+
+local cache = table.setmetatableindex(function(t,k)
+ local code = "return function() local n = interfaces.numbers local a = interfaces.arrays return " .. k .. " end"
+ code = loadstring(code)
+ if code then
+ code = code()
+ end
+ t[k] = code or false
+ return code
+end)
+
+table.makeweak(cache)
+
+interfaces.implement {
+ name = "luaexpression",
+ public = true,
+ actions = function()
+ local how = scanword()
+ local code = cache[scanargument()]
+ if code then
+ local result = code()
+ if result then
+ if not how then
+ context(tostring(code()))
+ elseif how == "float" then
+ context("%.99g",result)
+ elseif how == "integer" then
+ context("%i",round(result))
+ elseif how == "cardinal" then
+ context("%d",abs(round(result)))
+ elseif how == "dimen" then
+ context("%p",result)
+ elseif how == "boolean" then
+ context("%d",result and 1 or 0)
+ elseif how == "lua" then
+ context("%q",result)
+ else
+ context(tostring(code()))
+ end
+ end
+ end
+ end
+}
+
+local dimenfactors = number.dimenfactors
+
+interfaces.implement {
+ name = "nodimen",
+ public = true,
+ value = true,
+ actions = function(b)
+ if b then
+ local how = scanword()
+ local what = scandimen()
+ if how then
+ local factor = dimenfactors[how]
+ if factor then
+ context("%.6N%s",factor*what,how)
+ else
+ return dimension_code, what
+ end
+ else
+ return dimension_code, what
+ end
+ else
+ local t = scantoken()
+ if t then
+ local i = getindex(t)
+ if i then
+ local d = scandimen(false,false,true)
+ texsetdimen(i,d)
+ end
+ end
+ end
+ end,
+}