0

I store contents in lua variables and use them in a lualatex document. I know how to do insert that content in the TeX flow, in a macro but I don't know how to launch a lua program contained in a lua variable.

\documentclass{article}  
\usepackage{luatextra} % pour LuaLaTex  
\begin{document}  
\newcommand{\amacro}[1]{*#1*}  
\luaexec{  
a=1  
atext='stupid text'  
apgm='a=a+1' % the content is a program  
}  
\luaexec{tex.print(atext)} % contents in the TeX flow  : works  
\amacro{\luaexec{tex.print(atext)}} % contents used in a macro : works  
\luaexec{\luaexec{tex.print(apgm)}} % contents used as a program : fails 
\luaexec{tex.print(a)}  
\end{document}  

How shall I launch the lua program stored in the lua variable apgm ?

  • please fix your example so people can run it, it is missing a \documentclass line and a definition for \luaexec and \lprint – David Carlisle Sep 2 '17 at 12:07
  • I would guess that you are using the luacode packge but you don't say? the primitive \directlua is expandable so more easily nested in this way, but storing the lua expression in a lua string and passing back to tex to be re-evaluated as lua is somewhat unusual (and means you will have lots of issues of quoting any characters special to tex or lua) , what is the actual use case? – David Carlisle Sep 2 '17 at 12:11
  • why are you storing a+1 as a string (so needing a nested execution) rather than defining a function? function apgm (a) return a+1 end ? – David Carlisle Sep 2 '17 at 12:32
  • @DavidCarlisle in fact I store bits of lua programs in a database and get them back to be executed. To be more precise, I insert these programs in a the value of a key-value to have them executed later. So itused to be : ...keyvalue1=\luaexec{a=a+1}, ... and I wish to replace the literal a=a+1 by a lua variable containing "a=a+1". – user1771398 Sep 2 '17 at 12:39
  • 1
    but why store a lua function in a lua string rather than a lua function ? The issue with \directlua/\luaexec is basically as described in answers to your earlier question tex.stackexchange.com/questions/284748/… where as egreg explained there, \luaexec is not expandable. But here I do not think you needed nested eval at all. – David Carlisle Sep 2 '17 at 12:42
1

You can use the load() function from Lua and load your code stored in apgm without tossing it to TeX and back.

\documentclass{article}
\usepackage{luacode}
\begin{document}

\newcommand{\amacro}[1]{bla#1bla}
\newcommand{\lprint}[1]{\directlua{tex.print(#1)}}
\newcommand{\leval}[1]{\directlua{assert(load(#1))()}}

\luaexec{  
a=1  
atext='stupid text'  
apgm='a=a+1' % the content is a program  
}

\lprint{atext} % contents in the TeX flow  : works  

\amacro{\lprint{atext}} % contents used in a macro : works  

\lprint{a} % prints 1
\leval{apgm} % contents used as a program
\lprint{a} % prints 2
\end{document}

Note the \leval macro which just loads and immediately executes the code stored in a Lua variable. Assert is helpful in case of syntax errors in the loaded code. Without it the error message becomes too cryptic.

  • @David also : I agree that "the natural Lua datatype to hold a program fragment is a function not a string". But I have a string (that come from a database). The key between the two is "load". I understood the propositions of you both thus : I replaced \luadirect{a=a+1} first by \luadirect{function anonymous() a=a+1; anonymous()} and then naturally by \luadirect{load(apgm)()} where apgm="a=a+1" coming from the database. And it works in the real context :) – user1771398 Sep 2 '17 at 21:12
  • @David : avoiding going to TeX and back is a big plus : it avoids problems with special TeX characters. – user1771398 Sep 2 '17 at 21:48
2

The use case seems a bit strange and you have not defined \luaexec or \lprint but I think you want something like this:

enter image description here

\documentclass{article}
\begin{document}

\newcommand{\amacro}[1]{bla#1bla}

\directlua{  
a=1  
atext='stupid text'  
apgm='a=a+1' % the content is a program  
}

\directlua{tex.print(atext)} % contents in the TeX flow  : works  

\amacro{\directlua{tex.print(atext)}} % contents used in a macro : works  

\directlua{tex.print(a)} % a is 1

\directlua{\directlua{tex.print(apgm)}} % nested lua eval why??????

\directlua{tex.print(a)} % a is 2

 \end{document}

You can avoid going to tex and back by using load() as in Sergei's answer, however the natural Lua datatype to hold a program fragment is a function not a string.

The same output is obtained from the following without needing any nested evaluation.

\documentclass{article}
\begin{document}

\newcommand{\amacro}[1]{bla#1bla}

\directlua{  
a=1  
atext='stupid text'  
function apgm () a=a+1 end % the content is a program  
}

\directlua{tex.print(atext)} % contents in the TeX flow  : works  

\amacro{\directlua{tex.print(atext)}} % contents used in a macro : works  

\directlua{tex.print(a)} % a is 1

\directlua{apgm()} %

\directlua{tex.print(a)} % a is 2

 \end{document}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.