1if not modules then modules = { } end modules ['java-ini'] = {
2 version = 1.001,
3 comment = "companion to java-ini.mkiv",
4 author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5 copyright = "PRAGMA ADE / ConTeXt Development Team",
6 license = "see context related readme files"
7}
8
9
10
11local format, gsub, find = string.format, string.gsub, string.find
12local concat = table.concat
13local lpegmatch, P, S, C, Carg, Cc = lpeg.match, lpeg.P, lpeg.S, lpeg.C, lpeg.Carg, lpeg.Cc
14
15local allocate = utilities.storage.allocate
16local settings_to_array = utilities.parsers.settings_to_array
17
18local variables = interfaces.variables
19local formatters = string.formatters
20
21local context = context
22local implement = interfaces.implement
23
24local trace_javascript = false trackers.register("backends.javascript", function(v) trace_javascript = v end)
25
26local report_javascripts = logs.reporter ("interactions","javascripts")
27local status_javascripts = logs.messenger("interactions","javascripts")
28
29local javascripts = interactions.javascripts or { }
30interactions.javascripts = javascripts
31
32local codes = allocate()
33local preambles = allocate()
34local functions = allocate()
35
36javascripts.codes = codes
37javascripts.preambles = preambles
38javascripts.functions = functions
39
40local preambled = { }
41
42local function storefunction(s,preamble)
43 if trace_javascript then
44 report_javascripts("found function %a",s)
45 end
46 functions[s] = preamble
47end
48
49local uses = P("uses")
50local used = P("used")
51local left = P("{")
52local right = P("}")
53local space = S(" \r\n")
54local spaces = space^0
55local braced = left * C((1-right-space)^1) * right
56local unbraced = C((1-space)^1)
57local name = spaces * (braced + unbraced) * spaces
58local any = P(1)
59local script = C(any^1)
60local funct = P("function")
61local leftp = P("(")
62local rightp = P(")")
63local fname = spaces * funct * spaces * (C((1-space-left-leftp)^1) * Carg(1) / storefunction) * spaces * leftp
64
65local parsecode = name * ((uses * name) + Cc("")) * spaces * script
66local parsepreamble = name * ((used * name) + Cc("")) * spaces * script
67local parsefunctions = (fname + any)^0
68
69function javascripts.storecode(str)
70 local name, uses, script = lpegmatch(parsecode,str)
71 if name and name ~= "" then
72 script = gsub(script,"%s*([^\n\r]+)%s*[\n\r]+$","%1")
73 codes[name] = { uses, script }
74 end
75end
76
77function javascripts.storepreamble(str)
78 local name, used, script = lpegmatch(parsepreamble,str)
79 if name and name ~= "" and not preambled[name] then
80 local n = #preambles + 1
81 preambles[n] = { name, used, script }
82 preambled[name] = n
83 if trace_javascript then
84 report_javascripts("stored preamble %a, state %a, order %a",name,used,n)
85 end
86 lpegmatch(parsefunctions,script,1,n)
87 end
88end
89
90function javascripts.setpreamble(name,script)
91 if name and name ~= "" and not preambled[name] then
92 local n = #preambles + 1
93 preambles[n] = { name, "now", script }
94 preambled[name] = n
95 if trace_javascript then
96 report_javascripts("adapted preamble %a, state %a, order %a",name,"now",n)
97 end
98 lpegmatch(parsefunctions,script,1,n)
99 end
100end
101
102function javascripts.addtopreamble(name,script)
103 if name and name ~= "" then
104 local p = preambled[name]
105 if p then
106 preambles[p] = { "now", preambles[p] .. " ;\n" .. script }
107 if trace_javascript then
108 report_javascripts("extended preamble %a, state %a, order %a",name,"now",p)
109 end
110 else
111 local n = #preambles + 1
112 preambles[n] = { name, "now", script }
113 preambled[name] = n
114 if trace_javascript then
115 report_javascripts("stored preamble %a, state %a, order %a",name,"now",n)
116 end
117 lpegmatch(parsefunctions,script,1,n)
118 end
119 end
120end
121
122function javascripts.usepreamblenow(name)
123 if name and name ~= "" and name ~= variables.reset then
124 local names = settings_to_array(name)
125 for i=1,#names do
126 local somename = names[i]
127 local preamble = preambled[somename]
128 if preamble then
129 preambles[preamble][2] = "now"
130 if trace_javascript then
131 report_javascripts("used preamble %a, state %a, order %a",somename,"now","auto")
132 end
133 end
134 end
135 end
136end
137
138local splitter = lpeg.tsplitat(lpeg.patterns.commaspacer)
139
140local used, reported = false, { }
141
142function javascripts.code(name,arguments)
143 local c = codes[name]
144 if c then
145 local u, code = c[1], c[2]
146 if u ~= "" then
147 local p = preambled[u]
148 if p then
149 preambles[p][2] = "now"
150 if trace_javascript and not reported[name] then
151 reported[name] = true
152 report_javascripts("used code %a, preamble %a",name,u)
153 end
154 elseif trace_javascript and not reported[name] then
155 reported[name] = true
156 report_javascripts("used code %a",name)
157 end
158 elseif trace_javascript and not reported[name] then
159 reported[name] = true
160 report_javascripts("used code %a",name)
161 end
162 used = true
163 return code
164 end
165 local f = functions[name]
166 if f then
167 used = true
168 if trace_javascript and not reported[name] then
169 reported[name] = true
170 report_javascripts("used function %a",name)
171 end
172 preambles[f][2] = "now"
173 if arguments then
174 local args = lpegmatch(splitter,arguments)
175 for i=1,#args do
176 args[i] = formatters["%q"](args[i])
177 end
178 return formatters["%s(%s)"](name,concat(args,","))
179 else
180 return formatters["%s()"](name)
181 end
182 end
183end
184
185function javascripts.flushpreambles()
186 local t = { }
187
188 for i=1,#preambles do
189 local preamble = preambles[i]
190 if preamble[2] == "now" then
191 if trace_javascript then
192 report_javascripts("flushed preamble %a",preamble[1])
193 end
194 t[#t+1] = { preamble[1], preamble[3] }
195 end
196 end
197
198 return t
199end
200
201local patterns = {
202 CONTEXTLMTXMODE > 0 and "java-imp-%s.mkxl" or "",
203 "java-imp-%s.mkiv",
204 "java-imp-%s.tex",
205
206 "java-%s.mkiv",
207 "java-%s.tex"
208}
209
210local function action(name,foundname)
211 commands.loadlibrary(name,foundname,true)
212 status_javascripts("loaded: library %a",name)
213end
214
215local function failure(name)
216 report_javascripts("unknown library %a",name)
217end
218
219function javascripts.usescripts(name)
220 if name ~= variables.reset then
221 resolvers.uselibrary {
222 name = name,
223 patterns = patterns,
224 action = action,
225 failure = failure,
226 onlyonce = true,
227 }
228 end
229end
230
231
232
233implement {
234 name = "storejavascriptcode",
235 actions = javascripts.storecode,
236 arguments = "string"
237}
238
239implement {
240 name = "storejavascriptpreamble",
241 actions = javascripts.storepreamble,
242 arguments = "string"
243}
244
245implement {
246 name = "setjavascriptpreamble",
247 actions = javascripts.setpreamble,
248 arguments = "2 strings",
249}
250
251implement {
252 name = "addtojavascriptpreamble",
253 actions = javascripts.addtopreamble,
254 arguments = "2 strings",
255}
256
257implement {
258 name = "usejavascriptpreamble",
259 actions = javascripts.usepreamblenow,
260 arguments = "string"
261}
262
263implement {
264 name = "usejavascriptscripts",
265 actions = javascripts.usescripts,
266 arguments = "string"
267}
268 |