1if not modules then modules = { } end modules ['syst-lua'] = {
2 version = 1.001,
3 comment = "companion to syst-lua.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
9local load, type, tonumber = load, type, tonumber
10local concat = table.concat
11local utfchar = utf.char
12local find = string.find
13local S, C, P, lpegmatch, lpegtsplitat = lpeg.S, lpeg.C, lpeg.P, lpeg.match, lpeg.tsplitat
14
15local xmath = xmath or math
16local xcomplex = xcomplex or { }
17
18local cmd = tokens.commands
19
20local scannext = token.scan_next or token.get_next
21
22local getcommand = token.get_command
23local getmode = token.get_mode
24local getindex = token.get_index
25local getcsname = token.get_csname
26local getmacro = token.get_macro
27local putnext = token.put_next
28local scantoken = token.scan_token or token.get_token
29
30local getdimen = tex.getdimen
31local getglue = tex.getglue
32local getcount = tex.getcount
33local gettoks = tex.gettoks
34local gettex = tex.get
35
36local context = context
37local dimenfactors = number.dimenfactors
38
39commands = commands or { }
40local commands = commands
41local context = context
42local implement = interfaces.implement
43
44local ctx_protected_cs = context.protected.cs
45local ctx_firstoftwoarguments = context.firstoftwoarguments
46local ctx_secondoftwoarguments = context.secondoftwoarguments
47local ctx_firstofoneargument = context.firstofoneargument
48local ctx_gobbleoneargument = context.gobbleoneargument
49
50implement {
51 name = "writestatus",
52 arguments = "2 strings",
53 actions = logs.status,
54}
55
56function commands.doifelse(b)
57 if b then
58 ctx_firstoftwoarguments()
59 else
60 ctx_secondoftwoarguments()
61 end
62end
63
64function commands.doifelsesomething(b)
65 if b and b ~= "" then
66 ctx_firstoftwoarguments()
67 else
68 ctx_secondoftwoarguments()
69 end
70end
71
72function commands.doif(b)
73 if b then
74 ctx_firstofoneargument()
75 else
76 ctx_gobbleoneargument()
77 end
78end
79
80function commands.doifsomething(b)
81 if b and b ~= "" then
82 ctx_firstofoneargument()
83 else
84 ctx_gobbleoneargument()
85 end
86end
87
88function commands.doifnot(b)
89 if b then
90 ctx_gobbleoneargument()
91 else
92 ctx_firstofoneargument()
93 end
94end
95
96function commands.doifnotthing(b)
97 if b and b ~= "" then
98 ctx_gobbleoneargument()
99 else
100 ctx_firstofoneargument()
101 end
102end
103
104commands.testcase = commands.doifelse
105
106function commands.boolcase(b)
107 context(b and 1 or 0)
108end
109
110function commands.doifelsespaces(str)
111 if find(str,"^ +$") then
112 ctx_firstoftwoarguments()
113 else
114 ctx_secondoftwoarguments()
115 end
116end
117
118local pattern = lpeg.patterns.validdimen
119
120function commands.doifelsedimenstring(str)
121 if lpegmatch(pattern,str) then
122 ctx_firstoftwoarguments()
123 else
124 ctx_secondoftwoarguments()
125 end
126end
127
128local p_first = C((1-P(",")-P(-1))^0)
129
130implement {
131 name = "firstinset",
132 arguments = "string",
133 actions = function(str) context(lpegmatch(p_first,str or "")) end,
134 public = true,
135}
136
137implement {
138 name = "ntimes",
139 arguments = { "string", "integer" },
140 actions = { string.rep, context }
141}
142
143implement {
144 name = "execute",
145 arguments = "string",
146 actions = os.execute
147}
148
149implement {
150 name = "doifelsesame",
151 arguments = "2 strings",
152 actions = function(a,b)
153 if a == b then
154 ctx_firstoftwoarguments()
155 else
156 ctx_secondoftwoarguments()
157 end
158 end
159}
160
161implement {
162 name = "doifsame",
163 arguments = "2 strings",
164 actions = function(a,b)
165 if a == b then
166 ctx_firstofoneargument()
167 else
168 ctx_gobbleoneargument()
169 end
170 end
171}
172
173implement {
174 name = "doifnotsame",
175 arguments = "2 strings",
176 actions = function(a,b)
177 if a == b then
178 ctx_gobbleoneargument()
179 else
180 ctx_firstofoneargument()
181 end
182 end
183}
184
185
186
187
188
189
190
191
192do
193
194 local result = CONTEXTLMTXMODE > 0 and
195 { "local xmath = xmath local xcomplex = xcomplex return " }
196 or { "local xmath = math local xcomplex = { } return " }
197 local word = { }
198 local r = 1
199 local w = 0
200
201 local report = logs.reporter("system","expression")
202
203 local function unexpected(c)
204 report("unexpected token %a",c)
205 end
206
207 local function expression()
208 local w = 0
209 local r = 1
210 while true do
211 local t = scannext()
212 local n = getcommand(t)
213 local c = cmd[n]
214
215 if c == "letter" then
216 w = w + 1 ; word[w] = utfchar(getmode(t))
217 else
218 if w > 0 then
219 local s = concat(word,"",1,w)
220 local d = dimenfactors[s]
221 if d then
222 r = r + 1 ; result[r] = "*"
223 r = r + 1 ; result[r] = 1/d
224 else
225 if xmath[s] then
226 r = r + 1 ; result[r] = "xmath."
227 elseif xcomplex[s] then
228 r = r + 1 ; result[r] = "xcomplex."
229 end
230 r = r + 1 ; result[r] = s
231 end
232 w = 0
233 end
234 if c == "other_char" then
235 r = r + 1 ; result[r] = utfchar(getmode(t))
236 elseif c == "spacer" then
237
238 elseif c == "relax" then
239 break
240 elseif c == "assign_int" then
241 r = r + 1 ; result[r] = getcount(getindex(t))
242 elseif c == "assign_dimen" then
243 r = r + 1 ; result[r] = getdimen(getindex(t))
244 elseif c == "assign_glue" then
245 r = r + 1 ; result[r] = getglue(getindex(t))
246 elseif c == "assign_toks" then
247 r = r + 1 ; result[r] = gettoks(getindex(t))
248 elseif c == "char_given" or c == "math_given" or c == "xmath_given" then
249 r = r + 1 ; result[r] = getmode(t)
250 elseif c == "last_item" then
251 local n = getcsname(t)
252 if n then
253 local s = gettex(n)
254 if s then
255 r = r + 1 ; result[r] = s
256 else
257 unexpected(c)
258 end
259 else
260 unexpected(c)
261 end
262 elseif c == "call" then
263 local n = getcsname(t)
264 if n then
265 local s = getmacro(n)
266 if s then
267 r = r + 1 ; result[r] = s
268 else
269 unexpected(c)
270 end
271 else
272 unexpected(c)
273 end
274 elseif c == "the" or c == "convert" or c == "lua_expandable_call" then
275 putnext(t)
276 scantoken()
277 else
278 unexpected(c)
279 end
280 end
281 end
282 local code = concat(result,"",1,r)
283 local func = load(code)
284 if type(func) == "function" then
285 context(func())
286 else
287 report("invalid lua %a",code)
288 end
289 end
290
291 implement {
292 public = true,
293 name = "expression",
294 actions = expression,
295 }
296
297end
298 |