# ConTeXt: How to use xmlflush in lua?

I tried to use context's xml with this xhtml file.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<body>
<q>Some quote with <em>italic</em> and a nested <q>quote</q></q>
</body>
</html>


with this environment file

\startxmlsetups xml:setup
\xmlsetsetup{\xmldocument}{*}{-}
\xmlsetsetup{\xmldocument}{html|body|q|em}{xml:*}
\stopxmlsetups

\xmlregistersetup{xml:setup}

\startxmlsetups xml:html
\xmlflush{#1}
\stopxmlsetups

\startxmlsetups xml:body
\startdocument
\xmlflush{#1}
\stopdocument
\stopxmlsetups

\startxmlsetups xml:q
\quotation{\xmlflush{#1}}
%\xmlfunction{#1}{q}
\stopxmlsetups
\startluacode
function xml.functions.q(t)
context.quotation(lxml.flush(t)) --does not work
end
\stopluacode

\definebodyfontenvironment[default][em=italic]
\startxmlsetups xml:em
\dontleavehmode{\em \xmlflush{#1}}
\stopxmlsetups


This works if I use the TeX version. If I switch to the lua function it does not work anymore. Whats the lua equivalent of \quotation{\xmlflush{#1}}?

• context.quotation(lxml.flush(t)) cannot work you expect, because lxml.flush(t) does not return anything. What is the reason why you want to do this at the Lua end? Aug 30, 2017 at 21:30
• Thanks for clarification. I was trying to do this because its easier in lua to have conditionals cause I can use logical operators. Aug 31, 2017 at 7:20
• I have updated my answer after reading the ConTeXt Lua Documents manual. Very useful! Jan 13, 2018 at 2:25

First of all, context.quotation(lxml.flush(t)) cannot work because lxml.flush does not yield a return value. Why that is and what the consequences are is discussed below.

You have encountered the hen-egg problem of LuaTeX. The fundamental question of which comes first, the Lua backend code or the typeset output.

The LuaTeX designers decided, that the Lua backend code comes first. Therefore, there is no way to access text which is typeset using tex.sprint in the same Lua chunk (which is what lxml.flush does under the hood). You first have to hand back to the TeX end before you process it. In this case the solution is to simply do \quotation{\xmlfunction{#1}{q}}.

Taking a closer look we realize that when we call the function quotation the arguments are evaluated before the function is called. That means that lxml.flush(t) happens before quotation even starts and the output has already been handed back to TeX. That is why we need to defer the evaluation using a lambda function.

function xml.functions.q(t)
context.quotation(function() lxml.flush(t) end)
end


You can find more such tricks in section 3 “More on functions” of the ConTeXt Lua Documents manual.

\startbuffer[test]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<body>
<q>Some quote with <em>italic</em> and a nested <q>quote</q></q>
</body>
</html>
\stopbuffer

\startxmlsetups xml:setup
\xmlsetsetup{\xmldocument}{*}{-}
\xmlsetsetup{\xmldocument}{html|body|q|em}{xml:*}
\stopxmlsetups

\xmlregistersetup{xml:setup}

\startxmlsetups xml:html
\xmlflush{#1}
\stopxmlsetups

\startxmlsetups xml:body
\startdocument
\xmlflush{#1}
\stopdocument
\stopxmlsetups

\startxmlsetups xml:q
\xmlfunction{#1}{q}
\stopxmlsetups
\startluacode
function xml.functions.q(t)
context.quotation(function() lxml.flush(t) end)
end
\stopluacode

\definebodyfontenvironment[default][em=italic]
\startxmlsetups xml:em
\dontleavehmode{\em \xmlflush{#1}}
\stopxmlsetups

\xmlprocessbuffer{test}{test}{}