Editing Writing Lua in TeX

From LuaTeXWiki

Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.

The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.
Latest revision Your text
Line 44: Line 44:
  
 
defines <tt>myvar</tt> as the number <tt>1</tt>. To store the control sequence <tt>\macro</tt> instead, another course of action is needed: see the [[#Backslash|section on backslash]] below.
 
defines <tt>myvar</tt> as the number <tt>1</tt>. To store the control sequence <tt>\macro</tt> instead, another course of action is needed: see the [[#Backslash|section on backslash]] below.
 
It should be noted that <tt>\par</tt> tokens are removed from <tt>\directlua</tt> if they are unexpandable (i.e., most likely, if they have their original meaning). Hence, empty lines can be used in Lua code.
 
  
 
== Line ends ==
 
== Line ends ==
Line 119: Line 117:
 
\bgroup
 
\bgroup
 
\catcode`\^^M=12 %
 
\catcode`\^^M=12 %
\long\gdef\doluacode#1^^M#2\endluacode{\directlua{#2}\egroup}%
+
\gdef\doluacode#1^^M#2\endluacode{\directlua{#2}\egroup}%
 
\egroup
 
\egroup
 
</pre>
 
</pre>
Line 166: Line 164:
  
 
because the double brackets signals a string in Lua where no escape sequence occurs (and the string can also run on several lines). Note however that in the second case <tt>myvar</tt> will be defined with a trailing space, i.e. as <tt>"\macro "</tt>, because of TeX's habit to append a trailing space to unexpanded (or unexpandable) control sequences.
 
because the double brackets signals a string in Lua where no escape sequence occurs (and the string can also run on several lines). Note however that in the second case <tt>myvar</tt> will be defined with a trailing space, i.e. as <tt>"\macro "</tt>, because of TeX's habit to append a trailing space to unexpanded (or unexpandable) control sequences.
 
If one wants the backslash to be treated as any other character (not creating control sequences), then one has to rewrite <tt>\luacode</tt> as follows:
 
 
<pre>
 
\def\luacode{%
 
  \bgroup
 
  \catcode`\\=12
 
  \catcode`\{=12
 
  \catcode`\}=12
 
  \catcode`\^^M=12
 
  \catcode`\#=12
 
  \catcode`\~=12
 
  \catcode`\%=12
 
  \doluacode
 
}
 
 
\bgroup
 
\catcode`\|=0
 
\catcode`\^^M=12 %
 
\catcode`\\=12 %
 
|long|gdef|doluacode#1^^M#2\endluacode{|directlua{#2}|egroup}%
 
|egroup
 
</pre>
 
 
Backslashes remain escape characters in Lua, though.
 
  
 
=== Braces ===
 
=== Braces ===
Line 234: Line 207:
 
=== Other characters ===
 
=== Other characters ===
  
When processing verbatim text in TeX, one generally also changes the catcodes of <tt>$</tt>, <tt>&</tt>, <tt>^</tt>, <tt>_</tt> and the space character, because they too are special. When passed to the Lua interpreter, though, their usual catcodes won't do any harm, that is why they are left unmodified here.
+
When processing verbatim text in TeX, one generally also change the catcodes of <tt>$</tt>, <tt>&</tt>, <tt>^</tt>, <tt>_</tt> and the space character, because they too are special. When passed to the Lua interpreter, though, their usual catcodes won't do any harm, that is why they are left unmodified here.
  
== \luaescapestring ==
+
=== <tt>\luaescapestring</tt> ===
  
 
Although it can't do all of what's been explained, the <tt>\luaescapestring</tt> command might be useful in some cases: it expands its argument (which must be enclosed in ''real'' braces) fully, then modify it so that dangerous characters are escaped: backslashes, hashes, quotes and line ends. For instance:
 
Although it can't do all of what's been explained, the <tt>\luaescapestring</tt> command might be useful in some cases: it expands its argument (which must be enclosed in ''real'' braces) fully, then modify it so that dangerous characters are escaped: backslashes, hashes, quotes and line ends. For instance:
Line 254: Line 227:
  
 
so that <tt>myvar</tt> is defined as <tt>"\foo "</tt>, with the quotes as parts of it. Note that the trailing space after <tt>\foo</tt> still happens.
 
so that <tt>myvar</tt> is defined as <tt>"\foo "</tt>, with the quotes as parts of it. Note that the trailing space after <tt>\foo</tt> still happens.
 
= From Lua to TeX =
 
 
Inside Lua code, one can pass strings to be processed by TeX with the functions <tt>tex.print()</tt>, <tt>tex.sprint()</tt> and <tt>tex.tprint()</tt>. All such calls are processed at the end of a <tt>\directlua</tt> call, even though they might happen in the middle of the code. This behavior is worth noting because it might be surprising in some cases, although it is generally harmless.
 
 
== tex.print() ==
 
 
This function receives as its argument(s) either one or more strings or an array of strings. Each string is processed as an input line: an end-of-line character is appended (except to the last string), and TeX is in state <tt>newline</tt> when processing it (i.e. leading spaces are skipped). Hence the two equivalent calls:
 
 
<pre>
 
tex.print("a", "b")
 
tex.print({"a", "b"})
 
</pre>
 
 
are both interpreted by TeX as would the following two lines:
 
 
<pre>
 
a
 
b
 
</pre>
 
 
Thus `a b' is produced, since line ends normally produce a space.
 
 
The function can also take an optional number as its first argument; it is interpreted as referring to a catcode table (as defined by <tt>\initcatcodetable</tt> and <tt>\savecatcodetable</tt>), and each line is processed by TeX with that catcode regime. For instance (note that with such a minimal catcode table, braces don't even have their usual values):
 
 
<pre>
 
\bgroup
 
\initcatcodetable1
 
\catcode`\_=0
 
\savecatcodetable1
 
\egroup
 
 
\directlua{tex.print(1, "_TeX")}
 
</pre>
 
 
The string will be read with <tt>_</tt> as an escape character, and thus interpreted as the command commonly known as <tt>\TeX</tt>. The catcode regime holds only for the strings passed to <tt>tex.print()</tt> and the rest of the document isn't affected.
 
 
If the optional number is <tt>-1</tt>, or points to an invalid (i.e. undefined) catcode table, then the strings are processed with the current catcodes, as if there was no optional argument. If it is <tt>-2</tt>, then the strings are read as if the result of <tt>\detokenize</tt>: all characters have catcode 12 (i.e. `other', characters that have no function beside representing themselves), except space, which has catcode 10 (as usual).
 
 
== tex.sprint() ==
 
 
Like <tt>tex.print()</tt>, this function can receive either one or more strings or an array of strings, with an optional number as its first argument pointing to a catcode table. Unlike <tt>tex.print()</tt>, however, each string is processed as if TeX were in the middle of a line and not at the beginning of a new one: spaces aren't skipped, no end-of-line character is added and trailing spaces aren't ignored. Thus:
 
 
<pre>
 
tex.sprint("a", "b")
 
</pre>
 
 
is interpreted by TeX as
 
 
<pre>
 
ab
 
</pre>
 
 
without any space inbetween.
 
 
== tex.tprint() ==
 
 
This function takes an unlimited number of tables as its arguments; each table must be an array of strings, with the first entry optionally being a number pointing to a catcode table. Then each table is processed as if passed to <tt>tex.sprint()</tt>. Thus:
 
 
<pre>
 
tex.tprint({1, "a", "b"}, {"c", "d"})
 
</pre>
 
 
is equivalent to
 
 
<pre>
 
tex.sprint(1, "a", "b")
 
tex.sprint("c", "d")
 
</pre>
 
 
=== debug note ===
 
 
Note that there are some tables that Lua inside LuaTeX has; one reference is in [http://www.luatex.org/svn/trunk/manual/functionref.pdf functionref]: ''`<tt>luatex</tt> is a typesetter; <tt>texlua</tt> and <tt>luatex --luaonly</tt> are lua interpreters. In lua interpreter mode, the lua tables <tt>tex</tt>, <tt>token</tt>, <tt>node</tt>, and <tt>pdf</tt> are unavailable.'''
 
 
For utilizing lua-specific debug techniques, see
 
* [http://www.lua.org/pil/23.html 23. The Debug Library - Lua],
 
* [http://www.lua.org/pil/23.1.html 23.1 - Introspective Facilities],
 
* [http://lua-users.org/wiki/DebugLibraryTutorial lua -users wiki: Debug Library Tutorial]
 
 
You can use commands like these in your .tex file:
 
<pre>
 
\directlua{
 
for k,v in pairs(tex) do print(k, v) end
 
print"==="
 
for k,v in pairs(lua) do print(k,v) end
 
print"==="
 
print(debug.traceback(1))
 
}
 
</pre>
 
... and the output of lua's <tt>print</tt> will be sent to stdout; the three <tt>=</tt> signs will serve simply as `delimiters' in the output, which will look something like:
 
 
<pre style="height:250px;overflow:scroll;">
 
tprint function: 0x89086e8
 
box table: 0x895a0a0
 
getsfcode function: 0x895ae10
 
pdffontsize function: 0x895b048
 
shipout function: 0x895b2d8
 
getmath function: 0x895b380
 
setuccode function: 0x895ae48
 
getskip function: 0x8908860
 
pdfxformname function: 0x895b170
 
setlist function: 0x895ab38
 
setattribute function: 0x8908898
 
count table: 0x895b600
 
getuccode function: 0x895ae80
 
getbox function: 0x895ab00
 
uniformdeviate function: 0x895b080
 
fontname function: 0x895af58
 
primitives function: 0x895b220
 
badness function: 0x895b310
 
setmath function: 0x895b348
 
setskip function: 0x8908828
 
getmathcode function: 0x895ada0
 
getcount function: 0x8908950
 
toks table: 0x895b6b0
 
setsfcode function: 0x895add8
 
run function: 0x8908638
 
sfcode table: 0x895a130
 
pdfpageref function: 0x895b138
 
setcount function: 0x8908918
 
setdimen function: 0x89087b8
 
print function: 0x89086d0
 
setlccode function: 0x895acf8
 
fontidentifier function: 0x895af90
 
getlccode function: 0x895ad30
 
setmathcode function: 0x895ad68
 
round function: 0x895aeb8
 
getdimen function: 0x89087f0
 
write function: 0x89086b8
 
set function: 0x8908770
 
definefont function: 0x895b1b0
 
dimen table: 0x895b550
 
get function: 0x89087a0
 
number function: 0x895b0c0
 
nest table: 0x895a600
 
lists table: 0x895a550
 
setcatcode function: 0x895ac18
 
delcode table: 0x895a4a0
 
setnest function: 0x895aba8
 
mathcode table: 0x895a3f0
 
getdelcode function: 0x895acc0
 
catcode table: 0x895a340
 
pdffontname function: 0x895afd0
 
uccode table: 0x895a290
 
setdelcode function: 0x895ac88
 
lccode table: 0x895a1e0
 
sp function: 0x895af28
 
attribute table: 0x895b410
 
getcatcode function: 0x895ac50
 
extraprimitives function: 0x895b258
 
linebreak function: 0x895b3b8
 
setbox function: 0x895aac8
 
skip table: 0x895b4c0
 
pdffontobjnum function: 0x895b008
 
settoks function: 0x8908988
 
gettoks function: 0x895aa90
 
enableprimitives function: 0x895b298
 
getlist function: 0x895ab70
 
getnest function: 0x895abe0
 
getattribute function: 0x89088d8
 
romannumeral function: 0x895b0f8
 
scale function: 0x895aef0
 
hashtokens function: 0x895b1e8
 
error function: 0x8908720
 
finish function: 0x8908668
 
 
====
 
setluaname function: 0x895efb8
 
setbytecode function: 0x895f028
 
name table: 0x895ef50
 
getluaname function: 0x895ef80
 
getbytecode function: 0x895eff0
 
version Lua 5.1
 
bytecode table: 0x895f080
 
====
 
1
 
stack traceback:
 
<\directlua >:1: in main chunk
 
</pre>
 
 
Note that the string returned by <tt>debug.traceback</tt> contains <tt>\directlua</tt> and thus should be handled with care if passed to TeX, which might try to execute it.
 
 
= The expansion of \directlua =
 
 
A call to <tt>\directlua</tt> is fully expandable; i.e. it can be used in contexts where full expansion is required, as in:
 
 
<pre>
 
\csname\directlua{tex.print("TeX")}\endcsname
 
</pre>
 
 
which is a somewhat convoluted way of saying <tt>\TeX</tt>. Besides, since Lua code is processed at once, things that were previously unthinkable can now be done easily. For instance, it is impossible to perform an assignment in an <tt>\edef</tt> by TeX's traditional means. I.e. the following:
 
 
<pre>
 
\edef\macro{\count1=5}
 
</pre>
 
 
defines <tt>\macro</tt> as <tt>\count1=5</tt> but doesn't perform the assignment (the <tt>\edef</tt> does nothing more than a simple <tt>\def</tt>). After the definition, the value of <tt>\count1</tt> hasn't changed. The same is not true, though, if such an assigment is made with Lua code. The following:
 
 
<pre>
 
\edef\macro{\directlua{tex.count[1] = 5}}
 
</pre>
 
 
defines <tt>\macro</tt> emptily (since nothing remains after <tt>\directlua</tt> has been processed) ''and'' sets count 1 to 5. Since such a behavior is totally unexpected in normal TeX, one should be wary when using <tt>\directlua</tt> in such contexts.
 

Please note that all contributions to LuaTeXWiki are considered to be released under the GNU Free Documentation License 1.3 (see LuaTeXWiki:Copyrights for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource. Do not submit copyrighted work without permission!

Cancel Editing help (opens in new window)