# In LuaLaTeX, how do I pass the content of an environment to Lua verbatim?

In LuaLaTeX, how would I go about capturing the content of an environment for (verbatim) processing by Lua? For example, consider something like

\begin{foobar}
Hello {World}
\end{foobar}


I'd like to be able to take the content of the environment and pass it to Lua, as in

foobar("  Hello {World}\n")


(and Lua would then eventually pass the processed version back to LaTeX, but I can presumably handle that).

-
If you think that one of the answers solves your problem, you should accept it. If it doesn't, it would be nice to hear what could be improved. – dıʞsdoʇ Dec 16 '11 at 13:04

Start the "recording" mode when you enter \begin{foobar} and end it when you close the environment. That way you get the pure buffer contents.

\documentclass{article}
\usepackage{luacode}
\begin{luacode*}
do
local mybuf = ""
mybuf = mybuf .. buf .. "\n"
end
function startrecording()
end

function stoprecording()
local buf_without_end = mybuf:gsub("\\end{foobar}\n","")
print(string.format("Lua: %q", buf_without_end))
end
end
\end{luacode*}
\begin{document}
\newenvironment{foobar}{\directlua{startrecording()}}{\directlua{stoprecording()}}
\begin{foobar}
Hello {World}
\end{foobar}

\end{document}

-
 Amazing! Why do you include the lua code inside a closure do...end? Just best practice in lua coding? – cjorssen Dec 14 '11 at 11:29 @cjorssen I define a local variable mybuf (which act as a kind of global variable for these two functions) and I don't want it to be visible outside the scope of the functions where I use it (to avoid clashes). In this case it is actually not necessary as the do / end pair is implicitly given by the luacode environment, but I like the explicit scoping here so anyone can see "hey, there is something inside that scope that must not be visible outside". – dıʞsdoʇ Dec 14 '11 at 11:44 In your example: Is it also possible to suppress the TeX output of the contents of {foobar}? I.e. read the environement contents to Lua, but hide it from TeX? – arney Mar 24 at 23:55 @arney I am not sure (didn't try) - did you try to return nil or an empty string from readbuf()? – dıʞsdoʇ Mar 25 at 7:15

In ConTeXt, you can simply use buffers for this.

\def\startfoobar
{\definebuffer[foobar][startfoobar][stopfoobar]}

\def\stopfoobar
{\ctxlua{userdata.luafunction(buffers.getcontents('foobar'))}


The function userdata.luafunction will then receive the contents of the environment.

See the ConTeXt wiki for more examples.

-