Changes

Jump to navigation Jump to search
5,021 bytes removed ,  00:01, 3 October 2010
→‎Getting text into LuaTex verbatim: Moving and rewriting the section
The lua functions such as <code>context.bTABLE()</code> and <code>context.bTR()</code> are just abbreviations for running <code>context ("\\bTABLE")</code>, <code>context("\\bTR")</code>, etc. See the [http://www.pragma-ade.com/general/manuals/cld-mkiv.pdf ConTeXt lua document] manual for more details about such functions. The rest of the code is a simple nested for-loop that computes the sum of two dice. We do not need to worry about macro expansion at all!
= Getting text into LuaTex verbatim =
This section gives example code for passing text to a call to a LuaTeX function verbatim. The first subsection shows how to define a macro <code>\Dedent{...}</code> that processes its argument in LuaTeX; the second subsection shows how to define an environment <code>\startDedent ... \stopDedent</code> that does the same. First, however, here is the LuaTeX <code>dedent()</code> function.
 
<texcode>
\startluacode
 
-- Keep our own functions out of the global namespace
thirddata = thirddata or {}
 
thirddata.dedent = function(code)
-- Finds out by how much the first line is indented,
-- and dedents the entire block by that much.
-- N.B. This function does not handle tabs.
 
-- First some debugging stuff: dump the input to a text file
-- to check that we got what we wanted.
-- Feel free to delete these three lines.
logfile = io.open("debug.txt", "w")
logfile:write(code)
logfile:close()
 
-- Now for the meat of it.
-- How many leading spaces in the first line?
lead = string.match(code, '^ +') or ''
-- remove lead from every line
code = string.gsub(code, '^' .. lead, '')
code = string.gsub(code, '\n' .. lead, '\n')
 
-- print the resulting starttyping environment to the TeX stream
-- (context.starttyping() doesn't seem to work)
tex.sprint("\\starttyping" .. "\n" ..
code ..
"\\stoptyping" .. "\n")
end
 
\stopluacode
</texcode>
 
== A macro that passes its argument to LuaTeX verbatim ==
 
<!-- wikify \obeylines, \obeyspaces, \begingroup, \normalunexpanded -->
This code uses the two-macro pattern. The first macro begins a grouping with
<code>\begingroup</code>, initialises <code>\obeylines</code> and
<code>\obeyspaces</code>, and finally calls <code>\doDedent</code>. The
<code>\doDedent</code> macro, after performing the call to LuaTex, then closes
the grouping, thereby turning off the no-longer-needed<code>\obeylines</code>
and <code>\obeyspaces</code>. Macros' contents get expanded before they are
evaluated, so if this were all one single macro its argument <code>#1</code>
would get expanded the normal way before the <code>\obey...</code> could take
effect.
 
<texcode>
%% This code is due to Wolfgang Schuster on the ntg-ConTeXt mailing list.
\unprotect
% Two-macro structure to define \Dedent{...}
\def\Dedent{\begingroup\obeylines\obeyspaces\doDedent}
\def\doDedent#1{\directlua{
thirddata.dedent(\!!bs\normalunexpanded{#1}\!!es)}
\endgroup}
\protect
 
% Try it out
\starttext
\DedentOne{
andra
moi
ennepe}
\stoptext
</texcode>
 
== An environment that passes its contents to LuaTeX verbatim ==
 
There are two ways to define a startstop environment so that it passes its
contents to LuaTeX verbatim. The first resembles the macro definition in the
previous structure. The second makes use of
<code>\dostartbuffer[</code><i>name</i><code>][</code><i>bufferstart</i><code>][<i>bufferstop</i><code>]</code>, which creates a pair of buffer commands that write their contents verbatim to a named buffer. This buffer can then be accessed in LuaTeX via <code>buffers.content(</code><i>name</i><code>)</code>. Examples of both are provided below.
 
<!--
[[Inside_ConTeXt#Passing_verbatim_text_as_macro_parameter|Inside Context]]
article on this wiki. Luckily, however, ConTeXt provides the
-->
 
First, a definition using the two-macro pattern seen above. The cleaner named-buffer pattern is below.
<texcode>
% This code, too, is due to Wolfgang Schuster on the ntg-ConTeXt mailing list.
\unprotect
\def\startDedentA
{\begingroup
\obeylines\obeyspaces%
\dostartDedentA}
\def\dostartDedentA#1\stopDedentA
{\ctxlua{thirddata.dedent(\!!bs\normalunexpanded{#1}\!!es)}%
\endgroup}
\protect
 
% Try it out:
\starttext
\startDedentA
andra
moi
ennepe
\stopDedentA
\stoptext
</texcode>
 
<texcode>
%% Define a buffer \startDedentA ... \stopDedentB that feeds its contents
%% to LuaTex for processing.
 
% Tell TeX what strings the dedentBuffer starts and ends with.
\def\startDedentB
{\dostartbuffer[dedentBuffer][startDedentB][stopDedentB]}
% Make the ending command (which will also signal the buffer's end)
% call LuaTeX to read out the buffer and dedent its contents.
\def\stopDedentB
{\directlua{
local code = buffers.content("dedentbuffer")
thirddata.dedent(buffers.content(code))}}
 
% Try it out:
\starttext
\startDedentB
andra
moi
ennepe
\stopDedentB
\stoptext
</texcode>
 
Don't worry about this code re-using the same named buffer each time: each
<code>\stopDedentB</code> immediately uses the <code>dedentBuffer</code>'s contents, and each <code>\startDedentB</code> flushes the buffer's contents, so you can use as many <code>\startDedentB</code> blocks as you want.
= Parsing input without exploding your head =

Navigation menu