diff options
Diffstat (limited to 'tex/context/base/mkiv/cldf-lmt.lua')
-rw-r--r-- | tex/context/base/mkiv/cldf-lmt.lua | 399 |
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, +} |