diff options
-rw-r--r-- | tex/context/base/java-ini.lua | 158 | ||||
-rw-r--r-- | tex/context/base/java-ini.mkiv | 150 | ||||
-rw-r--r-- | tex/context/base/pack-obj.mkiv | 38 |
3 files changed, 339 insertions, 7 deletions
diff --git a/tex/context/base/java-ini.lua b/tex/context/base/java-ini.lua new file mode 100644 index 000000000..ecab94920 --- /dev/null +++ b/tex/context/base/java-ini.lua @@ -0,0 +1,158 @@ +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" +} + +local format = string.format +local concat = table.concat +local lpegmatch, lpegP, lpegR, lpegS, lpegC = lpeg.match, lpeg.P, lpeg.R, lpeg.S, lpeg.C + +local allocate = utilities.storage.allocate +local variables = interfaces.variables + +-- todo: don't flush scripts if no JS key + +interactions.javascripts = interactions.javascripts or { } +local javascripts = interactions.javascripts + +javascripts.codes = allocate() +javascripts.preambles = allocate() +javascripts.functions = allocate() + +local codes, preambles, functions = javascripts.codes, javascripts.preambles, javascripts.functions + +local preambled = { } + +local function storefunction(s) + functions[s] = true +end + +local uses = lpegP("uses") +local used = lpegP("used") +local left = lpegP("{") +local right = lpegP("}") +local space = lpegS(" \r\n") +local spaces = space^0 +local braced = left * lpegC((1-right-space)^1) * right +local unbraced = lpegC((1-space)^1) +local name = spaces * (braced + unbraced) * spaces +local any = lpegP(1) +local script = lpegC(any^1) +local funct = lpegP("function") +local leftp = lpegP("(") +local rightp = lpegP(")") +local fname = spaces * funct * spaces * (((1-space-left)^1)/storefunction) * spaces * leftp + +local parsecode = name * ((uses * name) + lpeg.Cc("")) * spaces * script +local parsepreamble = name * ((used * name) + lpeg.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 ~= "" then + preambles[#preambles+1] = { name, used, script } + preambled[name] = #preambles + lpegmatch(parsefunctions,script) + end +end + +function javascripts.setpreamble(name,script) -- now later + if name and name ~= "" then + preambles[#preambles+1] = { name, "now", script } + preambled[name] = #preambles + lpegmatch(parsefunctions,script) + end +end + +function javascripts.addtopreamble(name,script) -- now later + if name and name ~= "" then + local p = preambled[name] + if p then + preambles[p] = { "now", preambles[p] .. " ;\n" .. script } + else + preambles[#preambles+1] = { name, "now", script } + preambled[name] = #preambles + lpegmatch(parsefunctions,script) + end + end +end + +function javascripts.usepreamblenow(name) -- now later + if name and name ~= "" and name ~= variables.reset then -- todo: reset + local names = utilities.parsers.settings_to_array(name) + for i=1,#names do + local somename = names[i] + if not preambled[somename] then + preambles[preambled[somename]][2] = "now" + end + end + end +end + +local splitter = lpeg.Ct(lpeg.splitat(lpeg.patterns.commaspacer)) + +local used = false + +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][1] = "now" + end + end + used = true + return code + end + local f = functions[name] + if f then + used = true + if arguments then + local args = lpegmatch(splitter,arguments) + for i=1,#args do -- can be a helper + args[i] = format("%q",args[i]) + end + return format("%s(%s)",name,concat(args,",")) + else + return format("%s()",name) + end + end +end + +function javascripts.flushpreambles() + local t = { } + if used then + for i=1,#preambles do + local preamble = preambles[i] + if preamble[2] == "now" then + t[#t+1] = { preamble[1], preamble[3] } + end + end + end + return t +end + +local patterns = { "java-imp-%s.mkiv", "java-imp-%s.tex", "java-%s.mkiv", "java-%s.tex" } + +function javascripts.usescripts(name) + if name ~= variables.reset then + commands.uselibrary(name,patterns,function(name,foundname) + context.startreadingfile() + context.input(foundname) + context.showcolormessage("javascript",1,name) + context.stopreadingfile() + end) + end +end diff --git a/tex/context/base/java-ini.mkiv b/tex/context/base/java-ini.mkiv new file mode 100644 index 000000000..a0d641240 --- /dev/null +++ b/tex/context/base/java-ini.mkiv @@ -0,0 +1,150 @@ +%D \module +%D [ file=java-ini, +%D version=1998.01.30, +%D title=\CONTEXT\ JavaScript Macros, +%D subtitle=Initialization, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt JavaScript Macros / Initialization} + +\registerctxluafile{java-ini}{1.001} + +\unprotect + +%D \macros +%D {JS*} +%D +%D Because \JAVASCRIPT's are activated by the user, for +%D instance by activating on a button, their support is closely +%D related to the referencing mechanism. Integration takes +%D place by +%D +%D \starttyping +%D \goto{calculate total}[Sum()] +%D \stoptyping +%D +%D The \type{()} classify this as a script. If they are absent, +%D the keyword is treated as a normal reference. +%D +%D One can pass arguments to such a script by saying: +%D +%D \starttyping +%D \goto{calculate total}[Sum(1.5,2.3)] +%D \stoptyping + + +%D \macros +%D {startJScode} +%D +%D A piece of \JAVASCRIPT\ code is defined by saying: +%D +%D \starttyping +%D \startJScode{name} +%D name = 4 ; +%D \stopJScode +%D \stoptyping +%D +%D This assumes uses no preamble or presumes that the preamble is +%D always loaded, the next definition also tells \CONTEXT\ to +%D actually include the preamble needed. +%D +%D \starttyping +%D \startJScode{uses} uses {later} +%D uses = 6 ; +%D \stopJScode +%D \stoptyping +%D +%D \macros +%D {startJSpreamble} +%D +%D One can define insert \JAVASCRIPT\ code at the document level +%D by using: +%D +%D \starttyping +%D \startJSpreamble{oeps} +%D oeps = 1 ; +%D \stopJSpreamble +%D \stoptyping +%D +%D which is the same as: +%D +%D \starttyping +%D \startJSpreamble{now} used now +%D now = 2 ; +%D \stopJSpreamble +%D \stoptyping +%D +%D while the next definition is only included when actually +%D used. +%D +%D \starttyping +%D \startJSpreamble{later} used later +%D later = 3 ; +%D \stopJSpreamble +%D \stoptyping +%D +%D This command may be used more that once, but always before +%D the first page is shipped out. +%D +%D \macros +%D {setJSpreamble, addtoJSpreamble} +%D +%D In addition to the previous preamble definitions, we can +%D set a preamble \quote {in||line} and add tokens to a +%D preamble. +%D +%D \macros +%D {useJSpreamblenow} +%D +%D This macro can be used to force inclusion of postponed +%D \JAVASCRIPT\ preambles. + +\unexpanded\def\startJScode + {\begingroup\obeylualines\obeyluatokens\dostartJScode} + +\long\def\dostartJScode#1\stopJScode + {\normalexpanded{\endgroup\ctxlua{interactions.javascripts.storecode(\!!bs#1\!!es)}}} + +\let\stopJScode\relax + +\unexpanded\def\startJSpreamble + {\begingroup\obeylualines\obeyluatokens\dostartJSpreamble} + +\long\def\dostartJSpreamble#1\stopJSpreamble + {\normalexpanded{\endgroup\ctxlua{interactions.javascripts.storepreamble(\!!bs#1\!!es)}}} + +\let\stopJSpreamble\relax + +\def\setJSpreamble #1#2{\ctxlua{interactions.javascripts.storepreamble ("#1",\!!bs#2\!!es)}} +\def\addtoJSpreamble #1#2{\ctxlua{interactions.javascripts.addtopreamble ("#1",\!!bs#2\!!es)}} +\def\douseJSpreamblenow#1{\ctxlua{interactions.javascripts.usepreamblenow("#1")}} + +%D \macros +%D {useJSscripts} +%D +%D In due time, users will build their collections of scripts, +%D which can be used (loaded) when applicable. Although not all +%D public, we will provide some general purpose scripts, +%D collected in files with names like \type{java-...}. One can +%D load these scripts with \type{\useJSscripts}, like: +%D +%D \starttyping +%D \useJSscripts[fld] +%D \stoptyping +%D +%D The not so complicated implementation of this macro is: + +\def\douseJSscripts[#1][#2]% + {\ctxlua{interactions.javascripts.usescripts(\!!bs#1\!!es)}% + \douseJSpreamblenow{#2}} + +\def\useJSscripts + {\dodoubleempty\douseJSscripts} + +\protect \endinput diff --git a/tex/context/base/pack-obj.mkiv b/tex/context/base/pack-obj.mkiv index 682dc02ff..e2620955d 100644 --- a/tex/context/base/pack-obj.mkiv +++ b/tex/context/base/pack-obj.mkiv @@ -263,10 +263,36 @@ {\globalpopmacro\crossreferenceobject \dododosetobject{#1}{#2}{#3}\egroup}} -\def\dododosetobject#1#2#3% +% \def\dododosetobject#1#2#3% +% {\begingroup +% \dontshowcomposition % rather fuzzy in \setxvalue ... \hbox +% \scratchdimen\objectoffset +% \@EA\xdef\csname\r!object#2::#3\endcsname +% {\noexpand\dohandleobject{#2}{#3}% +% {\ifhbox\nextbox\hbox\else\vbox\fi}% +% {\number\nextboxwd}{\number\nextboxht}{\number\nextboxdp}% +% {\number\scratchdimen}}% +% \expanded % freeze the dimensions since \dostartobject may use \nextbox +% {\dostartobject{#2}{#3}{\the\nextboxwd}{\the\nextboxht}{\the\nextboxdp}}% +% \ifcase#1\relax\else \ifdim\objectoffset>\zeropoint +% \setbox\nextbox\vbox spread 2\scratchdimen +% {\forgetall \offinterlineskip +% \vss\hbox spread 2\scratchdimen{\hss\flushnextbox\hss}\vss}% +% \fi \fi +% \flushnextbox +% \dostopobject +% \endgroup} + +\def\dododosetobject#1#2#3% this is a hack: luatex adds 1bp around each side {\begingroup \dontshowcomposition % rather fuzzy in \setxvalue ... \hbox - \scratchdimen\objectoffset + \ifcase#1\relax + \scratchdimen-\onebasepoint % compensates auto 1 bp + \else\ifdim\objectoffset>\zeropoint + \scratchdimen \objectoffset + \else + \scratchdimen-\onebasepoint % compensates auto 1 bp + \fi\fi \@EA\xdef\csname\r!object#2::#3\endcsname {\noexpand\dohandleobject{#2}{#3}% {\ifhbox\nextbox\hbox\else\vbox\fi}% @@ -274,11 +300,9 @@ {\number\scratchdimen}}% \expanded % freeze the dimensions since \dostartobject may use \nextbox {\dostartobject{#2}{#3}{\the\nextboxwd}{\the\nextboxht}{\the\nextboxdp}}% - \ifcase#1\relax\else \ifdim\objectoffset>\zeropoint - \setbox\nextbox\vbox spread 2\scratchdimen - {\forgetall \offinterlineskip - \vss\hbox spread 2\scratchdimen{\hss\flushnextbox\hss}\vss}% - \fi \fi + \setbox\nextbox\vbox spread 2\scratchdimen + {\forgetall \offinterlineskip + \vss\hbox spread 2\scratchdimen{\hss\flushnextbox\hss}\vss}% \flushnextbox \dostopobject \endgroup} |