Changes

Jump to navigation Jump to search
1,980 bytes added ,  09:06, 22 September 2015
m
Corrected typo in URL to lpeg
= To Calling Lua from TeX and vice versa =
The interweaving of ConTeXt and Lua consists of two elements: first you tell TeX that you're starting some Lua code; then, once inside Lua, you need to use the appropriate functions to put things into the TeX stream.
-- Print a countdown '10, 8, ..., 0!'
-- `..` is Lua for string concatenation
-- Look! we can use # and $ with impunity!
for i = 10, 2, -2 do
context(i .. ", ")
end
context("0!")  -- \\par is equivalent to a blank line in the input -- (Notice the escaped backslash: TeX won't mind the above comment.) context.par() 
-- Look! we can use # and $ with impunity!
context("Unless we print them, then we must \\#\\$\\& print the escape themcharacters, too.")
\stopluacode
</texcode>
== Putting Lua code in an external file == You can put your lua code in an external file (with the <code>.lua</code> extension) and include it with the <code>require</code> command: <texcode>\startluacode-- include the file my-lua-lib.luarequire("my-lua-lib")\endluacode</texcode> == Namespaces ===
It is a good habit to put your custom-defined functions in their own namespace. The traditional namespace for this is <code>userdata</code>:
-- if userdata doesn't exist yet, create it
userdata = userdata or {}
-- define a shorter synonym
u = userdata
-- create my custom function inside the userdata namespace
function userdatau.myfunction()
-- do stuff
end
\stopluacode
</texcode>
The full list of canonical namespaces, taken from [http://minimals.contextgarden.net/current/context/alpha/tex/context/base/luat-ini.lua luat-ini.lua]: <code><pre>userdata = userdata or { } -- for users (e.g. functions etc)thirddata = thirddata or { } -- only for third party modulesmoduledata = moduledata or { } -- only for development teamdocumentdata = documentdata or { } -- for users (e.g. raw data)parametersets = parametersets or { } -- experimental for team</pre></code> If your module, environment, or document is going to be used by other people, you should create your own subnamespaces within these tables. <code><pre>moduledata['mymodule'] = { }mm =moduledata.mymodulefunction mm.mainfunction() -- do stuffend</pre></code> = Putting stuff in your TeX document from Lua ==
=== Simple printing: context(), tex.print(), and tex.sprint() ===
Use <code>context(...)</code> for most things. It is equivalent to <code>tex.print(string.format(...))</code>, so
<texcode>
\startluacode
name = "Jane"date = "today"context("Hello %s, how are you %s?", "Jane"name, "today"date)-- becomes Becomes 'Hello Jane, how are youtoday?'
\stopluacode
</texcode>
without any space in between.
=== Context commands ===
Most commands that you would type with a backslash in plain ConTeXt, you can access from Lua with <code>context.<em>command</em></code>. Unadorned strings end up in TeX as arguments in curly braces; Lua tables end up in TeX as paramater blocks in square brackets. The following two pieces of code are equivalent:
One final note: arguments can also be specified in the form of nested functions. Because LuaTeX evaluates the deepest-nested argument first, this may cause the <code>context()</code> calls to be evaluated in the wrong order. For more on this, see the article on [[cld|ConTeXt Lua documents]], and also, again, the [http://www.pragma-ade.com/general/manuals/cld-mkiv.pdf CLD manual].
 
= Passing arguments and buffers: ConTeXt commands that hook into Lua =
== Making \command{arg1}{arg2} hook into Lua ==
<texcode>
\def\surroundwd#1%
{\ctxlua{userdata.surroundwithdashes([==[#1]==])}}
</texcode>
''NB'': quoting with <code>[==[#1]==]</code>
([http://www.lua.org/manual/5.2/manual.html#3.1 long strings])
works just like <code>"#1"</code> in most cases, but in addition
it is robust against <code>#1</code> containing the quotation mark
<code>"</code> which would terminate the Lua string prematurely.
Inside <code>\protect .. \unprotect</code> the macros <code>\!!bs</code>
and <code>\!!es</code> are at your disposition.
They are equivalent to <code>[===[</code> and <code>]===]</code> and --
being single tokens to TeX -- parsed faster.
(See [http://repo.or.cz/w/context.git/blob/refs/heads/origin:/tex/context/base/luat-ini.mkiv#l174 <code>luat-ini.mkiv</code>].)
== Making \startenv...\stopenv hook into Lua ==
:<code>\molecule{H_3SO_4^+}</code>.
So, we need a function that can take a string like that, parse it, and turn it into the appropriate TeX code. LuaTeX includes a general parser based on PEG (parsing expression grammar) called [http://www.inf.puc-rio.br/~roberto/lpeg/lpeg.html lpeg], and it makes writing little parsers positively joyful. (Once you've got the knack of it, at least.) For example, the above <code>\molecule</code> macro can be written as follows.
<texcode>
Quite terse and readable by parser standards, isn't it?
== Manipulating verbatim text for dummies ==
''This example demonstrates defining a custom \start...\stop buffer that gets processed through Lua in its entirety.''
To a first approximation, the interaction between TeX and Lua is straightforward. When TeX (i.e., the LuaTeX engine) starts, it loads the input file in memory and processes it token by token. When TeX encounters <code>\directlua</code>, it stops reading the file in memory, <em>fully expands the argument of <code>\directlua</code></em>, and passes the control to a Lua instance. The Lua instance, which runs with a few preloaded libraries, processes the expanded arguments of <code>\directlua</code>. This Lua instance has a special output stream which can be accessed using <code>tex.print(...)</code>. The function <code>tex.print(...)</code> is just like the Lua function <code>print(...)</code> except that <code>tex.print(...)</code> prints to a <em>TeX stream</em> rather than to the standard output. When the Lua instance finishes processing its input, it passes the contents of the <em>TeX stream</em> back to TeX.<ref>The output of <code>tex.print(...)</code> is buffered and not passed to TeX until the Lua instance has stopped.</ref> TeX then inserts the contents of the <em>TeX stream</em> at the current location of the file that it was reading; expands the contents of the <em>TeX stream</em>; and continues. If TeX encounters another <code>\directlua</code>, the above process is repeated.
As an exercise, imagine what happens when the following input is processed by LuaTeX. The answer is in the footnotes. <ref>In this example, two different kinds of quotations are used to avoid escaping quotes. Escaping quotes inside <code>\directlua</code> is tricky. The above was a contrived example; if you ever need to escape quotes, you can use the <code>\startluacode ... \stopluacode</code> syntax explained later.</ref>
<texcode>
[[Category:Lua]]
[[Category:LuaTeX]]
[[Category:Programming]]
2

edits

Navigation menu