1
2
3
4
5\usemodule[presentboring,abbreviationslogos]
6
7\startdocument
8 [title={IMPLEMENTERS},
9 banner={an old feature still evolving},
10 location={context\enspace {\bf 2020}\enspace meeting}]
11
12\starttitle[title=Interfacing with \LUA]
13
14\startitemize
15
16\startitem
17 Quite some activity is delegated to \LUA.
18\stopitem
19\startitem
20 Normally the initiative is at the \TEX\ end.
21\stopitem
22\startitem
23 We can set variables or call functions etc.
24\stopitem
25\startitem
26 We can parameters to function calls.
27\stopitem
28\startitem
29 From the \LUA\ end we can use scanners to pick up data.
30\stopitem
31\startitem
32 We provide some consistent interfaces for doing all that.
33\stopitem
34\startitem
35 From \TEX\ to \LUA\ we use \type {\ctxlua{...}} and friends.
36\stopitem
37\startitem
38 From \LUA\ to \TEX\ we use \type {context(...)} and alike.
39\stopitem
40\startitem
41 For adding functionality we use so called implementers.
42\stopitem
43
44\stopitemize
45
46\stoptitle
47
48\starttitle[title=Calling \LUA]
49
50\startbuffer
51\ctxlua{context("ok")}
52\stopbuffer
53
54\typebuffer \getbuffer
55
56\startbuffer
57\ctxlua{context(2 * tokens.scanners.integer())} 10
58\stopbuffer
59
60\typebuffer \getbuffer
61
62\startbuffer
63\startluacode
64function document.MyThing() context(2 * tokens.scanners.integer()) end
65\stopluacode
66\stopbuffer
67
68\typebuffer \getbuffer
69
70\startbuffer
71\ctxlua{document.MyThing()} 20 \quad
72\ctxlua{document.MyThing()} 30 \quad
73\ctxlua{document.MyThing()} 40
74\stopbuffer
75
76\typebuffer \getbuffer
77
78\stoptitle
79
80\starttitle[title=Streamlining \LUA]
81
82\startbuffer
83\startluacode
84interfaces.implement {
85 name = "MyThing",
86 public = true,
87 arguments = "integer",
88 actions = function(i) context(i * 2) end,
89
90}
91\stopluacode
92\stopbuffer
93
94\typebuffer \getbuffer
95
96\startbuffer
97\MyThing 20 \quad \MyThing 30 \quad \MyThing 40
98\stopbuffer
99
100\typebuffer \getbuffer
101
102\stoptitle
103
104\starttitle[title=Making commands]
105
106\startbuffer
107\startluacode
108interfaces.implement {
109 name = "MyRoot",
110 public = true,
111 actions = function()
112 local a = tokens.scanners.integer()
113 if not tokens.scanners.keyword("of") then
114
115 end
116 local b = tokens.scanners.integer()
117 context("%0.6N",math.sqrt(b,a))
118 end,
119}
120\stopluacode
121\stopbuffer
122
123\typebuffer \getbuffer
124
125\startbuffer
126\MyRoot 2 of 40 \quad \MyRoot 3 60
127\stopbuffer
128
129\typebuffer \getbuffer
130
131\stoptitle
132
133\starttitle[title=Scanners]
134
135There are lots of scanners: \blank
136
137\startalign[flushleft,broad] \tttf
138 \cldcontext { table.concat ( table.sortedkeys (tokens.scanners), " " ) }
139\stopalign
140
141\stoptitle
142
143\starttitle[title=A more complex example]
144
145Lets implement a matcher: \blank
146
147\startbuffer
148\doloopovermatch {(.)} {luametatex} { [#1] }
149\stopbuffer
150
151\typebuffer \getbuffer
152
153\startbuffer
154\doloopovermatch {([\letterpercent w])} {\cldloadfile{tufte.tex}} { [#1] }
155\stopbuffer
156
157\typebuffer \getbuffer
158
159\stoptitle
160
161\starttitle[title=A more complex example (\TEX)]
162
163Here is the macro definition of this loop: \blank
164
165\starttyping
166\protected\def\doloopovermatch#1#2#3
167 {\pushmacro\matchloopcommand
168 \def\matchloopcommand##1##2##3##4##5##6##7##8##9{#3}
169 \ctxluamatch\matchloopcommand{#1}{#2}
170 \popmacro\matchloopcommand}
171\stoptyping
172
173\startitemize
174
175\startitem The pushing and popping makes it possible to nest this macro. \stopitem
176\startitem The definition of the internal match macro permits argument references. \stopitem
177
178\stopitemize
179
180\stoptitle
181
182\starttitle[title=A more complex example (\LUA)]
183
184At the \LUA\ end we use an implementer: \blank
185
186\starttyping[style=\small\tt]
187local escape = function(s) return "\\" .. string.byte(s) end
188
189interfaces.implement {
190 name = "ctxluamatch",
191 public = true,
192 usage = "value",
193 actions = function()
194 local command = context[tokens.scanners.csname()]
195 local pattern = string.gsub(tokens.scanners.string(),"\\.",escape)
196 local input = string.gsub(tokens.scanners.string(),"\\.",escape)
197 for a, b, c, d, e, f, g, h, i in string.gmatch(input,pattern) do
198 command(a, b or "", c or "", d or "", e or "", f or "", g or "",
199 h or "", i or "")
200 end
201 return tokens.values.none
202 end,
203}
204\stoptyping
205
206So what does the \type {usage} key tells the implementer?
207
208\stoptitle
209
210\starttitle[title=Value functions]
211
212Normally we pipe back verbose strings that are interpreted as if they were
213files. Value functions are different;
214
215\startitemize
216
217\startitem
218 The return value indicates what gets fed back in the input.
219\stopitem
220\startitem
221 This can be: \cldcontext { table.concat(token.getfunctionvalues(), ", ", 0) }.
222\stopitem
223\startitem
224 When possible an efficient token is injected.
225\stopitem
226\startitem
227 Value function can check if they are supposed to feed back a value.
228\stopitem
229\startitem
230 So, they can be used as setters and getters.
231\stopitem
232\startitem
233 A variant is a function that is seen as conditional.
234\stopitem
235\startitem
236 In (simple) tracing they are presented as primitives.
237\stopitem
238\startitem
239 They are protected against user overload (aka: frozen).
240\stopitem
241\startitem
242 All this is experimental and might evolve.
243\stopitem
244
245\stopitemize
246
247\stoptitle
248
249\starttitle[title=So, lets step up a level]
250
251Say that we want an expandable command:
252
253\startbuffer
254\edef\foo{\doloopovermatched{.}{123}{(#1)}} \meaning\foo
255\stopbuffer
256
257\typebuffer \blank \getbuffer \blank
258
259Or nested:
260
261\startbuffer
262\edef\foo {
263 \doloopovermatched {(..)} {123456} {
264 \doloopovermatched {(.)(.)} {#1} {
265 [##1][##2]
266 }
267 }
268} \meaning\foo
269\stopbuffer
270
271\typebuffer \blank \getbuffer \blank
272
273\stoptitle
274
275\starttitle[title=So, lets step up a level]
276
277Compare:
278
279\starttyping[style=\small\tt]
280\protected\def\doloopovermatch#1#2#3
281 {\pushmacro\matchloopcommand
282 \def\matchloopcommand##1##2##3##4##5##6##7##8##9{#3}
283 \ctxluamatch\matchloopcommand{#1}{#2}
284 \popmacro\matchloopcommand}
285\stoptyping
286
287With:
288
289\starttyping[style=\small\tt]
290\def\doloopovermatched#1#2#3
291 {\beginlocalcontrol
292 \pushmacro\matchloopcommand
293 \def\matchloopcommand##1##2##3##4##5##6##7##8##9{#3}
294 \endlocalcontrol
295 \the\ctxluamatch\matchloopcommand{#1}{#2}
296 \beginlocalcontrol
297 \popmacro\matchloopcommand
298 \endlocalcontrol}
299\stoptyping
300
301Local control hides the assignments (it basically nests the mail loop).
302
303\stoptitle
304
305\starttitle[title=A few teasers (\TEX)]
306
307\starttyping[style=\small\tt]
308\doloopovermatch {(\letterpercent d)} {this 1 is 22 a 333 test} { [#1] }
309
310\doloopovermatch {(\letterpercent w) *(\letterpercent w*)} {aa bb cc dd} {
311 [
312 \doloopovermatch{(\letterpercent w)(\letterpercent w)} {#1} {(##1 ##2)}
313 \doloopovermatch{(\letterpercent w)(\letterpercent w)} {#2} {(##1 ##2)}
314 ]
315}
316
317\doloopovermatch
318 {(.)\letterpercent{\bf (.)\letterpercent}(.*)}
319 {this is {\bf a} test}
320 {#1{\it not #2}#3}
321\stoptyping
322
323\stoptitle
324
325\starttitle[title=A few teasers (\LUA)]
326
327\starttyping[style=\small\tt]
328interfaces.implement {
329 name = "bitwisexor", public = true, usage = "value", actions =
330 function(what)
331 local a = tokens.scanners.cardinal()
332 scankeyword("with")
333 local b = tokens.scanners.cardinal()
334 if what == "value" then
335 return tokens.values.cardinal, a b
336 else
337 logs.texerrormessage("you cant use \\bitwiseor this way")
338 end
339 end
340}
341interfaces.implement {
342 name = "ifbitwiseand", public = true, usage = "condition", actions =
343 function(what)
344 local a = tokens.scanners.cardinal()
345 local b = tokens.scanners.cardinal()
346 return tokens.values.boolean, (a b) = 0
347 end
348}
349\stoptyping
350
351\stoptitle
352
353\starttitle[title=Questions and more examples]
354
355More examples will be given in the editor.
356
357\stoptitle
358
359\stopdocument
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381 |