diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkiv/java-ini.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkiv/java-ini.lua | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/java-ini.lua b/Master/texmf-dist/tex/context/base/mkiv/java-ini.lua new file mode 100644 index 00000000000..069eb5ab610 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/mkiv/java-ini.lua @@ -0,0 +1,268 @@ +if not modules then modules = { } end modules ['java-ini'] = { + version = 1.001, + comment = "companion to java-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- todo: don't flush scripts if no JS key + +local format = string.format +local concat = table.concat +local lpegmatch, P, S, C, Carg, Cc = lpeg.match, lpeg.P, lpeg.S, lpeg.C, lpeg.Carg, lpeg.Cc + +local allocate = utilities.storage.allocate +local settings_to_array = utilities.parsers.settings_to_array + +local variables = interfaces.variables +local formatters = string.formatters + +local context = context +local implement = interfaces.implement + +local trace_javascript = false trackers.register("backends.javascript", function(v) trace_javascript = v end) + +local report_javascripts = logs.reporter ("interactions","javascripts") +local status_javascripts = logs.messenger("interactions","javascripts") + +local javascripts = interactions.javascripts or { } +interactions.javascripts = javascripts + +local codes = allocate() +local preambles = allocate() +local functions = allocate() + +javascripts.codes = codes +javascripts.preambles = preambles +javascripts.functions = functions + +local preambled = { } + +local function storefunction(s,preamble) + if trace_javascript then + report_javascripts("found function %a",s) + end + functions[s] = preamble +end + +local uses = P("uses") +local used = P("used") +local left = P("{") +local right = P("}") +local space = S(" \r\n") +local spaces = space^0 +local braced = left * C((1-right-space)^1) * right +local unbraced = C((1-space)^1) +local name = spaces * (braced + unbraced) * spaces +local any = P(1) +local script = C(any^1) +local funct = P("function") +local leftp = P("(") +local rightp = P(")") +local fname = spaces * funct * spaces * (C((1-space-left-leftp)^1) * Carg(1) / storefunction) * spaces * leftp + +local parsecode = name * ((uses * name) + Cc("")) * spaces * script +local parsepreamble = name * ((used * name) + Cc("")) * spaces * script +local parsefunctions = (fname + any)^0 + +function javascripts.storecode(str) + local name, uses, script = lpegmatch(parsecode,str) + if name and name ~= "" then + codes[name] = { uses, script } + end +end + +function javascripts.storepreamble(str) -- now later + local name, used, script = lpegmatch(parsepreamble,str) + if name and name ~= "" and not preambled[name] then + local n = #preambles + 1 + preambles[n] = { name, used, script } + preambled[name] = n + if trace_javascript then + report_javascripts("stored preamble %a, state %a, order %a",name,used,n) + end + lpegmatch(parsefunctions,script,1,n) + end +end + +function javascripts.setpreamble(name,script) -- now later + if name and name ~= "" and not preambled[name] then + local n = #preambles + 1 + preambles[n] = { name, "now", script } + preambled[name] = n + if trace_javascript then + report_javascripts("adapted preamble %a, state %a, order %a",name,"now",n) + end + lpegmatch(parsefunctions,script,1,n) + end +end + +function javascripts.addtopreamble(name,script) + if name and name ~= "" then + local p = preambled[name] + if p then + preambles[p] = { "now", preambles[p] .. " ;\n" .. script } + if trace_javascript then + report_javascripts("extended preamble %a, state %a, order %a",name,"now",p) + end + else + local n = #preambles + 1 + preambles[n] = { name, "now", script } + preambled[name] = n + if trace_javascript then + report_javascripts("stored preamble %a, state %a, order %a",name,"now",n) + end + lpegmatch(parsefunctions,script,1,n) + end + end +end + +function javascripts.usepreamblenow(name) -- now later + if name and name ~= "" and name ~= variables.reset then -- todo: reset + local names = settings_to_array(name) + for i=1,#names do + local somename = names[i] + if not preambled[somename] then + preambles[preambled[somename]][2] = "now" + if trace_javascript then + report_javascripts("used preamble %a, state %a, order %a",somename,"now","auto") + end + end + end + end +end + +local splitter = lpeg.tsplitat(lpeg.patterns.commaspacer) + +local used, reported = false, { } -- we can cache more + +function javascripts.code(name,arguments) + local c = codes[name] + if c then + local u, code = c[1], c[2] + if u ~= "" then + local p = preambled[u] + if p then + preambles[p][2] = "now" + if trace_javascript and not reported[name] then + reported[name] = true + report_javascripts("used code %a, preamble %a",name,u) + end + elseif trace_javascript and not reported[name] then + reported[name] = true + report_javascripts("used code %a",name) + end + elseif trace_javascript and not reported[name] then + reported[name] = true + report_javascripts("used code %a",name) + end + used = true + return code + end + local f = functions[name] + if f then + used = true + if trace_javascript and not reported[name] then + reported[name] = true + report_javascripts("used function %a",name) + end + preambles[f][2] = "now" -- automatically tag preambles that define the function (as later) + if arguments then + local args = lpegmatch(splitter,arguments) + for i=1,#args do -- can be a helper + args[i] = formatters["%q"](args[i]) + end + return formatters["%s(%s)"](name,concat(args,",")) + else + return formatters["%s()"](name) + end + end +end + +function javascripts.flushpreambles() + local t = { } +-- if used then -- we want to be able to enforce inclusion + for i=1,#preambles do + local preamble = preambles[i] + if preamble[2] == "now" then + if trace_javascript then + report_javascripts("flushed preamble %a",preamble[1]) + end + t[#t+1] = { preamble[1], preamble[3] } + end + end +-- end + return t +end + +local patterns = { + "java-imp-%s.mkiv", + "java-imp-%s.tex", + -- obsolete: + "java-%s.mkiv", + "java-%s.tex" +} + +local function action(name,foundname) + context.startnointerference() + context.startreadingfile() + context.input(foundname) + status_javascripts("loaded: library %a",name) + context.stopreadingfile() + context.stopnointerference() +end + +local function failure(name) + report_javascripts("unknown library %a",name) +end + +function javascripts.usescripts(name) + if name ~= variables.reset then -- reset is obsolete + resolvers.uselibrary { + name = name, + patterns = patterns, + action = action, + failure = failure, + onlyonce = true, + } + end +end + +-- interface + +implement { + name = "storejavascriptcode", + actions = javascripts.storecode, + arguments = "string" +} + +implement { + name = "storejavascriptpreamble", + actions = javascripts.storepreamble, + arguments = "string" +} + +implement { + name = "setjavascriptpreamble", + actions = javascripts.setpreamble, + arguments = { "string", "string" } +} + +implement { + name = "addtojavascriptpreamble", + actions = javascripts.addtopreamble, + arguments = { "string", "string" } +} + +implement { + name = "usejavascriptpreamble", + actions = javascripts.usepreamblenow, + arguments = "string" +} + +implement { + name = "usejavascriptscripts", + actions = javascripts.usescripts, + arguments = "string" +} |