# How execute expl3 commands inside lua code

When I try execute expl3 commands inside Lua code, I get an error:

! Undefined control sequence.
\\  ->\let \reserved@e
\relax \let \reserved@f \relax \@ifstar {\let \reserv...

l.13 \test{1}


Yes, I know, what the example below possible write using fully expl3 functions, but I have some code, which save some data in Lua, so I need in example, how to execute expl3 code in Lua. Help me please that my example work in Lua. The second question, how I can in \directlua use space instead of ~, because ~ used in Lua too.

\documentclass{article}
\usepackage{expl3}
\ExplSyntaxOn
\prop_gset_from_keyval:Nn \g__my_prop
{ value0 = -1 , value1 = 0 }
\cs_new_eq:NN \PropRemovecn \prop_remove:cn
\ExplSyntaxOff
\newcommand{\test}[1]{%
\directlua{%
if #1==1 then
tex.print("\\PropRemovecn{g__my_prop}{value1}")
end
}}
\begin{document}
\test{1}
\end{document}


Your error comes from \directlua trying to expand \\. You get the same error from \edef\x{\\} (in LaTeX versions older than 2020-02-02). You need to make sure that \\ becomes two character tokens before the Lua interpreter kicks in. You can use either \string\\prop... or \luaescapestring{\prop...} (or, more expl3-y, \lua_escape:e).

Also, different from expanding a macro, whose replacement text is already tokenized, when you do tex.print it is as if you typed those tokens in the input file, at the time \directlua is expanded. Since you use your \test command outside of an expl3 code context, _ and : are not letters, so \prop_remove:cn is misinterpreted as \prop _remove:cn. As if you were typing the code yourself, you have to use \ExplSyntaxOn/Off:

tex.print("\luaescapestring{\\ExplSyntaxOn\\prop_remove:cn{g__my_prop}{value1}\\ExplSyntaxOff}")


However this has some overhead, and if you happened to use \test in the middle of some expl3 code, then it would recklessly do \ExplSyntaxOff without you wanting it to. I recommend defining an interface for \prop_remove:cn:

\documentclass{article}
\usepackage{expl3}
\ExplSyntaxOn
\prop_gset_from_keyval:Nn \g__my_prop
{ value0 = -1 , value1 = 0 }
\cs_new_eq:NN \PropRemovecn \prop_remove:cn
\ExplSyntaxOff
\newcommand{\test}[1]{%
\directlua{%
if #1==1 then
tex.print("\luaescapestring{\PropRemovecn{g__my_prop}{value1}}")
end
}}
\begin{document}
\test{1}
\end{document}


You can also pass a catcode table to tex.print as Ulrike suggested, then LuaTeX will print the tokens with that catcode setting. If you load l3cctab then you can use \int_use:N \c_code_cctab (the code definition has to be inside \ExplSyntaxOn/Off, in this case):

\documentclass{article}
\usepackage{expl3}
\usepackage{l3cctab}
\ExplSyntaxOn
\prop_gset_from_keyval:Nn \g__my_prop
{ value0 = -1 , value1 = 0 }
\cs_new_eq:NN \PropRemovecn \prop_remove:cn
\newcommand{\test}[1]{%
\lua_now:e {%
if~#1==1~then~
tex.print(\int_use:N \c_code_cctab,
"\lua_escape:e {\prop_remove:cn{g__my_prop}{value1}}")
end
}}
\ExplSyntaxOff
\begin{document}
\test{1}
\end{document}


As for your second question: if you need lots of spaces, define the command outside of the expl3 code environment (the fact that it's in \directlua doesn't matter, as the tokenization rules still apply when you define the \test macro).

• tex.print(\int_use:N\c_code_cctab,"\\prop_remove:cn{g__my_prop}{value1}") should work to set the catcode table (needs l3cctab). Jan 10, 2020 at 20:44
• @phelype-oleinik I edited my question and your variant compile with the same error. Jan 10, 2020 at 21:36
• @AleksandrKozlovskiy See my edit Jan 10, 2020 at 21:50
• +1: Are you sure, that LaTeX versions older than **2020-02-02** is correct? :) Jan 11, 2020 at 9:01
• @Dr.ManuelKuehner Yes (as odd as it may seem :-). In the current development version of LaTeX \\ has been made \protected, so it doesn't expand in \edef/\write/\directlua/etc. This development version is scheduled to be released on 2020-02-02, so it's LaTeX-from-the-future :-) You can try this version now using lualatex-dev (or xelatex-dev or pdflatex-dev). Jan 11, 2020 at 13:22