1
2
3\environment luametatexstyle
4
5\startdocument[title=Libraries]
6
7\startsection[title={Introduction}]
8
9The engines has quite some libraries built in of which some are discussed in
10dedicated chapters. Not all libraries will be detailed here, for instance, so
11called optional libraries depend on system libraries and usage is wrapped in
12modules because we delegate as much as possible to \LUA.
13
14\stopsection
15
16\startsection[title={Third party}]
17
18There is not much to tell here other than it depends on the \LUA\ symbols being
19visible and the \LUA\ version matching. We dont use this in \CONTEXT\ and have a
20different mechanism instead: optional libraries.
21
22\stopsection
23
24\startsection[title={Core}]
25
26The core libraries are those that interface with \TEX\ and \METAPOST, these are
27discussed in dedicated chapters:
28
29\starttabulate[lTl]
30\FL
31\BC chapter \BC library \NC \NR
32\TL
33\NC \LUA \NC lua luac \NC \NR
34\NC \TEX \NC status tex texio \NC \NR
35\NC \METAPOST \NC mp \NC \NR
36\NC Nodes \NC node \NC \NR
37\NC Tokens \NC token \NC \NR
38\NC Callbacks \NC callback \NC \NR
39\NC Fonts \NC font \NC \NR
40\NC Languages \NC language \NC \NR
41\NC Libraries \NC library \NC \NR
42\LL
43\stoptabulate
44
45Some, like \type {node}, \type {token} and \type {tex} provide a lot of functions
46but most are used in more higher level \CONTEXT\ specific functions and
47interfaces. This means that in the code you will more often font \type {nodes}
48and \type {tokens} being used as well as functions that the macro package adds to
49the various builtin libraries.
50
51\stopsection
52
53\startsection[title={Auxiliary}]
54
55\startsubsection[title=Extensions]
56
57These are the libraries that are needed to implement various subsystems, like for
58instance the backend and image inclusion. Although much can be done in pure \LUA\
59for performance reasons helpers make sense. However, we try to minimize this,
60which means that for instance the \type {zip} library provides what we need for
61(de)compressing for instance \PDF\ streams but that unzipping files is done with
62\LUA\ code wrapped around the core zip routines. The same is true for \PNG\
63inclusion: all that was done in pure \LUA\ but a few critical helpers were
64translated to \CCODE.
65
66Some libraries extend existing ones, like for instance \type {file}, \type {io}
67and \type {os} and \type {string}.
68
69\stopsubsection
70
71\startsubsection[title=Extra file helpers]
72
73The original \type {lfs} module has been adapted a bit to our needs but for
74practical reasons we kept the namespace. In \LUAMETATEX\ we operate in \UTF8
75so for \MSWINDOWS\ system interfaces we convert from and to \UNICODE16.
76
77The \type {attributes} checker returns a table with details.
78
79\starttyping[option=LUA]
80function lfs.attributes ( <t:string> name )
81 return <t:table> details
82end
83\stoptyping
84
85The table has the following fields:
86
87\starttabulate[T]
88\FL
89\BC field \BC type \BC meaning \NC \NR
90\TL
91\NC \type {mode} \NC string \NC \type{file} \type{directory} \type{link} \type{other} \NC \NR
92\NC \type {size} \NC integer \NC bytes \NC \NR
93\NC \type {modification} \NC integer \NC time \NC \NR
94\NC \type {access} \NC integer \NC time \NC \NR
95\NC \type {change} \NC integer \NC time \NC \NR
96\NC \type {permissions} \NC string \NC \type {rwxrwxrwx} \NC \NR
97\NC \type {nlink} \NC integer \NC number of links \NC \NR
98\LL
99\stoptabulate
100
101If youre not interested in details, then the next calls are more efficient:
102
103\starttyping[option=LUA]
104function lfs.isdir ( <t:string> name ) return <t:boolean> end
105function lfs.isfile ( <t:string> name ) return <t:boolean> end
106function lfs.iswriteabledir ( <t:string> name ) return <t:boolean> end
107function lfs.iswriteablefile ( <t:string> name ) return <t:boolean> end
108function lfs.isreadabledir ( <t:string> name ) return <t:boolean> end
109function lfs.isreadablefile ( <t:string> name ) return <t:boolean> end
110\stoptyping
111
112The current (working) directory is fetch with:
113
114\starttyping[option=LUA]
115function lfs.currentdir ( )
116 return <t:string> directory
117end
118\stoptyping
119
120These three return \type {true} is the action was a success:
121
122\starttyping[option=LUA]
123function lfs.chdir ( <t:string> name ) return <t:boolean> end
124function lfs.mkdir ( <t:string> name ) return <t:boolean> end
125function lfs.rmdir ( <t:string> name ) return <t:boolean> end
126\stoptyping
127
128Here the second and third argument are optional:
129
130\starttyping[option=LUA]
131function lfs.touch (
132 <t:string> name,
133 <t:integer> accesstime,
134 <t:integer> modificationtime
135)
136 return <t:boolean> success
137end
138\stoptyping
139
140The \type {dir} function is a traverser which in addition to the name returns
141some more properties. Keep in mind that the traverser loops over a directory and
142that it doesnt run well when used nested. This is a side effect of the operating
143system. It is also the reason why we return some properties because querying them
144via \type {attributes} would interfere badly. The directory iterator has two
145variants:
146
147\starttyping[option=LUA]
148for
149 <t:string> name,
150 <t:string> mode
151in lfs.dir (
152 <t:string> name
153)
154 actions
155end
156\stoptyping
157
158This one provides more details:
159
160\starttyping[option=LUA]
161for
162 <t:string> name,
163 <t:string> mode,
164 <t:integer> size,
165 <t:integer> mtime
166in lfs.dir (
167 <t:string> name,
168 <t:true>
169)
170 actions
171end
172\stoptyping
173
174Here the boolean indicates if we want a symlink (\type {true}) or hard link
175(\type {false}).
176
177\starttyping[option=LUA]
178function lfs.link (
179 <t:string> source,
180 <t:string> target,
181 <t:boolean> symlink
182)
183 return <t:boolean> success
184end
185\stoptyping
186
187The next one is sort of redundant but explicit:
188
189\starttyping[option=LUA]
190function lfs.symlink (
191 <t:string> source,
192 <t:string> target,
193)
194 return <t:boolean> success
195end
196\stoptyping
197
198Helpers like these are a bit operating system and user permission dependent:
199
200\starttyping[option=LUA]
201function lfs.setexecutable ( <t:string> name )
202 return <t:boolean> success
203end
204\stoptyping
205
206\starttyping[option=LUA]
207function lfs.symlinktarget ( <t:string> name )
208 return <t:string> target
209end
210\stoptyping
211
212\stopsubsection
213
214\startsubsection[title=Reading from a file]
215
216Because we load fonts in \LUA\ and because these are binary files we have some
217helpers that can read integers of various kind and some more. Originally we did
218this in pure \LUA, which actually didnt perform that bad but this is of course
219more efficient.
220
221We have readers for signed and unsigned, little and big endian. All return a (64
222bit) \LUA\ integer.
223
224\starttyping[option=LUA]
225function fio.readcardinal1 ( <t:file> handle ) return <t:integer> end
226function fio.readcardinal2 ( <t:file> handle ) return <t:integer> end
227function fio.readcardinal3 ( <t:file> handle ) return <t:integer> end
228function fio.readcardinal4 ( <t:file> handle ) return <t:integer> end
229
230function fio.readcardinal1le ( <t:file> handle ) return <t:integer> end
231function fio.readcardinal2le ( <t:file> handle ) return <t:integer> end
232function fio.readcardinal3le ( <t:file> handle ) return <t:integer> end
233function fio.readcardinal4le ( <t:file> handle ) return <t:integer> end
234
235function fio.readinteger1 ( <t:file> handle ) return <t:integer> end
236function fio.readinteger2 ( <t:file> handle ) return <t:integer> end
237function fio.readinteger3 ( <t:file> handle ) return <t:integer> end
238function fio.readinteger4 ( <t:file> handle ) return <t:integer> end
239
240function fio.readinteger1le ( <t:file> handle ) return <t:integer> end
241function fio.readinteger2le ( <t:file> handle ) return <t:integer> end
242function fio.readinteger3le ( <t:file> handle ) return <t:integer> end
243function fio.readinteger4le ( <t:file> handle ) return <t:integer> end
244\stoptyping
245
246These float readers are rather specific for fonts:
247
248\starttyping[option=LUA]
249function fio.readfixed2 ( <t:file> handle ) return <t:number> end
250function fio.readfixed4 ( <t:file> handle ) return <t:number> end
251function fio.read2dot14 ( <t:file> handle ) return <t:number> end
252\stoptyping
253
254Of these two the first reads a line and the second a string the \CCODE\ way, so
255ending with a newline and null character:
256
257\starttyping[option=LUA]
258function fio.readcline ( <t:file> handle ) return <t:string> end
259function fio.readcstring ( <t:file> handle ) return <t:string> end
260\stoptyping
261
262The next set of readers reads multiple integers in one call:
263
264\starttyping[option=LUA]
265function fio.readbytes (
266 <t:file> handle
267)
268 return <t:integer> one or more
269end
270\stoptyping
271
272\starttyping[option=LUA]
273function fio.readintegertable (
274 <t:file> handle,
275 <t:integer> size,
276 <t:integer> bytes
277)
278 return <t:table>
279end
280
281function fio.readcardinaltable (
282 <t:file> handle,
283 <t:integer> size,
284 <t:integer> bytes
285)
286 return <t:table>
287end
288
289function fio.readbytetable (
290 <t:file> handle
291)
292 return <t:table>
293end
294\stoptyping
295
296In case we need a random access the following have to be used:
297
298\starttyping[option=LUA]
299function fio.setposition ( <t:file> handle, <t:integer> ) return <t:integer> end
300function fio.getposition ( <t:file> handle ) return <t:integer> end
301function fio.skipposition ( <t:file> handle, <t:integer> ) return <t:integer> end
302\stoptyping
303
304The library also provide a few writers:
305
306\starttyping[option=LUA]
307function fio.writecardinal1 ( <t:file> handle, <t:integer> value ) end
308function fio.writecardinal2 ( <t:file> handle, <t:integer> value ) end
309function fio.writecardinal3 ( <t:file> handle, <t:integer> value ) end
310function fio.writecardinal4 ( <t:file> handle, <t:integer> value ) end
311
312function fio.writecardinal1le ( <t:file> handle, <t:integer> value ) end
313function fio.writecardinal2le ( <t:file> handle, <t:integer> value ) end
314function fio.writecardinal3le ( <t:file> handle, <t:integer> value ) end
315function fio.writecardinal4le ( <t:file> handle, <t:integer> value ) end
316\stoptyping
317
318\stopsubsection
319
320\startsubsection[title=Reading from a string]
321
322These readers take a string and position. We could have used a userdata approach
323but it saves little. (Nowadays we can more easily store the position with the
324userdata so maybe some day \unknown).
325
326\starttyping[option=LUA]
327function sio.readcardinal1 ( <t:string> s, <t:integer> p ) return <t:integer> end
328function sio.readcardinal2 ( <t:string> s, <t:integer> p ) return <t:integer> end
329function sio.readcardinal3 ( <t:string> s, <t:integer> p ) return <t:integer> end
330function sio.readcardinal4 ( <t:string> s, <t:integer> p ) return <t:integer> end
331
332function sio.readcardinal1le ( <t:string> s, <t:integer> p ) return <t:integer> end
333function sio.readcardinal2le ( <t:string> s, <t:integer> p ) return <t:integer> end
334function sio.readcardinal3le ( <t:string> s, <t:integer> p ) return <t:integer> end
335function sio.readcardinal4le ( <t:string> s, <t:integer> p ) return <t:integer> end
336
337function sio.readinteger1 ( <t:string> s, <t:integer> p ) return <t:integer> end
338function sio.readinteger2 ( <t:string> s, <t:integer> p ) return <t:integer> end
339function sio.readinteger3 ( <t:string> s, <t:integer> p ) return <t:integer> end
340function sio.readinteger4 ( <t:string> s, <t:integer> p ) return <t:integer> end
341
342function sio.readinteger1le ( <t:string> s, <t:integer> p ) return <t:integer> end
343function sio.readinteger2le ( <t:string> s, <t:integer> p ) return <t:integer> end
344function sio.readinteger3le ( <t:string> s, <t:integer> p ) return <t:integer> end
345function sio.readinteger4le ( <t:string> s, <t:integer> p ) return <t:integer> end
346\stoptyping
347
348Here are the (handy for fonts) float readers:
349
350\starttyping[option=LUA]
351function sio.readfixed2 ( <t:string> s, <t:integer> p ) return <t:number> end
352function sio.readfixed4 ( <t:string> s, <t:integer> p ) return <t:number> end
353function sio.read2dot14 ( <t:string> s, <t:integer> p ) return <t:number> end
354\stoptyping
355
356A \CCODE\ line (terminated by a newline) and string (terminated by null) are read
357by:
358
359\starttyping[option=LUA]
360function sio.readcline ( <t:string> s, <t:integer> p ) return <t:string> end
361function sio.readcstring ( <t:string> s, <t:integer> p ) return <t:string> end
362\stoptyping
363
364\starttyping[option=LUA]
365function sio.readbytes (
366 <t:string> str,
367 <t:integer> pos
368)
369 return <t:integer> one or more
370end
371\stoptyping
372
373\starttyping[option=LUA]
374function sio.readintegertable (
375 <t:string> str,
376 <t:integer> pos,
377 <t:integer> size,
378 <t:integer> bytes
379)
380 return <t:table>
381end
382
383function sio.readcardinaltable (
384 <t:string> str,
385 <t:integer> pos,
386 <t:integer> size,
387 <t:integer> bytes
388)
389 return <t:table>
390end
391
392function sio.readbytetable (
393 <t:string> str,
394 <t:integer> pos
395)
396 return <t:table>
397end
398\stoptyping
399
400Here are a few straightforward converters:
401
402\starttyping[option=LUA]
403function sio.tocardinal1 ( <t:string> ) return <t:integer> end
404function sio.tocardinal2 ( <t:string> ) return <t:integer> end
405function sio.tocardinal3 ( <t:string> ) return <t:integer> end
406function sio.tocardinal4 ( <t:string> ) return <t:integer> end
407
408function sio.tocardinal1le ( <t:string> ) return <t:integer> end
409function sio.tocardinal2le ( <t:string> ) return <t:integer> end
410function sio.tocardinal3le ( <t:string> ) return <t:integer> end
411function sio.tocardinal4le ( <t:string> ) return <t:integer> end
412\stoptyping
413
414\stopsubsection
415
416\startsubsection[title=Extra file helpers]
417
418This function gobble characters upto a newline. When characters are gobbled.
419\type {true} is returned when we end up at a newline or when something is gobbled
420before the file ends, other wise we get \type {false}. A \type {nil} return value
421indicates a bad handle.
422
423\starttyping[option=LUA]
424function io.gobble( <t:file> )
425 return <t:boolean> <t:nil>
426end
427\stoptyping
428
429Function like type {io.open} \type {io.popen} are patched to support files on
430\MSWINDOWS\ that use wide \UNICODE.
431
432\stopsubsection
433
434\startsubsection[title=Extra operating system helpers]
435
436The \type {os} library has a few extra functions and variables so for complete
437overview you need to look in the \LUA\ manual.
438
439We can sleep for the given number of seconds. When the optional \type {units}
440arguments is (for instance) 1000 we assume milliseconds.
441
442\starttyping[option=LUA]
443function os.sleep (
444 <t:integer> seconds,
445 <t:integers> units
446)
447 no return values
448end
449\stoptyping
450
451The \type {os.uname} function returns a table with specific operating system
452information acquired at runtime. The fields in the returned table are:
453\showenginekeylist {os.getunamefields()}.
454
455\starttyping[option=LUA]
456function os.uname ( )
457 return <t:table>
458\stoptyping
459
460The \type {os.gettimeofday} function returns the current \quote {\UNIX\ time},
461but as a float. Keep in mind that there might be platforms where this function is
462not available.
463
464\starttyping[option=LUA]
465function os.gettimeofday ( )
466 return <t:number>
467end
468\stoptyping
469
470When we execute a command the return code is returned. Interpretation is up to
471the caller.
472
473\starttyping[option=LUA]
474function os.execute ( <t:string> )
475 return <t:integer> return code
476end
477\stoptyping
478
479This one enable interpreting \ANSI\ escape sequences in the console. It is only
480implemented for \MSWINDOWS. In \CONTEXT\ you can run with \type {ansi}.
481
482\starttyping[option=LUA]
483function os.enableansi ( )
484 return <t:boolean>
485end
486\stoptyping
487
488This one only returns something useful for \MSWINDOWS. One can of course just set
489your the system for \UTF8. Its just a reporter meant for debugging issues.
490
491\starttyping[option=LUA]
492function os.getcodepage ( )
493 return
494 <t:integer> oemcodepage,
495 <t:integer> applicationcodepage
496end
497\stoptyping
498
499The \type {os.setenv} function sets a variable in the environment. Passing
500\type {nil} instead of a value string will remove the variable.
501
502\starttyping[option=LUA]
503function os.setenv (
504 <t:string> key,
505 <t:string> value
506)
507 no return values
508end
509\stoptyping
510
511The possible values of \type {os.type} are: \showenginekeylist
512{os.gettypevalues()}.
513
514\starttyping[option=LUA]
515local currenttype = os.type
516\stoptyping
517
518The \type {os.name} string gives a more precise indication of the operating
519system. The possible values are: \showenginekeylist {os.getnamevalues()}.
520
521\starttyping[option=LUA]
522local currentname = os.name
523\stoptyping
524
525On \MSWINDOWS\ the original \type {os.rename}, \type {os.remove} and \type
526{os.getenv} functions are replaced by variants that interface to and convert from
527\UNICODE16\ to \UTF8.
528
529\stopsubsection
530
531\startsubsection[title=Extra string helpers]
532
533The \type {string} library has gotten a couple of extra functions too, some of
534which are iterators. There are some \UNICODE\ related helpers too. When we
535started \LUA\ had no \UTF8 function, now it has a few, but we keep using our own,
536if only because they were there before. We also add plenty extra functions in the
537\type {string} name space at the \LUA\ end.
538
539This first function runs over a string and pick sup single characters:
540
541\starttyping[option=LUA]
542for <t:string> c in string.characters ( <t:string> s ) do
543 some action
544end
545\stoptyping
546
547\startbuffer
548\startluacode
549for c in string.characters("τεχ") do
550 context("[%02X]",string.byte(c))
551end
552\stopluacode
553\stopbuffer
554
555\typebuffer
556
557gives: \inlinebuffer.
558
559\starttyping[option=LUA]
560for <t:string> l, <t:string> r in string.characterpairs ( <t:string> s ) do
561 some action
562end
563\stoptyping
564
565\startbuffer
566\startluacode
567for l, r in string.characterpairs("τεχ") do
568 context("[%02X %02X]",string.byte(l),string.byte(r))
569end
570\stopluacode
571\stopbuffer
572
573\typebuffer
574
575gives: \inlinebuffer.
576
577\starttyping[option=LUA]
578for <t:string> c in string.utfcharacters( <t:string> s ) do
579 some action
580end
581\stoptyping
582
583\startbuffer
584\startluacode
585for c in string.utfcharacters("τεχ") do
586 context("[%s]",c)
587end
588\stopluacode
589\stopbuffer
590
591\typebuffer
592
593gives: \inlinebuffer.
594
595Instead of getting strings back we can also get integers.
596
597\starttyping[option=LUA]
598for <t:integer> c in string.bytes ( <t:string> s ) do
599 some action
600end
601\stoptyping
602
603\startbuffer
604\startluacode
605for b in string.bytes("τεχ") do
606 context("[%02X]",b)
607end
608\stopluacode
609\stopbuffer
610
611\typebuffer
612
613gives: \inlinebuffer.
614
615\starttyping[option=LUA]
616for <t:integer> l, <t:integer> r in string.bytepairs ( <t:string> s ) do
617 some action
618end
619\stoptyping
620
621\startbuffer
622\startluacode
623for l, r in string.bytepairs("τεχ") do
624 context("[%02X %02X]",l,r)
625end
626\stopluacode
627\stopbuffer
628
629\typebuffer
630
631gives: \inlinebuffer.
632
633\starttyping[option=LUA]
634for <t:integer> u in string.utfvalues( <t:string> s ) do
635 some action
636end
637\stoptyping
638
639\startbuffer
640\startluacode
641for c in string.utfvalues("τεχ") do
642 context("[%U]",c)
643end
644\stopluacode
645\stopbuffer
646
647\typebuffer
648
649gives: \inlinebuffer.
650
651The \type {bytetable} function splits a string in bytes.
652
653\starttyping[option=LUA]
654function string.bytetable ( <s:string> s) do
655 return <t:table> with bytes
656end
657\stoptyping
658
659Here is a line splitter:
660
661\starttyping[option=LUA]
662function string.linetable ( <s:string> s) do
663 return <t:table> with lines
664end
665\stoptyping
666
667This one converts an integer (code point) into an \UTF\ string:
668
669\starttyping[option=LUA]
670function string.utfcharacter ( <t:string> s )
671 return <t:string>
672end
673\stoptyping
674
675We also have a variant that takes a table. The table can have integers, strings,
676and subtables.
677
678\starttyping[option=LUA]
679function string.utfcharacter ( <t:table> s )
680 return <t:string>
681end
682\stoptyping
683
684This an \UTF8\ variant of \type {string.byte} and it returns the code points of
685the split on the stack.
686
687\starttyping[option=LUA]
688function string.utfvalue ( <t:string> s )
689 return <t:integer> zero or more
690end
691\stoptyping
692
693Instead of a list on the stack you can get a table:
694
695\starttyping[option=LUA]
696function string.utfvaluetable ( <t:string> s )
697 return <t:table> indexed
698end
699\stoptyping
700
701The name says it all:
702
703\starttyping[option=LUA]
704function string.utflength ( <tr:string> s )
705 return <t:integer>
706end
707\stoptyping
708
709Here we split a string in characters that are collected in an indexed table:
710
711\starttyping[option=LUA]
712function string.utfcharactertable ( <t:string> s )
713 return <t:table> indexed
714end
715\stoptyping
716
717In \CONTEXT\ we mostly use \type {string.formatters} which is often more
718efficient then \type {string.format} and also has additional formatting options,
719one being for instance \type {N} which is like \type {f} but strips trailing zero
720and returns efficient zeros and ones. Here is a similar low level formatter:
721
722\starttyping[option=LUA]
723function string.f6 ( <t:number> n )
724 return <t:string>
725end
726
727function string.f6 ( <t:number> n, <t:string> f )
728 return <t:string>
729end
730\stoptyping
731
732In the first case it returns a string with at most 6 digits while the second one
733uses given format but tail strips the result.
734
735\starttyping[option=LUA]
736function string.tounicode16 ( <t:integer> code ) return <t:string> end
737\stoptyping
738
739\starttyping[option=LUA]
740function string.toutf8 ( <t:table> codes ) return <t:string> end
741 string.toutf16 ( <t:table> codes ) return <t:string> end
742function string.toutf32 ( <t:table> codes ) return <t:string> end
743\stoptyping
744
745The next one has quite some variation in calling:
746
747\starttyping[option=LUA]
748function string.utf16toutf8 ( <t:string> str, <t:true> )
749 return <t:string> big endian
750end
751\stoptyping
752
753\starttyping[option=LUA]
754function string.utf16toutf8 ( <t:string> str, <t:false> )
755 return <t:string> little endian
756end
757\stoptyping
758
759\starttyping[option=LUA]
760function string.utf16toutf8 ( <t:string> str, <t:nil>, <t:true> )
761 return <t:string> check bom, default to big endian
762end
763\stoptyping
764
765\starttyping[option=LUA]
766function string.utf16toutf8 ( <t:string> str, <t:nil>, <t:false> )
767 return <t:string> end check bom, default to little endian
768end
769\stoptyping
770
771\starttyping[option=LUA]
772function string.utf16toutf8 ( <t:string> str, <t:nil>, <t:nil> )
773 return <t:string> end check bom, default to little endian
774end
775\stoptyping
776
777The next packer is used for creating bitmaps:
778
779\starttyping[option=LUA]
780function string.packrowscolumns ( <t:table> data )
781 return <t:string>
782end
783\stoptyping
784
785\startbuffer
786\startluacode
787local t = {
788 { 65, 66, 67 },
789 { 68, 69, 70 },
790}
791context(string.packrowscolumns(t))
792\stopluacode
793\stopbuffer
794
795For example:
796
797\typebuffer
798
799gives: \inlinebuffer
800
801\startbuffer
802\startluacode
803local t = {
804 { { 114, 103, 98 }, { 114, 103, 98 } },
805 { { 114, 103, 98 }, { 114, 103, 98 } },
806}
807
808context(string.packrowscolumns(t))
809\stopluacode
810\stopbuffer
811
812While:
813
814\typebuffer
815
816gives: \inlinebuffer
817
818A string with hexadecimals can be converted with the following. Spaces are
819ignored. We use this for instance in the \METAPOST\ potrace interface to
820permits nice input.
821
822\starttyping[option=LUA]
823function string.hextocharacters ( <t:string> data )
824 return <t:string>
825end
826\stoptyping
827
828\startbuffer
829\startluacode
830local t = [[
831 414243 44 4546 47
832 414243 44 4546 47
833]]
834
835context(string.hextocharacters(t))
836\stopluacode
837\stopbuffer
838
839So:
840
841\typebuffer
842
843gives: \inlinebuffer
844
845These take strings and return integers:
846
847\starttyping[option=LUA]
848function string.octtointeger ( <t:string> octstr ) return <t:integer> end
849function string.dectointeger ( <t:string> decstr ) return <t:integer> end
850function string.hextointeger ( <t:string> hexstr ) return <t:integer> end
851function string.chrtointeger ( <t:string> chrstr ) return <t:integer> end
852\stoptyping
853
854\stopsubsection
855
856\startsubsection[title=Extra table helpers]
857
858This returns the keys of the given table:
859
860\starttyping[option=LUA]
861function table.getkeys ( < t:table> )
862 return <t:table>
863end
864\stoptyping
865
866\stopsubsection
867
868\startsubsection[title=Byte encoding and decoding]
869
870We use some helpers from \type {pplib}.
871
872\starttyping[option=LUA]
873function basexx.encode16 ( <t:string> str, <t:boolean> newline )
874 return <t:string>
875end
876function basexx.encode64 ( <t:string> str, <t:boolean> newline )
877 return <t:string>
878end
879function basexx.encode85 ( <t:string> str, <t:boolean> newline )
880 return <t:string>
881end
882
883function basexx.decode16 ( <t:string> str ) return <t:string> end
884function basexx.decode64 ( <t:string> str ) return <t:string> end
885function basexx.decode85 ( <t:string> str ) return <t:string> end
886
887function basexx.encodeRL ( <t:string> str ) return <t:string> end
888function basexx.decodeRL ( <t:string> str ) return <t:string> end
889
890function basexx.encodeLZW ( <t:string> str ) return <t:string> end
891function basexx.decodeLZW ( <t:string> str ) return <t:string> end
892\stoptyping
893
894The last two functions accept an optional bitset with coder flags that we leave
895for the user to ponder about. The \type {newline} directive in the first three is
896optional.
897
898\stopsubsection
899
900\startsubsection[title=\PNG\ decoding]
901
902These function started out as pure \LUA\ functions (extrapolated from the
903descriptions in the standard) but eventually became library helpers. It is
904worth noticing that \PDF\ supports \JPEG\ directly so there we can just use
905\LUA\ to interpret the file and pass relevant data. Support for \PNG\ is
906actually just support for \PNG\ compression, so there we need to do more
907work and filter the content:
908
909\starttyping[option=LUA]
910function decode.applyfilter (
911 <t:string> data,
912 <t:integer> nx,
913 <t:integer> ny,
914 <t:integer> slice
915)
916 return <t:string>
917end
918\stoptyping
919
920We also need to split off the mask as ie becomes a separate object:
921
922\starttyping[option=LUA]
923function decode.splitmask (
924 <t:string> data,
925 <t:integer> nx,
926 <t:integer> ny,
927 <t:integer> bpp,
928 <t:integer> bytes
929)
930 return
931 <t:string>, bitmap
932 <t:string> mask
933end
934\stoptyping
935
936If present we have to deinterlace:
937
938\starttyping[option=LUA]
939function decode.interlace (
940 <t:string> data,
941 <t:integer> nx,
942 <t:integer> ny,
943 <t:integer> slice,
944 <t:integer> pass
945)
946 return <t:string>
947end
948\stoptyping
949
950And maybe expand compressed:
951
952\starttyping[option=LUA]
953function decode.expand (
954 <t:string> data,
955 <t:integer> nx,
956 <t:integer> ny,
957 <t:integer> parts,
958 <t:integer> xline,
959 <t:integer> factor
960)
961 return <t:string>
962end
963\stoptyping
964
965These are just helpers that permit integration in the \CONTEXT\ graphic
966ecosystem (including \METAPOST):
967
968\starttyping[option=LUA]
969function decode.tocmyk ( <t:string data )
970 return <t:string>
971end
972\stoptyping
973
974For usage see the \CONTEXT\ sources.
975
976\starttyping[option=LUA]
977function decode.tomask (
978 <t:string> content,
979 <t:string> mapping,
980 <t:integer> xsize,
981 <t:integer> ysize,
982 <t:integer> colordepth
983)
984 return <t:string>
985end
986\stoptyping
987
988There are to variants:
989
990\starttyping[option=LUA]
991function decode.makemask (
992 <t:string> content,
993 <t:integer> mapping
994)
995 return <t:string>
996end
997
998function decode.makemask (
999 <t:string> content,
1000 <t:table> mapping
1001)
1002 return <t:string>
1003end
1004\stoptyping
1005
1006\stopsubsection
1007
1008\startsubsection[title=MD5 hashing]
1009
1010In the meantime we use some helpers from \type {pplib} because we have that
1011anyway. These are useful when we need a reasonable unique hash of limited length:
1012
1013\starttyping[option=LUA]
1014function md5.sum ( <t:string> ) return <t:string> end
1015function md5.hex ( <t:string> ) return <t:string> end
1016function md5.HEX ( <t:string> ) return <t:string> end
1017\stoptyping
1018
1019\startbuffer
1020\startluacode
1021context.type(md5.HEX("normally this is unique enough"))
1022\stopluacode
1023\stopbuffer
1024
1025Using a hexadecimal representation of the 16 byte calculated checksum is less
1026sensitive for escaping. This:
1027
1028\typebuffer
1029
1030gives: \inlinebuffer.
1031
1032\stopsubsection
1033
1034\startsubsection[title=SHA2 hashing]
1035
1036Because \type {pplib} comes with some SHA2 support we can borrow its helpers
1037instead of the \LUA\ code we used before (which was anyway fun to write).
1038
1039\starttyping[option=LUA]
1040function sha2.digest256 ( <t:string> data ) return <t:string> end
1041function sha2.digest384 ( <t:string> data ) return <t:string> end
1042function sha2.digest512 ( <t:string> data ) return <t:string> end
1043function sha2.sum256 ( <t:string> data ) return <t:string> end
1044function sha2.sum384 ( <t:string> data ) return <t:string> end
1045function sha2.sum512 ( <t:string> data ) return <t:string> end
1046function sha2.hex256 ( <t:string> data ) return <t:string> end
1047function sha2.hex384 ( <t:string> data ) return <t:string> end
1048function sha2.hex512 ( <t:string> data ) return <t:string> end
1049function sha2.HEX256 ( <t:string> data ) return <t:string> end
1050function sha2.HEX384 ( <t:string> data ) return <t:string> end
1051function sha2.HEX512 ( <t:string> data ) return <t:string> end
1052\stoptyping
1053
1054\startbuffer
1055\startluacode
1056context.type(sha2.HEX256("normally this is unique enough"))
1057\stopluacode
1058\stopbuffer
1059
1060The number refers to bytes, so with 256 we get a 32 byte hash that we show in
1061hexadecimal because that is less sensitive for escaping:
1062
1063\typebuffer
1064
1065gives: \inlinebuffer.
1066
1067\stopsubsection
1068
1069\startsubsection[title=AES encryption]
1070
1071In the next encryption functions the key should be 16, 24 or 32 bytes long.
1072
1073\starttyping[option=LUA]
1074function aes.encode (
1075 <t:string> data,
1076 <t:string> key
1077)
1078 return <t:string>
1079end
1080
1081function aes.decode (
1082 <t:string> data,
1083 <t:string> key
1084)
1085 return <t:string>
1086end
1087\stoptyping
1088
1089This returns a string. The default length is 16; the optional length is limited
1090to 32.
1091
1092\starttyping[option=LUA]
1093function aes.random ( <t:integer> length )
1094 return <t:string>
1095end
1096\stoptyping
1097
1098Here is an example:
1099
1100\startbuffer
1101\startluacode
1102context.type ( basexx.encode16 ( aes.encode (
1103 "normally this is unique enough",
1104 "The key of live!"
1105) ) )
1106\stopluacode
1107\stopbuffer
1108
1109\typebuffer
1110
1111This gives: \inlinebuffer, where we hexed the result because
1112it is unlikely to be valid \UTF8.
1113
1114\stopsubsection
1115
1116\startsubsection[title=ZIP (de)compression]
1117
1118We provide the minimum needed to support compression in the backend but even this
1119limited set makes it possible to implement a zip file compression utility which
1120is indeed what we do in \CONTEXT. We use \type {minizip} as codebase, without the
1121zip utility code. The meaning and application of the various arguments can be
1122found (and are better explained) on the internet.
1123
1124\starttyping[option=LUA]
1125function xzip.compress (
1126 <t:string> data,
1127 <t:integer> compresslevel,
1128 <t:integer> method,
1129 <t:integer> window,
1130 <t:integer> memory,
1131 <t:integer> strategy
1132)
1133 return <t:string>
1134end
1135
1136function xzip.compresssize (
1137 <t:string> data,
1138 <t:integer> buffersize,
1139 <t:integer> compresslevel,
1140 <t:integer> window
1141)
1142 return <t:string>
1143end
1144
1145function xzip.decompress (
1146 <t:string> data,
1147 <t:integer> window
1148)
1149 return <t:string>
1150end
1151
1152function xzip.decompresssize (
1153 <t:string> data,
1154 <t:integer> targetsize,
1155 <t:integer> window
1156)
1157 return <t:string>
1158end
1159
1160function xzip.adler32 (
1161 <t:string> buffer,
1162 <t:integer> checksum
1163)
1164 return <t:integer>
1165end
1166
1167function xzip.crc32 (
1168 <t:string> buffer,
1169 <t:integer> checksum
1170)
1171 return <t:integer>
1172end
1173\stoptyping
1174
1175\stopsubsection
1176
1177\startsubsection[title=Potrace]
1178
1179The excellent potrace manual explains everything about this library therefore
1180here we just show the interface. Possible fields in specification are:
1181\showenginekeylist {table.sortedkeys (potrace.getnewfields ())}
1182
1183\starttyping[option=LUA]
1184function potrace.new ( <t:table> specification )
1185 return <t:userdata> instance
1186end
1187\stoptyping
1188
1189
1190\starttyping[option=LUA]
1191function potrace.free ( <t:userdata> instance)
1192 no return values
1193end
1194\stoptyping
1195
1196The process is controlled by the specification: \showenginekeylist {table.sortedkeys
1197(potrace.getprocessfields ())}, where permitted policy values are \showenginekeylist
1198{potrace.getpolicyvalues()}.
1199
1200\starttyping[option=LUA]
1201function potrace.process ( <t:userdata> instance, <t:table> specification )
1202 return <t:boolean> success
1203end
1204\stoptyping
1205
1206Results are collected in a table that we can feed into \METAPOST, The table has
1207subtables per traced shape and these contain indexed tables with two (pair) or
1208six (curve) entries. There is a boolean \type {sign} field and an integer \type
1209{index} field. In the next function only the first argument is mandate.
1210
1211\starttyping[option=LUA]
1212function potrace.totable (
1213 <t:userdata> instance,
1214 <t:boolean> debug,
1215 <t:integer> first,
1216 <t:integer> last
1217)
1218 return <t:table>
1219end
1220\stoptyping
1221
1222\stopsubsection
1223
1224\startsubsection[title=Sparse hashes]
1225
1226The sparse library is just there because we use similar code to store all these
1227character related codes that way (\type {\lccode}) and such). The entries can be
12281 (\type {0xFF}), 2 (\type {0xFFFF}) or 4 (\type {0xFFFFFFFF}) bytes wide. When 0
1229is used as width then nibbles (\type {0xF}) are assumed.
1230
1231\starttyping[option=LUA]
1232function sparse.new (
1233 <t:integer> bytes,
1234 <t:integer> default
1235)
1236 return <t:userdata>
1237end
1238\stoptyping
1239
1240You set a value by index. Optionally there can be the \type {"global"} keyword
1241before the second argument.
1242
1243\starttyping[option=LUA]
1244function sparse.set (
1245 <t:userdata> instance,
1246 <t:integer> index,
1247 <t:integer> value
1248)
1249 return <t:integer>
1250end
1251\stoptyping
1252
1253We get back integers as that is what we store:
1254
1255\starttyping[option=LUA]
1256function sparse.get ( <t:userdata> instance ) return <t:integer> end
1257function sparse.min ( <t:userdata> instance ) return <t:integer> end
1258function sparse.max ( <t:userdata> instance ) return <t:integer> end
1259\stoptyping
1260
1261The range is fetched with:
1262
1263\starttyping[option=LUA]
1264function sparse.range ( <t:userdata> instance )
1265 return
1266 <t:integer>, min
1267 <t:integer> max
1268end
1269\stoptyping
1270
1271We can iterate over the hash:
1272
1273\starttyping[option=LUA]
1274for
1275 <t:integer> index,
1276 <t:integer> value
1277in sparse.traverse (
1278 <t:userdata> instance
1279) do
1280 actions
1281end
1282\stoptyping
1283
1284This is a somewhat strange one but it permits packing all values in a string.
1285Its another way to create bitmaps.
1286
1287\starttyping[option=LUA]
1288function sparse.concat (
1289 <t:userdata> instance
1290 <t:integer> min,
1291 <t:integer> max,
1292 <t:integer> how 0=byte, 1=lsb 2=msb
1293)
1294 return <t:string>
1295end
1296\stoptyping
1297
1298Setting values obeys grouping in \TEX, but we can restore any time:
1299
1300\starttyping[option=LUA]
1301function sparse.restore ( <t:userdata> instance )
1302 nothing to return
1303end
1304\stoptyping
1305
1306We can also wipe all values:
1307
1308\starttyping[option=LUA]
1309function sparse.wipe (<t:userdata> instance )
1310 nothing to return
1311end
1312\stoptyping
1313
1314\stopsubsection
1315
1316\startsubsection[title=Posits]
1317
1318We implement posits as userdata . We use the library from the posit team,
1319although it is not complete so we might roll out our own variant (as we need less
1320anyway). The advance of userdata is that we can use the binary and relation
1321operators.
1322
1323Here are the housekeeping functions. Some are more tolerant with respect to
1324arguments, take the allocator:
1325
1326\starttyping[option=LUA]
1327function posit.new ( ) return <t:posit> end
1328function posit.new ( <t:string> s ) return <t:posit> end
1329function posit.new ( <t:number> n ) return <t:posit> end
1330\stoptyping
1331
1332When a posit is expected a number or string is also accepted which is then
1333converted to a posit.
1334
1335\starttyping[option=LUA]
1336function posit.copy ( <t:posit> p ) return <t:posit> end
1337function posit.tostring ( <t:posit> p ) return <t:string> end
1338function posit.tonumber ( <t:posit> p ) return <t:number> end
1339function posit.integer ( <t:posit> p ) return <t:integer end
1340function posit.rounded ( <t:posit> p ) return <t:integer> end
1341function posit.toposit ( <t:number> n ) return <t:posit> end
1342function posit.fromposit ( <t:posit> p ) return <t:number> end
1343\stoptyping
1344
1345\starttyping[option=LUA]
1346function posit.NaN ( <t:posit> p ) return <t:boolean> end
1347function posit.NaR ( <t:posit> p ) return <t:boolean> end
1348\stoptyping
1349
1350Here are the logical operators:
1351
1352\starttyping[option=LUA]
1353function posit.bor ( <t:posit> p1, <t:posit> p2 ) return <t:posit> end
1354function posit.bxor ( <t:posit> p1, <t:posit> p2 ) return <t:posit> end
1355function posit.band ( <t:posit> p1, <t:posit> p2 ) return <t:posit> end
1356\stoptyping
1357
1358Ans shifters:
1359
1360\starttyping[option=LUA]
1361function posit.shift ( <t:posit> p1, <t:integer> n ) return <t:posit> end
1362function posit.rotate ( <t:posit> p, <t:integer> n ) return <t:posit> end
1363\stoptyping
1364
1365There is a limited repertoire of math functions (basically what we needed for
1366\METAPOST):
1367
1368\starttyping[option=LUA]
1369function posit.abs ( <t:posit> p ) return <t:posit> end
1370function posit.conj ( <t:posit> p ) return <t:posit> end
1371function posit.acos ( <t:posit> p ) return <t:posit> end
1372function posit.asin ( <t:posit> p ) return <t:posit> end
1373function posit.atan ( <t:posit> p ) return <t:posit> end
1374function posit.ceil ( <t:posit> p ) return <t:posit> end
1375function posit.cos ( <t:posit> p ) return <t:posit> end
1376function posit.exp ( <t:posit> p ) return <t:posit> end
1377function posit.exp2 ( <t:posit> p ) return <t:posit> end
1378function posit.floor ( <t:posit> p ) return <t:posit> end
1379function posit.log ( <t:posit> p ) return <t:posit> end
1380function posit.log10 ( <t:posit> p ) return <t:posit> end
1381function posit.log1p ( <t:posit> p ) return <t:posit> end
1382function posit.log2 ( <t:posit> p ) return <t:posit> end
1383function posit.logb ( <t:posit> p ) return <t:posit> end
1384function posit.round ( <t:posit> p ) return <t:posit> end
1385function posit.sin ( <t:posit> p ) return <t:posit> end
1386function posit.sqrt ( <t:posit> p ) return <t:posit> end
1387function posit.tan ( <t:posit> p ) return <t:posit> end
1388
1389function posit.modf ( <t:posit> p )
1390 return
1391 <t:posit>,
1392 <t:posit>
1393end
1394
1395function posit.min ( <t:posit> p1, <t:posit> p2 ) return <t:posit> end
1396function posit.max ( <t:posit> p1, <t:posit> p2 ) return <t:posit> end
1397function posit.pow ( <t:posit> p1, <t:posit> p2 ) return <t:posit> end
1398\stoptyping
1399
1400
1401
1402
1403
1404
1405
1406
1407\stopsubsection
1408
1409\startsubsection[title=Complex numbers]
1410
1411\starttyping[option=LUA]
1412function xcomplex.new ( )
1413 return <t:complex>
1414end
1415
1416function xcomplex.new (
1417 <t:number> re,
1418 <t:number> im
1419)
1420 return <t:complex>
1421end
1422\stoptyping
1423
1424\starttyping[option=LUA]
1425function xcomplex.tostring ( <t:complex> z )
1426 return <t:string>
1427end
1428\stoptyping
1429
1430\starttyping[option=LUA]
1431function xcomplex.topair ( <t:complex> z )
1432 return
1433 <t:number>, re
1434 <t:number> im
1435end
1436\stoptyping
1437
1438There is a bunch of functions that take a complex number:
1439
1440\starttyping[option=LUA]
1441function xcomplex.abs ( <t:complex> z ) return <t:complex> end
1442function xcomplex.arg ( <t:complex> z ) return <t:complex> end
1443function xcomplex.imag ( <t:complex> z ) return <t:complex> end
1444function xcomplex.real ( <t:complex> z ) return <t:complex> end
1445function xcomplex.onj ( <t:complex> z ) return <t:complex> end
1446function xcomplex.proj ( <t:complex> z ) return <t:complex> end
1447function xcomplex.exp ( <t:complex> z ) return <t:complex> end
1448function xcomplex.log ( <t:complex> z ) return <t:complex> end
1449function xcomplex.sqrt ( <t:complex> z ) return <t:complex> end
1450function xcomplex.sin ( <t:complex> z ) return <t:complex> end
1451function xcomplex.cos ( <t:complex> z ) return <t:complex> end
1452function xcomplex.tan ( <t:complex> z ) return <t:complex> end
1453function xcomplex.asin ( <t:complex> z ) return <t:complex> end
1454function xcomplex.acos ( <t:complex> z ) return <t:complex> end
1455function xcomplex.atan ( <t:complex> z ) return <t:complex> end
1456function xcomplex.sinh ( <t:complex> z ) return <t:complex> end
1457function xcomplex.cosh ( <t:complex> z ) return <t:complex> end
1458function xcomplex.tanh ( <t:complex> z ) return <t:complex> end
1459function xcomplex.asinh ( <t:complex> z ) return <t:complex> end
1460function xcomplex.acosh ( <t:complex> z ) return <t:complex> end
1461function xcomplex.atanh ( <t:complex> z ) return <t:complex> end
1462
1463function xcomplex.pow ( <t:complex> z1, <t:complex> z2 ) return <t:complex> end
1464\stoptyping
1465
1466We added the \type {cerf} functions but none can wonder if we should carry that
1467burden around (instead of just assuming a library to be used).
1468
1469The complex error function \type {erf(z)}:
1470
1471\starttyping[option=LUA]
1472function cerf.erf ( <t:complex> z )
1473 return <t:complex>
1474end
1475\stoptyping
1476
1477The complex complementary error function \type {erfc(z) = 1 erf(z)}:
1478
1479\starttyping[option=LUA]
1480function cerf.erfc ( <t:complex> z )
1481 return <t:complex>
1482end
1483\stoptyping
1484
1485The underflowcompensating function \type {erfcx(z) = exp(z2) erfc(z)}:
1486
1487\starttyping[option=LUA]
1488function cerf.erfcx ( <t:complex> z )
1489 return <t:complex>
1490end
1491\stoptyping
1492
1493The imaginary error function \type {erfi(z) = i erf(iz)}:
1494
1495\starttyping[option=LUA]
1496function cerf.erfi ( <t:complex> z )
1497 return <t:complex>
1498end
1499\stoptyping
1500
1501Dawsons integral \type {D(z) = sqrt(pi)2 * exp(z2) * erfi(z)}:
1502
1503\starttyping[option=LUA]
1504function cerf.dawson ( <t:complex> z )
1505 return <t:complex>
1506end
1507\stoptyping
1508
1509The convolution of a Gaussian and a Lorentzian:
1510
1511\starttyping[option=LUA]
1512function cerf.voigt (
1513 <t:number> n1,
1514 <t:number> n2,
1515 <t:number> n3
1516)
1517 return <t:number>
1518end
1519\stoptyping
1520
1521The half width at half maximum of the Voigt profile:
1522
1523\starttyping[option=LUA]
1524function cerf.voigthwhm (
1525 <t:number> n1,
1526 <t:number> n2
1527)
1528 return <t:number>
1529end
1530\stoptyping
1531
1532\stopsubsection
1533
1534\startsubsection[title=Decimal numbers]
1535
1536Because in \METAPOST\ we support the decimal number system, we also provide this
1537at the \TEX\ end Apart from the usual support for operators there are some
1538functions available.
1539
1540\starttyping[option=LUA]
1541function xdecimal.new ( ) return <t:decimal> end
1542function xdecimal.new ( <t:number> n ) return <t:decimal> end
1543function xdecimal.new ( <t:string> s ) return <t:decimal> end
1544\stoptyping
1545
1546\starttyping[option=LUA]
1547function xdecimal.copy ( <t:decimal> a ) return <t:decimal> end
1548function xdecimal.tostring ( <t:decimal> a ) return <t:string> end
1549function xdecimal.tonumber ( <t:decimal> a ) return <t:number> end
1550\stoptyping
1551
1552\starttyping[option=LUA]
1553function xdecimal.setprecision ( <t:integer> digits )
1554 nothing to return
1555end
1556
1557function xdecimal.getprecision ( )
1558 return <t:integer>
1559end
1560\stoptyping
1561
1562\starttyping[option=LUA]
1563function xdecimal.bor ( <t:decimal> a, <t:decimal> b ) return <t:decimal> end
1564function xdecimal.bxor ( <t:decimal> a, <t:decimal> b ) return <t:decimal> end
1565function xdecimal.band ( <t:decimal> a, <t:decimal> b ) return <t:decimal> end
1566\stoptyping
1567
1568\starttyping[option=LUA]
1569function xdecimal.shift ( <t:decimal> a, <t:integer> n ) return <t:decimal> end
1570function xdecimal.rotate ( <t:decimal> a, <t:integer> n ) return <t:decimal> end
1571\stoptyping
1572
1573\starttyping[option=LUA]
1574function xdecimal.abs ( <t:decimal> a ) return <t:decimal> end
1575function xdecimal.trim ( <t:decimal> a ) return <t:decimal> end
1576function xdecimal.conj ( <t:decimal> a ) return <t:decimal> end
1577function xdecimal.abs ( <t:decimal> a ) return <t:decimal> end
1578function xdecimal.sqrt ( <t:decimal> a ) return <t:decimal> end
1579function xdecimal.ln ( <t:decimal> a ) return <t:decimal> end
1580function xdecimal.log ( <t:decimal> a ) return <t:decimal> end
1581function xdecimal.exp ( <t:decimal> a ) return <t:decimal> end
1582function xdecimal.minus ( <t:decimal> a ) return <t:decimal> end
1583function xdecimal.plus ( <t:decimal> a ) return <t:decimal> end
1584
1585function xdecimal.min ( <t:decimal> a, <t:decimal> b ) return <t:decimal> end
1586function xdecimal.max ( <t:decimal> a, <t:decimal> b ) return <t:decimal> end
1587function xdecimal.pow ( <t:decimal> a, <t:decimal> b ) return <t:decimal> end
1588\stoptyping
1589
1590\stopsubsection
1591
1592\startsubsection[title=Math helpers]
1593
1594The \type {xmath} library provides function and a few constants:
1595
1596\starttyping[option=LUA]
1597local infinty = xmath.inf
1598local notanumber = xmath.nan
1599local pi = xmath.pi
1600\stoptyping
1601
1602There are more helpers than the average used needs. We also use these
1603to extend the \METAPOST\ repertoire.
1604
1605\starttyping[option=LUA]
1606function xmath.acos ( <t:number> a ) return <t:number> end
1607function xmath.acosh ( <t:number> a ) return <t:number> end
1608function xmath.asin ( <t:number> a ) return <t:number> end
1609function xmath.asinh ( <t:number> a ) return <t:number> end
1610function xmath.atan ( <t:number> a ) return <t:number> end
1611function xmath.atan ( <t:number> a, <t:number> b ) return <t:number> end
1612function xmath.atan2 ( <t:number> a ) return <t:number> end
1613function xmath.atan2 ( <t:number> a, <t:number> b ) return <t:number> end
1614function xmath.atanh ( <t:number> a ) return <t:number> end
1615function xmath.cbrt ( <t:number> a ) return <t:number> end
1616function xmath.ceil ( <t:number> a ) return <t:number> end
1617function xmath.copysign ( <t:number> a, <t:number> b ) return <t:number> end
1618function xmath.cos ( <t:number> a ) return <t:number> end
1619function xmath.cosh ( <t:number> a ) return <t:number> end
1620function xmath.deg ( <t:number> a ) return <t:number> end
1621function xmath.erf ( <t:number> a ) return <t:number> end
1622function xmath.erfc ( <t:number> a ) return <t:number> end
1623function xmath.exp ( <t:number> a ) return <t:number> end
1624function xmath.exp2 ( <t:number> a ) return <t:number> end
1625function xmath.expm1 ( <t:number> a ) return <t:number> end
1626function xmath.fabs ( <t:number> a ) return <t:number> end
1627function xmath.fdim ( <t:number> a, <t:number> b ) return <t:number> end
1628function xmath.floor ( <t:number> a ) return <t:number> end
1629function xmath.fmax ( ... ) return <t:number> end
1630function xmath.fmin ( ... ) return <t:number> end
1631function xmath.fmod ( <t:number> a, <t:number> b ) return <t:number> end
1632function xmath.frexp ( <t:number> a, <t:number> b ) return <t:number> end
1633function xmath.gamma ( <t:number> a ) return <t:number> end
1634function xmath.hypot ( <t:number> a, <t:number> b ) return <t:number> end
1635function xmath.isfinite ( <t:number> a ) return <t:number> end
1636function xmath.isinf ( <t:number> a ) return <t:number> end
1637function xmath.isnan ( <t:number> a ) return <t:number> end
1638function xmath.isnormal ( <t:number> a ) return <t:number> end
1639function xmath.j0 ( <t:number> a ) return <t:number> end
1640function xmath.j1 ( <t:number> a ) return <t:number> end
1641function xmath.jn ( <t:number> a, <t:number> b ) return <t:number> end
1642function xmath.ldexp ( <t:number> a, <t:number> b ) return <t:number> end
1643function xmath.lgamma ( <t:number> a ) return <t:number> end
1644function xmath.l0 ( <t:number> a ) return <t:number> end
1645function xmath.l1 ( <t:number> a ) return <t:number> end
1646function xmath.ln ( <t:number> a, <t:number> b ) return <t:number> end
1647function xmath.log ( <t:number> a [,b]) return <t:number> end
1648function xmath.log10 ( <t:number> a ) return <t:number> end
1649function xmath.log1p ( <t:number> a ) return <t:number> end
1650function xmath.log2 ( <t:number> a ) return <t:number> end
1651function xmath.logb ( <t:number> a ) return <t:number> end
1652function xmath.modf ( <t:number> a, <t:number> b ) return <t:number> end
1653function xmath.nearbyint ( <t:number> a ) return <t:number> end
1654function xmath.nextafter ( <t:number> a, <t:number> b ) return <t:number> end
1655function xmath.pow ( <t:number> a, <t:number> b ) return <t:number> end
1656function xmath.rad ( <t:number> a ) return <t:number> end
1657function xmath.remainder ( <t:number> a, <t:number> b ) return <t:number> end
1658function xmath.remquo ( <t:number> a, <t:number> b ) return <t:number> end
1659function xmath.round ( <t:number> a ) return <t:number> end
1660function xmath.scalbn ( <t:number> a, <t:number> b ) return <t:number> end
1661function xmath.sin ( <t:number> a ) return <t:number> end
1662function xmath.sinh ( <t:number> a ) return <t:number> end
1663function xmath.sqrt ( <t:number> a ) return <t:number> end
1664function xmath.tan ( <t:number> a ) return <t:number> end
1665function xmath.tanh ( <t:number> a ) return <t:number> end
1666function xmath.tgamma ( <t:number> a ) return <t:number> end
1667function xmath.trunc ( <t:number> a ) return <t:number> end
1668function xmath.y0 ( <t:number> a ) return <t:number> end
1669function xmath.y1 ( <t:number> a ) return <t:number> end
1670function xmath.yn ( <t:number> a ) return <t:number> end
1671
1672function xmath.fma (
1673 <t:number> a,
1674 <t:number> b,
1675 <t:number> c
1676)
1677 return <t:number>
1678end
1679\stoptyping
1680
1681\stopsubsection
1682
1683\stopsection
1684
1685\startsection[title={Optional}]
1686
1687\startsubsection[title=Loading]
1688
1689The optional libraries are (indeed) optional. Compilation of \LUAMETATEX\ doesnt
1690depend on them being present. Loading (and binding) is delayed. In practice we
1691only see a few being of interest and used, like \type {zint} for barcodes, \type
1692{mysql} for database processing and \type {graphicmagick} for an occasional
1693runtime conversion. Some are just there to show the principles and were used to
1694test the interfaces and loading.
1695
1696A library can be loaded, and thereby registered in the \quote {optional}
1697namespace, assuming that \type {permitloadlib} is given with:
1698
1699\starttyping[option=LUA]
1700function library.load (
1701 <t:string> filename,
1702 <t:string> openname,
1703)
1704 return
1705 <t:function>, target
1706 <t:string> foundname
1707end
1708\stoptyping
1709
1710but there are no guarantees that it will work.
1711
1712\stopsubsection
1713
1714\startsubsection[title=Management]
1715
1716{\em Todo: something about how optionals are implemented and are supposed to work.}
1717
1718\stopsubsection
1719
1720\startsubsection[title=TDS (kpse)]
1721
1722The optional \type {kpse} library deals with lookups in the \TEX\ Directory
1723Structure and before it can be used it has to be initialized:
1724
1725\starttyping[option=LUA]
1726function optional.kpse.initialize ( <t:string> filename )
1727 return <t:boolean>
1728end
1729\stoptyping
1730
1731By setting the program name the library knows in what namespace to resolve
1732filenames and variables.
1733
1734\starttyping[option=LUA]
1735function optional.kpse.setprogramname (
1736 <t:string> binaryname,
1737 <t:string> programname
1738)
1739 no return values
1740end
1741\stoptyping
1742
1743The main finder has one or more arguments. When the second and later arguments
1744can be a boolean, string or number. The boolean indicates if the file must exist.
1745A string sets the file type and a number does the same.
1746
1747\starttyping[option=LUA]
1748function optional.kpse.findfile(
1749 <t:string> filename,
1750 <t:string> filetype.
1751 <t:boolean> mustexist
1752)
1753 return <t:string>
1754end
1755\stoptyping
1756
1757You can also ask for a list of found files:
1758
1759\starttyping[option=LUA]
1760function optional.kpse.findfiles (
1761 <t:string> userpath,
1762 <t:string> filename
1763)
1764 return <t:table>
1765end
1766\stoptyping
1767
1768These return variables, values and paths:
1769
1770\starttyping[option=LUA]
1771function optional.kpse.expandpath ( <t:string> name ) return <t:string> end
1772function optional.kpse.expandvar ( <t:string> name ) return <t:string> end
1773function optional.kpse.expandbraces ( <t:string> name ) return <t:string> end
1774function optional.kpse.varvalue ( <t:string> name ) return <t:string> end
1775\stoptyping
1776
1777If possible this returns the (first found) filename that is readable:
1778
1779\starttyping[option=LUA]
1780function optional.kpse.readablefile ( <t:string> filename )
1781 return <t:string>
1782end
1783\stoptyping
1784
1785The list of supported file types can be fetched with:
1786
1787\starttyping[option=LUA]
1788function optional.kpse.getfiletypes ( )
1789 return <t:table>
1790end
1791\stoptyping
1792
1793\stopsubsection
1794
1795\startsubsection[title=Graphics]
1796
1797\startsubsubsubject[title=ghostscript]
1798
1799The \type {ghostscript} library has to be initialized:
1800
1801\starttyping[option=LUA]
1802function optional.ghostscript.initialize ( <t:string> filename )
1803 return <t:boolean>
1804end
1805\stoptyping
1806
1807A conversion is executed with the following command. Here the table is a mixed
1808list of strings and numbers that represent the otherwise command like arguments.
1809
1810\starttyping[option=LUA]
1811function optional.ghostscript.execute ( <t:table> )
1812 return
1813 <t:boolean>, success
1814 <t:string>, result
1815 <t:string> message
1816end
1817\stoptyping
1818
1819\stopsubsubsubject
1820
1821\startsubsubsubject[title=graphicsmagick]
1822
1823The \type {graphicsmagick} library has to be initialized:
1824
1825\starttyping[option=LUA]
1826function optional.graphicsmagick.initialize ( <t:string> filename )
1827 return <t:boolean>
1828end
1829\stoptyping
1830
1831A conversion is executed with the following command.
1832
1833\starttyping[option=LUA]
1834function optional.graphicsmagick.execute (
1835 {
1836 inputfilename = <t:string>,
1837 outputfilename = <t:string>,
1838 blur = {
1839 radius = <t:number>,
1840 sigma = <t:number>,
1841 },
1842 noise {
1843 type = <t:integer>,
1844 },
1845 }
1846)
1847 return <t:boolean>
1848end
1849\stoptyping
1850
1851The noise types can be fetched with:
1852
1853\starttyping[option=LUA]
1854function optional.graphicsmagick.noisetypes ( )
1855 return <t:table>
1856end
1857\stoptyping
1858
1859\stopsubsubsubject
1860
1861\startsubsubsubject[title=imagemagick]
1862
1863The \type {imagemagick} library is initialized with:
1864
1865\starttyping[option=LUA]
1866function optional.imagemagick.initialize ( <t:string> filename )
1867 return <t:boolean>
1868end
1869\stoptyping
1870
1871After that you can execute convert commands. The options table is a sequence of
1872strings, numbers and booleans that gets passes, in the same order, but where a
1873boolean becomes one of the strings \type {true} or \type {false}.
1874
1875\starttyping[option=LUA]
1876function optional.imagemagick.execute (
1877 {
1878 inputfilename = <t:string>,
1879 outputfilename = <t:string>,
1880 options = <t:table>,
1881 }
1882)
1883 return <t:boolean>
1884end
1885\stoptyping
1886
1887\stopsubsubsubject
1888
1889\startsubsubsubject[title=zint]
1890
1891The \type {zint} library is initialized with:
1892
1893\starttyping[option=LUA]
1894function optional.zint.initialize ( <t:string> filename )
1895 return <t:boolean>
1896end
1897\stoptyping
1898
1899As with the other graphic libraries we execute a command but here we implement a
1900converter a bit more specific because we want back a result that we can handle in
1901a combination of \TEX\ and \METAPOST.
1902
1903\starttyping[option=LUA]
1904function optional.zint.execute (
1905 {
1906 code = <t:integer>,
1907 text = <t:string>,
1908 option = <t:string>, "square"
1909 }
1910)
1911 return <t:table>
1912end
1913\stoptyping
1914
1915We get back a table that has graphic components, where each components table can
1916zero or more subtables.
1917
1918\starttyping[option=LUA]
1919result = {
1920 rectangles = {
1921 { <t:integer> x, <t:integer> y, <t:integer> w, <t:integer> h }, ...
1922 },
1923 hexagons = {
1924 { <t:integer> x, <t:integer> y, <t:integer> d }, ...
1925 },
1926 circles = {
1927 { <t:integer> x, <t:integer> y, <t:nteger> d }, ...
1928 },
1929 strings = {
1930 { <t:integer> x, <t:integer> y, <t:integer> s, <t:string> t }, ...
1931 }
1932}
1933\stoptyping
1934
1935\stopsubsubsubject
1936
1937\stopsubsection
1938
1939\startsubsection[title=Compression]
1940
1941\startsubsubsubject[title=lz4]
1942
1943The library is initialized with:
1944
1945\starttyping[option=LUA]
1946function optional.lz4.initialize ( )
1947 return <t:boolean> success
1948end
1949\stoptyping
1950
1951There are compressors and decompressors. If you want the more efficient
1952decompressor, make sure to save the size with the compressed stream and pass that
1953when decompressing.
1954
1955\starttyping[option=LUA]
1956function optional.lz4.compress (
1957 <t:string> data,
1958 <t:integer> acceleration default 1
1959)
1960 return <t:string>
1961end
1962
1963function optional.lz4.decompresssize (
1964 <t:string> data,
1965 <t:integer> size
1966)
1967 return <t:string>
1968end
1969\stoptyping
1970
1971These are the frame based variants:
1972
1973\starttyping[option=LUA]
1974function optional.lz4.framecompress ( <t:string> data )
1975 return <t:string>
1976end
1977
1978function optional.lz4.framedecompress ( return <t:string> )
1979 return <t:string>
1980end
1981\stoptyping
1982
1983\stopsubsubsubject
1984
1985\startsubsubsubject[title=lzma]
1986
1987The library is initialized with:
1988
1989\starttyping[option=LUA]
1990function optional.lzma.initialize ( )
1991 return <t:boolean> success
1992end
1993\stoptyping
1994
1995The compressor can take an estimated size which makes it possible to preallocate
1996a buffer.
1997
1998\starttyping[option=LUA]
1999function optional.lzma.compress (
2000 <t:string> data,
2001 <t:integer> level,
2002 <t:integer> size estimated
2003)
2004 return <t:string>
2005end
2006\stoptyping
2007
2008The decompressor can be told what the final size is which is more efficient.
2009
2010\starttyping[option=LUA]
2011function optional.lzma.decompress (
2012 <t:string> data,
2013 <t:integer> size estimated
2014)
2015 return <t:string>
2016end
2017\stoptyping
2018
2019\stopsubsubsubject
2020
2021\startsubsubsubject[title=lzo]
2022
2023The library is initialized with:
2024
2025\starttyping[option=LUA]
2026function optional.lzo.initialize ( )
2027 return <t:boolean> success
2028end
2029\stoptyping
2030
2031There is not much to tell about:
2032
2033\starttyping[option=LUA]
2034function optional.lzo.compress ( <t:string> data )
2035 return <t:string>
2036end
2037\stoptyping
2038
2039and
2040
2041\starttyping[option=LUA]
2042function optional.lzo.decompresssize (
2043 <t:string> data,
2044 <t:integer> size
2045)
2046 return <t:string>
2047end
2048\stoptyping
2049
2050\stopsubsubsubject
2051
2052\startsubsubsubject[title=zstd]
2053
2054The library is initialized with:
2055
2056\starttyping[option=LUA]
2057function optional.zstd.initialize ( )
2058 return <t:boolean> success
2059end
2060\stoptyping
2061
2062The compressor:
2063
2064\starttyping[option=LUA]
2065function optional.zstd.compress (
2066 <t:string> data,
2067 <t:integer> level
2068)
2069 return <t:string>
2070end
2071\stoptyping
2072
2073The decompressor:
2074
2075\starttyping[option=LUA]
2076function optional.zstd.decompress ( <t:string> data )
2077 return <t:string>
2078end
2079\stoptyping
2080
2081\stopsubsubsubject
2082
2083\stopsubsection
2084
2085\startsubsection[title=Databases]
2086
2087\startsubsubsubject[title=mysql]
2088
2089We start with the usual initializer:
2090
2091\starttyping[option=LUA]
2092function optional.mysql.initialize ( )
2093 return <t:boolean> success
2094end
2095\stoptyping
2096
2097Opening the database is done with:
2098
2099\starttyping[option=LUA]
2100function optional.mysql.open (
2101 <t:string> database,
2102 <t:string> username,
2103 <t:string> password,
2104 <t:string> host,
2105 <t:integer> port optional
2106)
2107 return <t:userdata> instance
2108end
2109\stoptyping
2110
2111The database is kept \quote {open} but can be closed with:
2112
2113\starttyping[option=LUA]
2114function optional.mysql.close ( <t:userdata> instance )
2115 no return values
2116end
2117\stoptyping
2118
2119A query is executed with:
2120
2121\starttyping[option=LUA]
2122function optional.mysql.execute (
2123 <t:userdata> instance,
2124 <t:string> query,
2125 <t:function> callback
2126)
2127 return <t:boolean> success
2128end
2129\stoptyping
2130
2131The callback is a \LUA\ function that looks like this:
2132
2133\starttyping[option=LUA]
2134function callback(nofcolumns,values,fields)
2135 ...
2136end
2137\stoptyping
2138
2139It gets called for every row of the result. The fields table is only filled the
2140first time, if at all.
2141
2142This interface is rather minimalistic but in \CONTEXT\ we wrap all in a more
2143advanced setup. Its among the oldest \LUA\ code in the distribution and evolved
2144with the possibilities (client as well as external libraries) and is quite
2145performing also due to the use of templates, caching, builtin conversions etc.
2146
2147If there is an error we can fetch the message with:
2148
2149\starttyping[option=LUA]
2150function optional.mysql.getmessage ( <t:userdata> instance )
2151 return <t:string> <t:nil> last error message
2152end
2153\stoptyping
2154
2155\stopsubsubsubject
2156
2157\startsubsubsubject[title=postgress]
2158
2159This library has the same interface as the \type {mysql} interface, so it can be
2160used instead.
2161
2162\stopsubsubsubject
2163
2164\startsubsubsubject[title=sqlite]
2165
2166This library has the same interface as the \type {mysql} interface, so it can be
2167used instead. The only function that differs is the opener:
2168
2169\starttyping[option=LUA]
2170function optional.sqlite.open ( <t:string> filename )
2171 return <t:userdata> instance
2172end
2173\stoptyping
2174
2175\stopsubsubsubject
2176
2177\stopsubsection
2178
2179\startsubsection[title=Whatever]
2180
2181\startsubsubsubject[title=cerf]
2182
2183This library is plugged in the \type {xcomplex} so there is no need to discuss it
2184here unless we decide to move it to an optional loaded library, which might
2185happen eventually (depends on need).
2186
2187\stopsubsubsubject
2188
2189\startsubsubsubject[title=curl]
2190
2191The library is initialized with:
2192
2193\starttyping[option=LUA]
2194function optional.curl.initialize ( )
2195 return <t:boolean> success
2196end
2197\stoptyping
2198
2199The fetcher stays kind of close to how the library wants it so we have no fancy
2200interface. We have pairs where the first member is an integer indicating the
2201option. The library only has string and integer options so booleans are effective
2202zeros or ones. A \LUA\ boolean therefore becomes an integer.
2203
2204\starttyping[option=LUA]
2205function optional.curl.fetch (
2206 {
2207 <t:integer>, <t:string> <t:integer> <t:boolean>,
2208 ...
2209 }
2210)
2211end
2212\stoptyping
2213
2214A \URL\ can be (un)escaped:
2215
2216\starttyping[option=LUA]
2217function optional.curl.escape ( <t:string> data )
2218 return <t:string>
2219end
2220
2221function optional.curl.unescape ( <t:string> data )
2222 return <t:string>
2223end
2224\stoptyping
2225
2226The current version of the library:
2227
2228\starttyping[option=LUA]
2229function optional.curl.getversion ( )
2230 return <t:string>
2231end
2232\stoptyping
2233
2234\stopsubsubsubject
2235
2236\startsubsubsubject[title=hb]
2237
2238This module is mostly there to help Idris Hamid (The Oriental \TEX\ Project
2239develop his fonts in such away that they work with other libraries (also
2240uniscribe). We need to initialize this library with the following function. Best
2241have the library in the \TEX\ tree because either more are present or the
2242operating system updates them. As we dont use this in \CONTEXT\ were also not
2243sure of things work ok but we can assume stable interfaces anyway. See the plugin
2244module for more info.
2245
2246\starttyping[option=LUA]
2247function optional.hb.initialize ( )
2248 return <t:boolean> success
2249end
2250\stoptyping
2251
2252It probably makes sense to check for the version because (in the \TEXLIVE\ code
2253base) it is one of the most frequently updated code bases and for \TEX\ stability
2254and predictability (when working on a specific project) is important. When you
2255initialize
2256
2257\starttyping[option=LUA]
2258function optional.hb.getversion ( )
2259 return <t:string>
2260end
2261\stoptyping
2262
2263\starttyping[option=LUA]
2264function optional.hb.getshapers ( )
2265 return <t:table> strings
2266end
2267\stoptyping
2268
2269\starttyping[option=LUA]
2270function optional.hb.loadfont (
2271 <t:integer> id,
2272 <t:string> name
2273)
2274 return <t:userdata> instance
2275end
2276\stoptyping
2277
2278A run over characters happens with the next one. You get back a list of tables
2279that specify to be handled glyphs. The interface is pretty much the same as what
2280Kai Eigner came up with at the time he wanted to compare the results with the
2281regular font loader, for which the \LUATEX\ and \LUAJITTEX) \FFI\ interfaces were
2282used.
2283
2284\starttyping[option=LUA]
2285function optional.hb.shapestring (
2286 <t:userdata> font,
2287 <t:string> script,
2288 <t:string> language,
2289 <t:string> direction,
2290 <t:table> shapers,
2291 <t:table> features,
2292 <t:string> text
2293 <t:boolean> reverse
2294 <t:integer> utfbits, default 8
2295)
2296 return {
2297 {
2298 <t:integer>, codepoint
2299 <t:integer>, cluster
2300 <t:integer>, xoffset
2301 <t:integer>, yoffset
2302 <t:integer>, xadvance
2303 <t:integer>, uadvance
2304 },
2305 ...
2306 }
2307end
2308\stoptyping
2309
2310\stopsubsubsubject
2311
2312\startsubsubsubject[title=mujs]
2313
2314This is just a fun experiment that permits \JAVASCRIPT\ code to be used instead of
2315\LUA. It was actually one of the first optional libraries I played with and as
2316with the other optionals there is a module that wraps it. The library is
2317initialized with:
2318
2319\starttyping[option=LUA]
2320function optional.mujs.initialize ( )
2321 return <t:boolean> success
2322end
2323\stoptyping
2324
2325There are a few \quote {mandate} callbacks than need to be implemented:
2326
2327\starttyping[option=LUA]
2328function optional.mujs.setfindfile (
2329 function ( <t:string> name )
2330 return <t:string>
2331 end
2332)
2333 no return values
2334end
2335
2336function optional.mujs.setopenfile (
2337 function ( <t:string> name )
2338 return <t:integer> id
2339 end
2340)
2341 no return values
2342end
2343
2344function optional.mujs.setclosefile (
2345 function ( <t:integer> id )
2346 no return values
2347 end
2348)
2349 no return values
2350end
2351
2352function optional.mujs.setreadfile (
2353 function ( <t:integer> id )
2354 return <t:string> <t:nil>
2355 end
2356)
2357 no return values
2358end
2359
2360function optional.mujs.setseekfile (
2361 function ( <t:integer> id, <t:integer> position )
2362 return <t:integer>
2363 end
2364)
2365 no return values
2366end
2367
2368function optional.mujs.setconsole ( )
2369 function ( <t:string> category, <t:string> message )
2370 no return values
2371 end
2372)
2373 no return values
2374end
2375\stoptyping
2376
2377The library implements a few \JAVASCRIPT\ functions, like the ones
2378printing to \TEX, they take an optional catcodes reference:
2379
2380\starttyping
2381texprint (catcodes, ...)
2382texsprint(catcodes, ...)
2383\stoptyping
2384
2385and a reporter:
2386
2387\starttyping
2388console (category, message)
2389\stoptyping
2390
2391The next function resets the interpreter:
2392
2393\starttyping[option=LUA]
2394function optional.mujs.reset ( )
2395 no return value
2396end
2397\stoptyping
2398
2399A snippet of \JAVASCRIPT\ can be executed with:
2400
2401\starttyping[option=LUA]
2402function optional.mujs.execute ( <t:string> filename )
2403 no return value
2404end
2405\stoptyping
2406
2407This loads a \JAVASCRIPT\ file:
2408
2409\starttyping[option=LUA]
2410function optional.mujs.dofile ( <t:string> filename )
2411 no return value
2412end
2413\stoptyping
2414
2415\stopsubsubsubject
2416
2417\startsubsubsubject[title=openssl]
2418
2419We use this module for some \PDF\ features. Given the frequent updates to the
2420(external) code base, its for sure not something one wants in the engine. We use
2421only a small subset of functionality. The library is initialized with:
2422
2423\starttyping[option=LUA]
2424function optional.openssl.initialize ( )
2425 return <t:boolean> success
2426end
2427\stoptyping
2428
2429When signing succeeds the first return value is \type {true} and possibly there
2430is a string as second return value. When \type {false} is returned the second
2431argument is an error code.
2432
2433\starttyping[option=LUA]
2434function optional.openssl.sign (
2435 {
2436 certfile = <t:string>,
2437 datafile = <t:string>,
2438 data = <t:string>,
2439 password = <t:string>,
2440 resultfile = <t:string>,
2441 }
2442)
2443 return
2444 <t:boolean>, success
2445 <t:string> <t:integer> <t:nil>
2446end
2447\stoptyping
2448
2449Verifying needs similar data:
2450
2451\starttyping[option=LUA]
2452function optional.openssl.verify (
2453 {
2454 certfile <t:string>,
2455 datafile <t:string>,
2456 data <t:string>,
2457 signature <t:string>,
2458 password <t:string>,
2459 }
2460)
2461 return
2462 <t:boolean>, success
2463 <t:integer> <t:nil>
2464end
2465\stoptyping
2466
2467This needs no explanation:
2468
2469\starttyping[option=LUA]
2470function optional.openssl.getversion ( )
2471 return <t:integer>
2472end
2473\stoptyping
2474
2475\stopsubsubsubject
2476
2477\stopsubsection
2478
2479\startsubsection[title=Foreign]
2480
2481{\em Todo: something about how the foreign interface can be used (inspired by
2482alien). Also see \typ {libsimpforeign.mkxl}.}
2483
2484\stopsubsection
2485
2486\stopsection
2487
2488\stopdocument
2489
2490
2491
2492
2493
2494
2495 |