summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/cldf-int.lmt
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/cldf-int.lmt')
-rw-r--r--tex/context/base/mkiv/cldf-int.lmt252
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
+--