summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/cldf-int.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/cldf-int.lua')
-rw-r--r--tex/context/base/mkiv/cldf-int.lua382
1 files changed, 271 insertions, 111 deletions
diff --git a/tex/context/base/mkiv/cldf-int.lua b/tex/context/base/mkiv/cldf-int.lua
index 52cfea8d0..937e1da60 100644
--- a/tex/context/base/mkiv/cldf-int.lua
+++ b/tex/context/base/mkiv/cldf-int.lua
@@ -11,8 +11,9 @@ if not modules then modules = { } end modules ['cldf-int'] = {
-- needs checking
-- todo: multilingual
-local format, insert, remove, concat = string.format, table.insert, table.remove, table.concat
-local unpack = unpack or table.unpack
+local format, byte = string.format, string.byte
+local insert, remove, concat = table.insert, table.remove, table.concat
+local unpack, type = unpack or table.unpack, type
local catcodenumbers = catcodes.numbers
@@ -24,140 +25,282 @@ local contextsprint = context.sprint
local trace_define = false trackers.register("context.define", function(v) trace_define = v end)
-interfaces = interfaces or { }
+interfaces = interfaces or { }
+local implement = interfaces.implement
+local estart = interfaces.elements.start
+local estop = interfaces.elements.stop
-_clmh_ = utilities.parsers.settings_to_hash
-_clma_ = utilities.parsers.settings_to_array
+if CONTEXTLMTXMODE > 0 then
-local starters, stoppers, macros, stack = { }, { }, { }, { }
+ local scanners = tokens.scanners
+ local shortcuts = tokens.shortcuts
-local checkers = {
- [0] = "",
- "\\dosingleempty",
- "\\dodoubleempty",
- "\\dotripleempty",
- "\\doquadrupleempty",
- "\\doquintupleempty",
- "\\dosixtupleempty",
-}
+ local scanpeek = scanners.peek
+ local scankey = scanners.key
+ local scanvalue = scanners.value
+ local scanskip = scanners.skip
-function _clmm_(name,...)
- macros[name](...)
-end
+ local open = byte('[')
+ local close = byte(']')
+ local equal = byte('=')
+ local comma = byte(',')
-function _clmb_(name,...)
- local sn = stack[name]
- insert(sn,{...})
- starters[name](...)
-end
-
-function _clme_(name)
- local sn = stack[name]
- local sv = remove(sn)
- if sv then
- stoppers[name](unpack(sv))
- else
- -- nesting error
+ function scanhash(t)
+ if scanpeek() == open then
+ local data = { }
+ scanskip()
+ while true do
+ local c = scanpeek()
+ if c == comma then
+ scanskip()
+ elseif c == close then
+ scanskip()
+ break
+ else
+ local key = scankey(equal)
+ if key then
+ if scanpeek() == equal then
+ scanskip()
+ data[key] = scanvalue(comma,close) or ""
+ else
+ break
+ end
+ else
+ break
+ end
+ end
+ end
+ return data
+ end
end
-end
-_clmn_ = tonumber
+ function scanarray(t)
+ if scanpeek() == open then
+ local data = { }
+ local d = 0
+ scanskip()
+ while true do
+ local c = scanpeek()
+ 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
-local estart = interfaces.elements.start
-local estop = interfaces.elements.stop
+ shortcuts.scanhash = scanhash
+ shortcuts.scanarray = scanarray
--- this is a bit old definition ... needs to be modernized
+ scanners.hash = scanhash
+ scanners.array = scanarray
-function interfaces.definecommand(name,specification) -- name is optional
- if type(name) == "table" then
- specification = name
- name = specification.name
+ 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
- if name and specification then
- local arguments = specification.arguments
- local na = (arguments and #arguments) or 0
- local environment = specification.environment
- if na == 0 then
+
+ 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
- contextsprint(ctxcatcodes,"\\setuvalue{",estart,name,"}{\\ctxlua{_clmb_('",name,"')}}")
- contextsprint(ctxcatcodes,"\\setuvalue{",estop, name,"}{\\ctxlua{_clme_('",name,"')}}")
+ 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
- contextsprint(ctxcatcodes,"\\setuvalue{", name,"}{\\ctxlua{_clmm_('",name,"')}}")
- end
- else
- -- we could flush immediate but tracing is bad then
- stack[name] = { }
- local opt = 0
- local done = false
- local snippets = { } -- we can reuse it
- local mkivdo = "\\mkivdo" .. name -- maybe clddo
- snippets[#snippets+1] = "\\def"
- snippets[#snippets+1] = mkivdo
- for i=1,na do
- local a = arguments[i]
- local variant = a[1]
- if variant == "option" then
- snippets[#snippets+1] = "[#"
- snippets[#snippets+1] = i
- snippets[#snippets+1] = "]"
- if not done then
- opt = opt + 1
- end
+ local macro = specification.macro
+ if macro then
+ implement {
+ name = name,
+ arguments = arguments,
+ public = true,
+ protected = true,
+ actions = macro,
+ }
else
- done = true -- no more optional checking after this
- snippets[#snippets+1] = "#"
- snippets[#snippets+1] = i
+ -- message
end
end
- if environment then
- snippets[#snippets+1] = "{\\ctxlua{_clmb_('"
- snippets[#snippets+1] = name
- snippets[#snippets+1] = "'"
+ else
+ -- message
+ end
+ end
+
+
+else
+
+ _clmh_ = utilities.parsers.settings_to_hash
+ _clma_ = utilities.parsers.settings_to_array
+
+ local starters, stoppers, macros, stack = { }, { }, { }, { }
+
+ local checkers = {
+ [0] = "",
+ "\\dosingleempty",
+ "\\dodoubleempty",
+ "\\dotripleempty",
+ "\\doquadrupleempty",
+ "\\doquintupleempty",
+ "\\dosixtupleempty",
+ }
+
+ function _clmm_(name,...)
+ macros[name](...)
+ end
+
+ function _clmb_(name,...)
+ local sn = stack[name]
+ insert(sn,{...})
+ starters[name](...)
+ end
+
+ function _clme_(name)
+ local sn = stack[name]
+ local sv = remove(sn)
+ if sv then
+ stoppers[name](unpack(sv))
+ else
+ -- nesting error
+ end
+ end
+
+ _clmn_ = tonumber
+
+ local estart = interfaces.elements.start
+ local estop = interfaces.elements.stop
+
+ -- this is a bit old definition ... needs to be modernized
+
+ 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 arguments = specification.arguments
+ local na = (arguments and #arguments) or 0
+ local environment = specification.environment
+ if na == 0 then
+ if environment then
+ contextsprint(ctxcatcodes,"\\setuvalue{",estart,name,"}{\\ctxlua{_clmb_('",name,"')}}")
+ contextsprint(ctxcatcodes,"\\setuvalue{",estop, name,"}{\\ctxlua{_clme_('",name,"')}}")
+ end
+ if not environment or environment == "both" then
+ contextsprint(ctxcatcodes,"\\setuvalue{", name,"}{\\ctxlua{_clmm_('",name,"')}}")
+ end
else
- snippets[#snippets+1] = "{\\ctxlua{_clmm_('"
- snippets[#snippets+1] = name
- snippets[#snippets+1] = "'"
- end
- for i=1,na do
- local a = arguments[i]
- local variant = a[2]
- if variant == "list" then
- snippets[#snippets+1] = ",_clma_([[#"
- snippets[#snippets+1] = i
- snippets[#snippets+1] = "]])"
- elseif variant == "hash" then
- snippets[#snippets+1] = ",_clmh_([[#"
- snippets[#snippets+1] = i
- snippets[#snippets+1] = "]])"
- elseif variant == "number" then
- snippets[#snippets+1] = ",_clmn_([[#"
- snippets[#snippets+1] = i
- snippets[#snippets+1] = "]])"
+ -- we could flush immediate but tracing is bad then
+ stack[name] = { }
+ local opt = 0
+ local done = false
+ local snippets = { } -- we can reuse it
+ local mkivdo = "\\mkivdo" .. name -- maybe clddo
+ snippets[#snippets+1] = "\\def"
+ snippets[#snippets+1] = mkivdo
+ for i=1,na do
+ local a = arguments[i]
+ local variant = a[1]
+ if variant == "option" then
+ snippets[#snippets+1] = "[#"
+ snippets[#snippets+1] = i
+ snippets[#snippets+1] = "]"
+ if not done then
+ opt = opt + 1
+ end
+ else
+ done = true -- no more optional checking after this
+ snippets[#snippets+1] = "#"
+ snippets[#snippets+1] = i
+ end
+ end
+ if environment then
+ snippets[#snippets+1] = "{\\ctxlua{_clmb_('"
+ snippets[#snippets+1] = name
+ snippets[#snippets+1] = "'"
else
- snippets[#snippets+1] = ",[[#"
- snippets[#snippets+1] = i
- snippets[#snippets+1] = "]]"
+ snippets[#snippets+1] = "{\\ctxlua{_clmm_('"
+ snippets[#snippets+1] = name
+ snippets[#snippets+1] = "'"
+ end
+ for i=1,na do
+ local a = arguments[i]
+ local variant = a[2]
+ if variant == "list" then
+ snippets[#snippets+1] = ",_clma_([==[#"
+ snippets[#snippets+1] = i
+ snippets[#snippets+1] = "]==])"
+ elseif variant == "hash" then
+ snippets[#snippets+1] = ",_clmh_([==[#"
+ snippets[#snippets+1] = i
+ snippets[#snippets+1] = "]==])"
+ elseif variant == "number" then
+ snippets[#snippets+1] = ",_clmn_([==[#"
+ snippets[#snippets+1] = i
+ snippets[#snippets+1] = "]==])"
+ else
+ snippets[#snippets+1] = ",[==[#"
+ snippets[#snippets+1] = i
+ snippets[#snippets+1] = "]==]"
+ end
+ end
+ snippets[#snippets+1] = ")}}"
+ contextsprint(ctxcatcodes,unpack(snippets))
+ if environment then
+ -- needs checking
+ contextsprint(ctxcatcodes,"\\setuvalue{",estart,name,"}{",checkers[opt],mkivdo,"}")
+ contextsprint(ctxcatcodes,"\\setuvalue{",estop, name,"}{\\ctxlua{_clme_('",name,"')}}")
+ end
+ if not environment or environment == "both" then
+ contextsprint(ctxcatcodes,"\\setuvalue{", name,"}{",checkers[opt],mkivdo,"}")
end
end
- snippets[#snippets+1] = ")}}"
- contextsprint(ctxcatcodes,unpack(snippets))
if environment then
- -- needs checking
- contextsprint(ctxcatcodes,"\\setuvalue{",estart,name,"}{",checkers[opt],mkivdo,"}")
- contextsprint(ctxcatcodes,"\\setuvalue{",estop, name,"}{\\ctxlua{_clme_('",name,"')}}")
- end
- if not environment or environment == "both" then
- contextsprint(ctxcatcodes,"\\setuvalue{", name,"}{",checkers[opt],mkivdo,"}")
+ starters[name] = specification.starter
+ stoppers[name] = specification.stopper
+ else
+ macros[name] = specification.macro
end
end
- if environment then
- starters[name] = specification.starter
- stoppers[name] = specification.stopper
- else
- macros[name] = specification.macro
- end
end
+
end
function interfaces.tolist(t)
@@ -223,3 +366,20 @@ end
-- \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
+--
+