How to Use LaTeX Macros in LuaLaTeX’s \directlua
At a glance
- 1. Choose the direction
Decide whether TeX should pass a macro’s expanded value to Lua or Lua should generate TeX code.
- 2. Escape text for Lua
Use \luaescapestring when inserting expanded TeX text into a quoted Lua string.
- 3. Build TeX output
Use tex.sprint to send text from Lua to TeX; construct backslashes as Lua characters when needed.
- 4. Check expansion
Remember that TeX expands much of the \directlua input before Lua executes it.
LuaLaTeX lets TeX and Lua exchange information, but they do not treat input the same way. TeX processes the contents of \directlua before Lua executes the resulting code. This means a TeX macro can expand while Lua code is being prepared, and a backslash intended for a LaTeX command may be interpreted by TeX before Lua sees it.
The safest approach depends on what you want to do: pass a macro’s text to Lua, or have Lua produce TeX commands. The examples below show both.
Pass an expanded macro value to Lua
Suppose a TeX macro holds plain text that Lua should use. Put \luaescapestring{...} inside a quoted Lua string:
\documentclass{article}
\newcommand{\person}{Ada}
\begin{document}
\directlua{
local person = "\luaescapestring{\person}"
tex.sprint("Hello, " .. person .. "!")
}
\end{document}
When TeX prepares the Lua code, \person expands to Ada. The \luaescapestring primitive escapes characters as needed for a Lua string, and Lua receives the value Ada. The call to tex.sprint then sends the resulting text back to TeX for typesetting.
This matters especially when the macro may contain quotation marks, backslashes, or other characters that have meaning in Lua source. Without escaping, a quote in the macro expansion could end the Lua string early and cause a Lua syntax error.
Have Lua generate a LaTeX command
If Lua should produce a command such as \textbf, it can construct the backslash as a character instead of putting a raw TeX control sequence in the Lua source:
\documentclass{article}
\begin{document}
\directlua{
tex.sprint(string.char(92) .. "textbf{Bold from Lua}")
}
\end{document}
string.char(92) returns the backslash character. Lua concatenates it with textbf{Bold from Lua} and tex.sprint sends that string to TeX, which processes it as \textbf{Bold from Lua}.
This technique is useful whenever Lua must generate TeX markup. It avoids confusion between a backslash in Lua source and a backslash that TeX might tokenize as the start of a control sequence.
What happens inside \directlua?
A useful mental model is that \directlua{...} is not a protected box of raw Lua text. TeX reads and expands its contents to form the Lua code that will run. Consequently, a TeX macro in that code may expand before Lua starts, and TeX-special input can affect the result.
There are two distinct directions of travel:
| Goal | Typical method |
|---|---|
| Give Lua the expanded text of a TeX macro | \luaescapestring{\mymacro} inside a quoted Lua string |
| Send text or markup from Lua to TeX | tex.sprint(...) |
| Include a backslash in Lua-generated TeX markup | string.char(92) |
Treat text and TeX code differently. A macro that expands to ordinary text is usually suitable as data for Lua. A macro that expands to formatting commands or other TeX code may not behave like plain text when expanded during Lua-code preparation. If you need Lua to emit markup, construct or store that markup deliberately and send it with tex.sprint.
Common mistakes
Inserting text into a Lua string without escaping it
This can fail if the macro expands to a quotation mark, backslash, or other character with special meaning in Lua. Use \luaescapestring for expanded text inside a quoted Lua string.
Expecting Lua to expand a TeX macro
Lua does not know TeX’s macro definitions. TeX expansion happens as \directlua is prepared; Lua only receives the resulting Lua code. If Lua needs a macro’s value, arrange for TeX to pass that value in.
Assuming tex.sprint typesets text directly
tex.sprint inserts tokens for TeX to process. If the string contains a TeX command, TeX interprets that command; if it contains ordinary text, TeX typesets the text. Invalid or unintended TeX markup can therefore cause TeX errors just as it would in the document source.
Confusing a TeX backslash with a Lua escape
Lua gives backslashes in quoted strings their own escape meanings. A string containing a sequence such as \t may be read as a tab escape rather than as a TeX command beginning with \text.... Building the backslash with string.char(92) sidesteps that ambiguity.
When to use each method
Use \luaescapestring when a TeX macro supplies data to Lua, such as a name or a short piece of text. Use tex.sprint when Lua needs to send output back for TeX to typeset. If that output includes a LaTeX command, construct the command string so that the backslash reaches TeX as a character, rather than accidentally becoming part of the Lua source’s syntax.
References
- LuaTeX Reference Manual
Spotted an error? Send a correction. Read how we write and check articles in our editorial policy.