luat-ini.mkxl /size: 12 Kb    last modification: 2023-12-21 09:44
1%D \module
2%D   [       file=luat-ini,
3%D        version=2005.08.11,
4%D          title=\CONTEXT\ Lua Macros,
5%D       subtitle=Initialization,
6%D         author=Hans Hagen,
7%D           date=\currentdate,
8%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
9%C
10%C This module is part of the \CONTEXT\ macro||package and is
11%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
12%C details.
13
14\writestatus{loading}{ConTeXt Lua Macros / Initialization}
15
16\unprotect
17
18%D Loading lua code can be done using \type {startup.lua}. The following method uses
19%D the \TEX\ input file locator of kpse. At least we need to use that way of loading
20%D when we haven't yet define our own code, which we keep outside the format. We
21%D will keep code outside \TEX\ files as much as possible. The solutions evolved
22%D with the engine but one can find some history in the \MKIV\ files and articles.
23
24\ifdefined\obeyluatokens \else \let\obeyluatokens\relax \fi
25
26%D A few more goodies:
27
28\permanent\protected\lettonothing\stoplua     % tex catcodes
29\permanent\protected\lettonothing\stopluacode % lua catcodes
30
31%D In the meantime the \LUATEX\ interface has become stable but we still see traces
32%D of old here (needs checking).
33
34\permanent\protected\def\startlua % \stoplua
35  {\begingroup
36   \luat_start_lua_indeed}
37
38\def\luat_start_lua_indeed#1\stoplua
39  {\normalexpanded{\endgroup\noexpand\directlua{#1}}}
40
41\permanent\protected\def\startluacode % \stopluacode
42  {\begingroup
43   \obeyluatokens
44   \luat_start_lua_code_indeed}
45
46\def\luat_start_lua_code_indeed#1\stopluacode
47 %{\normalexpanded{\endgroup\noexpand\directlua{#1}}}
48  {\directlua{#1\beginlocalcontrol\endgroup\endlocalcontrol}}
49
50%D Some delayed definitions:
51
52\ifdefined\obeylines   \else \let\obeylines   \relax \fi
53\ifdefined\obeyedline  \else \let\obeyedline  \relax \fi
54\ifdefined\obeyspaces  \else \let\obeyspaces  \relax \fi
55\ifdefined\obeyedspace \else \let\obeyedspace \relax \fi
56
57\newtoks\everyluacode
58
59%D It is nicer for checking with \type {s-system-macros} if we have some meaning:
60
61\pushoverloadmode
62
63    % We anyway need this:
64
65    \permanent\protected\def\superexplicitdiscretionary
66      {\begingroup
67       \hyphenationmode\explicithyphenationmodecode\explicitdiscretionary
68       \endgroup}
69
70    % Conceptually the best:
71
72    \aliased\let\-\explicitdiscretionary
73
74    % But we could do this to be compatible:
75
76  % \permanent\protected\def\-{\begingroup\hyphenationmode\explicithyphenationmodecode\explicitdiscretionary\endgroup}
77
78    % Or maybe even this:
79
80  % \aliased\let\lang_explicit_discretionary_nop\explicitdiscretionary
81  %
82  % \permanent\protected\def\lang_explicit_discretionary_yes-%
83  %   {\superexplicitdiscretionary}
84  %
85  % \permanent\protected\def\-%
86  %   {\doifelsenextcharcs-\lang_explicit_discretionary_yes\lang_explicit_discretionary_nop}
87
88\popoverloadmode
89
90\ifdefined\n \else \mutable\def\n{n} \fi \ifdefined\r \else \mutable\def\r{r} \fi
91\ifdefined\f \else \mutable\def\f{f} \fi \ifdefined\t \else \mutable\def\t{t} \fi
92\ifdefined\a \else \mutable\def\a{a} \fi \ifdefined\b \else \mutable\def\b{b} \fi
93\ifdefined\v \else \mutable\def\v{v} \fi \ifdefined\s \else \mutable\def\s{s} \fi
94
95\ifdefined\+ \else \mutable\def\+{+} \fi \ifdefined\- \else \mutable\def\-{-} \fi
96
97\ifdefined\? \else \mutable\def\?{?} \fi \ifdefined\! \else \mutable\def\!{!} \fi % bonus
98
99\ifdefined\1 \else \mutable\def\1{1} \fi \ifdefined\2 \else \mutable\def\2{2} \fi
100\ifdefined\3 \else \mutable\def\3{3} \fi \ifdefined\4 \else \mutable\def\4{4} \fi
101\ifdefined\5 \else \mutable\def\5{5} \fi \ifdefined\6 \else \mutable\def\6{6} \fi
102\ifdefined\7 \else \mutable\def\7{7} \fi \ifdefined\8 \else \mutable\def\8{8} \fi
103\ifdefined\9 \else \mutable\def\9{9} \fi \ifdefined\0 \else \mutable\def\0{0} \fi
104
105\immutable\edef\lua_letter_backslash{\string\\}
106\immutable\edef\lua_letter_bar      {\string\|} \immutable\edef\lua_letter_dash     {\string\-}
107\immutable\edef\lua_letter_lparent  {\string\(} \immutable\edef\lua_letter_rparent  {\string\)}
108\immutable\edef\lua_letter_lbrace   {\string\{} \immutable\edef\lua_letter_rbrace   {\string\}}
109\immutable\edef\lua_letter_squote   {\string\'} \immutable\edef\lua_letter_dquote   {\string\"}
110\immutable\edef\lua_letter_n        {\string\n} \immutable\edef\lua_letter_r        {\string\r}
111\immutable\edef\lua_letter_f        {\string\f} \immutable\edef\lua_letter_t        {\string\t}
112\immutable\edef\lua_letter_a        {\string\a} \immutable\edef\lua_letter_b        {\string\b}
113\immutable\edef\lua_letter_v        {\string\v} \immutable\edef\lua_letter_s        {\string\s}
114\immutable\edef\lua_letter_one      {\string\1} \immutable\edef\lua_letter_two      {\string\2}
115\immutable\edef\lua_letter_three    {\string\3} \immutable\edef\lua_letter_four     {\string\4}
116\immutable\edef\lua_letter_five     {\string\5} \immutable\edef\lua_letter_six      {\string\6}
117\immutable\edef\lua_letter_seven    {\string\7} \immutable\edef\lua_letter_eight    {\string\8}
118\immutable\edef\lua_letter_nine     {\string\9} \immutable\edef\lua_letter_zero     {\string\0}
119
120\everyluacode {% \appendtoks
121   \enforced\let\\\lua_letter_backslash
122   \enforced\let\|\lua_letter_bar       \enforced\let\-\lua_letter_dash
123   \enforced\let\(\lua_letter_lparent   \enforced\let\)\lua_letter_rparent
124   \enforced\let\{\lua_letter_lbrace    \enforced\let\}\lua_letter_rbrace
125   \enforced\let\'\lua_letter_squote    \enforced\let\"\lua_letter_dquote
126   \enforced\let\n\lua_letter_n         \enforced\let\r\lua_letter_r
127   \enforced\let\f\lua_letter_f         \enforced\let\t\lua_letter_t
128   \enforced\let\a\lua_letter_a         \enforced\let\b\lua_letter_b
129   \enforced\let\v\lua_letter_v         \enforced\let\s\lua_letter_s
130   \enforced\let\1\lua_letter_one       \enforced\let\2\lua_letter_two
131   \enforced\let\3\lua_letter_three     \enforced\let\4\lua_letter_four
132   \enforced\let\5\lua_letter_five      \enforced\let\6\lua_letter_six
133   \enforced\let\7\lua_letter_seven     \enforced\let\8\lua_letter_eight
134   \enforced\let\9\lua_letter_nine      \enforced\let\0\lua_letter_zero
135} % \to \everyluacode
136
137\permanent\protected\def\obeyluatokens
138  {\setcatcodetable\luacatcodes
139   \expand\everyluacode}
140
141\immutable\edef\luamajorversion{\ctxwrite{LUAMINORVERSION}}
142\immutable\edef\luaminorversion{\ctxwrite{LUAMAJORVERSION}}
143
144%D We need a way to pass strings safely to \LUA\ without the need for tricky
145%D escaping. Compare:
146%D
147%D \starttyping
148%D \ctxlua {something("anything tricky can go here")}
149%D \ctxlua {something([\luastringsep[anything tricky can go here]\luastringsep])}
150%D \stoptyping
151
152\def\luastringsep{===}       % this permits \typefile{self} otherwise nested b/e sep problems
153
154\edef\!!bs{[\luastringsep[}  % later redefined as mutable
155\edef\!!es{]\luastringsep]}
156
157%D We have a the following available as primitive so there is no need for it:
158%D
159%D \starttyping
160%D \edef\luaescapestring#1{\!!bs#1\!!es}
161%D \stoptyping
162
163\permanent\protected\def\setdocumentfilename       #1#2{\clf_setdocumentfilename\numexpr#1\relax{#2}}
164\permanent          \def\getdocumentfilename         #1{\clf_getdocumentfilename\numexpr#1\relax}
165\permanent\protected\def\setdocumentargument       #1#2{\clf_setdocumentargument{#1}{#2}}
166\permanent          \def\getdocumentargument         #1{\clf_getdocumentargument{#1}{}}
167\permanent\protected\def\setdocumentargumentdefault#1#2{\clf_setdocumentdefaultargument{#1}{#2}}
168\permanent          \def\getdocumentargumentdefault#1#2{\clf_getdocumentargument{#1}{#2}}
169
170% seldom used so no need for speedy variants:
171
172\permanent\def\doifelsedocumentargument    #1{\doifelsesomething{\clf_getdocumentargument{#1}}}
173\permanent\def\doifdocumentargument        #1{\doifsomething    {\clf_getdocumentargument{#1}}}
174\permanent\def\doifnotdocumentargument     #1{\doifnothing      {\clf_getdocumentargument{#1}}}
175\permanent\def\doifelsedocumentfilename    #1{\doifelsesomething{\clf_getdocumentfilename\numexpr#1\relax}}
176\permanent\def\doifdocumentfilename        #1{\doifsomething    {\clf_getdocumentfilename\numexpr#1\relax}}
177\permanent\def\doifnotdocumentfilename     #1{\doifnothing      {\clf_getdocumentfilename\numexpr#1\relax}}
178
179\aliased\let\doifdocumentargumentelse\doifelsedocumentargument
180\aliased\let\doifdocumentfilenameelse\doifelsedocumentfilename
181
182%D A handy helper:
183
184\permanent\def\luaexpanded#1{\luaescapestring\expandafter{\normalexpanded{#1}}}
185
186%D Experimental:
187
188\permanent\protected\def\startluaparameterset[#1]% \stopluaparameterset
189  {\begingroup
190   \obeyluatokens
191   \luat_start_lua_parameter_set{#1}}
192
193\def\luat_start_lua_parameter_set#1#2\stopluaparameterset
194  {\ctxlua{parametersets["#1"]={#2}}%
195   \endgroup}
196
197\permanent\protected\lettonothing\stopluaparameterset
198
199\permanent\def\luaparameterset#1#2{\ctxlua{parametersets["#1"]={#2} context("#1")}}
200
201% todo: \mergeparameterset
202
203% usage:
204%
205% \startluaparameterset [u3d:myset:display:1]
206%     toolbar=false,
207%     tree=true
208% \stopluaparameterset
209%
210% option=u3d:myset:display:1
211%
212% or:
213%
214% option=\luaparameterset{u3d:myset:display:1}{toolbar=false,tree=true}
215
216%D A Handy helper:
217
218\permanent\def\luaconditional#1{\ifcase#1tru\else fals\fi e}
219
220%D Goodie:
221%D
222%D \starttyping
223%D \ctxluacode{context("%0.5f",1/3)}
224%D \stoptyping
225
226\permanent\protected\def\ctxluacode
227  {\begingroup
228   \obeyluatokens
229   \catcode\leftbraceasciicode \plusone
230   \catcode\rightbraceasciicode\plustwo
231   \afterassignment\luat_lua_code
232   \scratchtoks=}
233
234% Hm, are we sure that the \* commands work out okay here? We could probably
235% use \setcatcodetable\luacatcodes instead of \obeyluatokens now.
236
237\def\luat_lua_code
238  {\normalexpanded{\endgroup\noexpand\directlua\expandafter{\the\scratchtoks}}} % \zerocount is default
239
240% \startctxfunction MyFunctionA
241%     context(" A1 ")
242% \stopctxfunction
243%
244% \startctxfunctiondefinition MyFunctionB
245%     context(" B2 ")
246% \stopctxfunctiondefinition
247%
248% \starttext
249%     \dorecurse{10000}{\ctxfunction{MyFunctionA}} \page
250%     \dorecurse{10000}{\MyFunctionB} \page
251%     \dorecurse{10000}{\ctxlua{context(" C3 ")}} \page
252% \stoptext
253
254\installsystemnamespace{ctxfunction}
255
256\permanent\protected\def\startctxfunctiondefinition #1 % \stopctxfunctiondefinition
257  {\begingroup \obeyluatokens \luat_start_lua_function_definition_indeed{#1}}
258
259\installsystemnamespace{luafunction}
260
261\def\luat_start_lua_function_definition_indeed#1#2\stopctxfunctiondefinition
262  {\endgroup
263   \expandafter\chardef\csname\??luafunction#1\endcsname\ctxcommand{ctxfunction(\!!bs#2\!!es)}\relax
264   \edefcsname#1\endcsname{\noexpand\luafunction\csname\??luafunction#1\endcsname}}
265
266\permanent\protected\def\setctxluafunction#1#2% experiment
267  {\expandafter\chardef\csname\??luafunction#1\endcsname#2\relax
268   \edefcsname#1\endcsname{\noexpand\luafunction\csname\??luafunction#1\endcsname}}
269
270\permanent\protected\lettonothing\stopctxfunctiondefinition
271
272\permanent\protected\def\startctxfunction #1 % \stopctxfunction
273  {\begingroup \obeyluatokens \luat_start_lua_function_indeed{#1}}
274
275\def\luat_start_lua_function_indeed#1#2\stopctxfunction
276  {\endgroup\edefcsname\??ctxfunction#1\endcsname{\noexpand\luafunction\ctxcommand{ctxfunction(\!!bs#2\!!es)}\relax}}
277
278\permanent\protected\lettonothing\stopctxfunction
279
280\permanent\def\ctxfunction#1%
281  {\begincsname\??ctxfunction#1\endcsname}
282
283%D In theory this is faster due to the call not being wrapped in a function but in
284%D practice the speedup can't be noticed. The actions called for often have lots of
285%D lookups so an extra one doesn't matter much. The kind of calls differs a lot per
286%D document and often there are other ways to optimize a style. For instance we can
287%D gain a lot when defining a font, but when a frozen definition is used that gain
288%D gets completely lost. For some calls (take list writers) it can get worse if only
289%D because readability gets worse and passing is already efficient due to selective
290%D flushing, while with the token scanners one has to scan all of them.
291
292% \startctxfunctiondefinition foo commands.foo() \stopctxfunctiondefinition
293%
294% \installctxfunction\foo{commands.foo}
295
296\permanent\protected\def\installctxfunction#1#2% expandable
297  {\edef\m_syst_name{\csstring#1}%
298   \global\expandafter\normalluadef\csname\m_syst_name\endcsname\ctxcommand{ctxfunction(\!!bs#2\!!es,true)}\relax}
299
300\permanent\protected\def\installctxscanner#1#2% expandable
301  {\edef\m_syst_name{\csstring#1}%
302   \global\expandafter\normalluadef\csname\m_syst_name\endcsname\ctxcommand{ctxscanner("\m_syst_name",\!!bs#2\!!es,true)}\relax}
303
304\permanent\protected\def\installprotectedctxfunction#1#2% protected
305  {\edef\m_syst_name{\csstring#1}%
306   \global\protected\expandafter\normalluadef\csname\m_syst_name\endcsname\ctxcommand{ctxfunction(\!!bs#2\!!es,true)}\relax}
307
308\permanent\protected\def\installprotectedctxscanner#1#2% protected
309  {\edef\m_syst_name{\csstring#1}%
310   \global\protected\expandafter\normalluadef\csname\m_syst_name\endcsname\ctxcommand{ctxscanner("\m_syst_name",\!!bs#2\!!es,true)}\relax}
311
312% \permanent\protected\def\resetctxscanner#1%
313%   {\edef\m_syst_name{\csstring#1}%
314%    \gletcsname\m_syst_name\endcsname\relax} % or better nothing
315
316\permanent\protected\def\resetctxscanner#1%
317  {\global\expandafter\lettonothing\csname\csstring#1\endcsname}
318
319\protect \endinput
320