diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkxl/mult-ini.lmt')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkxl/mult-ini.lmt | 389 |
1 files changed, 389 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkxl/mult-ini.lmt b/Master/texmf-dist/tex/context/base/mkxl/mult-ini.lmt new file mode 100644 index 00000000000..7c60d5b33af --- /dev/null +++ b/Master/texmf-dist/tex/context/base/mkxl/mult-ini.lmt @@ -0,0 +1,389 @@ +if not modules then modules = { } end modules ['mult-ini'] = { + version = 1.001, + comment = "companion to mult-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local format, gmatch, match, find, sub = string.format, string.gmatch, string.match, string.find, string.sub +local lpegmatch = lpeg.match +local serialize, concat = table.serialize, table.concat +local rawget, type, tonumber, next = rawget, type, tonumber, next + +local context = context +local commands = commands +local implement = interfaces.implement + +local allocate = utilities.storage.allocate +local mark = utilities.storage.mark +local prtcatcodes = catcodes.numbers.prtcatcodes +local vrbcatcodes = catcodes.numbers.vrbcatcodes +local contextsprint = context.sprint +local setmetatableindex = table.setmetatableindex +local formatters = string.formatters + +local report_interface = logs.reporter("interface","initialization") + +interfaces = interfaces or { } +interfaces.constants = mark(interfaces.constants or { }) +interfaces.variables = mark(interfaces.variables or { }) +interfaces.elements = mark(interfaces.elements or { }) +interfaces.formats = mark(interfaces.formats or { }) +interfaces.translations = mark(interfaces.translations or { }) +interfaces.setupstrings = mark(interfaces.setupstrings or { }) +interfaces.corenamespaces = mark(interfaces.corenamespaces or { }) +interfaces.usednamespaces = mark(interfaces.usednamespaces or { }) + +local registerstorage = storage.register +local sharedstorage = storage.shared + +local constants = interfaces.constants +local variables = interfaces.variables +local elements = interfaces.elements +local formats = interfaces.formats +local translations = interfaces.translations +local setupstrings = interfaces.setupstrings +local corenamespaces = interfaces.corenamespaces +local usednamespaces = interfaces.usednamespaces +local reporters = { } -- just an optimization + +local setmacro = tokens.setters.macro + +registerstorage("interfaces/constants", constants, "interfaces.constants") +registerstorage("interfaces/variables", variables, "interfaces.variables") +registerstorage("interfaces/elements", elements, "interfaces.elements") +registerstorage("interfaces/formats", formats, "interfaces.formats") +registerstorage("interfaces/translations", translations, "interfaces.translations") +registerstorage("interfaces/setupstrings", setupstrings, "interfaces.setupstrings") +registerstorage("interfaces/corenamespaces", corenamespaces, "interfaces.corenamespaces") +registerstorage("interfaces/usednamespaces", usednamespaces, "interfaces.usednamespaces") + +interfaces.interfaces = { + "cs", "de", "en", "fr", "it", "nl", "ro", "pe", +} + +sharedstorage.currentinterface = sharedstorage.currentinterface or "en" +sharedstorage.currentresponse = sharedstorage.currentresponse or "en" + +local currentinterface = sharedstorage.currentinterface +local currentresponse = sharedstorage.currentresponse + +interfaces.currentinterface = currentinterface +interfaces.currentresponse = currentresponse + +local complete = allocate() +interfaces.complete = complete + +local function resolve(t,k) -- one access needed to get loaded (not stored!) + report_interface("loading interface definitions from 'mult-def.lua'") + complete = dofile(resolvers.findfile("mult-def.lua")) + report_interface("loading interface messages from 'mult-mes.lua'") + complete.messages = dofile(resolvers.findfile("mult-mes.lua")) + interfaces.complete = complete + return rawget(complete,k) +end + +setmetatableindex(complete, resolve) + +local function valueiskey(t,k) -- will be helper + t[k] = k + return k +end + +setmetatableindex(variables, valueiskey) +setmetatableindex(constants, valueiskey) +setmetatableindex(elements, valueiskey) +setmetatableindex(formats, valueiskey) +setmetatableindex(translations, valueiskey) +setmetatableindex(setupstrings, valueiskey) + +function interfaces.registernamespace(n,namespace) + corenamespaces[n] = namespace + usednamespaces[namespace] = n +end + +function interfaces.getnamespace(n) + return usednamespaces[n] .. ">" +end + +if documentdata then + + local prefix, getmacro + + function documentdata.variable(name) + if not prefix then + prefix = usednamespaces.variables .. ">document:" + end + if not getmacro then + getmacro = tokens.getters.macro + end + return getmacro(prefix..name) + end + +end + +local function resolve(t,k) + local v = logs.reporter(k) + t[k] = v + return v +end + +setmetatableindex(reporters,resolve) + +for category, _ in next, translations do + -- We pre-create reporters for already defined messages + -- because otherwise listing is incomplete and we want + -- to use that for checking so delaying makes not much + -- sense there. + local r = reporters[category] +end + +-- adding messages + +local function add(target,tag,values) + local t = target[tag] + if not f then + target[tag] = values + else + for k, v in next, values do + if f[k] then + -- error + else + f[k] = v + end + end + end +end + +function interfaces.settranslation(tag,values) + add(translations,tag,values) +end + +function interfaces.setformat(tag,values) + add(formats,tag,values) +end + +local function getsetupstring(tag) + return setupstrings[tag] or tag +end + +interfaces.getsetupstring = getsetupstring + +-- the old method: + +local replacer = lpeg.replacer { { "--", "%%a" } } + +local function fulltag(category,tag) + return formatters["%s:%s"](category,lpegmatch(replacer,tag)) +end + +function interfaces.setmessages(category,str) + for tag, message in gmatch(str,"(%S+) *: *(.-) *[\n\r]") do + if tag == "title" then + translations[tag] = translations[tag] or tag + else + formats[fulltag(category,tag)] = lpegmatch(replacer,message) + end + end +end + +function interfaces.setmessage(category,tag,message) + formats[fulltag(category,tag)] = lpegmatch(replacer,message) +end + +function interfaces.getmessage(category,tag,default) + return formats[fulltag(category,tag)] or default or "unknown message" +end + +function interfaces.doifelsemessage(category,tag) + return rawget(formats,fulltag(category,tag)) +end + +local splitter = lpeg.splitat(",") + +function interfaces.showmessage(category,tag,arguments) + local r = reporters[category] + local f = formats[fulltag(category,tag)] + local t = type(arguments) + if t == "string" and #arguments > 0 then + r(f,lpegmatch(splitter,arguments)) + elseif t == "table" then + r(f,unpack(arguments)) + elseif arguments then + r(f,arguments) + else + r(f) + end +end + +-- till here + +function interfaces.setvariable(variable,given) + variables[given] = variable +end + +function interfaces.setconstant(constant,given) + constants[given] = constant +end + +function interfaces.setelement(element,given) + elements[given] = element +end + +-- the real thing: + +logs.setmessenger(context.verbatim.ctxreport) + +interfaces.cachedsetups = interfaces.cachedsetups or { } +interfaces.hashedsetups = interfaces.hashedsetups or { } + +local cachedsetups = interfaces.cachedsetups +local hashedsetups = interfaces.hashedsetups + +storage.register("interfaces/cachedsetups", cachedsetups, "interfaces.cachedsetups") +storage.register("interfaces/hashedsetups", hashedsetups, "interfaces.hashedsetups") + +function interfaces.cachesetup(t) + local hash = serialize(t) + local done = hashedsetups[hash] + if done then + return cachedsetups[done] + else + done = #cachedsetups + 1 + cachedsetups[done] = t + hashedsetups[hash] = done + return t + end +end + +function interfaces.interfacedcommand(name) + local command = complete.commands[name] + return command and command[currentinterface] or name +end + +-- interface + +function interfaces.writestatus(category,message) + reporters[category](message) -- could also be a setmetatablecall +end + +function interfaces.message(str) + texio.write(str) -- overloaded +end + +implement { name = "registernamespace", actions = interfaces.registernamespace, arguments = { "integer", "string" } } +implement { name = "setinterfaceconstant", actions = interfaces.setconstant, arguments = "2 strings" } +implement { name = "setinterfacevariable", actions = interfaces.setvariable, arguments = "2 strings" } +implement { name = "setinterfaceelement", actions = interfaces.setelement, arguments = "2 strings" } +implement { name = "setinterfacemessage", actions = interfaces.setmessage, arguments = "3 strings" } +implement { name = "setinterfacemessages", actions = interfaces.setmessages, arguments = "2 strings" } + +implement { + name = "showmessage", + public = true, + protected = true, + arguments = "3 arguments" , + actions = interfaces.showmessage, +} + +implement { + name = "doifelsemessage", + public = true, + protected = true, + arguments = "2 arguments", + actions = { interfaces.doifelsemessage, commands.doifelse }, +} + +implement { + name = "getmessage", + public = true, + protected = true, + arguments = "3 arguments", + actions = function(...) + setmacro("currentmessagetext", interfaces.getmessage(...)) + end, +} + +implement { + name = "writestatus", + overload = true, + public = true, + protected = true, + arguments = "2 arguments", + actions = interfaces.writestatus, +} + +implement { + name = "message", + overload = true, + public = true, + protected = true, + arguments = "string", + actions = interfaces.message, +} + +local function gss(s) + contextsprint(vrbcatcodes,getsetupstring(s)) +end + +implement { -- will be overloaded + name = "getsetupstring", + public = true, + -- protected = true, + arguments = "string", + actions = gss, +} + +implement { + name = "rawsetupstring", + public = true, + arguments = "string", + actions = gss, +} + + +local function showassignerror(namespace,key,line) + -- if key and key ~= "" and key ~= "," then + local ns, instance = match(namespace,"^(%d+)[^%a]+(%a*)") + if ns then + namespace = corenamespaces[tonumber(ns)] or ns + end + -- injected in the stream for timing: + if instance and instance ~= "" then + context.writestatus("setup",formatters["error in line %a, namespace %a, instance %a, key %a"](line,namespace,instance,key)) + else + context.writestatus("setup",formatters["error in line %a, namespace %a, key %a"](line,namespace,key)) + end + -- end +end + +implement { + name = "showassignerror", + actions = showassignerror, + arguments = { "string", "string", "integer" }, +} + +-- a simple helper + +local settings_to_hash = utilities.parsers.settings_to_hash + +local makesparse = function(t) + for k, v in next, t do + if not v or v == "" then + t[k] = nil + end + end + return t +end + +function interfaces.checkedspecification(specification) + local kind = type(specification) + if kind == "table" then + return makesparse(specification) + elseif kind == "string" and specification ~= "" then + return makesparse(settings_to_hash(specification)) + else + return { } + end +end |