diff options
Diffstat (limited to 'tex/context/base/mkiv/cldf-int.lmt')
-rw-r--r-- | tex/context/base/mkiv/cldf-int.lmt | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/tex/context/base/mkiv/cldf-int.lmt b/tex/context/base/mkiv/cldf-int.lmt new file mode 100644 index 000000000..4f486221b --- /dev/null +++ b/tex/context/base/mkiv/cldf-int.lmt @@ -0,0 +1,252 @@ +if not modules then modules = { } end modules ['cldf-int'] = { + version = 1.001, + comment = "companion to cldf-int.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- another experiment +-- needs upgrading +-- needs checking +-- todo: multilingual + +local byte = string.byte +local insert, remove, concat = table.insert, table.remove, table.concat +local unpack, type = unpack or table.unpack, type + +local ctxcatcodes = catcodes.numbers.ctxcatcodes +local context = context +local contextsprint = context.sprint + +local trace_define = false trackers.register("context.define", function(v) trace_define = v end) + +interfaces = interfaces or { } +local implement = interfaces.implement +local estart = interfaces.elements.start +local estop = interfaces.elements.stop + +local scanners = tokens.scanners +local shortcuts = tokens.shortcuts + +local peekchar = scanners.peekchar +local scankey = scanners.key +local scanvalue = scanners.value +local scanskip = scanners.skip + +local open = byte('[') +local close = byte(']') +local equal = byte('=') +local comma = byte(',') + +function scanhash(scanners) + if peekchar() == open then + local data = { } + scanskip() + while true do + local c = peekchar() + if c == comma then + scanskip() + elseif c == close then + scanskip() + break + else + local key = scankey(equal) + if key then + if peekchar() == equal then + scanskip() + if scanners then + local scanner = scanners[key] + if scanner then + data[key] = scanner() + else + data[key] = scanvalue(comma,close) or "" + end + else + data[key] = scanvalue(comma,close) or "" + end + else + break + end + else + break + end + end + end + return data + end +end + +function scanarray() + if peekchar() == open then + local data = { } + local d = 0 + scanskip() + while true do + local c = peekchar() + if c == comma then + scanskip() + elseif c == close then + scanskip() + break + else + local v = scanvalue(comma,close) or "" + d = d + 1 + data[d] = v + end + end + return data + end +end + +shortcuts.scanhash = scanhash +shortcuts.scanarray = scanarray + +scanners.hash = scanhash +scanners.array = scanarray + +local function remap(arguments) + -- backward compatibility + if type(arguments) == "table" then + for i=1,#arguments do + local a = arguments[i] + if type(a) == "table" then + local t = a[2] + arguments[i] = t == "list" and "array" or t + end + end + return arguments + end +end + +function interfaces.definecommand(name,specification) -- name is optional + if type(name) == "table" then + specification = name + name = specification.name + end + if name and specification then + local environment = specification.environment + local arguments = remap(specification.arguments) + if environment then + local starter = specification.starter + local stopper = specification.stopper + if starter and stopper then + implement { + name = estart .. name, + arguments = arguments, + public = true, + protected = true, + actions = starter, + } + implement { + name = estop .. name, + public = true, + protected = true, + actions = stopper, + } + else + -- message + end + end + if not environment or environment == "both" then + local macro = specification.macro + if macro then + implement { + name = name, + arguments = arguments, + public = true, + protected = true, + actions = macro, + } + else + -- message + end + end + else + -- message + end +end + +function interfaces.tolist(t) + if t then + local r = { } + for i=1,#t do + r[i] = t[i] + end + local n = #r + for k,v in table.sortedhash(t) do + if type(k) ~= "number" then + n = n + 1 + r[n] = k .. "=" .. v + end + end + return concat(r,", ") + else + return "" + end +end + +-- \startluacode +-- function test(opt_1, opt_2, arg_1) +-- context.startnarrower() +-- context("options 1: %s",interfaces.tolist(opt_1)) +-- context.par() +-- context("options 2: %s",interfaces.tolist(opt_2)) +-- context.par() +-- context("argument 1: %s",arg_1) +-- context.stopnarrower() +-- end +-- +-- interfaces.definecommand { +-- name = "test", +-- arguments = { +-- { "option", "list" }, +-- { "option", "hash" }, +-- { "content", "string" }, +-- }, +-- macro = test, +-- } +-- \stopluacode +-- +-- test: \test[1][a=3]{whatever} +-- +-- \startluacode +-- local function startmore(opt_1) +-- context.startnarrower() +-- context("start more, options: %s",interfaces.tolist(opt_1)) +-- context.startnarrower() +-- end +-- +-- local function stopmore() +-- context.stopnarrower() +-- context("stop more") +-- context.stopnarrower() +-- end +-- +-- interfaces.definecommand ( "more", { +-- environment = true, +-- arguments = { +-- { "option", "list" }, +-- }, +-- starter = startmore, +-- stopper = stopmore, +-- } ) +-- \stopluacode +-- +-- more: \startmore[1] one \startmore[2] two \stopmore one \stopmore +-- +-- More modern (no need for option or content): +-- +-- \startluacode +-- interfaces.definecommand { +-- name = "test", +-- arguments = { +-- "array", -- or list +-- "hash", +-- "string", +-- "number", +-- }, +-- macro = test, +-- } +-- \stopluacode +-- |