summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tex/context/base/java-ini.lua158
-rw-r--r--tex/context/base/java-ini.mkiv150
-rw-r--r--tex/context/base/pack-obj.mkiv38
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}