%D \module %D [ file=luat-ini, %D version=2005.08.11, %D title=\CONTEXT\ Lua Macros, %D subtitle=Initialization, %D author=Hans Hagen, %D date=\currentdate, %D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] %C %C This module is part of the \CONTEXT\ macro||package and is %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. \writestatus{loading}{ConTeXt Lua Macros / Initialization} \unprotect %D Loading lua code can be done using \type {startup.lua}. The following %D method uses the \TEX\ input file locator of kpse. At least we need to %D use that way of loading when we haven't yet define our own code, which %D we keep outside the format. We will keep code outside \TEX\ files as %D much as possible. \ifdefined\setnaturalcatcodes \else \let\setnaturalcatcodes\relax \fi \ifdefined\obeylualines \else \let\obeylualines \relax \fi \ifdefined\obeyluatokens \else \let\obeyluatokens \relax \fi %D A few more goodies: \let\stoplua \relax % tex catcodes \let\stopluacode\relax % lua catcodes % It might makes sense to have a \type {\directelua} so that we can avoid % the \type {\normalexpanded} around \type {\directlua}. Something to discuss % in the team. \normalprotected\def\startlua % \stoplua {\begingroup \obeylualines \luat_start_lua_indeed} \def\luat_start_lua_indeed#1\stoplua {\normalexpanded{\endgroup\noexpand\directlua{#1}}} % \zerocount is default \normalprotected\def\startluacode % \stopluacode {\begingroup \obeylualines \obeyluatokens \luat_start_lua_code_indeed} \def\luat_start_lua_code_indeed#1\stopluacode {\normalexpanded{\endgroup\noexpand\directlua{#1}}} % \zerocount is default %D Some delayed definitions: \ifdefined\obeylines \else \let\obeylines \relax \fi \ifdefined\obeyedline \else \let\obeyedline \relax \fi \ifdefined\obeyspaces \else \let\obeyspaces \relax \fi \ifdefined\obeyedspace \else \let\obeyedspace \relax \fi \let\obeylualines\relax \newtoks\everyluacode \edef\lua_letter_backslash{\string\\} \edef\lua_letter_bar {\string\|} \edef\lua_letter_dash {\string\-} \edef\lua_letter_lparent {\string\(} \edef\lua_letter_rparent {\string\)} \edef\lua_letter_lbrace {\string\{} \edef\lua_letter_rbrace {\string\}} \edef\lua_letter_squote {\string\'} \edef\lua_letter_dquote {\string\"} \edef\lua_letter_n {\string\n} \edef\lua_letter_r {\string\r} \edef\lua_letter_f {\string\f} \edef\lua_letter_t {\string\t} \edef\lua_letter_a {\string\a} \edef\lua_letter_b {\string\b} \edef\lua_letter_v {\string\v} \edef\lua_letter_s {\string\s} \edef\lua_letter_one {\string\1} \edef\lua_letter_two {\string\2} \edef\lua_letter_three {\string\3} \edef\lua_letter_four {\string\4} \edef\lua_letter_five {\string\5} \edef\lua_letter_six {\string\6} \edef\lua_letter_seven {\string\7} \edef\lua_letter_eight {\string\8} \edef\lua_letter_nine {\string\9} \edef\lua_letter_zero {\string\0} \everyluacode {% \appendtoks \let\\\lua_letter_backslash \let\|\lua_letter_bar \let\-\lua_letter_dash \let\(\lua_letter_lparent \let\)\lua_letter_rparent \let\{\lua_letter_lbrace \let\}\lua_letter_rbrace \let\'\lua_letter_squote \let\"\lua_letter_dquote \let\n\lua_letter_n \let\r\lua_letter_r \let\f\lua_letter_f \let\t\lua_letter_t \let\a\lua_letter_a \let\b\lua_letter_b \let\v\lua_letter_v \let\s\lua_letter_s \let\1\lua_letter_one \let\2\lua_letter_two \let\3\lua_letter_three \let\4\lua_letter_four \let\5\lua_letter_five \let\6\lua_letter_six \let\7\lua_letter_seven \let\8\lua_letter_eight \let\9\lua_letter_nine \let\0\lua_letter_zero } % \to \everyluacode \normalprotected\def\obeyluatokens {\setcatcodetable\luacatcodes \the\everyluacode} \edef\luamajorversion{\ctxwrite{LUAMINORVERSION}} \edef\luaminorversion{\ctxwrite{LUAMAJORVERSION}} %D We need a way to pass strings safely to \LUA\ without the %D need for tricky escaping. Compare: %D %D \starttyping %D \ctxlua {something("anything tricky can go here")} %D \ctxlua {something([\luastringsep[anything tricky can go here]\luastringsep])} %D \stoptyping \def\luastringsep{===} % this permits \typefile{self} otherwise nested b/e sep problems \edef\!!bs{[\luastringsep[} \edef\!!es{]\luastringsep]} %D We have a the following available as primitive so there is no need %D for it: %D %D \starttyping %D \edef\luaescapestring#1{\!!bs#1\!!es} %D \stoptyping \def\setdocumentfilename #1#2{\clf_setdocumentfilename\numexpr#1\relax{#2}} \def\setdocumentargument #1#2{\clf_setdocumentargument{#1}{#2}} \def\setdocumentargumentdefault#1#2{\clf_setdocumentdefaultargument{#1}{#2}} \def\getdocumentfilename #1{\clf_getdocumentfilename\numexpr#1\relax} \def\getdocumentargument #1{\clf_getdocumentargument{#1}{}} \def\setdocumentargument #1#2{\clf_setdocumentargument{#1}{#2}} \def\getdocumentargumentdefault#1#2{\clf_getdocumentargument{#1}{#2}} % seldom used so no need for speedy variants: \def\doifelsedocumentargument #1{\doifelsesomething{\clf_getdocumentargument{#1}}} \def\doifdocumentargument #1{\doifsomething {\clf_getdocumentargument{#1}}} \def\doifnotdocumentargument #1{\doifnothing {\clf_getdocumentargument{#1}}} \def\doifelsedocumentfilename #1{\doifelsesomething{\clf_getdocumentfilename\numexpr#1\relax}} \def\doifdocumentfilename #1{\doifsomething {\clf_getdocumentfilename\numexpr#1\relax}} \def\doifnotdocumentfilename #1{\doifnothing {\clf_getdocumentfilename\numexpr#1\relax}} \let\doifdocumentargumentelse\doifelsedocumentargument \let\doifdocumentfilenameelse\doifelsedocumentfilename %D A handy helper: \def\luaexpanded#1{\luaescapestring\expandafter{\normalexpanded{#1}}} %D Experimental: \normalprotected\def\startluaparameterset[#1]% {\begingroup \obeylualines \obeyluatokens \luat_start_lua_parameter_set{#1}} \def\luat_start_lua_parameter_set#1#2\stopluaparameterset {\ctxlua{parametersets["#1"]={#2}}% \endgroup} \let\stopluaparameterset\relax \def\luaparameterset#1#2{\ctxlua{parametersets["#1"]={#2} context("#1")}} % todo: \mergeparameterset % usage: % % \startluaparameterset [u3d:myset:display:1] % toolbar=false, % tree=true % \stopluaparameterset % % option=u3d:myset:display:1 % % or: % % option=\luaparameterset{u3d:myset:display:1}{toolbar=false,tree=true} %D A Handy helper: \def\luaconditional#1{\ifcase#1tru\else fals\fi e} %D Goodie: %D %D \starttyping %D \ctxluacode{context("%0.5f",1/3)} %D \stoptyping \normalprotected\def\ctxluacode {\begingroup \obeylualines \obeyluatokens \catcode\leftbraceasciicode \plusone \catcode\rightbraceasciicode\plustwo \afterassignment\luat_lua_code \scratchtoks=} % Hm, are we sure that the \* commands work out okay here? We could probably % use \setcatcodetable\luacatcodes instead of \obeyluatokens now. \def\luat_lua_code {\normalexpanded{\endgroup\noexpand\directlua\expandafter{\the\scratchtoks}}} % \zerocount is default % \startctxfunction MyFunctionA % context(" A1 ") % \stopctxfunction % % \startctxfunctiondefinition MyFunctionB % context(" B2 ") % \stopctxfunctiondefinition % % \starttext % \dorecurse{10000}{\ctxfunction{MyFunctionA}} \page % \dorecurse{10000}{\MyFunctionB} \page % \dorecurse{10000}{\ctxlua{context(" C3 ")}} \page % \stoptext \installsystemnamespace{ctxfunction} \normalprotected\def\startctxfunctiondefinition #1 % {\begingroup \obeylualines \obeyluatokens \luat_start_lua_function_definition_indeed{#1}} \installsystemnamespace{luafunction} \def\luat_start_lua_function_definition_indeed#1#2\stopctxfunctiondefinition {\endgroup \expandafter\chardef\csname\??luafunction#1\endcsname\ctxcommand{ctxfunction(\!!bs#2\!!es)}\relax \expandafter\edef\csname#1\endcsname{\noexpand\luafunction\csname\??luafunction#1\endcsname}} \normalprotected\def\setctxluafunction#1#2% experiment {\expandafter\chardef\csname\??luafunction#1\endcsname#2\relax \expandafter\edef\csname#1\endcsname{\noexpand\luafunction\csname\??luafunction#1\endcsname}} \let\stopctxfunctiondefinition\relax \normalprotected\def\startctxfunction #1 % {\begingroup \obeylualines \obeyluatokens \luat_start_lua_function_indeed{#1}} \def\luat_start_lua_function_indeed#1#2\stopctxfunction {\endgroup\expandafter\edef\csname\??ctxfunction#1\endcsname{\noexpand\luafunction\ctxcommand{ctxfunction(\!!bs#2\!!es)}\relax}} \let\stopctxfunction\relax \def\ctxfunction#1% {\csname\??ctxfunction#1\endcsname} % In theory this is faster due to the call not being wrapped in a function but in % practice the speedup can't be noticed. The actions called for often have lots of % lookups so an extra one doesn't matter much. The kind of calls differs a lot per % document and often there are other ways to optimize a style. For instance we can % gain a lot when defining a font, but when a frozen definition is used that gain % gets completely lost. For some calls (take list writers) it can get worse if only % because readability gets worse and passing is already efficient due to selective % flushing, while with the token scanners one has to scan all of them. % \startctxfunctiondefinition foo commands.foo() \stopctxfunctiondefinition % % \installctxfunction\foo{commands.foo} % This is a forward definition: % \def\checkedstrippedcsname#1% this permits \strippedcsname{\xxx} and \strippedcsname{xxx} % {\expandafter\syst_helpers_checked_stripped_csname\string#1} % % \def\syst_helpers_checked_stripped_csname#1% % {\if\noexpand#1\letterbackslash\else#1\fi} \ifdefined\normalluadef \normalprotected\def\installctxfunction#1#2% expandable {\edef\m_syst_name{\csstring#1}% \global\expandafter\normalluadef\csname\m_syst_name\endcsname\ctxcommand{ctxfunction("#2",true)}\relax} \normalprotected\def\installctxscanner#1#2% expandable {\edef\m_syst_name{\csstring#1}% \global\expandafter\normalluadef\csname\m_syst_name\endcsname\ctxcommand{ctxscanner("\m_syst_name","#2",true)}\relax} \normalprotected\def\installprotectedctxfunction#1#2% protected {\edef\m_syst_name{\csstring#1}% \global\normalprotected\expandafter\normalluadef\csname\m_syst_name\endcsname\ctxcommand{ctxfunction("#2",true)}\relax} \normalprotected\def\installprotectedctxscanner#1#2% protected {\edef\m_syst_name{\csstring#1}% \global\normalprotected\expandafter\normalluadef\csname\m_syst_name\endcsname\ctxcommand{ctxscanner("\m_syst_name","#2",true)}\relax} \normalprotected\def\resetctxscanner#1% {\edef\m_syst_name{\csstring#1}% \expandafter\glet\csname\m_syst_name\endcsname\relax} % \let\installctxfunctioncall \installctxfunction % \let\installctxscannercall \installctxscanner % \let\installprotectedctxfunctioncall\installprotectedctxfunction % \let\installprotectedctxscannercall \installprotectedctxscanner \else \ifdefined\luafunctioncall \else \normalprotected\def\luafunctioncall{\luafunction} \fi \normalprotected\def\installctxfunction#1#2% expandable {\edef\m_syst_name{\csstring#1}% \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxfunction("#2",true)}\relax \expandafter\xdef\csname\m_syst_name\endcsname{\noexpand\luafunction\csname\??luafunction\m_syst_name\endcsname}} \normalprotected\def\installctxscanner#1#2% expandable {\edef\m_syst_name{\csstring#1}% \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxscanner("\m_syst_name","#2",true)}\relax \expandafter\xdef\csname\m_syst_name\endcsname{\noexpand\luafunction\csname\??luafunction\m_syst_name\endcsname}} \normalprotected\def\installprotectedctxfunction#1#2% protected {\edef\m_syst_name{\csstring#1}% \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxfunction("#2",true)}\relax \expandafter\xdef\csname\m_syst_name\endcsname{\noexpand\luafunctioncall\csname\??luafunction\m_syst_name\endcsname}} \normalprotected\def\installprotectedctxscanner#1#2% protected {\edef\m_syst_name{\csstring#1}% \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxscanner("\m_syst_name","#2",true)}\relax \expandafter\xdef\csname\m_syst_name\endcsname{\noexpand\luafunctioncall\csname\??luafunction\m_syst_name\endcsname}} \normalprotected\def\resetctxscanner#1% {\edef\m_syst_name{\csstring#1}% \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\zerocount \expandafter\glet\csname\m_syst_name\endcsname\relax} % \normalprotected\def\installctxfunctioncall#1#2% % {\edef\m_syst_name{\csstring#1}% % \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxfunction("#2",true)}\relax % \expandafter\xdef\csname\m_syst_name\endcsname{\luafunctioncall\csname\??luafunction\m_syst_name\endcsname}} % % \normalprotected\def\installctxscannercall#1#2% % {\edef\m_syst_name{\csstring#1}% % \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxscanner("\m_syst_name","#2",true)}\relax % \expandafter\xdef\csname\m_syst_name\endcsname{\luafunctioncall\csname\??luafunction\m_syst_name\endcsname}} % % \normalprotected\def\installprotectedctxfunctioncall#1#2% % {\edef\m_syst_name{\csstring#1}% % \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxfunction("#2",true)}\relax % \normalprotected\expandafter\xdef\csname\m_syst_name\endcsname{\luafunctioncall\csname\??luafunction\m_syst_name\endcsname}} % % \normalprotected\def\installprotectedctxscannercall#1#2% % {\edef\m_syst_name{\csstring#1}% % \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxscanner("\m_syst_name","#2",true)}\relax % \normalprotected\expandafter\xdef\csname\m_syst_name\endcsname{\luafunctioncall\csname\??luafunction\m_syst_name\endcsname}} \fi \protect \endinput