Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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).

share|improve this question
2  
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. –  topskip Dec 16 '11 at 13:04
add comment

2 Answers

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 = ""
  function readbuf( buf )
    mybuf = mybuf .. buf .. "\n" 
  end
  function startrecording()
    luatexbase.add_to_callback('process_input_buffer', readbuf, 'readbuf')
  end

  function stoprecording()
    luatexbase.remove_from_callback('process_input_buffer', 'readbuf')
    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}
share|improve this answer
    
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". –  topskip 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 '13 at 23:55
    
@arney I am not sure (didn't try) - did you try to return nil or an empty string from readbuf()? –  topskip Mar 25 '13 at 7:15
add comment

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.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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