Changes

Jump to navigation Jump to search
2,480 bytes added ,  22:11, 29 September 2010
→‎Getting text into LuaTex verbatim: Now has two sections: one on verbatim macros, one on verbatim environments.
= Getting text into LuaTex verbatim =
Ordinarily, getting This section gives example code for passing text into to a call to a LuaTeX function verbatim. The first subsection shows how to define a TeX macro with spaces and newlinesintact requires mucking about with <code>\obeylinesDedent{...}</code> andthat processes its argument in LuaTeX; the second subsection shows how to define an environment <code>\obeyspacesstartDedent ... \stopDedent</code> &mdash; see that does the [[Inside_ConTeXt#Passing_verbatim_text_as_macro_parameter|Inside Context]] article on this wikisame. Luckily for usFirst, however, ConTeXt provides here is the <code>\dostartbuffer[</code><i>name</i><code>][</code><i>bufferstart</i><code>][<i>bufferstop</i><code>]</code> command, 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.contentdedent(</code><i>name</i><code>)</code>. Here is an example that shows how the buffer definition and the LuaTex call are combinedfunction.
<texcode>
%% Define a buffer \startDedent ... \stopDedent that feeds its contentsstartluacode%% to LuaTex for processing.%% LuaTex finds -- Keep our own functions out by how much of the first line is indented, and dedentsglobal namespace%% the entire block by that much. thirddata = thirddata or {}
\startluacode thirddata.dedent = function(namecode) % -- 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.
%% read out the buffer local code = buffers.content(name) %% -- 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, 4)}
\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.verbatim(\!!bs\normalunexpanded{#1}\!!es, 5)}%
\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\startDedentstartDedentB {\dostartbuffer[dedentBuffer][startDedentstartDedentB][stopDedentstopDedentB]}
% Make the ending command (which will also signal the buffer's end)
% call LuaTeX to read out the processing LuaTeXbuffer and dedent its contents.\def\stopDedentstopDedentB {\directlua{dedent local code = buffers.content("dedentBufferdedentbuffer") thirddata.dedent(buffers.content(code))}}
% Try it out:
\starttext
\startDedentstartDedentB
andra
moi
ennepe
\stopDedentstopDedentB
\stoptext
</texcode>
Each Don't worry about this code re-using the same named buffer each time: each<code>\stopDedentstopDedentB</code> immediately uses the <code>dedentBuffer</code>'scontents, and each <code>\startDedentstartDedentB</code> flushes the buffer's contents, sothe construction you can safely be used multiple times throughout the documentuse as many <code>\startDedentB</code> blocks as you want.
= Parsing input without exploding your head =

Navigation menu