<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.luatex.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Patrick</id>
	<title>LuaTeXWiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.luatex.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Patrick"/>
	<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php/Special:Contributions/Patrick"/>
	<updated>2026-05-31T06:21:27Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.31.1</generator>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=174</id>
		<title>TeX without TeX</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=174"/>
		<updated>2015-04-02T11:09:00Z</updated>

		<summary type="html">&lt;p&gt;Patrick: /* A first example */  fixed link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Use TeX&amp;#039;s power without TeX macros ==&lt;br /&gt;
&lt;br /&gt;
With the Lua-part in LuaTeX you have access to most of TeX&amp;#039;s capabilities for creating PDF documents. Most of the [http://www.luatex.org/svn/trunk/manual/luatexref-t.pdf LuaTeX reference manual] is about this topic. &lt;br /&gt;
&lt;br /&gt;
[[Writing_Lua_in_TeX|Remember]] that you can jump into Lua mode from TeX with &amp;lt;tt&amp;gt;\directlua{...Lua code...}&amp;lt;/tt&amp;gt;. For example this plain TeX document prints the first digits of the value of pi: &amp;lt;tt&amp;gt;$\pi = \directlua{ tex.print(math.pi)}$ \bye&amp;lt;/tt&amp;gt;. You can get the result PDF by running &amp;lt;tt&amp;gt;luatex testfile.tex&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The underlying idea is to create TeX&amp;#039;s internal data structure as TeX would do by transforming macros and primitives into something called nodes. These nodes are then transformed into instructions for the PDF file (PDF objects). So the following pages deal with node creation and the structures. &lt;br /&gt;
&lt;br /&gt;
Let&amp;#039;s start with a rule node. When you write &amp;lt;tt&amp;gt;\hrule width 20pt height 10pt depth 10pt &amp;lt;/tt&amp;gt; in TeX, a node of type rule will be created, which has three fields: height, depth and width. We can visualize this node by a simple box like this:&lt;br /&gt;
&lt;br /&gt;
[[File:rulenode.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r.width  = 20 * 65536&lt;br /&gt;
r.height = 10 * 65536&lt;br /&gt;
r.depth  = 10 * 65536&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some remarks: the size is in scaled points, and 65536 (=2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;) scaled points are 1 point, so 20pt becomes 20 * 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;. Not shown in the example are (among others) the next and prev fields. These fields hold a pointer (the node address) to the following and the previous nodes. A node that exist by itself has its prev and next fields set to nil.&lt;br /&gt;
&lt;br /&gt;
A slightly more complicated example is when you create two rules and pack then into a vertical box. This would look like this in plain TeX:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\vbox {\hrule width 20pt height 10pt depth 10pt&lt;br /&gt;
           \hrule width 20pt height 10pt depth 10pt }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would generate a node list like:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Rulenode2.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r1 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r1.width  = 20 * 65536&lt;br /&gt;
r1.height = 10 * 65536&lt;br /&gt;
r1.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r2 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r2.width  = 20 * 65536&lt;br /&gt;
r2.height = 10 * 65536&lt;br /&gt;
r2.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r1.next = r2&lt;br /&gt;
r2.prev = r1&lt;br /&gt;
&lt;br /&gt;
vbox = node.vpack(r1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result is a vbox containing the two rule nodes. The nodes are connected by their next and prev pointers, so the vbox contains them both. The size (width, height and depth) is adjusted automatically.&lt;br /&gt;
&lt;br /&gt;
This also applies to all other things you can put on a TeX page: glyphs, horizontal boxes, math, images, hyperlinks, glue .... For a complete list of the nodes, see the reference manual Chapter 8 &amp;quot;Nodes&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Beyond reports and articles ==&lt;br /&gt;
&lt;br /&gt;
Perhaps the question that comes into your mind is: why should I bother writing Lua code instead of TeX code? For many documents, including articles, reports and books, the classic way to create a PDF with TeX is to use LaTeX or ConTeXt. But there are applications that use TeX as an 100% automatic PDF generation software. If you want to create data sheets or product listings, your normal input is not a classic document, but most likely an Excel spreadsheet or an XML file, perhaps extracted from a database. You won&amp;#039;t have any TeX markup within these documents. So: if you don&amp;#039;t have TeX markup in these documents, you don&amp;#039;t need the TeX interpreter to read these files. More likely is an XML parser or a spreadsheet 2 ... converter.&lt;br /&gt;
&lt;br /&gt;
When you use regular LaTeX or ConTeXt code to put the contents of the database in your PDF (database publishing), you run into several problems:&lt;br /&gt;
&lt;br /&gt;
* Exact positioning of items on the page can be troublesome&lt;br /&gt;
* catcodes / command escapes are to be considered and surely get into your way&lt;br /&gt;
* TeX is no fun to program in (well it is, but only for some people) - calculations, tests, exception handling, control flow&lt;br /&gt;
* The packages that exist may reach their limit soon. You need a super flexible image-between-columns-with-parshape package? Write it yourself.&lt;br /&gt;
&lt;br /&gt;
With Lua you have a very decent programming language that &amp;#039;&amp;#039;is&amp;#039;&amp;#039; fun to program in. When you use the Lua interface to TeX, you have full control of what is happening, which is usually the level of control you need for high quality output.&lt;br /&gt;
&lt;br /&gt;
One approach is to create a stub TeX file and let Lua do the rest:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;myprogram.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The file &amp;lt;tt&amp;gt;myprogram.lua&amp;lt;/tt&amp;gt; then contains all the code to a) read the source file(s), b) extract the information and create the appropriate nodes and c) instruct TeX to create PDF pages from these nodes.&lt;br /&gt;
&lt;br /&gt;
In a future version of LuaTeX you will be able to run the Lua interpreter without the stub TeX file above.&lt;br /&gt;
&lt;br /&gt;
== A first example ==&lt;br /&gt;
&lt;br /&gt;
The example document given below creates two pages by using Lua code alone. You will learn how to access TeX&amp;#039;s boxes and counters from the Lua side, shipout a page into the PDF file, create horizontal and vertical boxes (hbox and vbox), create new nodes and manipulate the nodes links structure. The example covers the following node types: rule, whatsit, vlist, hlist and action.&lt;br /&gt;
&lt;br /&gt;
In the example code we use black squares as the contents of the pages and not normal text, because character handling takes more code and will be covered later on.&lt;br /&gt;
&lt;br /&gt;
Save the following file into &amp;lt;tt&amp;gt;myprogram.lua&amp;lt;/tt&amp;gt; and use the TeX stub from above (or get the source [https://gist.github.com/pgundlach/1062041 here]).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
  -- this will hold the items that go onto the page&lt;br /&gt;
  local pagelist&lt;br /&gt;
 &lt;br /&gt;
  -- Call tex.shipout() with the contents of the pagelist&lt;br /&gt;
  function shipout()&lt;br /&gt;
&lt;br /&gt;
    local vbox,b = node.vpack(pagelist) -- we ignore the badness &amp;#039;b&amp;#039;&lt;br /&gt;
    tex.box[666] = vbox&lt;br /&gt;
    tex.shipout(666)&lt;br /&gt;
&lt;br /&gt;
    pagelist = nil&lt;br /&gt;
    &lt;br /&gt;
    -- Not strictly necessary. TeX holds the current page number in counter 0.&lt;br /&gt;
    -- TeX displays the contents of this counter when it puts a page into&lt;br /&gt;
    -- the pdf (tex.shipout()). If we don&amp;#039;t change the counter, TeX will&lt;br /&gt;
    -- display [1] [1], instead of [1] [2] for our two page document.&lt;br /&gt;
    tex.count[0] = tex.count[0] + 1&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
  function add_to_page( list )&lt;br /&gt;
    -- We attach the nodelist &amp;#039;list&amp;#039; to the end of the pagelist&lt;br /&gt;
    -- if pagelist doesn&amp;#039;t exist, &amp;#039;list&amp;#039; is our new pagelist&lt;br /&gt;
    -- if it exists, we go to the end with node.tail() and adjust&lt;br /&gt;
    -- the prev and next pointers, so list becomes part&lt;br /&gt;
    -- of pagelist.&lt;br /&gt;
    if not pagelist then pagelist = list&lt;br /&gt;
    else&lt;br /&gt;
      local tail = node.tail(pagelist)&lt;br /&gt;
      tail.next = list&lt;br /&gt;
      list.prev  = tail&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- This creates a new square rule and returns the pointer to it.&lt;br /&gt;
function mkrule( size )&lt;br /&gt;
  local r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
  r.width  = size &lt;br /&gt;
  r.height = size / 2&lt;br /&gt;
  r.depth  = size / 2&lt;br /&gt;
  return r&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
do&lt;br /&gt;
  local destcounter = 0&lt;br /&gt;
  -- Create a pdf anchor (dest object). It returns a whatsit node and the &lt;br /&gt;
  -- number of the anchor, so it can be used in a pdf link or an outline.&lt;br /&gt;
  function mkdest()&lt;br /&gt;
    destcounter = destcounter + 1&lt;br /&gt;
    local d = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_dest&amp;quot;)&lt;br /&gt;
    d.named_id = 0&lt;br /&gt;
    d.dest_id = destcounter&lt;br /&gt;
    d.dest_type = 3&lt;br /&gt;
&lt;br /&gt;
    return d, destcounter&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Take a list of nodes and put them into an hbox. The prev and next fields&lt;br /&gt;
-- of the nodes will be set automatically. Return a pointer to the hbox.&lt;br /&gt;
function hpack( ... )&lt;br /&gt;
  local start, tmp, cur&lt;br /&gt;
  start = select(1,...)&lt;br /&gt;
  tmp = start&lt;br /&gt;
  for i=2,select(&amp;quot;#&amp;quot;,...) do&lt;br /&gt;
    cur = select(i,...)&lt;br /&gt;
    tmp.next = cur&lt;br /&gt;
    cur.prev = tmp&lt;br /&gt;
    tmp = cur&lt;br /&gt;
  end&lt;br /&gt;
  local h,b = node.hpack(start) -- ignore badness&lt;br /&gt;
  return h&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local tenpt = 10 * 2^16&lt;br /&gt;
---------------------------&lt;br /&gt;
-- page 1&lt;br /&gt;
---------------------------&lt;br /&gt;
local n,dest = mkdest() -- dest is needed for the link to this anchor&lt;br /&gt;
&lt;br /&gt;
add_to_page(n)&lt;br /&gt;
add_to_page(mkrule(2 * tenpt))&lt;br /&gt;
&lt;br /&gt;
-- The pagelist contains a pdf dest node (a link destination) and a rule of size 20pt x 20pt.&lt;br /&gt;
&lt;br /&gt;
shipout()&lt;br /&gt;
---------------------------&lt;br /&gt;
-- page 2&lt;br /&gt;
---------------------------&lt;br /&gt;
-- This is the page with the link to the anchor (dest) on page one. A&lt;br /&gt;
-- link consists of three nodes: a pdf_start_link, a pdf_end_link and and &lt;br /&gt;
-- action node that specifies the action to perform when the user clicks on&lt;br /&gt;
-- the link.&lt;br /&gt;
-- The pdf link must be inside a horizontal box, that&amp;#039;s why we hpack() it.&lt;br /&gt;
-- The link_attr (link attributes) is optional, here it draws a yellowish border&lt;br /&gt;
-- around the link.&lt;br /&gt;
local start_link = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_start_link&amp;quot;)&lt;br /&gt;
local end_link   = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_end_link&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
start_link.width     = tenpt&lt;br /&gt;
start_link.height    = tenpt / 2&lt;br /&gt;
start_link.depth     = tenpt / 2&lt;br /&gt;
start_link.link_attr = &amp;quot;/C [0.9 1 0] /Border [0 0 2]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
start_link.action = node.new(&amp;quot;action&amp;quot;)&lt;br /&gt;
start_link.action.action_type = 1&lt;br /&gt;
start_link.action.action_id   = dest&lt;br /&gt;
&lt;br /&gt;
local rule = mkrule(tenpt)&lt;br /&gt;
local hbox = hpack(start_link, rule, end_link)&lt;br /&gt;
add_to_page(hbox)&lt;br /&gt;
&lt;br /&gt;
-- This pagelist consists of an hbox whose contents is &amp;quot;start_link&amp;quot;,&lt;br /&gt;
-- the 10pt x 10pt rule and the &amp;quot;end_link&amp;quot; node. &lt;br /&gt;
&lt;br /&gt;
shipout()&lt;br /&gt;
---------------------------&lt;br /&gt;
&lt;br /&gt;
-- Just to show you that you can get some memory usage statistics:&lt;br /&gt;
print(string.format(&amp;quot;\nnode_mem_usage=%s&amp;quot;,status.node_mem_usage))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The idea is to create nodes, collect them in a list (here: pagelist) and use &amp;lt;tt&amp;gt;tex.shipout()&amp;lt;/tt&amp;gt; to put the page into the PDF.&lt;br /&gt;
&lt;br /&gt;
== And what about &amp;#039;&amp;#039;real&amp;#039;&amp;#039; content? ==&lt;br /&gt;
&lt;br /&gt;
Black squares won&amp;#039;t make anyone happy. So we need a typeset paragraph. For that we start with a single glyph and a glue first. A glyph node has this structure:&lt;br /&gt;
&lt;br /&gt;
[[File:Singleglyphnode.png]]&lt;br /&gt;
&lt;br /&gt;
whereas a glue is more complicated:&lt;br /&gt;
&lt;br /&gt;
[[File:Simplegluenode.png]]&lt;br /&gt;
&lt;br /&gt;
The glue item comes in pairs: a glue node and a glue_spec node. The information about the shrink/stretch values go into the glue_spec node. For example, the TeX glue &amp;lt;tt&amp;gt;2pt plus 1fill&amp;lt;/tt&amp;gt; has a width of 2*2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;, a stretch of 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt; and a stretch_order of 3. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local g = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g.font = font.current()&lt;br /&gt;
g.lang = tex.language&lt;br /&gt;
g.char = 86 -- V&lt;br /&gt;
&lt;br /&gt;
local hbox = node.hpack(g)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We create a glyph, pack it into an hbox (horizontal box), pack that hbox into a vbox (a vertical box) and write this box to the main vertical list. The char number (86 in the example above) is based on an internal encoding, so we have to keep an eye on what character is on what position. Now we do this for two glyphs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local g1 = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g1.font = font.current()&lt;br /&gt;
g1.lang = tex.language&lt;br /&gt;
g1.char = 86&lt;br /&gt;
&lt;br /&gt;
local g2 = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g2.font = font.current()&lt;br /&gt;
g2.lang = tex.language&lt;br /&gt;
g2.char = 97&lt;br /&gt;
&lt;br /&gt;
g1.next = g2&lt;br /&gt;
g2.prev = g1&lt;br /&gt;
&lt;br /&gt;
local hbox = node.hpack(g1)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pretty much the same as above. The glyphs g1 and g2 are chained together by setting the next and prev pointer to each other. If they were not connected, only glyph g1 gets into the hbox.&lt;br /&gt;
&lt;br /&gt;
If you take a close look at the PDF, you see that the two glyphs are too far away, a (negative) kern should be inserted. This can be done by inserting a kern-node manually or you can ask TeX to do that for you. The last lines of the example above should then read:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local head,tail,success = node.kerning(g1)&lt;br /&gt;
local hbox = node.hpack(head)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this approach you are able to put some glyphs into the PDF but you will run into problems when you want to create a whole paragraph. It is much easier to ask TeX to do the line breaking. The steps for paragraph creation are&lt;br /&gt;
&lt;br /&gt;
# put glyph nodes and glue nodes in a list (= chain them together with the prev/next pointers)&lt;br /&gt;
# add trailing infinite penalty and parfillskip&lt;br /&gt;
# call lang.hyphenate(), node.kerning() and node.ligaturing() to prepare the list for the linebreaking job&lt;br /&gt;
# call tex.linebreak()&lt;br /&gt;
&lt;br /&gt;
For the next task we want to create the following paragraph:&lt;br /&gt;
&lt;br /&gt;
[[File:Sample_paragraph.png|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We start with the small TeX stub as above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;myprogram.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and myprogram.lua ([https://gist.github.com/1063228 download]) defines a function &amp;lt;tt&amp;gt;mknodes()&amp;lt;/tt&amp;gt; that creates the list of nodes to be passed into the typesetter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function mknodes( text )&lt;br /&gt;
  local current_font = font.current()&lt;br /&gt;
  local font_parameters = font.getfont(current_font).parameters&lt;br /&gt;
  local n, head, last&lt;br /&gt;
  -- we should insert the paragraph indentation at the beginning&lt;br /&gt;
  head = node.new(&amp;quot;glue&amp;quot;)&lt;br /&gt;
  head.spec = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
  head.spec.width = 20 * 2^16&lt;br /&gt;
  last = head&lt;br /&gt;
&lt;br /&gt;
  for s in string.utfvalues( text ) do&lt;br /&gt;
    local char = unicode.utf8.char(s)&lt;br /&gt;
    if unicode.utf8.match(char,&amp;quot;^%s$&amp;quot;) then&lt;br /&gt;
      -- its a space&lt;br /&gt;
      n = node.new(&amp;quot;glue&amp;quot;)&lt;br /&gt;
      n.spec = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
      n.spec.width   = font_parameters.space&lt;br /&gt;
      n.spec.shrink  = font_parameters.space_shrink&lt;br /&gt;
      n.spec.stretch = font_parameters.space_stretch&lt;br /&gt;
    else -- a glyph&lt;br /&gt;
      n = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
      n.font = current_font&lt;br /&gt;
      n.subtype = 1&lt;br /&gt;
      n.char = s&lt;br /&gt;
      n.lang = tex.language&lt;br /&gt;
      n.uchyph = 1&lt;br /&gt;
      n.left = tex.lefthyphenmin&lt;br /&gt;
      n.right = tex.righthyphenmin&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    last.next = n&lt;br /&gt;
    last = n&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  -- now add the final parts: a penalty and the parfillskip glue&lt;br /&gt;
  local penalty = node.new(&amp;quot;penalty&amp;quot;)&lt;br /&gt;
  penalty.penalty = 10000&lt;br /&gt;
&lt;br /&gt;
  local parfillskip = node.new(&amp;quot;glue&amp;quot;)&lt;br /&gt;
  parfillskip.spec = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
  parfillskip.spec.stretch = 2^16&lt;br /&gt;
  parfillskip.spec.stretch_order = 2&lt;br /&gt;
  &lt;br /&gt;
  last.next = penalty&lt;br /&gt;
  penalty.next = parfillskip&lt;br /&gt;
&lt;br /&gt;
  -- just to create the prev pointers for tex.linebreak&lt;br /&gt;
  node.slide(head)&lt;br /&gt;
  return head&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local txt = &amp;quot;A wonderful serenity has taken possession of my entire soul, ... like mine.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
tex.baselineskip = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
tex.baselineskip.width = 14 * 2^16&lt;br /&gt;
&lt;br /&gt;
local head = mknodes(txt)&lt;br /&gt;
lang.hyphenate(head)&lt;br /&gt;
head = node.kerning(head)&lt;br /&gt;
head = node.ligaturing(head)&lt;br /&gt;
&lt;br /&gt;
local vbox = tex.linebreak(head,{ hsize = tex.sp(&amp;quot;3in&amp;quot;)})&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(You can safely skip this section if you are not interested in the details.)&lt;br /&gt;
&lt;br /&gt;
What has happened in detail? We have created a list of glyph and glue nodes and fed those into the line breaking part of TeX which gave us the vbox back. This vbox contains horizontal lists glued together:&lt;br /&gt;
&lt;br /&gt;
[[File:Paragraph_with_boxes.png|600px]]&lt;br /&gt;
&lt;br /&gt;
The dashed rectangle (vbox) should fit tight to the inner hboxes. It has a small offset just for demonstration purpose.&lt;br /&gt;
&lt;br /&gt;
To show you some of the nodes that TeX inserted for you, have a look at the following image:&lt;br /&gt;
&lt;br /&gt;
[[File:Nodes_in_sample_paragraph.png]]&lt;br /&gt;
&lt;br /&gt;
Here is an explanation of the nodes:&lt;br /&gt;
&lt;br /&gt;
# This is the dashed line in the image above. A paragraph is always vertical&lt;br /&gt;
# The first line. It has a width of three inches, a height and depth of together 8.888 pt&lt;br /&gt;
# The 20pt paragraph indent. This is the first item in the first line (note that the pointer comes from the head item of the node #2&lt;br /&gt;
# The first letter in the first line&lt;br /&gt;
# The interword glue.&lt;br /&gt;
# The second letter in the first line&lt;br /&gt;
# The clubpenalty&lt;br /&gt;
# The baselineskip minus the height of the hbox &amp;quot;above&amp;quot; (8.888pt + 5.111pt is approx. 14pt. The rounding error is due to the display of only few significant digits.) Note that TeX is in vertical mode, as it is the third item in the vbox (#1). &lt;br /&gt;
# The hbox of the second line&lt;br /&gt;
# The first letter of the second line&lt;br /&gt;
# A kern between the m and the y of the first word (second line)&lt;br /&gt;
# The last letter shown here&lt;br /&gt;
&lt;br /&gt;
There are many nodes created in the paragraph which are not shown here. A full view can be found in [[Media:Nodes_in_sample_paragraph_full.pdf|a separate PDF file]].&lt;br /&gt;
&lt;br /&gt;
== Inserting images is easy ==&lt;br /&gt;
&lt;br /&gt;
Now that you have survived the hard part of this tutorial, we get to something easier. Image inclusion. There are several ways to do this, and in my opinion this is the easiest. We again start with our plain (lua)TeX stub:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;includeimage.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and includeimage.lua is this small lua chunk:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local image_fixed = img.scan({filename = &amp;quot;oilpainting.jpg&amp;quot;})&lt;br /&gt;
&lt;br /&gt;
local image     = img.copy(image_fixed)&lt;br /&gt;
local halfimage = img.copy(image_fixed)&lt;br /&gt;
&lt;br /&gt;
halfimage.height = halfimage.height / 2&lt;br /&gt;
halfimage.width  = halfimage.width  / 2&lt;br /&gt;
&lt;br /&gt;
node.write(img.node(image))&lt;br /&gt;
node.write(img.node(halfimage))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You might be able to guess what happens here. We load the image [[Media:Oilpainting.jpg|oilpainting.jpg]] with &amp;lt;tt&amp;gt;img.scan&amp;lt;/tt&amp;gt; but do not write it out to the PDF file yet. We create a copy of the image data so we can manipulate the size for example (another option would be to obtain a specific page of a PDF document or do some rotation). After that we write a reference to that image to the PDF file. In the case above, two references to the image (XObject) get written but the image is only written once. That is easy, right?&lt;br /&gt;
&lt;br /&gt;
You can get an impression how the resulting document looks like:&lt;br /&gt;
&lt;br /&gt;
[[File:Oilpaintingdocument.jpg]]&lt;br /&gt;
&lt;br /&gt;
== Hyphenation ==&lt;br /&gt;
&lt;br /&gt;
Every now and then you have to hyphenate your words in other languages. When you create the paragraph to be hyphenated (with &amp;lt;tt&amp;gt;lang.hyphenate()&amp;lt;/tt&amp;gt;), you assemble it by creating glyph nodes which have a field lang (see above). This field accepts a number, the language id. So: how do we &amp;quot;create&amp;quot; a language? The first steps are simple, we start without TeX stub again:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;hyphenation.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the file hyphenation.lua is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local path = kpse.find_file(&amp;quot;hyph-de-1996.pat.txt&amp;quot;)&lt;br /&gt;
local l = lang.new()&lt;br /&gt;
&lt;br /&gt;
local hyph_file = io.open(path)&lt;br /&gt;
lang.patterns(l,hyph_file:read(&amp;quot;*all&amp;quot;))&lt;br /&gt;
hyph_file:close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now the function &amp;lt;tt&amp;gt;lang.id(l)&amp;lt;/tt&amp;gt; returns the language id of the language &amp;lt;tt&amp;gt;l&amp;lt;/tt&amp;gt;, which we can use in the glyph nodes. A peculiarity of TeX prevents that we can start with that right away. All characters that are in the paragraph get lowercased before hyphenation rules apply. So how will a word like &amp;quot;Œuvre&amp;quot; be converted to lowercase? TeX has an internal table called &amp;#039;&amp;#039;lccode&amp;#039;&amp;#039; where it looks up a character and the output is its lowercase variant. So the lccode of Œ would be œ, but as TeX stores numbers, the lccode of 338 is 339. But only lccodes of the letters A-Z and a-z are set, so we need to set the codes for all other characters that appear in a text. In TeX you would write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\lccode`\Œ=`\œ&lt;br /&gt;
\lccode`\œ=`\œ&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\lccode338=339&lt;br /&gt;
\lccode339=339&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You see that you need to set the lccode of the lowercase characters as well. In Lua you do something similar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tex.lccode[unicode.utf8.byte(&amp;quot;Œ&amp;quot;)] = [unicode.utf8.byte(&amp;quot;œ&amp;quot;)]&lt;br /&gt;
tex.lccode[unicode.utf8.byte(&amp;quot;œ&amp;quot;)] = [unicode.utf8.byte(&amp;quot;œ&amp;quot;)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or shorter:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tex.lccode[338] = [339]&lt;br /&gt;
tex.lccode[339] = [339]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have set all the necessary lccodes (remember you don&amp;#039;t need to do this with a to z and A to Z), you can expect the hyphenation to work.&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=173</id>
		<title>TeX without TeX</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=173"/>
		<updated>2014-03-29T18:21:49Z</updated>

		<summary type="html">&lt;p&gt;Patrick: Anchor %s regexp - important&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Use TeX&amp;#039;s power without TeX macros ==&lt;br /&gt;
&lt;br /&gt;
With the Lua-part in LuaTeX you have access to most of TeX&amp;#039;s capabilities for creating PDF documents. Most of the [http://www.luatex.org/svn/trunk/manual/luatexref-t.pdf LuaTeX reference manual] is about this topic. &lt;br /&gt;
&lt;br /&gt;
[[Writing_Lua_in_TeX|Remember]] that you can jump into Lua mode from TeX with &amp;lt;tt&amp;gt;\directlua{...Lua code...}&amp;lt;/tt&amp;gt;. For example this plain TeX document prints the first digits of the value of pi: &amp;lt;tt&amp;gt;$\pi = \directlua{ tex.print(math.pi)}$ \bye&amp;lt;/tt&amp;gt;. You can get the result PDF by running &amp;lt;tt&amp;gt;luatex testfile.tex&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The underlying idea is to create TeX&amp;#039;s internal data structure as TeX would do by transforming macros and primitives into something called nodes. These nodes are then transformed into instructions for the PDF file (PDF objects). So the following pages deal with node creation and the structures. &lt;br /&gt;
&lt;br /&gt;
Let&amp;#039;s start with a rule node. When you write &amp;lt;tt&amp;gt;\hrule width 20pt height 10pt depth 10pt &amp;lt;/tt&amp;gt; in TeX, a node of type rule will be created, which has three fields: height, depth and width. We can visualize this node by a simple box like this:&lt;br /&gt;
&lt;br /&gt;
[[File:rulenode.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r.width  = 20 * 65536&lt;br /&gt;
r.height = 10 * 65536&lt;br /&gt;
r.depth  = 10 * 65536&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some remarks: the size is in scaled points, and 65536 (=2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;) scaled points are 1 point, so 20pt becomes 20 * 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;. Not shown in the example are (among others) the next and prev fields. These fields hold a pointer (the node address) to the following and the previous nodes. A node that exist by itself has its prev and next fields set to nil.&lt;br /&gt;
&lt;br /&gt;
A slightly more complicated example is when you create two rules and pack then into a vertical box. This would look like this in plain TeX:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\vbox {\hrule width 20pt height 10pt depth 10pt&lt;br /&gt;
           \hrule width 20pt height 10pt depth 10pt }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would generate a node list like:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Rulenode2.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r1 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r1.width  = 20 * 65536&lt;br /&gt;
r1.height = 10 * 65536&lt;br /&gt;
r1.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r2 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r2.width  = 20 * 65536&lt;br /&gt;
r2.height = 10 * 65536&lt;br /&gt;
r2.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r1.next = r2&lt;br /&gt;
r2.prev = r1&lt;br /&gt;
&lt;br /&gt;
vbox = node.vpack(r1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result is a vbox containing the two rule nodes. The nodes are connected by their next and prev pointers, so the vbox contains them both. The size (width, height and depth) is adjusted automatically.&lt;br /&gt;
&lt;br /&gt;
This also applies to all other things you can put on a TeX page: glyphs, horizontal boxes, math, images, hyperlinks, glue .... For a complete list of the nodes, see the reference manual Chapter 8 &amp;quot;Nodes&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Beyond reports and articles ==&lt;br /&gt;
&lt;br /&gt;
Perhaps the question that comes into your mind is: why should I bother writing Lua code instead of TeX code? For many documents, including articles, reports and books, the classic way to create a PDF with TeX is to use LaTeX or ConTeXt. But there are applications that use TeX as an 100% automatic PDF generation software. If you want to create data sheets or product listings, your normal input is not a classic document, but most likely an Excel spreadsheet or an XML file, perhaps extracted from a database. You won&amp;#039;t have any TeX markup within these documents. So: if you don&amp;#039;t have TeX markup in these documents, you don&amp;#039;t need the TeX interpreter to read these files. More likely is an XML parser or a spreadsheet 2 ... converter.&lt;br /&gt;
&lt;br /&gt;
When you use regular LaTeX or ConTeXt code to put the contents of the database in your PDF (database publishing), you run into several problems:&lt;br /&gt;
&lt;br /&gt;
* Exact positioning of items on the page can be troublesome&lt;br /&gt;
* catcodes / command escapes are to be considered and surely get into your way&lt;br /&gt;
* TeX is no fun to program in (well it is, but only for some people) - calculations, tests, exception handling, control flow&lt;br /&gt;
* The packages that exist may reach their limit soon. You need a super flexible image-between-columns-with-parshape package? Write it yourself.&lt;br /&gt;
&lt;br /&gt;
With Lua you have a very decent programming language that &amp;#039;&amp;#039;is&amp;#039;&amp;#039; fun to program in. When you use the Lua interface to TeX, you have full control of what is happening, which is usually the level of control you need for high quality output.&lt;br /&gt;
&lt;br /&gt;
One approach is to create a stub TeX file and let Lua do the rest:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;myprogram.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The file &amp;lt;tt&amp;gt;myprogram.lua&amp;lt;/tt&amp;gt; then contains all the code to a) read the source file(s), b) extract the information and create the appropriate nodes and c) instruct TeX to create PDF pages from these nodes.&lt;br /&gt;
&lt;br /&gt;
In a future version of LuaTeX you will be able to run the Lua interpreter without the stub TeX file above.&lt;br /&gt;
&lt;br /&gt;
== A first example ==&lt;br /&gt;
&lt;br /&gt;
The example document given below creates two pages by using Lua code alone. You will learn how to access TeX&amp;#039;s boxes and counters from the Lua side, shipout a page into the PDF file, create horizontal and vertical boxes (hbox and vbox), create new nodes and manipulate the nodes links structure. The example covers the following node types: rule, whatsit, vlist, hlist and action.&lt;br /&gt;
&lt;br /&gt;
In the example code we use black squares as the contents of the pages and not normal text, because character handling takes more code and will be covered later on.&lt;br /&gt;
&lt;br /&gt;
Save the following file into &amp;lt;tt&amp;gt;myprogram.lua&amp;lt;/tt&amp;gt; and use the TeX stub from above (or get the source [https://raw.github.com/gist/1062041/d3de082e955f6535f3820742cef76fe9e50d5a6f/myprogram.lua here]).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
  -- this will hold the items that go onto the page&lt;br /&gt;
  local pagelist&lt;br /&gt;
 &lt;br /&gt;
  -- Call tex.shipout() with the contents of the pagelist&lt;br /&gt;
  function shipout()&lt;br /&gt;
&lt;br /&gt;
    local vbox,b = node.vpack(pagelist) -- we ignore the badness &amp;#039;b&amp;#039;&lt;br /&gt;
    tex.box[666] = vbox&lt;br /&gt;
    tex.shipout(666)&lt;br /&gt;
&lt;br /&gt;
    pagelist = nil&lt;br /&gt;
    &lt;br /&gt;
    -- Not strictly necessary. TeX holds the current page number in counter 0.&lt;br /&gt;
    -- TeX displays the contents of this counter when it puts a page into&lt;br /&gt;
    -- the pdf (tex.shipout()). If we don&amp;#039;t change the counter, TeX will&lt;br /&gt;
    -- display [1] [1], instead of [1] [2] for our two page document.&lt;br /&gt;
    tex.count[0] = tex.count[0] + 1&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
  function add_to_page( list )&lt;br /&gt;
    -- We attach the nodelist &amp;#039;list&amp;#039; to the end of the pagelist&lt;br /&gt;
    -- if pagelist doesn&amp;#039;t exist, &amp;#039;list&amp;#039; is our new pagelist&lt;br /&gt;
    -- if it exists, we go to the end with node.tail() and adjust&lt;br /&gt;
    -- the prev and next pointers, so list becomes part&lt;br /&gt;
    -- of pagelist.&lt;br /&gt;
    if not pagelist then pagelist = list&lt;br /&gt;
    else&lt;br /&gt;
      local tail = node.tail(pagelist)&lt;br /&gt;
      tail.next = list&lt;br /&gt;
      list.prev  = tail&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- This creates a new square rule and returns the pointer to it.&lt;br /&gt;
function mkrule( size )&lt;br /&gt;
  local r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
  r.width  = size &lt;br /&gt;
  r.height = size / 2&lt;br /&gt;
  r.depth  = size / 2&lt;br /&gt;
  return r&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
do&lt;br /&gt;
  local destcounter = 0&lt;br /&gt;
  -- Create a pdf anchor (dest object). It returns a whatsit node and the &lt;br /&gt;
  -- number of the anchor, so it can be used in a pdf link or an outline.&lt;br /&gt;
  function mkdest()&lt;br /&gt;
    destcounter = destcounter + 1&lt;br /&gt;
    local d = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_dest&amp;quot;)&lt;br /&gt;
    d.named_id = 0&lt;br /&gt;
    d.dest_id = destcounter&lt;br /&gt;
    d.dest_type = 3&lt;br /&gt;
&lt;br /&gt;
    return d, destcounter&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Take a list of nodes and put them into an hbox. The prev and next fields&lt;br /&gt;
-- of the nodes will be set automatically. Return a pointer to the hbox.&lt;br /&gt;
function hpack( ... )&lt;br /&gt;
  local start, tmp, cur&lt;br /&gt;
  start = select(1,...)&lt;br /&gt;
  tmp = start&lt;br /&gt;
  for i=2,select(&amp;quot;#&amp;quot;,...) do&lt;br /&gt;
    cur = select(i,...)&lt;br /&gt;
    tmp.next = cur&lt;br /&gt;
    cur.prev = tmp&lt;br /&gt;
    tmp = cur&lt;br /&gt;
  end&lt;br /&gt;
  local h,b = node.hpack(start) -- ignore badness&lt;br /&gt;
  return h&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local tenpt = 10 * 2^16&lt;br /&gt;
---------------------------&lt;br /&gt;
-- page 1&lt;br /&gt;
---------------------------&lt;br /&gt;
local n,dest = mkdest() -- dest is needed for the link to this anchor&lt;br /&gt;
&lt;br /&gt;
add_to_page(n)&lt;br /&gt;
add_to_page(mkrule(2 * tenpt))&lt;br /&gt;
&lt;br /&gt;
-- The pagelist contains a pdf dest node (a link destination) and a rule of size 20pt x 20pt.&lt;br /&gt;
&lt;br /&gt;
shipout()&lt;br /&gt;
---------------------------&lt;br /&gt;
-- page 2&lt;br /&gt;
---------------------------&lt;br /&gt;
-- This is the page with the link to the anchor (dest) on page one. A&lt;br /&gt;
-- link consists of three nodes: a pdf_start_link, a pdf_end_link and and &lt;br /&gt;
-- action node that specifies the action to perform when the user clicks on&lt;br /&gt;
-- the link.&lt;br /&gt;
-- The pdf link must be inside a horizontal box, that&amp;#039;s why we hpack() it.&lt;br /&gt;
-- The link_attr (link attributes) is optional, here it draws a yellowish border&lt;br /&gt;
-- around the link.&lt;br /&gt;
local start_link = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_start_link&amp;quot;)&lt;br /&gt;
local end_link   = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_end_link&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
start_link.width     = tenpt&lt;br /&gt;
start_link.height    = tenpt / 2&lt;br /&gt;
start_link.depth     = tenpt / 2&lt;br /&gt;
start_link.link_attr = &amp;quot;/C [0.9 1 0] /Border [0 0 2]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
start_link.action = node.new(&amp;quot;action&amp;quot;)&lt;br /&gt;
start_link.action.action_type = 1&lt;br /&gt;
start_link.action.action_id   = dest&lt;br /&gt;
&lt;br /&gt;
local rule = mkrule(tenpt)&lt;br /&gt;
local hbox = hpack(start_link, rule, end_link)&lt;br /&gt;
add_to_page(hbox)&lt;br /&gt;
&lt;br /&gt;
-- This pagelist consists of an hbox whose contents is &amp;quot;start_link&amp;quot;,&lt;br /&gt;
-- the 10pt x 10pt rule and the &amp;quot;end_link&amp;quot; node. &lt;br /&gt;
&lt;br /&gt;
shipout()&lt;br /&gt;
---------------------------&lt;br /&gt;
&lt;br /&gt;
-- Just to show you that you can get some memory usage statistics:&lt;br /&gt;
print(string.format(&amp;quot;\nnode_mem_usage=%s&amp;quot;,status.node_mem_usage))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The idea is to create nodes, collect them in a list (here: pagelist) and use &amp;lt;tt&amp;gt;tex.shipout()&amp;lt;/tt&amp;gt; to put the page into the PDF.&lt;br /&gt;
&lt;br /&gt;
== And what about &amp;#039;&amp;#039;real&amp;#039;&amp;#039; content? ==&lt;br /&gt;
&lt;br /&gt;
Black squares won&amp;#039;t make anyone happy. So we need a typeset paragraph. For that we start with a single glyph and a glue first. A glyph node has this structure:&lt;br /&gt;
&lt;br /&gt;
[[File:Singleglyphnode.png]]&lt;br /&gt;
&lt;br /&gt;
whereas a glue is more complicated:&lt;br /&gt;
&lt;br /&gt;
[[File:Simplegluenode.png]]&lt;br /&gt;
&lt;br /&gt;
The glue item comes in pairs: a glue node and a glue_spec node. The information about the shrink/stretch values go into the glue_spec node. For example, the TeX glue &amp;lt;tt&amp;gt;2pt plus 1fill&amp;lt;/tt&amp;gt; has a width of 2*2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;, a stretch of 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt; and a stretch_order of 3. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local g = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g.font = font.current()&lt;br /&gt;
g.lang = tex.language&lt;br /&gt;
g.char = 86 -- V&lt;br /&gt;
&lt;br /&gt;
local hbox = node.hpack(g)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We create a glyph, pack it into an hbox (horizontal box), pack that hbox into a vbox (a vertical box) and write this box to the main vertical list. The char number (86 in the example above) is based on an internal encoding, so we have to keep an eye on what character is on what position. Now we do this for two glyphs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local g1 = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g1.font = font.current()&lt;br /&gt;
g1.lang = tex.language&lt;br /&gt;
g1.char = 86&lt;br /&gt;
&lt;br /&gt;
local g2 = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g2.font = font.current()&lt;br /&gt;
g2.lang = tex.language&lt;br /&gt;
g2.char = 97&lt;br /&gt;
&lt;br /&gt;
g1.next = g2&lt;br /&gt;
g2.prev = g1&lt;br /&gt;
&lt;br /&gt;
local hbox = node.hpack(g1)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pretty much the same as above. The glyphs g1 and g2 are chained together by setting the next and prev pointer to each other. If they were not connected, only glyph g1 gets into the hbox.&lt;br /&gt;
&lt;br /&gt;
If you take a close look at the PDF, you see that the two glyphs are too far away, a (negative) kern should be inserted. This can be done by inserting a kern-node manually or you can ask TeX to do that for you. The last lines of the example above should then read:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local head,tail,success = node.kerning(g1)&lt;br /&gt;
local hbox = node.hpack(head)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this approach you are able to put some glyphs into the PDF but you will run into problems when you want to create a whole paragraph. It is much easier to ask TeX to do the line breaking. The steps for paragraph creation are&lt;br /&gt;
&lt;br /&gt;
# put glyph nodes and glue nodes in a list (= chain them together with the prev/next pointers)&lt;br /&gt;
# add trailing infinite penalty and parfillskip&lt;br /&gt;
# call lang.hyphenate(), node.kerning() and node.ligaturing() to prepare the list for the linebreaking job&lt;br /&gt;
# call tex.linebreak()&lt;br /&gt;
&lt;br /&gt;
For the next task we want to create the following paragraph:&lt;br /&gt;
&lt;br /&gt;
[[File:Sample_paragraph.png|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We start with the small TeX stub as above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;myprogram.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and myprogram.lua ([https://gist.github.com/1063228 download]) defines a function &amp;lt;tt&amp;gt;mknodes()&amp;lt;/tt&amp;gt; that creates the list of nodes to be passed into the typesetter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function mknodes( text )&lt;br /&gt;
  local current_font = font.current()&lt;br /&gt;
  local font_parameters = font.getfont(current_font).parameters&lt;br /&gt;
  local n, head, last&lt;br /&gt;
  -- we should insert the paragraph indentation at the beginning&lt;br /&gt;
  head = node.new(&amp;quot;glue&amp;quot;)&lt;br /&gt;
  head.spec = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
  head.spec.width = 20 * 2^16&lt;br /&gt;
  last = head&lt;br /&gt;
&lt;br /&gt;
  for s in string.utfvalues( text ) do&lt;br /&gt;
    local char = unicode.utf8.char(s)&lt;br /&gt;
    if unicode.utf8.match(char,&amp;quot;^%s$&amp;quot;) then&lt;br /&gt;
      -- its a space&lt;br /&gt;
      n = node.new(&amp;quot;glue&amp;quot;)&lt;br /&gt;
      n.spec = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
      n.spec.width   = font_parameters.space&lt;br /&gt;
      n.spec.shrink  = font_parameters.space_shrink&lt;br /&gt;
      n.spec.stretch = font_parameters.space_stretch&lt;br /&gt;
    else -- a glyph&lt;br /&gt;
      n = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
      n.font = current_font&lt;br /&gt;
      n.subtype = 1&lt;br /&gt;
      n.char = s&lt;br /&gt;
      n.lang = tex.language&lt;br /&gt;
      n.uchyph = 1&lt;br /&gt;
      n.left = tex.lefthyphenmin&lt;br /&gt;
      n.right = tex.righthyphenmin&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    last.next = n&lt;br /&gt;
    last = n&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  -- now add the final parts: a penalty and the parfillskip glue&lt;br /&gt;
  local penalty = node.new(&amp;quot;penalty&amp;quot;)&lt;br /&gt;
  penalty.penalty = 10000&lt;br /&gt;
&lt;br /&gt;
  local parfillskip = node.new(&amp;quot;glue&amp;quot;)&lt;br /&gt;
  parfillskip.spec = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
  parfillskip.spec.stretch = 2^16&lt;br /&gt;
  parfillskip.spec.stretch_order = 2&lt;br /&gt;
  &lt;br /&gt;
  last.next = penalty&lt;br /&gt;
  penalty.next = parfillskip&lt;br /&gt;
&lt;br /&gt;
  -- just to create the prev pointers for tex.linebreak&lt;br /&gt;
  node.slide(head)&lt;br /&gt;
  return head&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local txt = &amp;quot;A wonderful serenity has taken possession of my entire soul, ... like mine.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
tex.baselineskip = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
tex.baselineskip.width = 14 * 2^16&lt;br /&gt;
&lt;br /&gt;
local head = mknodes(txt)&lt;br /&gt;
lang.hyphenate(head)&lt;br /&gt;
head = node.kerning(head)&lt;br /&gt;
head = node.ligaturing(head)&lt;br /&gt;
&lt;br /&gt;
local vbox = tex.linebreak(head,{ hsize = tex.sp(&amp;quot;3in&amp;quot;)})&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(You can safely skip this section if you are not interested in the details.)&lt;br /&gt;
&lt;br /&gt;
What has happened in detail? We have created a list of glyph and glue nodes and fed those into the line breaking part of TeX which gave us the vbox back. This vbox contains horizontal lists glued together:&lt;br /&gt;
&lt;br /&gt;
[[File:Paragraph_with_boxes.png|600px]]&lt;br /&gt;
&lt;br /&gt;
The dashed rectangle (vbox) should fit tight to the inner hboxes. It has a small offset just for demonstration purpose.&lt;br /&gt;
&lt;br /&gt;
To show you some of the nodes that TeX inserted for you, have a look at the following image:&lt;br /&gt;
&lt;br /&gt;
[[File:Nodes_in_sample_paragraph.png]]&lt;br /&gt;
&lt;br /&gt;
Here is an explanation of the nodes:&lt;br /&gt;
&lt;br /&gt;
# This is the dashed line in the image above. A paragraph is always vertical&lt;br /&gt;
# The first line. It has a width of three inches, a height and depth of together 8.888 pt&lt;br /&gt;
# The 20pt paragraph indent. This is the first item in the first line (note that the pointer comes from the head item of the node #2&lt;br /&gt;
# The first letter in the first line&lt;br /&gt;
# The interword glue.&lt;br /&gt;
# The second letter in the first line&lt;br /&gt;
# The clubpenalty&lt;br /&gt;
# The baselineskip minus the height of the hbox &amp;quot;above&amp;quot; (8.888pt + 5.111pt is approx. 14pt. The rounding error is due to the display of only few significant digits.) Note that TeX is in vertical mode, as it is the third item in the vbox (#1). &lt;br /&gt;
# The hbox of the second line&lt;br /&gt;
# The first letter of the second line&lt;br /&gt;
# A kern between the m and the y of the first word (second line)&lt;br /&gt;
# The last letter shown here&lt;br /&gt;
&lt;br /&gt;
There are many nodes created in the paragraph which are not shown here. A full view can be found in [[Media:Nodes_in_sample_paragraph_full.pdf|a separate PDF file]].&lt;br /&gt;
&lt;br /&gt;
== Inserting images is easy ==&lt;br /&gt;
&lt;br /&gt;
Now that you have survived the hard part of this tutorial, we get to something easier. Image inclusion. There are several ways to do this, and in my opinion this is the easiest. We again start with our plain (lua)TeX stub:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;includeimage.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and includeimage.lua is this small lua chunk:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local image_fixed = img.scan({filename = &amp;quot;oilpainting.jpg&amp;quot;})&lt;br /&gt;
&lt;br /&gt;
local image     = img.copy(image_fixed)&lt;br /&gt;
local halfimage = img.copy(image_fixed)&lt;br /&gt;
&lt;br /&gt;
halfimage.height = halfimage.height / 2&lt;br /&gt;
halfimage.width  = halfimage.width  / 2&lt;br /&gt;
&lt;br /&gt;
node.write(img.node(image))&lt;br /&gt;
node.write(img.node(halfimage))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You might be able to guess what happens here. We load the image [[Media:Oilpainting.jpg|oilpainting.jpg]] with &amp;lt;tt&amp;gt;img.scan&amp;lt;/tt&amp;gt; but do not write it out to the PDF file yet. We create a copy of the image data so we can manipulate the size for example (another option would be to obtain a specific page of a PDF document or do some rotation). After that we write a reference to that image to the PDF file. In the case above, two references to the image (XObject) get written but the image is only written once. That is easy, right?&lt;br /&gt;
&lt;br /&gt;
You can get an impression how the resulting document looks like:&lt;br /&gt;
&lt;br /&gt;
[[File:Oilpaintingdocument.jpg]]&lt;br /&gt;
&lt;br /&gt;
== Hyphenation ==&lt;br /&gt;
&lt;br /&gt;
Every now and then you have to hyphenate your words in other languages. When you create the paragraph to be hyphenated (with &amp;lt;tt&amp;gt;lang.hyphenate()&amp;lt;/tt&amp;gt;), you assemble it by creating glyph nodes which have a field lang (see above). This field accepts a number, the language id. So: how do we &amp;quot;create&amp;quot; a language? The first steps are simple, we start without TeX stub again:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;hyphenation.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the file hyphenation.lua is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local path = kpse.find_file(&amp;quot;hyph-de-1996.pat.txt&amp;quot;)&lt;br /&gt;
local l = lang.new()&lt;br /&gt;
&lt;br /&gt;
local hyph_file = io.open(path)&lt;br /&gt;
lang.patterns(l,hyph_file:read(&amp;quot;*all&amp;quot;))&lt;br /&gt;
hyph_file:close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now the function &amp;lt;tt&amp;gt;lang.id(l)&amp;lt;/tt&amp;gt; returns the language id of the language &amp;lt;tt&amp;gt;l&amp;lt;/tt&amp;gt;, which we can use in the glyph nodes. A peculiarity of TeX prevents that we can start with that right away. All characters that are in the paragraph get lowercased before hyphenation rules apply. So how will a word like &amp;quot;Œuvre&amp;quot; be converted to lowercase? TeX has an internal table called &amp;#039;&amp;#039;lccode&amp;#039;&amp;#039; where it looks up a character and the output is its lowercase variant. So the lccode of Œ would be œ, but as TeX stores numbers, the lccode of 338 is 339. But only lccodes of the letters A-Z and a-z are set, so we need to set the codes for all other characters that appear in a text. In TeX you would write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\lccode`\Œ=`\œ&lt;br /&gt;
\lccode`\œ=`\œ&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\lccode338=339&lt;br /&gt;
\lccode339=339&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You see that you need to set the lccode of the lowercase characters as well. In Lua you do something similar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tex.lccode[unicode.utf8.byte(&amp;quot;Œ&amp;quot;)] = [unicode.utf8.byte(&amp;quot;œ&amp;quot;)]&lt;br /&gt;
tex.lccode[unicode.utf8.byte(&amp;quot;œ&amp;quot;)] = [unicode.utf8.byte(&amp;quot;œ&amp;quot;)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or shorter:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tex.lccode[338] = [339]&lt;br /&gt;
tex.lccode[339] = [339]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have set all the necessary lccodes (remember you don&amp;#039;t need to do this with a to z and A to Z), you can expect the hyphenation to work.&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=147</id>
		<title>TeX without TeX</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=147"/>
		<updated>2011-08-11T12:15:37Z</updated>

		<summary type="html">&lt;p&gt;Patrick: /* Inserting images is easy */ Show example resulting document&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Use TeX&amp;#039;s power without TeX macros ==&lt;br /&gt;
&lt;br /&gt;
With the Lua-part in LuaTeX you have access to most of TeX&amp;#039;s capabilities for creating PDF documents. Most of the [http://www.luatex.org/svn/trunk/manual/luatexref-t.pdf LuaTeX reference manual] is about this topic. &lt;br /&gt;
&lt;br /&gt;
[[Writing_Lua_in_TeX|Remember]] that you can jump into Lua mode from TeX with &amp;lt;tt&amp;gt;\directlua{...Lua code...}&amp;lt;/tt&amp;gt;. For example this plain TeX document prints the first digits of the value of pi: &amp;lt;tt&amp;gt;$\pi = \directlua{ tex.print(math.pi)}$ \bye&amp;lt;/tt&amp;gt;. You can get the result PDF by running &amp;lt;tt&amp;gt;luatex testfile.tex&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The underlying idea is to create TeX&amp;#039;s internal data structure as TeX would do by transforming macros and primitives into something called nodes. These nodes are then transformed into instructions for the PDF file (PDF objects). So the following pages deal with node creation and the structures. &lt;br /&gt;
&lt;br /&gt;
Let&amp;#039;s start with a rule node. When you write &amp;lt;tt&amp;gt;\hrule width 20pt height 10pt depth 10pt &amp;lt;/tt&amp;gt; in TeX, a node of type rule will be created, which has three fields: height, depth and width. We can visualize this node by a simple box like this:&lt;br /&gt;
&lt;br /&gt;
[[File:rulenode.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r.width  = 20 * 65536&lt;br /&gt;
r.height = 10 * 65536&lt;br /&gt;
r.depth  = 10 * 65536&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some remarks: the size is in scaled points, and 65536 (=2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;) scaled points are 1 point, so 20pt becomes 20 * 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;. Not shown in the example are (among others) the next and prev fields. These fields hold a pointer (the node address) to the following and the previous nodes. A node that exist by itself has its prev and next fields set to nil.&lt;br /&gt;
&lt;br /&gt;
A slightly more complicated example is when you create two rules and pack then into a vertical box. This would look like this in plain TeX:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\vbox {\hrule width 20pt height 10pt depth 10pt&lt;br /&gt;
           \hrule width 20pt height 10pt depth 10pt }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would generate a node list like:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Rulenode2.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r1 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r1.width  = 20 * 65536&lt;br /&gt;
r1.height = 10 * 65536&lt;br /&gt;
r1.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r2 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r2.width  = 20 * 65536&lt;br /&gt;
r2.height = 10 * 65536&lt;br /&gt;
r2.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r1.next = r2&lt;br /&gt;
r2.prev = r1&lt;br /&gt;
&lt;br /&gt;
vbox = node.vpack(r1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result is a vbox containing the two rule nodes. The nodes are connected by their next and prev pointers, so the vbox contains them both. The size (width, height and depth) is adjusted automatically.&lt;br /&gt;
&lt;br /&gt;
This also applies to all other things you can put on a TeX page: glyphs, horizontal boxes, math, images, hyperlinks, glue .... For a complete list of the nodes, see the reference manual Chapter 8 &amp;quot;Nodes&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Beyond reports and articles ==&lt;br /&gt;
&lt;br /&gt;
Perhaps the question that comes into your mind is: why should I bother writing Lua code instead of TeX code? For many documents, including articles, reports and books, the classic way to create a PDF with TeX is to use LaTeX or ConTeXt. But there are applications that use TeX as an 100% automatic PDF generation software. If you want to create data sheets or product listings, your normal input is not a classic document, but most likely an Excel spreadsheet or an XML file, perhaps extracted from a database. You won&amp;#039;t have any TeX markup within these documents. So: if you don&amp;#039;t have TeX markup in these documents, you don&amp;#039;t need the TeX interpreter to read these files. More likely is an XML parser or a spreadsheet 2 ... converter.&lt;br /&gt;
&lt;br /&gt;
When you use regular LaTeX or ConTeXt code to put the contents of the database in your PDF (database publishing), you run into several problems:&lt;br /&gt;
&lt;br /&gt;
* Exact positioning of items on the page can be troublesome&lt;br /&gt;
* catcodes / command escapes are to be considered and surely get into your way&lt;br /&gt;
* TeX is no fun to program in (well it is, but only for some people) - calculations, tests, exception handling, control flow&lt;br /&gt;
* The packages that exist may reach their limit soon. You need a super flexible image-between-columns-with-parshape package? Write it yourself.&lt;br /&gt;
&lt;br /&gt;
With Lua you have a very decent programming language that &amp;#039;&amp;#039;is&amp;#039;&amp;#039; fun to program in. When you use the Lua interface to TeX, you have full control of what is happening, which is usually the level of control you need for high quality output.&lt;br /&gt;
&lt;br /&gt;
One approach is to create a stub TeX file and let Lua do the rest:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;myprogram.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The file &amp;lt;tt&amp;gt;myprogram.lua&amp;lt;/tt&amp;gt; then contains all the code to a) read the source file(s), b) extract the information and create the appropriate nodes and c) instruct TeX to create PDF pages from these nodes.&lt;br /&gt;
&lt;br /&gt;
In a future version of LuaTeX you will be able to run the Lua interpreter without the stub TeX file above.&lt;br /&gt;
&lt;br /&gt;
== A first example ==&lt;br /&gt;
&lt;br /&gt;
The example document given below creates two pages by using Lua code alone. You will learn how to access TeX&amp;#039;s boxes and counters from the Lua side, shipout a page into the PDF file, create horizontal and vertical boxes (hbox and vbox), create new nodes and manipulate the nodes links structure. The example covers the following node types: rule, whatsit, vlist, hlist and action.&lt;br /&gt;
&lt;br /&gt;
In the example code we use black squares as the contents of the pages and not normal text, because character handling takes more code and will be covered later on.&lt;br /&gt;
&lt;br /&gt;
Save the following file into &amp;lt;tt&amp;gt;myprogram.lua&amp;lt;/tt&amp;gt; and use the TeX stub from above (or get the source [https://raw.github.com/gist/1062041/d3de082e955f6535f3820742cef76fe9e50d5a6f/myprogram.lua here]).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
  -- this will hold the items that go onto the page&lt;br /&gt;
  local pagelist&lt;br /&gt;
 &lt;br /&gt;
  -- Call tex.shipout() with the contents of the pagelist&lt;br /&gt;
  function shipout()&lt;br /&gt;
&lt;br /&gt;
    local vbox,b = node.vpack(pagelist) -- we ignore the badness &amp;#039;b&amp;#039;&lt;br /&gt;
    tex.box[666] = vbox&lt;br /&gt;
    tex.shipout(666)&lt;br /&gt;
&lt;br /&gt;
    pagelist = nil&lt;br /&gt;
    &lt;br /&gt;
    -- Not strictly necessary. TeX holds the current page number in counter 0.&lt;br /&gt;
    -- TeX displays the contents of this counter when it puts a page into&lt;br /&gt;
    -- the pdf (tex.shipout()). If we don&amp;#039;t change the counter, TeX will&lt;br /&gt;
    -- display [1] [1], instead of [1] [2] for our two page document.&lt;br /&gt;
    tex.count[0] = tex.count[0] + 1&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
  function add_to_page( list )&lt;br /&gt;
    -- We attach the nodelist &amp;#039;list&amp;#039; to the end of the pagelist&lt;br /&gt;
    -- if pagelist doesn&amp;#039;t exist, &amp;#039;list&amp;#039; is our new pagelist&lt;br /&gt;
    -- if it exists, we go to the end with node.tail() and adjust&lt;br /&gt;
    -- the prev and next pointers, so list becomes part&lt;br /&gt;
    -- of pagelist.&lt;br /&gt;
    if not pagelist then pagelist = list&lt;br /&gt;
    else&lt;br /&gt;
      local tail = node.tail(pagelist)&lt;br /&gt;
      tail.next = list&lt;br /&gt;
      list.prev  = tail&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- This creates a new square rule and returns the pointer to it.&lt;br /&gt;
function mkrule( size )&lt;br /&gt;
  local r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
  r.width  = size &lt;br /&gt;
  r.height = size / 2&lt;br /&gt;
  r.depth  = size / 2&lt;br /&gt;
  return r&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
do&lt;br /&gt;
  local destcounter = 0&lt;br /&gt;
  -- Create a pdf anchor (dest object). It returns a whatsit node and the &lt;br /&gt;
  -- number of the anchor, so it can be used in a pdf link or an outline.&lt;br /&gt;
  function mkdest()&lt;br /&gt;
    destcounter = destcounter + 1&lt;br /&gt;
    local d = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_dest&amp;quot;)&lt;br /&gt;
    d.named_id = 0&lt;br /&gt;
    d.dest_id = destcounter&lt;br /&gt;
    d.dest_type = 3&lt;br /&gt;
&lt;br /&gt;
    return d, destcounter&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Take a list of nodes and put them into an hbox. The prev and next fields&lt;br /&gt;
-- of the nodes will be set automatically. Return a pointer to the hbox.&lt;br /&gt;
function hpack( ... )&lt;br /&gt;
  local start, tmp, cur&lt;br /&gt;
  start = select(1,...)&lt;br /&gt;
  tmp = start&lt;br /&gt;
  for i=2,select(&amp;quot;#&amp;quot;,...) do&lt;br /&gt;
    cur = select(i,...)&lt;br /&gt;
    tmp.next = cur&lt;br /&gt;
    cur.prev = tmp&lt;br /&gt;
    tmp = cur&lt;br /&gt;
  end&lt;br /&gt;
  local h,b = node.hpack(start) -- ignore badness&lt;br /&gt;
  return h&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local tenpt = 10 * 2^16&lt;br /&gt;
---------------------------&lt;br /&gt;
-- page 1&lt;br /&gt;
---------------------------&lt;br /&gt;
local n,dest = mkdest() -- dest is needed for the link to this anchor&lt;br /&gt;
&lt;br /&gt;
add_to_page(n)&lt;br /&gt;
add_to_page(mkrule(2 * tenpt))&lt;br /&gt;
&lt;br /&gt;
-- The pagelist contains a pdf dest node (a link destination) and a rule of size 20pt x 20pt.&lt;br /&gt;
&lt;br /&gt;
shipout()&lt;br /&gt;
---------------------------&lt;br /&gt;
-- page 2&lt;br /&gt;
---------------------------&lt;br /&gt;
-- This is the page with the link to the anchor (dest) on page one. A&lt;br /&gt;
-- link consists of three nodes: a pdf_start_link, a pdf_end_link and and &lt;br /&gt;
-- action node that specifies the action to perform when the user clicks on&lt;br /&gt;
-- the link.&lt;br /&gt;
-- The pdf link must be inside a horizontal box, that&amp;#039;s why we hpack() it.&lt;br /&gt;
-- The link_attr (link attributes) is optional, here it draws a yellowish border&lt;br /&gt;
-- around the link.&lt;br /&gt;
local start_link = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_start_link&amp;quot;)&lt;br /&gt;
local end_link   = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_end_link&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
start_link.width     = tenpt&lt;br /&gt;
start_link.height    = tenpt / 2&lt;br /&gt;
start_link.depth     = tenpt / 2&lt;br /&gt;
start_link.link_attr = &amp;quot;/C [0.9 1 0] /Border [0 0 2]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
start_link.action = node.new(&amp;quot;action&amp;quot;)&lt;br /&gt;
start_link.action.action_type = 1&lt;br /&gt;
start_link.action.action_id   = dest&lt;br /&gt;
&lt;br /&gt;
local rule = mkrule(tenpt)&lt;br /&gt;
local hbox = hpack(start_link, rule, end_link)&lt;br /&gt;
add_to_page(hbox)&lt;br /&gt;
&lt;br /&gt;
-- This pagelist consists of an hbox whose contents is &amp;quot;start_link&amp;quot;,&lt;br /&gt;
-- the 10pt x 10pt rule and the &amp;quot;end_link&amp;quot; node. &lt;br /&gt;
&lt;br /&gt;
shipout()&lt;br /&gt;
---------------------------&lt;br /&gt;
&lt;br /&gt;
-- Just to show you that you can get some memory usage statistics:&lt;br /&gt;
print(string.format(&amp;quot;\nnode_mem_usage=%s&amp;quot;,status.node_mem_usage))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The idea is to create nodes, collect them in a list (here: pagelist) and use &amp;lt;tt&amp;gt;tex.shipout()&amp;lt;/tt&amp;gt; to put the page into the PDF.&lt;br /&gt;
&lt;br /&gt;
== And what about &amp;#039;&amp;#039;real&amp;#039;&amp;#039; content? ==&lt;br /&gt;
&lt;br /&gt;
Black squares won&amp;#039;t make anyone happy. So we need a typeset paragraph. For that we start with a single glyph and a glue first. A glyph node has this structure:&lt;br /&gt;
&lt;br /&gt;
[[File:Singleglyphnode.png]]&lt;br /&gt;
&lt;br /&gt;
whereas a glue is more complicated:&lt;br /&gt;
&lt;br /&gt;
[[File:Simplegluenode.png]]&lt;br /&gt;
&lt;br /&gt;
The glue item comes in pairs: a glue node and a glue_spec node. The information about the shrink/stretch values go into the glue_spec node. For example, the TeX glue &amp;lt;tt&amp;gt;2pt plus 1fill&amp;lt;/tt&amp;gt; has a width of 2*2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;, a stretch of 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt; and a stretch_order of 3. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local g = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g.font = font.current()&lt;br /&gt;
g.lang = tex.language&lt;br /&gt;
g.char = 86 -- V&lt;br /&gt;
&lt;br /&gt;
local hbox = node.hpack(g)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We create a glyph, pack it into an hbox (horizontal box), pack that hbox into a vbox (a vertical box) and write this box to the main vertical list. The char number (86 in the example above) is based on an internal encoding, so we have to keep an eye on what character is on what position. Now we do this for two glyphs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local g1 = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g1.font = font.current()&lt;br /&gt;
g1.lang = tex.language&lt;br /&gt;
g1.char = 86&lt;br /&gt;
&lt;br /&gt;
local g2 = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g2.font = font.current()&lt;br /&gt;
g2.lang = tex.language&lt;br /&gt;
g2.char = 97&lt;br /&gt;
&lt;br /&gt;
g1.next = g2&lt;br /&gt;
g2.prev = g1&lt;br /&gt;
&lt;br /&gt;
local hbox = node.hpack(g1)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pretty much the same as above. The glyphs g1 and g2 are chained together by setting the next and prev pointer to each other. If they were not connected, only glyph g1 gets into the hbox.&lt;br /&gt;
&lt;br /&gt;
If you take a close look at the PDF, you see that the two glyphs are too far away, a (negative) kern should be inserted. This can be done by inserting a kern-node manually or you can ask TeX to do that for you. The last lines of the example above should then read:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local head,tail,success = node.kerning(g1)&lt;br /&gt;
local hbox = node.hpack(head)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this approach you are able to put some glyphs into the PDF but you will run into problems when you want to create a whole paragraph. It is much easier to ask TeX to do the line breaking. The steps for paragraph creation are&lt;br /&gt;
&lt;br /&gt;
# put glyph nodes and glue nodes in a list (= chain them together with the prev/next pointers)&lt;br /&gt;
# add trailing infinite penalty and parfillskip&lt;br /&gt;
# call lang.hyphenate(), node.kerning() and node.ligaturing() to prepare the list for the linebreaking job&lt;br /&gt;
# call tex.linebreak()&lt;br /&gt;
&lt;br /&gt;
For the next task we want to create the following paragraph:&lt;br /&gt;
&lt;br /&gt;
[[File:Sample_paragraph.png|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We start with the small TeX stub as above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;myprogram.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and myprogram.lua ([https://gist.github.com/1063228 download]) defines a function &amp;lt;tt&amp;gt;mknodes()&amp;lt;/tt&amp;gt; that creates the list of nodes to be passed into the typesetter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function mknodes( text )&lt;br /&gt;
  local current_font = font.current()&lt;br /&gt;
  local font_parameters = font.getfont(current_font).parameters&lt;br /&gt;
  local n, head, last&lt;br /&gt;
  -- we should insert the paragraph indentation at the beginning&lt;br /&gt;
  head = node.new(&amp;quot;glue&amp;quot;)&lt;br /&gt;
  head.spec = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
  head.spec.width = 20 * 2^16&lt;br /&gt;
  last = head&lt;br /&gt;
&lt;br /&gt;
  for s in string.utfvalues( text ) do&lt;br /&gt;
    local char = unicode.utf8.char(s)&lt;br /&gt;
    if unicode.utf8.match(char,&amp;quot;%s&amp;quot;) then&lt;br /&gt;
      -- its a space&lt;br /&gt;
      n = node.new(&amp;quot;glue&amp;quot;)&lt;br /&gt;
      n.spec = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
      n.spec.width   = font_parameters.space&lt;br /&gt;
      n.spec.shrink  = font_parameters.space_shrink&lt;br /&gt;
      n.spec.stretch = font_parameters.space_stretch&lt;br /&gt;
    else -- a glyph&lt;br /&gt;
      n = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
      n.font = current_font&lt;br /&gt;
      n.subtype = 1&lt;br /&gt;
      n.char = s&lt;br /&gt;
      n.lang = tex.language&lt;br /&gt;
      n.uchyph = 1&lt;br /&gt;
      n.left = tex.lefthyphenmin&lt;br /&gt;
      n.right = tex.righthyphenmin&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    last.next = n&lt;br /&gt;
    last = n&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  -- now add the final parts: a penalty and the parfillskip glue&lt;br /&gt;
  local penalty = node.new(&amp;quot;penalty&amp;quot;)&lt;br /&gt;
  penalty.penalty = 10000&lt;br /&gt;
&lt;br /&gt;
  local parfillskip = node.new(&amp;quot;glue&amp;quot;)&lt;br /&gt;
  parfillskip.spec = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
  parfillskip.spec.stretch = 2^16&lt;br /&gt;
  parfillskip.spec.stretch_order = 2&lt;br /&gt;
  &lt;br /&gt;
  last.next = penalty&lt;br /&gt;
  penalty.next = parfillskip&lt;br /&gt;
&lt;br /&gt;
  -- just to create the prev pointers for tex.linebreak&lt;br /&gt;
  node.slide(head)&lt;br /&gt;
  return head&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local txt = &amp;quot;A wonderful serenity has taken possession of my entire soul, ... like mine.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
tex.baselineskip = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
tex.baselineskip.width = 14 * 2^16&lt;br /&gt;
&lt;br /&gt;
local head = mknodes(txt)&lt;br /&gt;
lang.hyphenate(head)&lt;br /&gt;
head = node.kerning(head)&lt;br /&gt;
head = node.ligaturing(head)&lt;br /&gt;
&lt;br /&gt;
local vbox = tex.linebreak(head,{ hsize = tex.sp(&amp;quot;3in&amp;quot;)})&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(You can safely skip this section if you are not interested in the details.)&lt;br /&gt;
&lt;br /&gt;
What has happened in detail? We have created a list of glyph and glue nodes and fed those into the line breaking part of TeX which gave us the vbox back. This vbox contains horizontal lists glued together:&lt;br /&gt;
&lt;br /&gt;
[[File:Paragraph_with_boxes.png|600px]]&lt;br /&gt;
&lt;br /&gt;
The dashed rectangle (vbox) should fit tight to the inner hboxes. It has a small offset just for demonstration purpose.&lt;br /&gt;
&lt;br /&gt;
To show you some of the nodes that TeX inserted for you, have a look at the following image:&lt;br /&gt;
&lt;br /&gt;
[[File:Nodes_in_sample_paragraph.png]]&lt;br /&gt;
&lt;br /&gt;
Here is an explanation of the nodes:&lt;br /&gt;
&lt;br /&gt;
# This is the dashed line in the image above. A paragraph is always vertical&lt;br /&gt;
# The first line. It has a width of three inches, a height and depth of together 8.888 pt&lt;br /&gt;
# The 20pt paragraph indent. This is the first item in the first line (note that the pointer comes from the head item of the node #2&lt;br /&gt;
# The first letter in the first line&lt;br /&gt;
# The interword glue.&lt;br /&gt;
# The second letter in the first line&lt;br /&gt;
# The clubpenalty&lt;br /&gt;
# The baselineskip minus the height of the hbox &amp;quot;above&amp;quot; (8.888pt + 5.111pt is approx. 14pt. The rounding error is due to the display of only few significant digits.) Note that TeX is in vertical mode, as it is the third item in the vbox (#1). &lt;br /&gt;
# The hbox of the second line&lt;br /&gt;
# The first letter of the second line&lt;br /&gt;
# A kern between the m and the y of the first word (second line)&lt;br /&gt;
# The last letter shown here&lt;br /&gt;
&lt;br /&gt;
There are many nodes created in the paragraph which are not shown here. A full view can be found in [[Media:Nodes_in_sample_paragraph_full.pdf|a separate PDF file]].&lt;br /&gt;
&lt;br /&gt;
== Inserting images is easy ==&lt;br /&gt;
&lt;br /&gt;
Now that you have survived the hard part of this tutorial, we get to something easier. Image inclusion. There are several ways to do this, and in my opinion this is the easiest. We again start with our plain (lua)TeX stub:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;includeimage.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and includeimage.lua is this small lua chunk:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local image_fixed = img.scan({filename = &amp;quot;oilpainting.jpg&amp;quot;})&lt;br /&gt;
&lt;br /&gt;
local image     = img.copy(image_fixed)&lt;br /&gt;
local halfimage = img.copy(image_fixed)&lt;br /&gt;
&lt;br /&gt;
halfimage.height = halfimage.height / 2&lt;br /&gt;
halfimage.width  = halfimage.width  / 2&lt;br /&gt;
&lt;br /&gt;
node.write(img.node(image))&lt;br /&gt;
node.write(img.node(halfimage))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You might be able to guess what happens here. We load the image [[Media:Oilpainting.jpg|oilpainting.jpg]] with &amp;lt;tt&amp;gt;img.scan&amp;lt;/tt&amp;gt; but do not write it out to the PDF file yet. We create a copy of the image data so we can manipulate the size for example (another option would be to obtain a specific page of a PDF document or do some rotation). After that we write a reference to that image to the PDF file. In the case above, two references to the image (XObject) get written but the image is only written once. That is easy, right?&lt;br /&gt;
&lt;br /&gt;
You can get an impression how the resulting document looks like:&lt;br /&gt;
&lt;br /&gt;
[[File:Oilpaintingdocument.jpg]]&lt;br /&gt;
&lt;br /&gt;
== Hyphenation ==&lt;br /&gt;
&lt;br /&gt;
Every now and then you have to hyphenate your words in other languages. When you create the paragraph to be hyphenated (with &amp;lt;tt&amp;gt;lang.hyphenate()&amp;lt;/tt&amp;gt;), you assemble it by creating glyph nodes which have a field lang (see above). This field accepts a number, the language id. So: how do we &amp;quot;create&amp;quot; a language? The first steps are simple, we start without TeX stub again:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;hyphenation.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the file hyphenation.lua is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local path = kpse.find_file(&amp;quot;hyph-de-1996.pat.txt&amp;quot;)&lt;br /&gt;
local l = lang.new()&lt;br /&gt;
&lt;br /&gt;
local hyph_file = io.open(path)&lt;br /&gt;
lang.patterns(l,hyph_file:read(&amp;quot;*all&amp;quot;))&lt;br /&gt;
hyph_file:close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now the function &amp;lt;tt&amp;gt;lang.id(l)&amp;lt;/tt&amp;gt; returns the language id of the language &amp;lt;tt&amp;gt;l&amp;lt;/tt&amp;gt;, which we can use in the glyph nodes. A peculiarity of TeX prevents that we can start with that right away. All characters that are in the paragraph get lowercased before hyphenation rules apply. So how will a word like &amp;quot;Œuvre&amp;quot; be converted to lowercase? TeX has an internal table called &amp;#039;&amp;#039;lccode&amp;#039;&amp;#039; where it looks up a character and the output is its lowercase variant. So the lccode of Œ would be œ, but as TeX stores numbers, the lccode of 338 is 339. But only lccodes of the letters A-Z and a-z are set, so we need to set the codes for all other characters that appear in a text. In TeX you would write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\lccode`\Œ=`\œ&lt;br /&gt;
\lccode`\œ=`\œ&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\lccode338=339&lt;br /&gt;
\lccode339=339&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You see that you need to set the lccode of the lowercase characters as well. In Lua you do something similar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tex.lccode[unicode.utf8.byte(&amp;quot;Œ&amp;quot;)] = [unicode.utf8.byte(&amp;quot;œ&amp;quot;)]&lt;br /&gt;
tex.lccode[unicode.utf8.byte(&amp;quot;œ&amp;quot;)] = [unicode.utf8.byte(&amp;quot;œ&amp;quot;)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or shorter:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tex.lccode[338] = [339]&lt;br /&gt;
tex.lccode[339] = [339]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have set all the necessary lccodes (remember you don&amp;#039;t need to do this with a to z and A to Z), you can expect the hyphenation to work.&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=File:Oilpaintingdocument.jpg&amp;diff=146</id>
		<title>File:Oilpaintingdocument.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=File:Oilpaintingdocument.jpg&amp;diff=146"/>
		<updated>2011-08-11T12:14:02Z</updated>

		<summary type="html">&lt;p&gt;Patrick: Sample document of two oilpaintings&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Sample document of two oilpaintings&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=File:Fontsampleroutput.png&amp;diff=145</id>
		<title>File:Fontsampleroutput.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=File:Fontsampleroutput.png&amp;diff=145"/>
		<updated>2011-08-09T10:02:35Z</updated>

		<summary type="html">&lt;p&gt;Patrick: example output of the fontsampler code&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;example output of the fontsampler code&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=141</id>
		<title>TeX without TeX</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=141"/>
		<updated>2011-07-07T11:14:59Z</updated>

		<summary type="html">&lt;p&gt;Patrick: Language and Hyphenation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Use TeX&amp;#039;s power without TeX macros ==&lt;br /&gt;
&lt;br /&gt;
With the Lua-part in LuaTeX you have access to most of TeX&amp;#039;s capabilities for creating PDF documents. Most of the [http://www.luatex.org/svn/trunk/manual/luatexref-t.pdf LuaTeX reference manual] is about this topic. &lt;br /&gt;
&lt;br /&gt;
[[Writing_Lua_in_TeX|Remember]] that you can jump into Lua mode from TeX with &amp;lt;tt&amp;gt;\directlua{...Lua code...}&amp;lt;/tt&amp;gt;. For example this plain TeX document prints the first digits of the value of pi: &amp;lt;tt&amp;gt;$\pi = \directlua{ tex.print(math.pi)}$ \bye&amp;lt;/tt&amp;gt;. You can get the result PDF by running &amp;lt;tt&amp;gt;luatex testfile.tex&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The underlying idea is to create TeX&amp;#039;s internal data structure as TeX would do by transforming macros and primitives into something called nodes. These nodes are then transformed into instructions for the PDF file (PDF objects). So the following pages deal with node creation and the structures. &lt;br /&gt;
&lt;br /&gt;
Let&amp;#039;s start with a rule node. When you write &amp;lt;tt&amp;gt;\hrule width 20pt height 10pt depth 10pt &amp;lt;/tt&amp;gt; in TeX, a node of type rule will be created, which has three fields: height, depth and width. We can visualize this node by a simple box like this:&lt;br /&gt;
&lt;br /&gt;
[[File:rulenode.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r.width  = 20 * 65536&lt;br /&gt;
r.height = 10 * 65536&lt;br /&gt;
r.depth  = 10 * 65536&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some remarks: the size is in scaled points, and 65536 (=2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;) scaled points are 1 point, so 20pt becomes 20 * 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;. Not shown in the example are (among others) the next and prev fields. These fields hold a pointer (the node address) to the following and the previous nodes. A node that exist by itself has its prev and next fields set to nil.&lt;br /&gt;
&lt;br /&gt;
A slightly more complicated example is when you create two rules and pack then into a vertical box. This would look like this in plain TeX:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\vbox {\hrule width 20pt height 10pt depth 10pt&lt;br /&gt;
           \hrule width 20pt height 10pt depth 10pt }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would generate a node list like:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Rulenode2.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r1 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r1.width  = 20 * 65536&lt;br /&gt;
r1.height = 10 * 65536&lt;br /&gt;
r1.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r2 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r2.width  = 20 * 65536&lt;br /&gt;
r2.height = 10 * 65536&lt;br /&gt;
r2.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r1.next = r2&lt;br /&gt;
r2.prev = r1&lt;br /&gt;
&lt;br /&gt;
vbox = node.vpack(r1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result is a vbox containing the two rule nodes. The nodes are connected by their next and prev pointers, so the vbox contains them both. The size (width, height and depth) is adjusted automatically.&lt;br /&gt;
&lt;br /&gt;
This also applies to all other things you can put on a TeX page: glyphs, horizontal boxes, math, images, hyperlinks, glue .... For a complete list of the nodes, see the reference manual Chapter 8 &amp;quot;Nodes&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Beyond reports and articles ==&lt;br /&gt;
&lt;br /&gt;
Perhaps the question that comes into your mind is: why should I bother writing Lua code instead of TeX code? For many documents, including articles, reports and books, the classic way to create a PDF with TeX is to use LaTeX or ConTeXt. But there are applications that use TeX as an 100% automatic PDF generation software. If you want to create data sheets or product listings, your normal input is not a classic document, but most likely an Excel spreadsheet or an XML file, perhaps extracted from a database. You won&amp;#039;t have any TeX markup within these documents. So: if you don&amp;#039;t have TeX markup in these documents, you don&amp;#039;t need the TeX interpreter to read these files. More likely is an XML parser or a spreadsheet 2 ... converter.&lt;br /&gt;
&lt;br /&gt;
When you use regular LaTeX or ConTeXt code to put the contents of the database in your PDF (database publishing), you run into several problems:&lt;br /&gt;
&lt;br /&gt;
* Exact positioning of items on the page can be troublesome&lt;br /&gt;
* catcodes / command escapes are to be considered and surely get into your way&lt;br /&gt;
* TeX is no fun to program in (well it is, but only for some people) - calculations, tests, exception handling, control flow&lt;br /&gt;
* The packages that exist may reach their limit soon. You need a super flexible image-between-columns-with-parshape package? Write it yourself.&lt;br /&gt;
&lt;br /&gt;
With Lua you have a very decent programming language that &amp;#039;&amp;#039;is&amp;#039;&amp;#039; fun to program in. When you use the Lua interface to TeX, you have full control of what is happening, which is usually the level of control you need for high quality output.&lt;br /&gt;
&lt;br /&gt;
One approach is to create a stub TeX file and let Lua do the rest:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;myprogram.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The file &amp;lt;tt&amp;gt;myprogram.lua&amp;lt;/tt&amp;gt; then contains all the code to a) read the source file(s), b) extract the information and create the appropriate nodes and c) instruct TeX to create PDF pages from these nodes.&lt;br /&gt;
&lt;br /&gt;
In a future version of LuaTeX you will be able to run the Lua interpreter without the stub TeX file above.&lt;br /&gt;
&lt;br /&gt;
== A first example ==&lt;br /&gt;
&lt;br /&gt;
The example document given below creates two pages by using Lua code alone. You will learn how to access TeX&amp;#039;s boxes and counters from the Lua side, shipout a page into the PDF file, create horizontal and vertical boxes (hbox and vbox), create new nodes and manipulate the nodes links structure. The example covers the following node types: rule, whatsit, vlist, hlist and action.&lt;br /&gt;
&lt;br /&gt;
In the example code we use black squares as the contents of the pages and not normal text, because character handling takes more code and will be covered later on.&lt;br /&gt;
&lt;br /&gt;
Save the following file into &amp;lt;tt&amp;gt;myprogram.lua&amp;lt;/tt&amp;gt; and use the TeX stub from above (or get the source [https://raw.github.com/gist/1062041/d3de082e955f6535f3820742cef76fe9e50d5a6f/myprogram.lua here]).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
  -- this will hold the items that go onto the page&lt;br /&gt;
  local pagelist&lt;br /&gt;
 &lt;br /&gt;
  -- Call tex.shipout() with the contents of the pagelist&lt;br /&gt;
  function shipout()&lt;br /&gt;
&lt;br /&gt;
    local vbox,b = node.vpack(pagelist) -- we ignore the badness &amp;#039;b&amp;#039;&lt;br /&gt;
    tex.box[666] = vbox&lt;br /&gt;
    tex.shipout(666)&lt;br /&gt;
&lt;br /&gt;
    pagelist = nil&lt;br /&gt;
    &lt;br /&gt;
    -- Not strictly necessary. TeX holds the current page number in counter 0.&lt;br /&gt;
    -- TeX displays the contents of this counter when it puts a page into&lt;br /&gt;
    -- the pdf (tex.shipout()). If we don&amp;#039;t change the counter, TeX will&lt;br /&gt;
    -- display [1] [1], instead of [1] [2] for our two page document.&lt;br /&gt;
    tex.count[0] = tex.count[0] + 1&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
  function add_to_page( list )&lt;br /&gt;
    -- We attach the nodelist &amp;#039;list&amp;#039; to the end of the pagelist&lt;br /&gt;
    -- if pagelist doesn&amp;#039;t exist, &amp;#039;list&amp;#039; is our new pagelist&lt;br /&gt;
    -- if it exists, we go to the end with node.tail() and adjust&lt;br /&gt;
    -- the prev and next pointers, so list becomes part&lt;br /&gt;
    -- of pagelist.&lt;br /&gt;
    if not pagelist then pagelist = list&lt;br /&gt;
    else&lt;br /&gt;
      local tail = node.tail(pagelist)&lt;br /&gt;
      tail.next = list&lt;br /&gt;
      list.prev  = tail&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- This creates a new square rule and returns the pointer to it.&lt;br /&gt;
function mkrule( size )&lt;br /&gt;
  local r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
  r.width  = size &lt;br /&gt;
  r.height = size / 2&lt;br /&gt;
  r.depth  = size / 2&lt;br /&gt;
  return r&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
do&lt;br /&gt;
  local destcounter = 0&lt;br /&gt;
  -- Create a pdf anchor (dest object). It returns a whatsit node and the &lt;br /&gt;
  -- number of the anchor, so it can be used in a pdf link or an outline.&lt;br /&gt;
  function mkdest()&lt;br /&gt;
    destcounter = destcounter + 1&lt;br /&gt;
    local d = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_dest&amp;quot;)&lt;br /&gt;
    d.named_id = 0&lt;br /&gt;
    d.dest_id = destcounter&lt;br /&gt;
    d.dest_type = 3&lt;br /&gt;
&lt;br /&gt;
    return d, destcounter&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Take a list of nodes and put them into an hbox. The prev and next fields&lt;br /&gt;
-- of the nodes will be set automatically. Return a pointer to the hbox.&lt;br /&gt;
function hpack( ... )&lt;br /&gt;
  local start, tmp, cur&lt;br /&gt;
  start = select(1,...)&lt;br /&gt;
  tmp = start&lt;br /&gt;
  for i=2,select(&amp;quot;#&amp;quot;,...) do&lt;br /&gt;
    cur = select(i,...)&lt;br /&gt;
    tmp.next = cur&lt;br /&gt;
    cur.prev = tmp&lt;br /&gt;
    tmp = cur&lt;br /&gt;
  end&lt;br /&gt;
  local h,b = node.hpack(start) -- ignore badness&lt;br /&gt;
  return h&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local tenpt = 10 * 2^16&lt;br /&gt;
---------------------------&lt;br /&gt;
-- page 1&lt;br /&gt;
---------------------------&lt;br /&gt;
local n,dest = mkdest() -- dest is needed for the link to this anchor&lt;br /&gt;
&lt;br /&gt;
add_to_page(n)&lt;br /&gt;
add_to_page(mkrule(2 * tenpt))&lt;br /&gt;
&lt;br /&gt;
-- The pagelist contains a pdf dest node (a link destination) and a rule of size 20pt x 20pt.&lt;br /&gt;
&lt;br /&gt;
shipout()&lt;br /&gt;
---------------------------&lt;br /&gt;
-- page 2&lt;br /&gt;
---------------------------&lt;br /&gt;
-- This is the page with the link to the anchor (dest) on page one. A&lt;br /&gt;
-- link consists of three nodes: a pdf_start_link, a pdf_end_link and and &lt;br /&gt;
-- action node that specifies the action to perform when the user clicks on&lt;br /&gt;
-- the link.&lt;br /&gt;
-- The pdf link must be inside a horizontal box, that&amp;#039;s why we hpack() it.&lt;br /&gt;
-- The link_attr (link attributes) is optional, here it draws a yellowish border&lt;br /&gt;
-- around the link.&lt;br /&gt;
local start_link = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_start_link&amp;quot;)&lt;br /&gt;
local end_link   = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_end_link&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
start_link.width     = tenpt&lt;br /&gt;
start_link.height    = tenpt / 2&lt;br /&gt;
start_link.depth     = tenpt / 2&lt;br /&gt;
start_link.link_attr = &amp;quot;/C [0.9 1 0] /Border [0 0 2]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
start_link.action = node.new(&amp;quot;action&amp;quot;)&lt;br /&gt;
start_link.action.action_type = 1&lt;br /&gt;
start_link.action.action_id   = dest&lt;br /&gt;
&lt;br /&gt;
local rule = mkrule(tenpt)&lt;br /&gt;
local hbox = hpack(start_link, rule, end_link)&lt;br /&gt;
add_to_page(hbox)&lt;br /&gt;
&lt;br /&gt;
-- This pagelist consists of an hbox whose contents is &amp;quot;start_link&amp;quot;,&lt;br /&gt;
-- the 10pt x 10pt rule and the &amp;quot;end_link&amp;quot; node. &lt;br /&gt;
&lt;br /&gt;
shipout()&lt;br /&gt;
---------------------------&lt;br /&gt;
&lt;br /&gt;
-- Just to show you that you can get some memory usage statistics:&lt;br /&gt;
print(string.format(&amp;quot;\nnode_mem_usage=%s&amp;quot;,status.node_mem_usage))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The idea is to create nodes, collect them in a list (here: pagelist) and use &amp;lt;tt&amp;gt;tex.shipout()&amp;lt;/tt&amp;gt; to put the page into the PDF.&lt;br /&gt;
&lt;br /&gt;
== And what about &amp;#039;&amp;#039;real&amp;#039;&amp;#039; content? ==&lt;br /&gt;
&lt;br /&gt;
Black squares won&amp;#039;t make anyone happy. So we need a typeset paragraph. For that we start with a single glyph and a glue first. A glyph node has this structure:&lt;br /&gt;
&lt;br /&gt;
[[File:Singleglyphnode.png]]&lt;br /&gt;
&lt;br /&gt;
whereas a glue is more complicated:&lt;br /&gt;
&lt;br /&gt;
[[File:Simplegluenode.png]]&lt;br /&gt;
&lt;br /&gt;
The glue item comes in pairs: a glue node and a glue_spec node. The information about the shrink/stretch values go into the glue_spec node. For example, the TeX glue &amp;lt;tt&amp;gt;2pt plus 1fill&amp;lt;/tt&amp;gt; has a width of 2*2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;, a stretch of 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt; and a stretch_order of 3. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local g = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g.font = font.current()&lt;br /&gt;
g.lang = tex.language&lt;br /&gt;
g.char = 86 -- V&lt;br /&gt;
&lt;br /&gt;
local hbox = node.hpack(g)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We create a glyph, pack it into an hbox (horizontal box), pack that hbox into a vbox (a vertical box) and write this box to the main vertical list. The char number (86 in the example above) is based on an internal encoding, so we have to keep an eye on what character is on what position. Now we do this for two glyphs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local g1 = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g1.font = font.current()&lt;br /&gt;
g1.lang = tex.language&lt;br /&gt;
g1.char = 86&lt;br /&gt;
&lt;br /&gt;
local g2 = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g2.font = font.current()&lt;br /&gt;
g2.lang = tex.language&lt;br /&gt;
g2.char = 97&lt;br /&gt;
&lt;br /&gt;
g1.next = g2&lt;br /&gt;
g2.prev = g1&lt;br /&gt;
&lt;br /&gt;
local hbox = node.hpack(g1)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pretty much the same as above. The glyphs g1 and g2 are chained together by setting the next and prev pointer to each other. If they were not connected, only glyph g1 gets into the hbox.&lt;br /&gt;
&lt;br /&gt;
If you take a close look at the PDF, you see that the two glyphs are too far away, a (negative) kern should be inserted. This can be done by inserting a kern-node manually or you can ask TeX to do that for you. The last lines of the example above should then read:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local head,tail,success = node.kerning(g1)&lt;br /&gt;
local hbox = node.hpack(head)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this approach you are able to put some glyphs into the PDF but you will run into problems when you want to create a whole paragraph. It is much easier to ask TeX to do the line breaking. The steps for paragraph creation are&lt;br /&gt;
&lt;br /&gt;
# put glyph nodes and glue nodes in a list (= chain them together with the prev/next pointers)&lt;br /&gt;
# add trailing infinite penalty and parfillskip&lt;br /&gt;
# call lang.hyphenate(), node.kerning() and node.ligaturing() to prepare the list for the linebreaking job&lt;br /&gt;
# call tex.linebreak()&lt;br /&gt;
&lt;br /&gt;
For the next task we want to create the following paragraph:&lt;br /&gt;
&lt;br /&gt;
[[File:Sample_paragraph.png|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We start with the small TeX stub as above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;myprogram.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and myprogram.lua ([https://gist.github.com/1063228 download]) defines a function &amp;lt;tt&amp;gt;mknodes()&amp;lt;/tt&amp;gt; that creates the list of nodes to be passed into the typesetter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function mknodes( text )&lt;br /&gt;
  local current_font = font.current()&lt;br /&gt;
  local font_parameters = font.getfont(current_font).parameters&lt;br /&gt;
  local n, head, last&lt;br /&gt;
  -- we should insert the paragraph indentation at the beginning&lt;br /&gt;
  head = node.new(&amp;quot;glue&amp;quot;)&lt;br /&gt;
  head.spec = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
  head.spec.width = 20 * 2^16&lt;br /&gt;
  last = head&lt;br /&gt;
&lt;br /&gt;
  for s in string.utfvalues( text ) do&lt;br /&gt;
    local char = unicode.utf8.char(s)&lt;br /&gt;
    if unicode.utf8.match(char,&amp;quot;%s&amp;quot;) then&lt;br /&gt;
      -- its a space&lt;br /&gt;
      n = node.new(&amp;quot;glue&amp;quot;)&lt;br /&gt;
      n.spec = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
      n.spec.width   = font_parameters.space&lt;br /&gt;
      n.spec.shrink  = font_parameters.space_shrink&lt;br /&gt;
      n.spec.stretch = font_parameters.space_stretch&lt;br /&gt;
    else -- a glyph&lt;br /&gt;
      n = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
      n.font = current_font&lt;br /&gt;
      n.subtype = 1&lt;br /&gt;
      n.char = s&lt;br /&gt;
      n.lang = tex.language&lt;br /&gt;
      n.uchyph = 1&lt;br /&gt;
      n.left = tex.lefthyphenmin&lt;br /&gt;
      n.right = tex.righthyphenmin&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    last.next = n&lt;br /&gt;
    last = n&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  -- now add the final parts: a penalty and the parfillskip glue&lt;br /&gt;
  local penalty = node.new(&amp;quot;penalty&amp;quot;)&lt;br /&gt;
  penalty.penalty = 10000&lt;br /&gt;
&lt;br /&gt;
  local parfillskip = node.new(&amp;quot;glue&amp;quot;)&lt;br /&gt;
  parfillskip.spec = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
  parfillskip.spec.stretch = 2^16&lt;br /&gt;
  parfillskip.spec.stretch_order = 2&lt;br /&gt;
  &lt;br /&gt;
  last.next = penalty&lt;br /&gt;
  penalty.next = parfillskip&lt;br /&gt;
&lt;br /&gt;
  -- just to create the prev pointers for tex.linebreak&lt;br /&gt;
  node.slide(head)&lt;br /&gt;
  return head&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local txt = &amp;quot;A wonderful serenity has taken possession of my entire soul, ... like mine.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
tex.baselineskip = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
tex.baselineskip.width = 14 * 2^16&lt;br /&gt;
&lt;br /&gt;
local head = mknodes(txt)&lt;br /&gt;
lang.hyphenate(head)&lt;br /&gt;
head = node.kerning(head)&lt;br /&gt;
head = node.ligaturing(head)&lt;br /&gt;
&lt;br /&gt;
local vbox = tex.linebreak(head,{ hsize = tex.sp(&amp;quot;3in&amp;quot;)})&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(You can safely skip this section if you are not interested in the details.)&lt;br /&gt;
&lt;br /&gt;
What has happened in detail? We have created a list of glyph and glue nodes and fed those into the line breaking part of TeX which gave us the vbox back. This vbox contains horizontal lists glued together:&lt;br /&gt;
&lt;br /&gt;
[[File:Paragraph_with_boxes.png|600px]]&lt;br /&gt;
&lt;br /&gt;
The dashed rectangle (vbox) should fit tight to the inner hboxes. It has a small offset just for demonstration purpose.&lt;br /&gt;
&lt;br /&gt;
To show you some of the nodes that TeX inserted for you, have a look at the following image:&lt;br /&gt;
&lt;br /&gt;
[[File:Nodes_in_sample_paragraph.png]]&lt;br /&gt;
&lt;br /&gt;
Here is an explanation of the nodes:&lt;br /&gt;
&lt;br /&gt;
# This is the dashed line in the image above. A paragraph is always vertical&lt;br /&gt;
# The first line. It has a width of three inches, a height and depth of together 8.888 pt&lt;br /&gt;
# The 20pt paragraph indent. This is the first item in the first line (note that the pointer comes from the head item of the node #2&lt;br /&gt;
# The first letter in the first line&lt;br /&gt;
# The interword glue.&lt;br /&gt;
# The second letter in the first line&lt;br /&gt;
# The clubpenalty&lt;br /&gt;
# The baselineskip minus the height of the hbox &amp;quot;above&amp;quot; (8.888pt + 5.111pt is approx. 14pt. The rounding error is due to the display of only few significant digits.) Note that TeX is in vertical mode, as it is the third item in the vbox (#1). &lt;br /&gt;
# The hbox of the second line&lt;br /&gt;
# The first letter of the second line&lt;br /&gt;
# A kern between the m and the y of the first word (second line)&lt;br /&gt;
# The last letter shown here&lt;br /&gt;
&lt;br /&gt;
There are many nodes created in the paragraph which are not shown here. A full view can be found in [[Media:Nodes_in_sample_paragraph_full.pdf|a separate PDF file]].&lt;br /&gt;
&lt;br /&gt;
== Inserting images is easy ==&lt;br /&gt;
&lt;br /&gt;
Now that you have survived the hard part of this tutorial, we get to something easier. Image inclusion. There are several ways to do this, and in my opinion this is the easiest. We again start with our plain (lua)TeX stub:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;includeimage.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and includeimage.lua is this small lua chunk:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local image_fixed = img.scan({filename = &amp;quot;oilpainting.jpg&amp;quot;})&lt;br /&gt;
&lt;br /&gt;
local image     = img.copy(image_fixed)&lt;br /&gt;
local halfimage = img.copy(image_fixed)&lt;br /&gt;
&lt;br /&gt;
halfimage.height = halfimage.height / 2&lt;br /&gt;
halfimage.width  = halfimage.width  / 2&lt;br /&gt;
&lt;br /&gt;
node.write(img.node(image))&lt;br /&gt;
node.write(img.node(halfimage))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You might be able to guess what happens here. We load the image [[Media:Oilpainting.jpg|oilpainting.jpg]] with &amp;lt;tt&amp;gt;img.scan&amp;lt;/tt&amp;gt; but do not write it out to the PDF file yet. We create a copy of the image data so we can manipulate the size for example (another option would be to obtain a specific page of a PDF document or do some rotation). After that we write a reference to that image to the PDF file. In the case above, two references to the image (XObject) get written but the image is only written once. That is easy, right?&lt;br /&gt;
&lt;br /&gt;
== Hyphenation ==&lt;br /&gt;
&lt;br /&gt;
Every now and then you have to hyphenate your words in other languages. When you create the paragraph to be hyphenated (with &amp;lt;tt&amp;gt;lang.hyphenate()&amp;lt;/tt&amp;gt;), you assemble it by creating glyph nodes which have a field lang (see above). This field accepts a number, the language id. So: how do we &amp;quot;create&amp;quot; a language? The first steps are simple, we start without TeX stub again:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;hyphenation.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the file hyphenation.lua is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local path = kpse.find_file(&amp;quot;hyph-de-1996.pat.txt&amp;quot;)&lt;br /&gt;
local l = lang.new()&lt;br /&gt;
&lt;br /&gt;
local hyph_file = io.open(path)&lt;br /&gt;
lang.patterns(l,hyph_file:read(&amp;quot;*all&amp;quot;))&lt;br /&gt;
hyph_file:close()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now the function &amp;lt;tt&amp;gt;lang.id(l)&amp;lt;/tt&amp;gt; returns the language id of the language &amp;lt;tt&amp;gt;l&amp;lt;/tt&amp;gt;, which we can use in the glyph nodes. A peculiarity of TeX prevents that we can start with that right away. All characters that are in the paragraph get lowercased before hyphenation rules apply. So how will a word like &amp;quot;Œuvre&amp;quot; be converted to lowercase? TeX has an internal table called &amp;#039;&amp;#039;lccode&amp;#039;&amp;#039; where it looks up a character and the output is its lowercase variant. So the lccode of Œ would be œ, but as TeX stores numbers, the lccode of 338 is 339. But only lccodes of the letters A-Z and a-z are set, so we need to set the codes for all other characters that appear in a text. In TeX you would write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\lccode`\Œ=`\œ&lt;br /&gt;
\lccode`\œ=`\œ&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\lccode338=339&lt;br /&gt;
\lccode339=339&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You see that you need to set the lccode of the lowercase characters as well. In Lua you do something similar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tex.lccode[unicode.utf8.byte(&amp;quot;Œ&amp;quot;)] = [unicode.utf8.byte(&amp;quot;œ&amp;quot;)]&lt;br /&gt;
tex.lccode[unicode.utf8.byte(&amp;quot;œ&amp;quot;)] = [unicode.utf8.byte(&amp;quot;œ&amp;quot;)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or shorter:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tex.lccode[338] = [339]&lt;br /&gt;
tex.lccode[339] = [339]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have set all the necessary lccodes (remember you don&amp;#039;t need to do this with a to z and A to Z), you can expect the hyphenation to work.&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=140</id>
		<title>TeX without TeX</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=140"/>
		<updated>2011-07-06T06:53:42Z</updated>

		<summary type="html">&lt;p&gt;Patrick: Introduction of \directlua&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Use TeX&amp;#039;s power without TeX macros ==&lt;br /&gt;
&lt;br /&gt;
With the Lua-part in LuaTeX you have access to most of TeX&amp;#039;s capabilities for creating PDF documents. Most of the [http://www.luatex.org/svn/trunk/manual/luatexref-t.pdf LuaTeX reference manual] is about this topic. &lt;br /&gt;
&lt;br /&gt;
[[Writing_Lua_in_TeX|Remember]] that you can jump into Lua mode from TeX with &amp;lt;tt&amp;gt;\directlua{...Lua code...}&amp;lt;/tt&amp;gt;. For example this plain TeX document prints the first digits of the value of pi: &amp;lt;tt&amp;gt;$\pi = \directlua{ tex.print(math.pi)}$ \bye&amp;lt;/tt&amp;gt;. You can get the result PDF by running &amp;lt;tt&amp;gt;luatex testfile.tex&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The underlying idea is to create TeX&amp;#039;s internal data structure as TeX would do by transforming macros and primitives into something called nodes. These nodes are then transformed into instructions for the PDF file (PDF objects). So the following pages deal with node creation and the structures. &lt;br /&gt;
&lt;br /&gt;
Let&amp;#039;s start with a rule node. When you write &amp;lt;tt&amp;gt;\hrule width 20pt height 10pt depth 10pt &amp;lt;/tt&amp;gt; in TeX, a node of type rule will be created, which has three fields: height, depth and width. We can visualize this node by a simple box like this:&lt;br /&gt;
&lt;br /&gt;
[[File:rulenode.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r.width  = 20 * 65536&lt;br /&gt;
r.height = 10 * 65536&lt;br /&gt;
r.depth  = 10 * 65536&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some remarks: the size is in scaled points, and 65536 (=2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;) scaled points are 1 point, so 20pt becomes 20 * 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;. Not shown in the example are (among others) the next and prev fields. These fields hold a pointer (the node address) to the following and the previous nodes. A node that exist by itself has its prev and next fields set to nil.&lt;br /&gt;
&lt;br /&gt;
A slightly more complicated example is when you create two rules and pack then into a vertical box. This would look like this in plain TeX:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\vbox {\hrule width 20pt height 10pt depth 10pt&lt;br /&gt;
           \hrule width 20pt height 10pt depth 10pt }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would generate a node list like:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Rulenode2.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r1 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r1.width  = 20 * 65536&lt;br /&gt;
r1.height = 10 * 65536&lt;br /&gt;
r1.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r2 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r2.width  = 20 * 65536&lt;br /&gt;
r2.height = 10 * 65536&lt;br /&gt;
r2.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r1.next = r2&lt;br /&gt;
r2.prev = r1&lt;br /&gt;
&lt;br /&gt;
vbox = node.vpack(r1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result is a vbox containing the two rule nodes. The nodes are connected by their next and prev pointers, so the vbox contains them both. The size (width, height and depth) is adjusted automatically.&lt;br /&gt;
&lt;br /&gt;
This also applies to all other things you can put on a TeX page: glyphs, horizontal boxes, math, images, hyperlinks, glue .... For a complete list of the nodes, see the reference manual Chapter 8 &amp;quot;Nodes&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Beyond reports and articles ==&lt;br /&gt;
&lt;br /&gt;
Perhaps the question that comes into your mind is: why should I bother writing Lua code instead of TeX code? For many documents, including articles, reports and books, the classic way to create a PDF with TeX is to use LaTeX or ConTeXt. But there are applications that use TeX as an 100% automatic PDF generation software. If you want to create data sheets or product listings, your normal input is not a classic document, but most likely an Excel spreadsheet or an XML file, perhaps extracted from a database. You won&amp;#039;t have any TeX markup within these documents. So: if you don&amp;#039;t have TeX markup in these documents, you don&amp;#039;t need the TeX interpreter to read these files. More likely is an XML parser or a spreadsheet 2 ... converter.&lt;br /&gt;
&lt;br /&gt;
When you use regular LaTeX or ConTeXt code to put the contents of the database in your PDF (database publishing), you run into several problems:&lt;br /&gt;
&lt;br /&gt;
* Exact positioning of items on the page can be troublesome&lt;br /&gt;
* catcodes / command escapes are to be considered and surely get into your way&lt;br /&gt;
* TeX is no fun to program in (well it is, but only for some people) - calculations, tests, exception handling, control flow&lt;br /&gt;
* The packages that exist may reach their limit soon. You need a super flexible image-between-columns-with-parshape package? Write it yourself.&lt;br /&gt;
&lt;br /&gt;
With Lua you have a very decent programming language that &amp;#039;&amp;#039;is&amp;#039;&amp;#039; fun to program in. When you use the Lua interface to TeX, you have full control of what is happening, which is usually the level of control you need for high quality output.&lt;br /&gt;
&lt;br /&gt;
One approach is to create a stub TeX file and let Lua do the rest:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;myprogram.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The file &amp;lt;tt&amp;gt;myprogram.lua&amp;lt;/tt&amp;gt; then contains all the code to a) read the source file(s), b) extract the information and create the appropriate nodes and c) instruct TeX to create PDF pages from these nodes.&lt;br /&gt;
&lt;br /&gt;
In a future version of LuaTeX you will be able to run the Lua interpreter without the stub TeX file above.&lt;br /&gt;
&lt;br /&gt;
== A first example ==&lt;br /&gt;
&lt;br /&gt;
The example document given below creates two pages by using Lua code alone. You will learn how to access TeX&amp;#039;s boxes and counters from the Lua side, shipout a page into the PDF file, create horizontal and vertical boxes (hbox and vbox), create new nodes and manipulate the nodes links structure. The example covers the following node types: rule, whatsit, vlist, hlist and action.&lt;br /&gt;
&lt;br /&gt;
In the example code we use black squares as the contents of the pages and not normal text, because character handling takes more code and will be covered later on.&lt;br /&gt;
&lt;br /&gt;
Save the following file into &amp;lt;tt&amp;gt;myprogram.lua&amp;lt;/tt&amp;gt; and use the TeX stub from above (or get the source [https://raw.github.com/gist/1062041/d3de082e955f6535f3820742cef76fe9e50d5a6f/myprogram.lua here]).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
  -- this will hold the items that go onto the page&lt;br /&gt;
  local pagelist&lt;br /&gt;
 &lt;br /&gt;
  -- Call tex.shipout() with the contents of the pagelist&lt;br /&gt;
  function shipout()&lt;br /&gt;
&lt;br /&gt;
    local vbox,b = node.vpack(pagelist) -- we ignore the badness &amp;#039;b&amp;#039;&lt;br /&gt;
    tex.box[666] = vbox&lt;br /&gt;
    tex.shipout(666)&lt;br /&gt;
&lt;br /&gt;
    pagelist = nil&lt;br /&gt;
    &lt;br /&gt;
    -- Not strictly necessary. TeX holds the current page number in counter 0.&lt;br /&gt;
    -- TeX displays the contents of this counter when it puts a page into&lt;br /&gt;
    -- the pdf (tex.shipout()). If we don&amp;#039;t change the counter, TeX will&lt;br /&gt;
    -- display [1] [1], instead of [1] [2] for our two page document.&lt;br /&gt;
    tex.count[0] = tex.count[0] + 1&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
  function add_to_page( list )&lt;br /&gt;
    -- We attach the nodelist &amp;#039;list&amp;#039; to the end of the pagelist&lt;br /&gt;
    -- if pagelist doesn&amp;#039;t exist, &amp;#039;list&amp;#039; is our new pagelist&lt;br /&gt;
    -- if it exists, we go to the end with node.tail() and adjust&lt;br /&gt;
    -- the prev and next pointers, so list becomes part&lt;br /&gt;
    -- of pagelist.&lt;br /&gt;
    if not pagelist then pagelist = list&lt;br /&gt;
    else&lt;br /&gt;
      local tail = node.tail(pagelist)&lt;br /&gt;
      tail.next = list&lt;br /&gt;
      list.prev  = tail&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- This creates a new square rule and returns the pointer to it.&lt;br /&gt;
function mkrule( size )&lt;br /&gt;
  local r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
  r.width  = size &lt;br /&gt;
  r.height = size / 2&lt;br /&gt;
  r.depth  = size / 2&lt;br /&gt;
  return r&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
do&lt;br /&gt;
  local destcounter = 0&lt;br /&gt;
  -- Create a pdf anchor (dest object). It returns a whatsit node and the &lt;br /&gt;
  -- number of the anchor, so it can be used in a pdf link or an outline.&lt;br /&gt;
  function mkdest()&lt;br /&gt;
    destcounter = destcounter + 1&lt;br /&gt;
    local d = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_dest&amp;quot;)&lt;br /&gt;
    d.named_id = 0&lt;br /&gt;
    d.dest_id = destcounter&lt;br /&gt;
    d.dest_type = 3&lt;br /&gt;
&lt;br /&gt;
    return d, destcounter&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Take a list of nodes and put them into an hbox. The prev and next fields&lt;br /&gt;
-- of the nodes will be set automatically. Return a pointer to the hbox.&lt;br /&gt;
function hpack( ... )&lt;br /&gt;
  local start, tmp, cur&lt;br /&gt;
  start = select(1,...)&lt;br /&gt;
  tmp = start&lt;br /&gt;
  for i=2,select(&amp;quot;#&amp;quot;,...) do&lt;br /&gt;
    cur = select(i,...)&lt;br /&gt;
    tmp.next = cur&lt;br /&gt;
    cur.prev = tmp&lt;br /&gt;
    tmp = cur&lt;br /&gt;
  end&lt;br /&gt;
  local h,b = node.hpack(start) -- ignore badness&lt;br /&gt;
  return h&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local tenpt = 10 * 2^16&lt;br /&gt;
---------------------------&lt;br /&gt;
-- page 1&lt;br /&gt;
---------------------------&lt;br /&gt;
local n,dest = mkdest() -- dest is needed for the link to this anchor&lt;br /&gt;
&lt;br /&gt;
add_to_page(n)&lt;br /&gt;
add_to_page(mkrule(2 * tenpt))&lt;br /&gt;
&lt;br /&gt;
-- The pagelist contains a pdf dest node (a link destination) and a rule of size 20pt x 20pt.&lt;br /&gt;
&lt;br /&gt;
shipout()&lt;br /&gt;
---------------------------&lt;br /&gt;
-- page 2&lt;br /&gt;
---------------------------&lt;br /&gt;
-- This is the page with the link to the anchor (dest) on page one. A&lt;br /&gt;
-- link consists of three nodes: a pdf_start_link, a pdf_end_link and and &lt;br /&gt;
-- action node that specifies the action to perform when the user clicks on&lt;br /&gt;
-- the link.&lt;br /&gt;
-- The pdf link must be inside a horizontal box, that&amp;#039;s why we hpack() it.&lt;br /&gt;
-- The link_attr (link attributes) is optional, here it draws a yellowish border&lt;br /&gt;
-- around the link.&lt;br /&gt;
local start_link = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_start_link&amp;quot;)&lt;br /&gt;
local end_link   = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_end_link&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
start_link.width     = tenpt&lt;br /&gt;
start_link.height    = tenpt / 2&lt;br /&gt;
start_link.depth     = tenpt / 2&lt;br /&gt;
start_link.link_attr = &amp;quot;/C [0.9 1 0] /Border [0 0 2]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
start_link.action = node.new(&amp;quot;action&amp;quot;)&lt;br /&gt;
start_link.action.action_type = 1&lt;br /&gt;
start_link.action.action_id   = dest&lt;br /&gt;
&lt;br /&gt;
local rule = mkrule(tenpt)&lt;br /&gt;
local hbox = hpack(start_link, rule, end_link)&lt;br /&gt;
add_to_page(hbox)&lt;br /&gt;
&lt;br /&gt;
-- This pagelist consists of an hbox whose contents is &amp;quot;start_link&amp;quot;,&lt;br /&gt;
-- the 10pt x 10pt rule and the &amp;quot;end_link&amp;quot; node. &lt;br /&gt;
&lt;br /&gt;
shipout()&lt;br /&gt;
---------------------------&lt;br /&gt;
&lt;br /&gt;
-- Just to show you that you can get some memory usage statistics:&lt;br /&gt;
print(string.format(&amp;quot;\nnode_mem_usage=%s&amp;quot;,status.node_mem_usage))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The idea is to create nodes, collect them in a list (here: pagelist) and use &amp;lt;tt&amp;gt;tex.shipout()&amp;lt;/tt&amp;gt; to put the page into the PDF.&lt;br /&gt;
&lt;br /&gt;
== And what about &amp;#039;&amp;#039;real&amp;#039;&amp;#039; content? ==&lt;br /&gt;
&lt;br /&gt;
Black squares won&amp;#039;t make anyone happy. So we need a typeset paragraph. For that we start with a single glyph and a glue first. A glyph node has this structure:&lt;br /&gt;
&lt;br /&gt;
[[File:Singleglyphnode.png]]&lt;br /&gt;
&lt;br /&gt;
whereas a glue is more complicated:&lt;br /&gt;
&lt;br /&gt;
[[File:Simplegluenode.png]]&lt;br /&gt;
&lt;br /&gt;
The glue item comes in pairs: a glue node and a glue_spec node. The information about the shrink/stretch values go into the glue_spec node. For example, the TeX glue &amp;lt;tt&amp;gt;2pt plus 1fill&amp;lt;/tt&amp;gt; has a width of 2*2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;, a stretch of 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt; and a stretch_order of 3. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local g = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g.font = font.current()&lt;br /&gt;
g.lang = tex.language&lt;br /&gt;
g.char = 86 -- V&lt;br /&gt;
&lt;br /&gt;
local hbox = node.hpack(g)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We create a glyph, pack it into an hbox (horizontal box), pack that hbox into a vbox (a vertical box) and write this box to the main vertical list. The char number (86 in the example above) is based on an internal encoding, so we have to keep an eye on what character is on what position. Now we do this for two glyphs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local g1 = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g1.font = font.current()&lt;br /&gt;
g1.lang = tex.language&lt;br /&gt;
g1.char = 86&lt;br /&gt;
&lt;br /&gt;
local g2 = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g2.font = font.current()&lt;br /&gt;
g2.lang = tex.language&lt;br /&gt;
g2.char = 97&lt;br /&gt;
&lt;br /&gt;
g1.next = g2&lt;br /&gt;
g2.prev = g1&lt;br /&gt;
&lt;br /&gt;
local hbox = node.hpack(g1)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pretty much the same as above. The glyphs g1 and g2 are chained together by setting the next and prev pointer to each other. If they were not connected, only glyph g1 gets into the hbox.&lt;br /&gt;
&lt;br /&gt;
If you take a close look at the PDF, you see that the two glyphs are too far away, a (negative) kern should be inserted. This can be done by inserting a kern-node manually or you can ask TeX to do that for you. The last lines of the example above should then read:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local head,tail,success = node.kerning(g1)&lt;br /&gt;
local hbox = node.hpack(head)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this approach you are able to put some glyphs into the PDF but you will run into problems when you want to create a whole paragraph. It is much easier to ask TeX to do the line breaking. The steps for paragraph creation are&lt;br /&gt;
&lt;br /&gt;
# put glyph nodes and glue nodes in a list (= chain them together with the prev/next pointers)&lt;br /&gt;
# add trailing infinite penalty and parfillskip&lt;br /&gt;
# call lang.hyphenate(), node.kerning() and node.ligaturing() to prepare the list for the linebreaking job&lt;br /&gt;
# call tex.linebreak()&lt;br /&gt;
&lt;br /&gt;
For the next task we want to create the following paragraph:&lt;br /&gt;
&lt;br /&gt;
[[File:Sample_paragraph.png|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We start with the small TeX stub as above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;myprogram.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and myprogram.lua ([https://gist.github.com/1063228 download]) defines a function &amp;lt;tt&amp;gt;mknodes()&amp;lt;/tt&amp;gt; that creates the list of nodes to be passed into the typesetter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function mknodes( text )&lt;br /&gt;
  local current_font = font.current()&lt;br /&gt;
  local font_parameters = font.getfont(current_font).parameters&lt;br /&gt;
  local n, head, last&lt;br /&gt;
  -- we should insert the paragraph indentation at the beginning&lt;br /&gt;
  head = node.new(&amp;quot;glue&amp;quot;)&lt;br /&gt;
  head.spec = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
  head.spec.width = 20 * 2^16&lt;br /&gt;
  last = head&lt;br /&gt;
&lt;br /&gt;
  for s in string.utfvalues( text ) do&lt;br /&gt;
    local char = unicode.utf8.char(s)&lt;br /&gt;
    if unicode.utf8.match(char,&amp;quot;%s&amp;quot;) then&lt;br /&gt;
      -- its a space&lt;br /&gt;
      n = node.new(&amp;quot;glue&amp;quot;)&lt;br /&gt;
      n.spec = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
      n.spec.width   = font_parameters.space&lt;br /&gt;
      n.spec.shrink  = font_parameters.space_shrink&lt;br /&gt;
      n.spec.stretch = font_parameters.space_stretch&lt;br /&gt;
    else -- a glyph&lt;br /&gt;
      n = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
      n.font = current_font&lt;br /&gt;
      n.subtype = 1&lt;br /&gt;
      n.char = s&lt;br /&gt;
      n.lang = tex.language&lt;br /&gt;
      n.uchyph = 1&lt;br /&gt;
      n.left = tex.lefthyphenmin&lt;br /&gt;
      n.right = tex.righthyphenmin&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    last.next = n&lt;br /&gt;
    last = n&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  -- now add the final parts: a penalty and the parfillskip glue&lt;br /&gt;
  local penalty = node.new(&amp;quot;penalty&amp;quot;)&lt;br /&gt;
  penalty.penalty = 10000&lt;br /&gt;
&lt;br /&gt;
  local parfillskip = node.new(&amp;quot;glue&amp;quot;)&lt;br /&gt;
  parfillskip.spec = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
  parfillskip.spec.stretch = 2^16&lt;br /&gt;
  parfillskip.spec.stretch_order = 2&lt;br /&gt;
  &lt;br /&gt;
  last.next = penalty&lt;br /&gt;
  penalty.next = parfillskip&lt;br /&gt;
&lt;br /&gt;
  -- just to create the prev pointers for tex.linebreak&lt;br /&gt;
  node.slide(head)&lt;br /&gt;
  return head&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local txt = &amp;quot;A wonderful serenity has taken possession of my entire soul, ... like mine.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
tex.baselineskip = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
tex.baselineskip.width = 14 * 2^16&lt;br /&gt;
&lt;br /&gt;
local head = mknodes(txt)&lt;br /&gt;
lang.hyphenate(head)&lt;br /&gt;
head = node.kerning(head)&lt;br /&gt;
head = node.ligaturing(head)&lt;br /&gt;
&lt;br /&gt;
local vbox = tex.linebreak(head,{ hsize = tex.sp(&amp;quot;3in&amp;quot;)})&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(You can safely skip this section if you are not interested in the details.)&lt;br /&gt;
&lt;br /&gt;
What has happened in detail? We have created a list of glyph and glue nodes and fed those into the line breaking part of TeX which gave us the vbox back. This vbox contains horizontal lists glued together:&lt;br /&gt;
&lt;br /&gt;
[[File:Paragraph_with_boxes.png|600px]]&lt;br /&gt;
&lt;br /&gt;
The dashed rectangle (vbox) should fit tight to the inner hboxes. It has a small offset just for demonstration purpose.&lt;br /&gt;
&lt;br /&gt;
To show you some of the nodes that TeX inserted for you, have a look at the following image:&lt;br /&gt;
&lt;br /&gt;
[[File:Nodes_in_sample_paragraph.png]]&lt;br /&gt;
&lt;br /&gt;
Here is an explanation of the nodes:&lt;br /&gt;
&lt;br /&gt;
# This is the dashed line in the image above. A paragraph is always vertical&lt;br /&gt;
# The first line. It has a width of three inches, a height and depth of together 8.888 pt&lt;br /&gt;
# The 20pt paragraph indent. This is the first item in the first line (note that the pointer comes from the head item of the node #2&lt;br /&gt;
# The first letter in the first line&lt;br /&gt;
# The interword glue.&lt;br /&gt;
# The second letter in the first line&lt;br /&gt;
# The clubpenalty&lt;br /&gt;
# The baselineskip minus the height of the hbox &amp;quot;above&amp;quot; (8.888pt + 5.111pt is approx. 14pt. The rounding error is due to the display of only few significant digits.) Note that TeX is in vertical mode, as it is the third item in the vbox (#1). &lt;br /&gt;
# The hbox of the second line&lt;br /&gt;
# The first letter of the second line&lt;br /&gt;
# A kern between the m and the y of the first word (second line)&lt;br /&gt;
# The last letter shown here&lt;br /&gt;
&lt;br /&gt;
There are many nodes created in the paragraph which are not shown here. A full view can be found in [[Media:Nodes_in_sample_paragraph_full.pdf|a separate PDF file]].&lt;br /&gt;
&lt;br /&gt;
== Inserting images is easy ==&lt;br /&gt;
&lt;br /&gt;
Now that you have survived the hard part of this tutorial, we get to something easier. Image inclusion. There are several ways to do this, and in my opinion this is the easiest. We again start with our plain (lua)TeX stub:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;includeimage.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and includeimage.lua is this small lua chunk:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local image_fixed = img.scan({filename = &amp;quot;oilpainting.jpg&amp;quot;})&lt;br /&gt;
&lt;br /&gt;
local image     = img.copy(image_fixed)&lt;br /&gt;
local halfimage = img.copy(image_fixed)&lt;br /&gt;
&lt;br /&gt;
halfimage.height = halfimage.height / 2&lt;br /&gt;
halfimage.width  = halfimage.width  / 2&lt;br /&gt;
&lt;br /&gt;
node.write(img.node(image))&lt;br /&gt;
node.write(img.node(halfimage))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You might be able to guess what happens here. We load the image [[Media:Oilpainting.jpg|oilpainting.jpg]] with &amp;lt;tt&amp;gt;img.scan&amp;lt;/tt&amp;gt; but do not write it out to the PDF file yet. We create a copy of the image data so we can manipulate the size for example (another option would be to obtain a specific page of a PDF document or do some rotation). After that we write a reference to that image to the PDF file. In the case above, two references to the image (XObject) get written but the image is only written once. That is easy, right?&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=139</id>
		<title>TeX without TeX</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=139"/>
		<updated>2011-07-04T16:38:50Z</updated>

		<summary type="html">&lt;p&gt;Patrick: Image inclusion&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Use TeX&amp;#039;s power without TeX macros ==&lt;br /&gt;
&lt;br /&gt;
With the Lua-part in LuaTeX you have access to most of TeX&amp;#039;s capabilities for creating PDF documents. Most of the [http://www.luatex.org/svn/trunk/manual/luatexref-t.pdf LuaTeX reference manual] is about this topic. &lt;br /&gt;
&lt;br /&gt;
The underlying idea is to create TeX&amp;#039;s internal data structure as TeX would do by transforming macros and primitives into something called nodes. These nodes are then transformed into instructions for the PDF file (PDF objects). So the following pages deal with node creation and the structures. &lt;br /&gt;
&lt;br /&gt;
Let&amp;#039;s start with a rule node. When you write &amp;lt;tt&amp;gt;\hrule width 20pt height 10pt depth 10pt &amp;lt;/tt&amp;gt; in TeX, a node of type rule will be created, which has three fields: height, depth and width. We can visualize this node by a simple box like this:&lt;br /&gt;
&lt;br /&gt;
[[File:rulenode.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r.width  = 20 * 65536&lt;br /&gt;
r.height = 10 * 65536&lt;br /&gt;
r.depth  = 10 * 65536&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some remarks: the size is in scaled points, and 65536 (=2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;) scaled points are 1 point, so 20pt becomes 20 * 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;. Not shown in the example are (among others) the next and prev fields. These fields hold a pointer (the node address) to the following and the previous nodes. A node that exist by itself has its prev and next fields set to nil.&lt;br /&gt;
&lt;br /&gt;
A slightly more complicated example is when you create two rules and pack then into a vertical box. This would look like this in plain TeX:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\vbox {\hrule width 20pt height 10pt depth 10pt&lt;br /&gt;
           \hrule width 20pt height 10pt depth 10pt }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would generate a node list like:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Rulenode2.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r1 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r1.width  = 20 * 65536&lt;br /&gt;
r1.height = 10 * 65536&lt;br /&gt;
r1.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r2 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r2.width  = 20 * 65536&lt;br /&gt;
r2.height = 10 * 65536&lt;br /&gt;
r2.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r1.next = r2&lt;br /&gt;
r2.prev = r1&lt;br /&gt;
&lt;br /&gt;
vbox = node.vpack(r1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result is a vbox containing the two rule nodes. The nodes are connected by their next and prev pointers, so the vbox contains them both. The size (width, height and depth) is adjusted automatically.&lt;br /&gt;
&lt;br /&gt;
This also applies to all other things you can put on a TeX page: glyphs, horizontal boxes, math, images, hyperlinks, glue .... For a complete list of the nodes, see the reference manual Chapter 8 &amp;quot;Nodes&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Beyond reports and articles ==&lt;br /&gt;
&lt;br /&gt;
Perhaps the question that comes into your mind is: why should I bother writing Lua code instead of TeX code? For many documents, including articles, reports and books, the classic way to create a PDF with TeX is to use LaTeX or ConTeXt. But there are applications that use TeX as an 100% automatic PDF generation software. If you want to create data sheets or product listings, your normal input is not a classic document, but most likely an Excel spreadsheet or an XML file, perhaps extracted from a database. You won&amp;#039;t have any TeX markup within these documents. So: if you don&amp;#039;t have TeX markup in these documents, you don&amp;#039;t need the TeX interpreter to read these files. More likely is an XML parser or a spreadsheet 2 ... converter.&lt;br /&gt;
&lt;br /&gt;
When you use regular LaTeX or ConTeXt code to put the contents of the database in your PDF (database publishing), you run into several problems:&lt;br /&gt;
&lt;br /&gt;
* Exact positioning of items on the page can be troublesome&lt;br /&gt;
* catcodes / command escapes are to be considered and surely get into your way&lt;br /&gt;
* TeX is no fun to program in (well it is, but only for some people) - calculations, tests, exception handling, control flow&lt;br /&gt;
* The packages that exist may reach their limit soon. You need a super flexible image-between-columns-with-parshape package? Write it yourself.&lt;br /&gt;
&lt;br /&gt;
With Lua you have a very decent programming language that &amp;#039;&amp;#039;is&amp;#039;&amp;#039; fun to program in. When you use the Lua interface to TeX, you have full control of what is happening, which is usually the level of control you need for high quality output.&lt;br /&gt;
&lt;br /&gt;
One approach is to create a stub TeX file and let Lua do the rest:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;myprogram.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The file &amp;lt;tt&amp;gt;myprogram.lua&amp;lt;/tt&amp;gt; then contains all the code to a) read the source file(s), b) extract the information and create the appropriate nodes and c) instruct TeX to create PDF pages from these nodes.&lt;br /&gt;
&lt;br /&gt;
In a future version of LuaTeX you will be able to run the Lua interpreter without the stub TeX file above.&lt;br /&gt;
&lt;br /&gt;
== A first example ==&lt;br /&gt;
&lt;br /&gt;
The example document given below creates two pages by using Lua code alone. You will learn how to access TeX&amp;#039;s boxes and counters from the Lua side, shipout a page into the PDF file, create horizontal and vertical boxes (hbox and vbox), create new nodes and manipulate the nodes links structure. The example covers the following node types: rule, whatsit, vlist, hlist and action.&lt;br /&gt;
&lt;br /&gt;
In the example code we use black squares as the contents of the pages and not normal text, because character handling takes more code and will be covered later on.&lt;br /&gt;
&lt;br /&gt;
Save the following file into &amp;lt;tt&amp;gt;myprogram.lua&amp;lt;/tt&amp;gt; and use the TeX stub from above (or get the source [https://raw.github.com/gist/1062041/d3de082e955f6535f3820742cef76fe9e50d5a6f/myprogram.lua here]).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
  -- this will hold the items that go onto the page&lt;br /&gt;
  local pagelist&lt;br /&gt;
 &lt;br /&gt;
  -- Call tex.shipout() with the contents of the pagelist&lt;br /&gt;
  function shipout()&lt;br /&gt;
&lt;br /&gt;
    local vbox,b = node.vpack(pagelist) -- we ignore the badness &amp;#039;b&amp;#039;&lt;br /&gt;
    tex.box[666] = vbox&lt;br /&gt;
    tex.shipout(666)&lt;br /&gt;
&lt;br /&gt;
    pagelist = nil&lt;br /&gt;
    &lt;br /&gt;
    -- Not strictly necessary. TeX holds the current page number in counter 0.&lt;br /&gt;
    -- TeX displays the contents of this counter when it puts a page into&lt;br /&gt;
    -- the pdf (tex.shipout()). If we don&amp;#039;t change the counter, TeX will&lt;br /&gt;
    -- display [1] [1], instead of [1] [2] for our two page document.&lt;br /&gt;
    tex.count[0] = tex.count[0] + 1&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
  function add_to_page( list )&lt;br /&gt;
    -- We attach the nodelist &amp;#039;list&amp;#039; to the end of the pagelist&lt;br /&gt;
    -- if pagelist doesn&amp;#039;t exist, &amp;#039;list&amp;#039; is our new pagelist&lt;br /&gt;
    -- if it exists, we go to the end with node.tail() and adjust&lt;br /&gt;
    -- the prev and next pointers, so list becomes part&lt;br /&gt;
    -- of pagelist.&lt;br /&gt;
    if not pagelist then pagelist = list&lt;br /&gt;
    else&lt;br /&gt;
      local tail = node.tail(pagelist)&lt;br /&gt;
      tail.next = list&lt;br /&gt;
      list.prev  = tail&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- This creates a new square rule and returns the pointer to it.&lt;br /&gt;
function mkrule( size )&lt;br /&gt;
  local r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
  r.width  = size &lt;br /&gt;
  r.height = size / 2&lt;br /&gt;
  r.depth  = size / 2&lt;br /&gt;
  return r&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
do&lt;br /&gt;
  local destcounter = 0&lt;br /&gt;
  -- Create a pdf anchor (dest object). It returns a whatsit node and the &lt;br /&gt;
  -- number of the anchor, so it can be used in a pdf link or an outline.&lt;br /&gt;
  function mkdest()&lt;br /&gt;
    destcounter = destcounter + 1&lt;br /&gt;
    local d = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_dest&amp;quot;)&lt;br /&gt;
    d.named_id = 0&lt;br /&gt;
    d.dest_id = destcounter&lt;br /&gt;
    d.dest_type = 3&lt;br /&gt;
&lt;br /&gt;
    return d, destcounter&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Take a list of nodes and put them into an hbox. The prev and next fields&lt;br /&gt;
-- of the nodes will be set automatically. Return a pointer to the hbox.&lt;br /&gt;
function hpack( ... )&lt;br /&gt;
  local start, tmp, cur&lt;br /&gt;
  start = select(1,...)&lt;br /&gt;
  tmp = start&lt;br /&gt;
  for i=2,select(&amp;quot;#&amp;quot;,...) do&lt;br /&gt;
    cur = select(i,...)&lt;br /&gt;
    tmp.next = cur&lt;br /&gt;
    cur.prev = tmp&lt;br /&gt;
    tmp = cur&lt;br /&gt;
  end&lt;br /&gt;
  local h,b = node.hpack(start) -- ignore badness&lt;br /&gt;
  return h&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local tenpt = 10 * 2^16&lt;br /&gt;
---------------------------&lt;br /&gt;
-- page 1&lt;br /&gt;
---------------------------&lt;br /&gt;
local n,dest = mkdest() -- dest is needed for the link to this anchor&lt;br /&gt;
&lt;br /&gt;
add_to_page(n)&lt;br /&gt;
add_to_page(mkrule(2 * tenpt))&lt;br /&gt;
&lt;br /&gt;
-- The pagelist contains a pdf dest node (a link destination) and a rule of size 20pt x 20pt.&lt;br /&gt;
&lt;br /&gt;
shipout()&lt;br /&gt;
---------------------------&lt;br /&gt;
-- page 2&lt;br /&gt;
---------------------------&lt;br /&gt;
-- This is the page with the link to the anchor (dest) on page one. A&lt;br /&gt;
-- link consists of three nodes: a pdf_start_link, a pdf_end_link and and &lt;br /&gt;
-- action node that specifies the action to perform when the user clicks on&lt;br /&gt;
-- the link.&lt;br /&gt;
-- The pdf link must be inside a horizontal box, that&amp;#039;s why we hpack() it.&lt;br /&gt;
-- The link_attr (link attributes) is optional, here it draws a yellowish border&lt;br /&gt;
-- around the link.&lt;br /&gt;
local start_link = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_start_link&amp;quot;)&lt;br /&gt;
local end_link   = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_end_link&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
start_link.width     = tenpt&lt;br /&gt;
start_link.height    = tenpt / 2&lt;br /&gt;
start_link.depth     = tenpt / 2&lt;br /&gt;
start_link.link_attr = &amp;quot;/C [0.9 1 0] /Border [0 0 2]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
start_link.action = node.new(&amp;quot;action&amp;quot;)&lt;br /&gt;
start_link.action.action_type = 1&lt;br /&gt;
start_link.action.action_id   = dest&lt;br /&gt;
&lt;br /&gt;
local rule = mkrule(tenpt)&lt;br /&gt;
local hbox = hpack(start_link, rule, end_link)&lt;br /&gt;
add_to_page(hbox)&lt;br /&gt;
&lt;br /&gt;
-- This pagelist consists of an hbox whose contents is &amp;quot;start_link&amp;quot;,&lt;br /&gt;
-- the 10pt x 10pt rule and the &amp;quot;end_link&amp;quot; node. &lt;br /&gt;
&lt;br /&gt;
shipout()&lt;br /&gt;
---------------------------&lt;br /&gt;
&lt;br /&gt;
-- Just to show you that you can get some memory usage statistics:&lt;br /&gt;
print(string.format(&amp;quot;\nnode_mem_usage=%s&amp;quot;,status.node_mem_usage))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The idea is to create nodes, collect them in a list (here: pagelist) and use &amp;lt;tt&amp;gt;tex.shipout()&amp;lt;/tt&amp;gt; to put the page into the PDF.&lt;br /&gt;
&lt;br /&gt;
== And what about &amp;#039;&amp;#039;real&amp;#039;&amp;#039; content? ==&lt;br /&gt;
&lt;br /&gt;
Black squares won&amp;#039;t make anyone happy. So we need a typeset paragraph. For that we start with a single glyph and a glue first. A glyph node has this structure:&lt;br /&gt;
&lt;br /&gt;
[[File:Singleglyphnode.png]]&lt;br /&gt;
&lt;br /&gt;
whereas a glue is more complicated:&lt;br /&gt;
&lt;br /&gt;
[[File:Simplegluenode.png]]&lt;br /&gt;
&lt;br /&gt;
The glue item comes in pairs: a glue node and a glue_spec node. The information about the shrink/stretch values go into the glue_spec node. For example, the TeX glue &amp;lt;tt&amp;gt;2pt plus 1fill&amp;lt;/tt&amp;gt; has a width of 2*2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;, a stretch of 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt; and a stretch_order of 3. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local g = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g.font = font.current()&lt;br /&gt;
g.lang = tex.language&lt;br /&gt;
g.char = 86 -- V&lt;br /&gt;
&lt;br /&gt;
local hbox = node.hpack(g)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We create a glyph, pack it into an hbox (horizontal box), pack that hbox into a vbox (a vertical box) and write this box to the main vertical list. The char number (86 in the example above) is based on an internal encoding, so we have to keep an eye on what character is on what position. Now we do this for two glyphs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local g1 = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g1.font = font.current()&lt;br /&gt;
g1.lang = tex.language&lt;br /&gt;
g1.char = 86&lt;br /&gt;
&lt;br /&gt;
local g2 = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g2.font = font.current()&lt;br /&gt;
g2.lang = tex.language&lt;br /&gt;
g2.char = 97&lt;br /&gt;
&lt;br /&gt;
g1.next = g2&lt;br /&gt;
g2.prev = g1&lt;br /&gt;
&lt;br /&gt;
local hbox = node.hpack(g1)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pretty much the same as above. The glyphs g1 and g2 are chained together by setting the next and prev pointer to each other. If they were not connected, only glyph g1 gets into the hbox.&lt;br /&gt;
&lt;br /&gt;
If you take a close look at the PDF, you see that the two glyphs are too far away, a (negative) kern should be inserted. This can be done by inserting a kern-node manually or you can ask TeX to do that for you. The last lines of the example above should then read:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local head,tail,success = node.kerning(g1)&lt;br /&gt;
local hbox = node.hpack(head)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this approach you are able to put some glyphs into the PDF but you will run into problems when you want to create a whole paragraph. It is much easier to ask TeX to do the line breaking. The steps for paragraph creation are&lt;br /&gt;
&lt;br /&gt;
# put glyph nodes and glue nodes in a list (= chain them together with the prev/next pointers)&lt;br /&gt;
# add trailing infinite penalty and parfillskip&lt;br /&gt;
# call lang.hyphenate(), node.kerning() and node.ligaturing() to prepare the list for the linebreaking job&lt;br /&gt;
# call tex.linebreak()&lt;br /&gt;
&lt;br /&gt;
For the next task we want to create the following paragraph:&lt;br /&gt;
&lt;br /&gt;
[[File:Sample_paragraph.png|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We start with the small TeX stub as above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;myprogram.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and myprogram.lua ([https://gist.github.com/1063228 download]) defines a function &amp;lt;tt&amp;gt;mknodes()&amp;lt;/tt&amp;gt; that creates the list of nodes to be passed into the typesetter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function mknodes( text )&lt;br /&gt;
  local current_font = font.current()&lt;br /&gt;
  local font_parameters = font.getfont(current_font).parameters&lt;br /&gt;
  local n, head, last&lt;br /&gt;
  -- we should insert the paragraph indentation at the beginning&lt;br /&gt;
  head = node.new(&amp;quot;glue&amp;quot;)&lt;br /&gt;
  head.spec = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
  head.spec.width = 20 * 2^16&lt;br /&gt;
  last = head&lt;br /&gt;
&lt;br /&gt;
  for s in string.utfvalues( text ) do&lt;br /&gt;
    local char = unicode.utf8.char(s)&lt;br /&gt;
    if unicode.utf8.match(char,&amp;quot;%s&amp;quot;) then&lt;br /&gt;
      -- its a space&lt;br /&gt;
      n = node.new(&amp;quot;glue&amp;quot;)&lt;br /&gt;
      n.spec = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
      n.spec.width   = font_parameters.space&lt;br /&gt;
      n.spec.shrink  = font_parameters.space_shrink&lt;br /&gt;
      n.spec.stretch = font_parameters.space_stretch&lt;br /&gt;
    else -- a glyph&lt;br /&gt;
      n = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
      n.font = current_font&lt;br /&gt;
      n.subtype = 1&lt;br /&gt;
      n.char = s&lt;br /&gt;
      n.lang = tex.language&lt;br /&gt;
      n.uchyph = 1&lt;br /&gt;
      n.left = tex.lefthyphenmin&lt;br /&gt;
      n.right = tex.righthyphenmin&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    last.next = n&lt;br /&gt;
    last = n&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  -- now add the final parts: a penalty and the parfillskip glue&lt;br /&gt;
  local penalty = node.new(&amp;quot;penalty&amp;quot;)&lt;br /&gt;
  penalty.penalty = 10000&lt;br /&gt;
&lt;br /&gt;
  local parfillskip = node.new(&amp;quot;glue&amp;quot;)&lt;br /&gt;
  parfillskip.spec = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
  parfillskip.spec.stretch = 2^16&lt;br /&gt;
  parfillskip.spec.stretch_order = 2&lt;br /&gt;
  &lt;br /&gt;
  last.next = penalty&lt;br /&gt;
  penalty.next = parfillskip&lt;br /&gt;
&lt;br /&gt;
  -- just to create the prev pointers for tex.linebreak&lt;br /&gt;
  node.slide(head)&lt;br /&gt;
  return head&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local txt = &amp;quot;A wonderful serenity has taken possession of my entire soul, ... like mine.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
tex.baselineskip = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
tex.baselineskip.width = 14 * 2^16&lt;br /&gt;
&lt;br /&gt;
local head = mknodes(txt)&lt;br /&gt;
lang.hyphenate(head)&lt;br /&gt;
head = node.kerning(head)&lt;br /&gt;
head = node.ligaturing(head)&lt;br /&gt;
&lt;br /&gt;
local vbox = tex.linebreak(head,{ hsize = tex.sp(&amp;quot;3in&amp;quot;)})&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(You can safely skip this section if you are not interested in the details.)&lt;br /&gt;
&lt;br /&gt;
What has happened in detail? We have created a list of glyph and glue nodes and fed those into the line breaking part of TeX which gave us the vbox back. This vbox contains horizontal lists glued together:&lt;br /&gt;
&lt;br /&gt;
[[File:Paragraph_with_boxes.png|600px]]&lt;br /&gt;
&lt;br /&gt;
The dashed rectangle (vbox) should fit tight to the inner hboxes. It has a small offset just for demonstration purpose.&lt;br /&gt;
&lt;br /&gt;
To show you some of the nodes that TeX inserted for you, have a look at the following image:&lt;br /&gt;
&lt;br /&gt;
[[File:Nodes_in_sample_paragraph.png]]&lt;br /&gt;
&lt;br /&gt;
Here is an explanation of the nodes:&lt;br /&gt;
&lt;br /&gt;
# This is the dashed line in the image above. A paragraph is always vertical&lt;br /&gt;
# The first line. It has a width of three inches, a height and depth of together 8.888 pt&lt;br /&gt;
# The 20pt paragraph indent. This is the first item in the first line (note that the pointer comes from the head item of the node #2&lt;br /&gt;
# The first letter in the first line&lt;br /&gt;
# The interword glue.&lt;br /&gt;
# The second letter in the first line&lt;br /&gt;
# The clubpenalty&lt;br /&gt;
# The baselineskip minus the height of the hbox &amp;quot;above&amp;quot; (8.888pt + 5.111pt is approx. 14pt. The rounding error is due to the display of only few significant digits.) Note that TeX is in vertical mode, as it is the third item in the vbox (#1). &lt;br /&gt;
# The hbox of the second line&lt;br /&gt;
# The first letter of the second line&lt;br /&gt;
# A kern between the m and the y of the first word (second line)&lt;br /&gt;
# The last letter shown here&lt;br /&gt;
&lt;br /&gt;
There are many nodes created in the paragraph which are not shown here. A full view can be found in [[Media:Nodes_in_sample_paragraph_full.pdf|a separate PDF file]].&lt;br /&gt;
&lt;br /&gt;
== Inserting images is easy ==&lt;br /&gt;
&lt;br /&gt;
Now that you have survived the hard part of this tutorial, we get to something easier. Image inclusion. There are several ways to do this, and in my opinion this is the easiest. We again start with our plain (lua)TeX stub:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;includeimage.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and includeimage.lua is this small lua chunk:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local image_fixed = img.scan({filename = &amp;quot;oilpainting.jpg&amp;quot;})&lt;br /&gt;
&lt;br /&gt;
local image     = img.copy(image_fixed)&lt;br /&gt;
local halfimage = img.copy(image_fixed)&lt;br /&gt;
&lt;br /&gt;
halfimage.height = halfimage.height / 2&lt;br /&gt;
halfimage.width  = halfimage.width  / 2&lt;br /&gt;
&lt;br /&gt;
node.write(img.node(image))&lt;br /&gt;
node.write(img.node(halfimage))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You might be able to guess what happens here. We load the image [[Media:Oilpainting.jpg|oilpainting.jpg]] with &amp;lt;tt&amp;gt;img.scan&amp;lt;/tt&amp;gt; but do not write it out to the PDF file yet. We create a copy of the image data so we can manipulate the size for example (another option would be to obtain a specific page of a PDF document or do some rotation). After that we write a reference to that image to the PDF file. In the case above, two references to the image (XObject) get written but the image is only written once. That is easy, right?&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=File:Oilpainting.jpg&amp;diff=138</id>
		<title>File:Oilpainting.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=File:Oilpainting.jpg&amp;diff=138"/>
		<updated>2011-07-04T16:30:38Z</updated>

		<summary type="html">&lt;p&gt;Patrick: some sample jpeg image&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;some sample jpeg image&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=137</id>
		<title>TeX without TeX</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=137"/>
		<updated>2011-07-04T15:50:29Z</updated>

		<summary type="html">&lt;p&gt;Patrick: forgot parindent&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Use TeX&amp;#039;s power without TeX macros ==&lt;br /&gt;
&lt;br /&gt;
With the Lua-part in LuaTeX you have access to most of TeX&amp;#039;s capabilities for creating PDF documents. Most of the [http://www.luatex.org/svn/trunk/manual/luatexref-t.pdf LuaTeX reference manual] is about this topic. &lt;br /&gt;
&lt;br /&gt;
The underlying idea is to create TeX&amp;#039;s internal data structure as TeX would do by transforming macros and primitives into something called nodes. These nodes are then transformed into instructions for the PDF file (PDF objects). So the following pages deal with node creation and the structures. &lt;br /&gt;
&lt;br /&gt;
Let&amp;#039;s start with a rule node. When you write &amp;lt;tt&amp;gt;\hrule width 20pt height 10pt depth 10pt &amp;lt;/tt&amp;gt; in TeX, a node of type rule will be created, which has three fields: height, depth and width. We can visualize this node by a simple box like this:&lt;br /&gt;
&lt;br /&gt;
[[File:rulenode.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r.width  = 20 * 65536&lt;br /&gt;
r.height = 10 * 65536&lt;br /&gt;
r.depth  = 10 * 65536&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some remarks: the size is in scaled points, and 65536 (=2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;) scaled points are 1 point, so 20pt becomes 20 * 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;. Not shown in the example are (among others) the next and prev fields. These fields hold a pointer (the node address) to the following and the previous nodes. A node that exist by itself has its prev and next fields set to nil.&lt;br /&gt;
&lt;br /&gt;
A slightly more complicated example is when you create two rules and pack then into a vertical box. This would look like this in plain TeX:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\vbox {\hrule width 20pt height 10pt depth 10pt&lt;br /&gt;
           \hrule width 20pt height 10pt depth 10pt }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would generate a node list like:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Rulenode2.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r1 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r1.width  = 20 * 65536&lt;br /&gt;
r1.height = 10 * 65536&lt;br /&gt;
r1.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r2 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r2.width  = 20 * 65536&lt;br /&gt;
r2.height = 10 * 65536&lt;br /&gt;
r2.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r1.next = r2&lt;br /&gt;
r2.prev = r1&lt;br /&gt;
&lt;br /&gt;
vbox = node.vpack(r1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result is a vbox containing the two rule nodes. The nodes are connected by their next and prev pointers, so the vbox contains them both. The size (width, height and depth) is adjusted automatically.&lt;br /&gt;
&lt;br /&gt;
This also applies to all other things you can put on a TeX page: glyphs, horizontal boxes, math, images, hyperlinks, glue .... For a complete list of the nodes, see the reference manual Chapter 8 &amp;quot;Nodes&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Beyond reports and articles ==&lt;br /&gt;
&lt;br /&gt;
Perhaps the question that comes into your mind is: why should I bother writing Lua code instead of TeX code? For many documents, including articles, reports and books, the classic way to create a PDF with TeX is to use LaTeX or ConTeXt. But there are applications that use TeX as an 100% automatic PDF generation software. If you want to create data sheets or product listings, your normal input is not a classic document, but most likely an Excel spreadsheet or an XML file, perhaps extracted from a database. You won&amp;#039;t have any TeX markup within these documents. So: if you don&amp;#039;t have TeX markup in these documents, you don&amp;#039;t need the TeX interpreter to read these files. More likely is an XML parser or a spreadsheet 2 ... converter.&lt;br /&gt;
&lt;br /&gt;
When you use regular LaTeX or ConTeXt code to put the contents of the database in your PDF (database publishing), you run into several problems:&lt;br /&gt;
&lt;br /&gt;
* Exact positioning of items on the page can be troublesome&lt;br /&gt;
* catcodes / command escapes are to be considered and surely get into your way&lt;br /&gt;
* TeX is no fun to program in (well it is, but only for some people) - calculations, tests, exception handling, control flow&lt;br /&gt;
* The packages that exist may reach their limit soon. You need a super flexible image-between-columns-with-parshape package? Write it yourself.&lt;br /&gt;
&lt;br /&gt;
With Lua you have a very decent programming language that &amp;#039;&amp;#039;is&amp;#039;&amp;#039; fun to program in. When you use the Lua interface to TeX, you have full control of what is happening, which is usually the level of control you need for high quality output.&lt;br /&gt;
&lt;br /&gt;
One approach is to create a stub TeX file and let Lua do the rest:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;myprogram.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The file &amp;lt;tt&amp;gt;myprogram.lua&amp;lt;/tt&amp;gt; then contains all the code to a) read the source file(s), b) extract the information and create the appropriate nodes and c) instruct TeX to create PDF pages from these nodes.&lt;br /&gt;
&lt;br /&gt;
In a future version of LuaTeX you will be able to run the Lua interpreter without the stub TeX file above.&lt;br /&gt;
&lt;br /&gt;
== A first example ==&lt;br /&gt;
&lt;br /&gt;
The example document given below creates two pages by using Lua code alone. You will learn how to access TeX&amp;#039;s boxes and counters from the Lua side, shipout a page into the PDF file, create horizontal and vertical boxes (hbox and vbox), create new nodes and manipulate the nodes links structure. The example covers the following node types: rule, whatsit, vlist, hlist and action.&lt;br /&gt;
&lt;br /&gt;
In the example code we use black squares as the contents of the pages and not normal text, because character handling takes more code and will be covered later on.&lt;br /&gt;
&lt;br /&gt;
Save the following file into &amp;lt;tt&amp;gt;myprogram.lua&amp;lt;/tt&amp;gt; and use the TeX stub from above (or get the source [https://raw.github.com/gist/1062041/d3de082e955f6535f3820742cef76fe9e50d5a6f/myprogram.lua here]).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
  -- this will hold the items that go onto the page&lt;br /&gt;
  local pagelist&lt;br /&gt;
 &lt;br /&gt;
  -- Call tex.shipout() with the contents of the pagelist&lt;br /&gt;
  function shipout()&lt;br /&gt;
&lt;br /&gt;
    local vbox,b = node.vpack(pagelist) -- we ignore the badness &amp;#039;b&amp;#039;&lt;br /&gt;
    tex.box[666] = vbox&lt;br /&gt;
    tex.shipout(666)&lt;br /&gt;
&lt;br /&gt;
    pagelist = nil&lt;br /&gt;
    &lt;br /&gt;
    -- Not strictly necessary. TeX holds the current page number in counter 0.&lt;br /&gt;
    -- TeX displays the contents of this counter when it puts a page into&lt;br /&gt;
    -- the pdf (tex.shipout()). If we don&amp;#039;t change the counter, TeX will&lt;br /&gt;
    -- display [1] [1], instead of [1] [2] for our two page document.&lt;br /&gt;
    tex.count[0] = tex.count[0] + 1&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
  function add_to_page( list )&lt;br /&gt;
    -- We attach the nodelist &amp;#039;list&amp;#039; to the end of the pagelist&lt;br /&gt;
    -- if pagelist doesn&amp;#039;t exist, &amp;#039;list&amp;#039; is our new pagelist&lt;br /&gt;
    -- if it exists, we go to the end with node.tail() and adjust&lt;br /&gt;
    -- the prev and next pointers, so list becomes part&lt;br /&gt;
    -- of pagelist.&lt;br /&gt;
    if not pagelist then pagelist = list&lt;br /&gt;
    else&lt;br /&gt;
      local tail = node.tail(pagelist)&lt;br /&gt;
      tail.next = list&lt;br /&gt;
      list.prev  = tail&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- This creates a new square rule and returns the pointer to it.&lt;br /&gt;
function mkrule( size )&lt;br /&gt;
  local r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
  r.width  = size &lt;br /&gt;
  r.height = size / 2&lt;br /&gt;
  r.depth  = size / 2&lt;br /&gt;
  return r&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
do&lt;br /&gt;
  local destcounter = 0&lt;br /&gt;
  -- Create a pdf anchor (dest object). It returns a whatsit node and the &lt;br /&gt;
  -- number of the anchor, so it can be used in a pdf link or an outline.&lt;br /&gt;
  function mkdest()&lt;br /&gt;
    destcounter = destcounter + 1&lt;br /&gt;
    local d = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_dest&amp;quot;)&lt;br /&gt;
    d.named_id = 0&lt;br /&gt;
    d.dest_id = destcounter&lt;br /&gt;
    d.dest_type = 3&lt;br /&gt;
&lt;br /&gt;
    return d, destcounter&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Take a list of nodes and put them into an hbox. The prev and next fields&lt;br /&gt;
-- of the nodes will be set automatically. Return a pointer to the hbox.&lt;br /&gt;
function hpack( ... )&lt;br /&gt;
  local start, tmp, cur&lt;br /&gt;
  start = select(1,...)&lt;br /&gt;
  tmp = start&lt;br /&gt;
  for i=2,select(&amp;quot;#&amp;quot;,...) do&lt;br /&gt;
    cur = select(i,...)&lt;br /&gt;
    tmp.next = cur&lt;br /&gt;
    cur.prev = tmp&lt;br /&gt;
    tmp = cur&lt;br /&gt;
  end&lt;br /&gt;
  local h,b = node.hpack(start) -- ignore badness&lt;br /&gt;
  return h&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local tenpt = 10 * 2^16&lt;br /&gt;
---------------------------&lt;br /&gt;
-- page 1&lt;br /&gt;
---------------------------&lt;br /&gt;
local n,dest = mkdest() -- dest is needed for the link to this anchor&lt;br /&gt;
&lt;br /&gt;
add_to_page(n)&lt;br /&gt;
add_to_page(mkrule(2 * tenpt))&lt;br /&gt;
&lt;br /&gt;
-- The pagelist contains a pdf dest node (a link destination) and a rule of size 20pt x 20pt.&lt;br /&gt;
&lt;br /&gt;
shipout()&lt;br /&gt;
---------------------------&lt;br /&gt;
-- page 2&lt;br /&gt;
---------------------------&lt;br /&gt;
-- This is the page with the link to the anchor (dest) on page one. A&lt;br /&gt;
-- link consists of three nodes: a pdf_start_link, a pdf_end_link and and &lt;br /&gt;
-- action node that specifies the action to perform when the user clicks on&lt;br /&gt;
-- the link.&lt;br /&gt;
-- The pdf link must be inside a horizontal box, that&amp;#039;s why we hpack() it.&lt;br /&gt;
-- The link_attr (link attributes) is optional, here it draws a yellowish border&lt;br /&gt;
-- around the link.&lt;br /&gt;
local start_link = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_start_link&amp;quot;)&lt;br /&gt;
local end_link   = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_end_link&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
start_link.width     = tenpt&lt;br /&gt;
start_link.height    = tenpt / 2&lt;br /&gt;
start_link.depth     = tenpt / 2&lt;br /&gt;
start_link.link_attr = &amp;quot;/C [0.9 1 0] /Border [0 0 2]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
start_link.action = node.new(&amp;quot;action&amp;quot;)&lt;br /&gt;
start_link.action.action_type = 1&lt;br /&gt;
start_link.action.action_id   = dest&lt;br /&gt;
&lt;br /&gt;
local rule = mkrule(tenpt)&lt;br /&gt;
local hbox = hpack(start_link, rule, end_link)&lt;br /&gt;
add_to_page(hbox)&lt;br /&gt;
&lt;br /&gt;
-- This pagelist consists of an hbox whose contents is &amp;quot;start_link&amp;quot;,&lt;br /&gt;
-- the 10pt x 10pt rule and the &amp;quot;end_link&amp;quot; node. &lt;br /&gt;
&lt;br /&gt;
shipout()&lt;br /&gt;
---------------------------&lt;br /&gt;
&lt;br /&gt;
-- Just to show you that you can get some memory usage statistics:&lt;br /&gt;
print(string.format(&amp;quot;\nnode_mem_usage=%s&amp;quot;,status.node_mem_usage))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The idea is to create nodes, collect them in a list (here: pagelist) and use &amp;lt;tt&amp;gt;tex.shipout()&amp;lt;/tt&amp;gt; to put the page into the PDF.&lt;br /&gt;
&lt;br /&gt;
== And what about &amp;#039;&amp;#039;real&amp;#039;&amp;#039; content? ==&lt;br /&gt;
&lt;br /&gt;
Black squares won&amp;#039;t make anyone happy. So we need a typeset paragraph. For that we start with a single glyph and a glue first. A glyph node has this structure:&lt;br /&gt;
&lt;br /&gt;
[[File:Singleglyphnode.png]]&lt;br /&gt;
&lt;br /&gt;
whereas a glue is more complicated:&lt;br /&gt;
&lt;br /&gt;
[[File:Simplegluenode.png]]&lt;br /&gt;
&lt;br /&gt;
The glue item comes in pairs: a glue node and a glue_spec node. The information about the shrink/stretch values go into the glue_spec node. For example, the TeX glue &amp;lt;tt&amp;gt;2pt plus 1fill&amp;lt;/tt&amp;gt; has a width of 2*2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;, a stretch of 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt; and a stretch_order of 3. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local g = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g.font = font.current()&lt;br /&gt;
g.lang = tex.language&lt;br /&gt;
g.char = 86 -- V&lt;br /&gt;
&lt;br /&gt;
local hbox = node.hpack(g)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We create a glyph, pack it into an hbox (horizontal box), pack that hbox into a vbox (a vertical box) and write this box to the main vertical list. The char number (86 in the example above) is based on an internal encoding, so we have to keep an eye on what character is on what position. Now we do this for two glyphs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local g1 = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g1.font = font.current()&lt;br /&gt;
g1.lang = tex.language&lt;br /&gt;
g1.char = 86&lt;br /&gt;
&lt;br /&gt;
local g2 = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g2.font = font.current()&lt;br /&gt;
g2.lang = tex.language&lt;br /&gt;
g2.char = 97&lt;br /&gt;
&lt;br /&gt;
g1.next = g2&lt;br /&gt;
g2.prev = g1&lt;br /&gt;
&lt;br /&gt;
local hbox = node.hpack(g1)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pretty much the same as above. The glyphs g1 and g2 are chained together by setting the next and prev pointer to each other. If they were not connected, only glyph g1 gets into the hbox.&lt;br /&gt;
&lt;br /&gt;
If you take a close look at the PDF, you see that the two glyphs are too far away, a (negative) kern should be inserted. This can be done by inserting a kern-node manually or you can ask TeX to do that for you. The last lines of the example above should then read:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local head,tail,success = node.kerning(g1)&lt;br /&gt;
local hbox = node.hpack(head)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this approach you are able to put some glyphs into the PDF but you will run into problems when you want to create a whole paragraph. It is much easier to ask TeX to do the line breaking. The steps for paragraph creation are&lt;br /&gt;
&lt;br /&gt;
# put glyph nodes and glue nodes in a list (= chain them together with the prev/next pointers)&lt;br /&gt;
# add trailing infinite penalty and parfillskip&lt;br /&gt;
# call lang.hyphenate(), node.kerning() and node.ligaturing() to prepare the list for the linebreaking job&lt;br /&gt;
# call tex.linebreak()&lt;br /&gt;
&lt;br /&gt;
For the next task we want to create the following paragraph:&lt;br /&gt;
&lt;br /&gt;
[[File:Sample_paragraph.png|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We start with the small TeX stub as above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;myprogram.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and myprogram.lua ([https://gist.github.com/1063228 download]) defines a function &amp;lt;tt&amp;gt;mknodes()&amp;lt;/tt&amp;gt; that creates the list of nodes to be passed into the typesetter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function mknodes( text )&lt;br /&gt;
  local current_font = font.current()&lt;br /&gt;
  local font_parameters = font.getfont(current_font).parameters&lt;br /&gt;
  local n, head, last&lt;br /&gt;
  -- we should insert the paragraph indentation at the beginning&lt;br /&gt;
  head = node.new(&amp;quot;glue&amp;quot;)&lt;br /&gt;
  head.spec = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
  head.spec.width = 20 * 2^16&lt;br /&gt;
  last = head&lt;br /&gt;
&lt;br /&gt;
  for s in string.utfvalues( text ) do&lt;br /&gt;
    local char = unicode.utf8.char(s)&lt;br /&gt;
    if unicode.utf8.match(char,&amp;quot;%s&amp;quot;) then&lt;br /&gt;
      -- its a space&lt;br /&gt;
      n = node.new(&amp;quot;glue&amp;quot;)&lt;br /&gt;
      n.spec = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
      n.spec.width   = font_parameters.space&lt;br /&gt;
      n.spec.shrink  = font_parameters.space_shrink&lt;br /&gt;
      n.spec.stretch = font_parameters.space_stretch&lt;br /&gt;
    else -- a glyph&lt;br /&gt;
      n = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
      n.font = current_font&lt;br /&gt;
      n.subtype = 1&lt;br /&gt;
      n.char = s&lt;br /&gt;
      n.lang = tex.language&lt;br /&gt;
      n.uchyph = 1&lt;br /&gt;
      n.left = tex.lefthyphenmin&lt;br /&gt;
      n.right = tex.righthyphenmin&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    last.next = n&lt;br /&gt;
    last = n&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  -- now add the final parts: a penalty and the parfillskip glue&lt;br /&gt;
  local penalty = node.new(&amp;quot;penalty&amp;quot;)&lt;br /&gt;
  penalty.penalty = 10000&lt;br /&gt;
&lt;br /&gt;
  local parfillskip = node.new(&amp;quot;glue&amp;quot;)&lt;br /&gt;
  parfillskip.spec = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
  parfillskip.spec.stretch = 2^16&lt;br /&gt;
  parfillskip.spec.stretch_order = 2&lt;br /&gt;
  &lt;br /&gt;
  last.next = penalty&lt;br /&gt;
  penalty.next = parfillskip&lt;br /&gt;
&lt;br /&gt;
  -- just to create the prev pointers for tex.linebreak&lt;br /&gt;
  node.slide(head)&lt;br /&gt;
  return head&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local txt = &amp;quot;A wonderful serenity has taken possession of my entire soul, ... like mine.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
tex.baselineskip = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
tex.baselineskip.width = 14 * 2^16&lt;br /&gt;
&lt;br /&gt;
local head = mknodes(txt)&lt;br /&gt;
lang.hyphenate(head)&lt;br /&gt;
head = node.kerning(head)&lt;br /&gt;
head = node.ligaturing(head)&lt;br /&gt;
&lt;br /&gt;
local vbox = tex.linebreak(head,{ hsize = tex.sp(&amp;quot;3in&amp;quot;)})&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(You can safely skip this section if you are not interested in the details.)&lt;br /&gt;
&lt;br /&gt;
What has happened in detail? We have created a list of glyph and glue nodes and fed those into the line breaking part of TeX which gave us the vbox back. This vbox contains horizontal lists glued together:&lt;br /&gt;
&lt;br /&gt;
[[File:Paragraph_with_boxes.png|600px]]&lt;br /&gt;
&lt;br /&gt;
The dashed rectangle (vbox) should fit tight to the inner hboxes. It has a small offset just for demonstration purpose.&lt;br /&gt;
&lt;br /&gt;
To show you some of the nodes that TeX inserted for you, have a look at the following image:&lt;br /&gt;
&lt;br /&gt;
[[File:Nodes_in_sample_paragraph.png]]&lt;br /&gt;
&lt;br /&gt;
Here is an explanation of the nodes:&lt;br /&gt;
&lt;br /&gt;
# This is the dashed line in the image above. A paragraph is always vertical&lt;br /&gt;
# The first line. It has a width of three inches, a height and depth of together 8.888 pt&lt;br /&gt;
# The 20pt paragraph indent. This is the first item in the first line (note that the pointer comes from the head item of the node #2&lt;br /&gt;
# The first letter in the first line&lt;br /&gt;
# The interword glue.&lt;br /&gt;
# The second letter in the first line&lt;br /&gt;
# The clubpenalty&lt;br /&gt;
# The baselineskip minus the height of the hbox &amp;quot;above&amp;quot; (8.888pt + 5.111pt is approx. 14pt. The rounding error is due to the display of only few significant digits.) Note that TeX is in vertical mode, as it is the third item in the vbox (#1). &lt;br /&gt;
# The hbox of the second line&lt;br /&gt;
# The first letter of the second line&lt;br /&gt;
# A kern between the m and the y of the first word (second line)&lt;br /&gt;
# The last letter shown here&lt;br /&gt;
&lt;br /&gt;
There are many nodes created in the paragraph which are not shown here. A full view can be found in [[Media:Nodes_in_sample_paragraph_full.pdf|a separate PDF file]].&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=136</id>
		<title>TeX without TeX</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=136"/>
		<updated>2011-07-04T13:03:12Z</updated>

		<summary type="html">&lt;p&gt;Patrick: New image size&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Use TeX&amp;#039;s power without TeX macros ==&lt;br /&gt;
&lt;br /&gt;
With the Lua-part in LuaTeX you have access to most of TeX&amp;#039;s capabilities for creating PDF documents. Most of the [http://www.luatex.org/svn/trunk/manual/luatexref-t.pdf LuaTeX reference manual] is about this topic. &lt;br /&gt;
&lt;br /&gt;
The underlying idea is to create TeX&amp;#039;s internal data structure as TeX would do by transforming macros and primitives into something called nodes. These nodes are then transformed into instructions for the PDF file (PDF objects). So the following pages deal with node creation and the structures. &lt;br /&gt;
&lt;br /&gt;
Let&amp;#039;s start with a rule node. When you write &amp;lt;tt&amp;gt;\hrule width 20pt height 10pt depth 10pt &amp;lt;/tt&amp;gt; in TeX, a node of type rule will be created, which has three fields: height, depth and width. We can visualize this node by a simple box like this:&lt;br /&gt;
&lt;br /&gt;
[[File:rulenode.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r.width  = 20 * 65536&lt;br /&gt;
r.height = 10 * 65536&lt;br /&gt;
r.depth  = 10 * 65536&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some remarks: the size is in scaled points, and 65536 (=2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;) scaled points are 1 point, so 20pt becomes 20 * 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;. Not shown in the example are (among others) the next and prev fields. These fields hold a pointer (the node address) to the following and the previous nodes. A node that exist by itself has its prev and next fields set to nil.&lt;br /&gt;
&lt;br /&gt;
A slightly more complicated example is when you create two rules and pack then into a vertical box. This would look like this in plain TeX:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\vbox {\hrule width 20pt height 10pt depth 10pt&lt;br /&gt;
           \hrule width 20pt height 10pt depth 10pt }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would generate a node list like:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Rulenode2.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r1 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r1.width  = 20 * 65536&lt;br /&gt;
r1.height = 10 * 65536&lt;br /&gt;
r1.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r2 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r2.width  = 20 * 65536&lt;br /&gt;
r2.height = 10 * 65536&lt;br /&gt;
r2.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r1.next = r2&lt;br /&gt;
r2.prev = r1&lt;br /&gt;
&lt;br /&gt;
vbox = node.vpack(r1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result is a vbox containing the two rule nodes. The nodes are connected by their next and prev pointers, so the vbox contains them both. The size (width, height and depth) is adjusted automatically.&lt;br /&gt;
&lt;br /&gt;
This also applies to all other things you can put on a TeX page: glyphs, horizontal boxes, math, images, hyperlinks, glue .... For a complete list of the nodes, see the reference manual Chapter 8 &amp;quot;Nodes&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Beyond reports and articles ==&lt;br /&gt;
&lt;br /&gt;
Perhaps the question that comes into your mind is: why should I bother writing Lua code instead of TeX code? For many documents, including articles, reports and books, the classic way to create a PDF with TeX is to use LaTeX or ConTeXt. But there are applications that use TeX as an 100% automatic PDF generation software. If you want to create data sheets or product listings, your normal input is not a classic document, but most likely an Excel spreadsheet or an XML file, perhaps extracted from a database. You won&amp;#039;t have any TeX markup within these documents. So: if you don&amp;#039;t have TeX markup in these documents, you don&amp;#039;t need the TeX interpreter to read these files. More likely is an XML parser or a spreadsheet 2 ... converter.&lt;br /&gt;
&lt;br /&gt;
When you use regular LaTeX or ConTeXt code to put the contents of the database in your PDF (database publishing), you run into several problems:&lt;br /&gt;
&lt;br /&gt;
* Exact positioning of items on the page can be troublesome&lt;br /&gt;
* catcodes / command escapes are to be considered and surely get into your way&lt;br /&gt;
* TeX is no fun to program in (well it is, but only for some people) - calculations, tests, exception handling, control flow&lt;br /&gt;
* The packages that exist may reach their limit soon. You need a super flexible image-between-columns-with-parshape package? Write it yourself.&lt;br /&gt;
&lt;br /&gt;
With Lua you have a very decent programming language that &amp;#039;&amp;#039;is&amp;#039;&amp;#039; fun to program in. When you use the Lua interface to TeX, you have full control of what is happening, which is usually the level of control you need for high quality output.&lt;br /&gt;
&lt;br /&gt;
One approach is to create a stub TeX file and let Lua do the rest:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;myprogram.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The file &amp;lt;tt&amp;gt;myprogram.lua&amp;lt;/tt&amp;gt; then contains all the code to a) read the source file(s), b) extract the information and create the appropriate nodes and c) instruct TeX to create PDF pages from these nodes.&lt;br /&gt;
&lt;br /&gt;
In a future version of LuaTeX you will be able to run the Lua interpreter without the stub TeX file above.&lt;br /&gt;
&lt;br /&gt;
== A first example ==&lt;br /&gt;
&lt;br /&gt;
The example document given below creates two pages by using Lua code alone. You will learn how to access TeX&amp;#039;s boxes and counters from the Lua side, shipout a page into the PDF file, create horizontal and vertical boxes (hbox and vbox), create new nodes and manipulate the nodes links structure. The example covers the following node types: rule, whatsit, vlist, hlist and action.&lt;br /&gt;
&lt;br /&gt;
In the example code we use black squares as the contents of the pages and not normal text, because character handling takes more code and will be covered later on.&lt;br /&gt;
&lt;br /&gt;
Save the following file into &amp;lt;tt&amp;gt;myprogram.lua&amp;lt;/tt&amp;gt; and use the TeX stub from above (or get the source [https://raw.github.com/gist/1062041/d3de082e955f6535f3820742cef76fe9e50d5a6f/myprogram.lua here]).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
  -- this will hold the items that go onto the page&lt;br /&gt;
  local pagelist&lt;br /&gt;
 &lt;br /&gt;
  -- Call tex.shipout() with the contents of the pagelist&lt;br /&gt;
  function shipout()&lt;br /&gt;
&lt;br /&gt;
    local vbox,b = node.vpack(pagelist) -- we ignore the badness &amp;#039;b&amp;#039;&lt;br /&gt;
    tex.box[666] = vbox&lt;br /&gt;
    tex.shipout(666)&lt;br /&gt;
&lt;br /&gt;
    pagelist = nil&lt;br /&gt;
    &lt;br /&gt;
    -- Not strictly necessary. TeX holds the current page number in counter 0.&lt;br /&gt;
    -- TeX displays the contents of this counter when it puts a page into&lt;br /&gt;
    -- the pdf (tex.shipout()). If we don&amp;#039;t change the counter, TeX will&lt;br /&gt;
    -- display [1] [1], instead of [1] [2] for our two page document.&lt;br /&gt;
    tex.count[0] = tex.count[0] + 1&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
  function add_to_page( list )&lt;br /&gt;
    -- We attach the nodelist &amp;#039;list&amp;#039; to the end of the pagelist&lt;br /&gt;
    -- if pagelist doesn&amp;#039;t exist, &amp;#039;list&amp;#039; is our new pagelist&lt;br /&gt;
    -- if it exists, we go to the end with node.tail() and adjust&lt;br /&gt;
    -- the prev and next pointers, so list becomes part&lt;br /&gt;
    -- of pagelist.&lt;br /&gt;
    if not pagelist then pagelist = list&lt;br /&gt;
    else&lt;br /&gt;
      local tail = node.tail(pagelist)&lt;br /&gt;
      tail.next = list&lt;br /&gt;
      list.prev  = tail&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- This creates a new square rule and returns the pointer to it.&lt;br /&gt;
function mkrule( size )&lt;br /&gt;
  local r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
  r.width  = size &lt;br /&gt;
  r.height = size / 2&lt;br /&gt;
  r.depth  = size / 2&lt;br /&gt;
  return r&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
do&lt;br /&gt;
  local destcounter = 0&lt;br /&gt;
  -- Create a pdf anchor (dest object). It returns a whatsit node and the &lt;br /&gt;
  -- number of the anchor, so it can be used in a pdf link or an outline.&lt;br /&gt;
  function mkdest()&lt;br /&gt;
    destcounter = destcounter + 1&lt;br /&gt;
    local d = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_dest&amp;quot;)&lt;br /&gt;
    d.named_id = 0&lt;br /&gt;
    d.dest_id = destcounter&lt;br /&gt;
    d.dest_type = 3&lt;br /&gt;
&lt;br /&gt;
    return d, destcounter&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Take a list of nodes and put them into an hbox. The prev and next fields&lt;br /&gt;
-- of the nodes will be set automatically. Return a pointer to the hbox.&lt;br /&gt;
function hpack( ... )&lt;br /&gt;
  local start, tmp, cur&lt;br /&gt;
  start = select(1,...)&lt;br /&gt;
  tmp = start&lt;br /&gt;
  for i=2,select(&amp;quot;#&amp;quot;,...) do&lt;br /&gt;
    cur = select(i,...)&lt;br /&gt;
    tmp.next = cur&lt;br /&gt;
    cur.prev = tmp&lt;br /&gt;
    tmp = cur&lt;br /&gt;
  end&lt;br /&gt;
  local h,b = node.hpack(start) -- ignore badness&lt;br /&gt;
  return h&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local tenpt = 10 * 2^16&lt;br /&gt;
---------------------------&lt;br /&gt;
-- page 1&lt;br /&gt;
---------------------------&lt;br /&gt;
local n,dest = mkdest() -- dest is needed for the link to this anchor&lt;br /&gt;
&lt;br /&gt;
add_to_page(n)&lt;br /&gt;
add_to_page(mkrule(2 * tenpt))&lt;br /&gt;
&lt;br /&gt;
-- The pagelist contains a pdf dest node (a link destination) and a rule of size 20pt x 20pt.&lt;br /&gt;
&lt;br /&gt;
shipout()&lt;br /&gt;
---------------------------&lt;br /&gt;
-- page 2&lt;br /&gt;
---------------------------&lt;br /&gt;
-- This is the page with the link to the anchor (dest) on page one. A&lt;br /&gt;
-- link consists of three nodes: a pdf_start_link, a pdf_end_link and and &lt;br /&gt;
-- action node that specifies the action to perform when the user clicks on&lt;br /&gt;
-- the link.&lt;br /&gt;
-- The pdf link must be inside a horizontal box, that&amp;#039;s why we hpack() it.&lt;br /&gt;
-- The link_attr (link attributes) is optional, here it draws a yellowish border&lt;br /&gt;
-- around the link.&lt;br /&gt;
local start_link = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_start_link&amp;quot;)&lt;br /&gt;
local end_link   = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_end_link&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
start_link.width     = tenpt&lt;br /&gt;
start_link.height    = tenpt / 2&lt;br /&gt;
start_link.depth     = tenpt / 2&lt;br /&gt;
start_link.link_attr = &amp;quot;/C [0.9 1 0] /Border [0 0 2]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
start_link.action = node.new(&amp;quot;action&amp;quot;)&lt;br /&gt;
start_link.action.action_type = 1&lt;br /&gt;
start_link.action.action_id   = dest&lt;br /&gt;
&lt;br /&gt;
local rule = mkrule(tenpt)&lt;br /&gt;
local hbox = hpack(start_link, rule, end_link)&lt;br /&gt;
add_to_page(hbox)&lt;br /&gt;
&lt;br /&gt;
-- This pagelist consists of an hbox whose contents is &amp;quot;start_link&amp;quot;,&lt;br /&gt;
-- the 10pt x 10pt rule and the &amp;quot;end_link&amp;quot; node. &lt;br /&gt;
&lt;br /&gt;
shipout()&lt;br /&gt;
---------------------------&lt;br /&gt;
&lt;br /&gt;
-- Just to show you that you can get some memory usage statistics:&lt;br /&gt;
print(string.format(&amp;quot;\nnode_mem_usage=%s&amp;quot;,status.node_mem_usage))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The idea is to create nodes, collect them in a list (here: pagelist) and use &amp;lt;tt&amp;gt;tex.shipout()&amp;lt;/tt&amp;gt; to put the page into the PDF.&lt;br /&gt;
&lt;br /&gt;
== And what about &amp;#039;&amp;#039;real&amp;#039;&amp;#039; content? ==&lt;br /&gt;
&lt;br /&gt;
Black squares won&amp;#039;t make anyone happy. So we need a typeset paragraph. For that we start with a single glyph and a glue first. A glyph node has this structure:&lt;br /&gt;
&lt;br /&gt;
[[File:Singleglyphnode.png]]&lt;br /&gt;
&lt;br /&gt;
whereas a glue is more complicated:&lt;br /&gt;
&lt;br /&gt;
[[File:Simplegluenode.png]]&lt;br /&gt;
&lt;br /&gt;
The glue item comes in pairs: a glue node and a glue_spec node. The information about the shrink/stretch values go into the glue_spec node. For example, the TeX glue &amp;lt;tt&amp;gt;2pt plus 1fill&amp;lt;/tt&amp;gt; has a width of 2*2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;, a stretch of 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt; and a stretch_order of 3. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local g = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g.font = font.current()&lt;br /&gt;
g.lang = tex.language&lt;br /&gt;
g.char = 86 -- V&lt;br /&gt;
&lt;br /&gt;
local hbox = node.hpack(g)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We create a glyph, pack it into an hbox (horizontal box), pack that hbox into a vbox (a vertical box) and write this box to the main vertical list. The char number (86 in the example above) is based on an internal encoding, so we have to keep an eye on what character is on what position. Now we do this for two glyphs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local g1 = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g1.font = font.current()&lt;br /&gt;
g1.lang = tex.language&lt;br /&gt;
g1.char = 86&lt;br /&gt;
&lt;br /&gt;
local g2 = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g2.font = font.current()&lt;br /&gt;
g2.lang = tex.language&lt;br /&gt;
g2.char = 97&lt;br /&gt;
&lt;br /&gt;
g1.next = g2&lt;br /&gt;
g2.prev = g1&lt;br /&gt;
&lt;br /&gt;
local hbox = node.hpack(g1)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pretty much the same as above. The glyphs g1 and g2 are chained together by setting the next and prev pointer to each other. If they were not connected, only glyph g1 gets into the hbox.&lt;br /&gt;
&lt;br /&gt;
If you take a close look at the PDF, you see that the two glyphs are too far away, a (negative) kern should be inserted. This can be done by inserting a kern-node manually or you can ask TeX to do that for you. The last lines of the example above should then read:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local head,tail,success = node.kerning(g1)&lt;br /&gt;
local hbox = node.hpack(head)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this approach you are able to put some glyphs into the PDF but you will run into problems when you want to create a whole paragraph. It is much easier to ask TeX to do the line breaking. The steps for paragraph creation are&lt;br /&gt;
&lt;br /&gt;
# put glyph nodes and glue nodes in a list (= chain them together with the prev/next pointers)&lt;br /&gt;
# add trailing infinite penalty and parfillskip&lt;br /&gt;
# call lang.hyphenate(), node.kerning() and node.ligaturing() to prepare the list for the linebreaking job&lt;br /&gt;
# call tex.linebreak()&lt;br /&gt;
&lt;br /&gt;
For the next task we want to create the following paragraph:&lt;br /&gt;
&lt;br /&gt;
[[File:Sample_paragraph.png|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We start with the small TeX stub as above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;myprogram.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and myprogram.lua ([https://gist.github.com/1063228 download]) defines a function &amp;lt;tt&amp;gt;mknodes()&amp;lt;/tt&amp;gt; that creates the list of nodes to be passed into the typesetter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function mknodes( text )&lt;br /&gt;
  local current_font = font.current()&lt;br /&gt;
  local font_parameters = font.getfont(current_font).parameters&lt;br /&gt;
  local n, head, last&lt;br /&gt;
  for s in string.utfvalues( text ) do&lt;br /&gt;
    local char = unicode.utf8.char(s)&lt;br /&gt;
    if unicode.utf8.match(char,&amp;quot;%s&amp;quot;) then&lt;br /&gt;
      -- its a space&lt;br /&gt;
      n = node.new(&amp;quot;glue&amp;quot;)&lt;br /&gt;
      n.spec = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
      n.spec.width   = font_parameters.space&lt;br /&gt;
      n.spec.shrink  = font_parameters.space_shrink&lt;br /&gt;
      n.spec.stretch = font_parameters.space_stretch&lt;br /&gt;
    else -- a glyph&lt;br /&gt;
      n = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
      n.font = current_font&lt;br /&gt;
      n.subtype = 1&lt;br /&gt;
      n.char = s&lt;br /&gt;
      n.lang = tex.language&lt;br /&gt;
      n.uchyph = 1&lt;br /&gt;
      n.left = tex.lefthyphenmin&lt;br /&gt;
      n.right = tex.righthyphenmin&lt;br /&gt;
    end&lt;br /&gt;
    if head then&lt;br /&gt;
      last.next = n&lt;br /&gt;
    else&lt;br /&gt;
      head = n&lt;br /&gt;
    end&lt;br /&gt;
    last = n&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  -- now add the final parts: a penalty and the parfillskip glue&lt;br /&gt;
  local penalty = node.new(&amp;quot;penalty&amp;quot;)&lt;br /&gt;
  penalty.penalty = 10000&lt;br /&gt;
&lt;br /&gt;
  local parfillskip = node.new(&amp;quot;glue&amp;quot;)&lt;br /&gt;
  parfillskip.spec = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
  parfillskip.spec.stretch = 2^16&lt;br /&gt;
  parfillskip.spec.stretch_order = 2&lt;br /&gt;
  &lt;br /&gt;
  last.next = penalty&lt;br /&gt;
  penalty.next = parfillskip&lt;br /&gt;
&lt;br /&gt;
  -- just to create the prev pointers for tex.linebreak&lt;br /&gt;
  node.slide(head)&lt;br /&gt;
  return head&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local txt = &amp;quot;A wonderful serenity has taken possession of my entire soul, ... like mine.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
tex.baselineskip = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
tex.baselineskip.width = 14 * 2^16&lt;br /&gt;
&lt;br /&gt;
local head = mknodes(txt)&lt;br /&gt;
lang.hyphenate(head)&lt;br /&gt;
head = node.kerning(head)&lt;br /&gt;
head = node.ligaturing(head)&lt;br /&gt;
&lt;br /&gt;
local vbox = tex.linebreak(head,{ hsize = tex.sp(&amp;quot;3in&amp;quot;)})&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(You can safely skip this section if you are not interested in the details.)&lt;br /&gt;
&lt;br /&gt;
What has happened in detail? We have created a list of glyph and glue nodes and fed those into the line breaking part of TeX which gave us the vbox back. This vbox contains horizontal lists glued together:&lt;br /&gt;
&lt;br /&gt;
[[File:Paragraph_with_boxes.png|600px]]&lt;br /&gt;
&lt;br /&gt;
The dashed rectangle (vbox) should fit tight to the inner hboxes. It has a small offset just for demonstration purpose.&lt;br /&gt;
&lt;br /&gt;
To show you some of the nodes that TeX inserted for you, have a look at the following image:&lt;br /&gt;
&lt;br /&gt;
[[File:Nodes_in_sample_paragraph.png]]&lt;br /&gt;
&lt;br /&gt;
Here is an explanation of the nodes:&lt;br /&gt;
&lt;br /&gt;
# This is the dashed line in the image above. A paragraph is always vertical&lt;br /&gt;
# The first line. It has a width of three inches, a height and depth of together 8.888 pt&lt;br /&gt;
# The 20pt paragraph indent. This is the first item in the first line (note that the pointer comes from the head item of the node #2&lt;br /&gt;
# The first letter in the first line&lt;br /&gt;
# The interword glue.&lt;br /&gt;
# The second letter in the first line&lt;br /&gt;
# The clubpenalty&lt;br /&gt;
# The baselineskip minus the height of the hbox &amp;quot;above&amp;quot; (8.888pt + 5.111pt is approx. 14pt. The rounding error is due to the display of only few significant digits.) Note that TeX is in vertical mode, as it is the third item in the vbox (#1). &lt;br /&gt;
# The hbox of the second line&lt;br /&gt;
# The first letter of the second line&lt;br /&gt;
# A kern between the m and the y of the first word (second line)&lt;br /&gt;
# The last letter shown here&lt;br /&gt;
&lt;br /&gt;
There are many nodes created in the paragraph which are not shown here. A full view can be found in [[Media:Nodes_in_sample_paragraph_full.pdf|a separate PDF file]].&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=File:Paragraph_with_boxes.png&amp;diff=135</id>
		<title>File:Paragraph with boxes.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=File:Paragraph_with_boxes.png&amp;diff=135"/>
		<updated>2011-07-04T13:01:14Z</updated>

		<summary type="html">&lt;p&gt;Patrick: uploaded a new version of &amp;amp;quot;File:Paragraph with boxes.png&amp;amp;quot;: Numbering as in explanation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A sample paragraph with hboxes and bounding box shown&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=134</id>
		<title>TeX without TeX</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=134"/>
		<updated>2011-07-04T12:49:39Z</updated>

		<summary type="html">&lt;p&gt;Patrick: More explanation on the sample paragraph&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Use TeX&amp;#039;s power without TeX macros ==&lt;br /&gt;
&lt;br /&gt;
With LuaTeX you have access to most of TeX&amp;#039;s capabilities for creating PDF documents. Most of the [http://www.luatex.org/svn/trunk/manual/luatexref-t.pdf LuaTeX reference manual] is about this topic. &lt;br /&gt;
&lt;br /&gt;
The underlying idea is to create TeX&amp;#039;s internal data structure as TeX would do by transforming macros and primitives into something called nodes. These nodes are then transformed into instructions for the PDF file (PDF objects). So the following pages deal with node creation and the structures. &lt;br /&gt;
&lt;br /&gt;
Let&amp;#039;s start with a rule node. When you write &amp;lt;tt&amp;gt;\hrule width 20pt height 10pt depth 10pt &amp;lt;/tt&amp;gt; in TeX, a node of type rule will be created, which has three fields: height, depth and width. We can visualize this node by a simple box like this:&lt;br /&gt;
&lt;br /&gt;
[[File:rulenode.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r.width  = 20 * 65536&lt;br /&gt;
r.height = 10 * 65536&lt;br /&gt;
r.depth  = 10 * 65536&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some remarks: the size is in scaled points, and 65536 (=2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;) scaled points are 1 point, so 20pt becomes 20 * 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;. Not shown in the example are (among others) the next and prev fields. These fields hold a pointer (the node address) to the following and the previous nodes. A node that exist by itself has its prev and next fields set to nil.&lt;br /&gt;
&lt;br /&gt;
A slightly more complicated example is when you create two rules and pack then into a vertical box. This would look like this in plain TeX:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\vbox {\hrule width 20pt height 10pt depth 10pt&lt;br /&gt;
           \hrule width 20pt height 10pt depth 10pt }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would generate a node list like:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Rulenode2.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r1 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r1.width  = 20 * 65536&lt;br /&gt;
r1.height = 10 * 65536&lt;br /&gt;
r1.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r2 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r2.width  = 20 * 65536&lt;br /&gt;
r2.height = 10 * 65536&lt;br /&gt;
r2.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r1.next = r2&lt;br /&gt;
r2.prev = r1&lt;br /&gt;
&lt;br /&gt;
vbox = node.vpack(r1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result is a vbox containing the two rule nodes. The nodes are connected by their next and prev pointers, so the vbox contains them both. The size (width, height and depth) is adjusted automatically.&lt;br /&gt;
&lt;br /&gt;
This also applies to all other things you can put on a TeX page: glyphs, horizontal boxes, math, images, hyperlinks, glue .... For a complete list of the nodes, see the reference manual Chapter 8 &amp;quot;Nodes&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Beyond reports and articles ==&lt;br /&gt;
&lt;br /&gt;
Perhaps the question that comes into your mind is: why should I bother writing Lua code instead of TeX code? For many documents, including articles, reports and books, the classic way to create a PDF with TeX is to use LaTeX or ConTeXt. But there are applications that use TeX as an 100% automatic PDF generation software. If you want to create data sheets or product listings, your normal input is not a classic document, but most likely an Excel spreadsheet or an XML file, perhaps extracted from a database. You won&amp;#039;t have any TeX markup within these documents. So: if you don&amp;#039;t have TeX markup in these documents, you don&amp;#039;t need the TeX interpreter to read these files. More likely is an XML parser or a spreadsheet 2 ... converter.&lt;br /&gt;
&lt;br /&gt;
When you use regular LaTeX or ConTeXt code to put the contents of the database in your PDF (database publishing), you run into several problems:&lt;br /&gt;
&lt;br /&gt;
* Exact positioning of items on the page can be troublesome&lt;br /&gt;
* catcodes / command escapes are to be considered and surely get into your way&lt;br /&gt;
* TeX is no fun to program in (well it is, but only for some people) - calculations, tests, exception handling, control flow&lt;br /&gt;
* The packages that exist may reach their limit soon. You need a super flexible image-between-columns-with-parshape package? Write it yourself.&lt;br /&gt;
&lt;br /&gt;
With Lua you have a very decent programming language that &amp;#039;&amp;#039;is&amp;#039;&amp;#039; fun to program in. When you use the Lua interface to TeX, you have full control of what is happening, which is usually the level of control you need for high quality output.&lt;br /&gt;
&lt;br /&gt;
One approach is to create a stub TeX file and let Lua do the rest:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;myprogram.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The file &amp;lt;tt&amp;gt;myprogram.lua&amp;lt;/tt&amp;gt; then contains all the code to a) read the source file(s), b) extract the information and create the appropriate nodes and c) instruct TeX to create PDF pages from these nodes.&lt;br /&gt;
&lt;br /&gt;
In a future version of LuaTeX you will be able to run the Lua interpreter without the stub TeX file above.&lt;br /&gt;
&lt;br /&gt;
== A first example ==&lt;br /&gt;
&lt;br /&gt;
The example document given below creates two pages by using Lua code alone. You will learn how to access TeX&amp;#039;s boxes and counters from the Lua side, shipout a page into the PDF file, create horizontal and vertical boxes (hbox and vbox), create new nodes and manipulate the nodes links structure. The example covers the following node types: rule, whatsit, vlist, hlist and action.&lt;br /&gt;
&lt;br /&gt;
In the example code we use black squares as the contents of the pages and not normal text, because character handling takes more code and will be covered later on.&lt;br /&gt;
&lt;br /&gt;
Save the following file into &amp;lt;tt&amp;gt;myprogram.lua&amp;lt;/tt&amp;gt; and use the TeX stub from above (or get the source [https://raw.github.com/gist/1062041/d3de082e955f6535f3820742cef76fe9e50d5a6f/myprogram.lua here]).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
  -- this will hold the items that go onto the page&lt;br /&gt;
  local pagelist&lt;br /&gt;
 &lt;br /&gt;
  -- Call tex.shipout() with the contents of the pagelist&lt;br /&gt;
  function shipout()&lt;br /&gt;
&lt;br /&gt;
    local vbox,b = node.vpack(pagelist) -- we ignore the badness &amp;#039;b&amp;#039;&lt;br /&gt;
    tex.box[666] = vbox&lt;br /&gt;
    tex.shipout(666)&lt;br /&gt;
&lt;br /&gt;
    pagelist = nil&lt;br /&gt;
    &lt;br /&gt;
    -- Not strictly necessary. TeX holds the current page number in counter 0.&lt;br /&gt;
    -- TeX displays the contents of this counter when it puts a page into&lt;br /&gt;
    -- the pdf (tex.shipout()). If we don&amp;#039;t change the counter, TeX will&lt;br /&gt;
    -- display [1] [1], instead of [1] [2] for our two page document.&lt;br /&gt;
    tex.count[0] = tex.count[0] + 1&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
  function add_to_page( list )&lt;br /&gt;
    -- We attach the nodelist &amp;#039;list&amp;#039; to the end of the pagelist&lt;br /&gt;
    -- if pagelist doesn&amp;#039;t exist, &amp;#039;list&amp;#039; is our new pagelist&lt;br /&gt;
    -- if it exists, we go to the end with node.tail() and adjust&lt;br /&gt;
    -- the prev and next pointers, so list becomes part&lt;br /&gt;
    -- of pagelist.&lt;br /&gt;
    if not pagelist then pagelist = list&lt;br /&gt;
    else&lt;br /&gt;
      local tail = node.tail(pagelist)&lt;br /&gt;
      tail.next = list&lt;br /&gt;
      list.prev  = tail&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- This creates a new square rule and returns the pointer to it.&lt;br /&gt;
function mkrule( size )&lt;br /&gt;
  local r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
  r.width  = size &lt;br /&gt;
  r.height = size / 2&lt;br /&gt;
  r.depth  = size / 2&lt;br /&gt;
  return r&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
do&lt;br /&gt;
  local destcounter = 0&lt;br /&gt;
  -- Create a pdf anchor (dest object). It returns a whatsit node and the &lt;br /&gt;
  -- number of the anchor, so it can be used in a pdf link or an outline.&lt;br /&gt;
  function mkdest()&lt;br /&gt;
    destcounter = destcounter + 1&lt;br /&gt;
    local d = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_dest&amp;quot;)&lt;br /&gt;
    d.named_id = 0&lt;br /&gt;
    d.dest_id = destcounter&lt;br /&gt;
    d.dest_type = 3&lt;br /&gt;
&lt;br /&gt;
    return d, destcounter&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Take a list of nodes and put them into an hbox. The prev and next fields&lt;br /&gt;
-- of the nodes will be set automatically. Return a pointer to the hbox.&lt;br /&gt;
function hpack( ... )&lt;br /&gt;
  local start, tmp, cur&lt;br /&gt;
  start = select(1,...)&lt;br /&gt;
  tmp = start&lt;br /&gt;
  for i=2,select(&amp;quot;#&amp;quot;,...) do&lt;br /&gt;
    cur = select(i,...)&lt;br /&gt;
    tmp.next = cur&lt;br /&gt;
    cur.prev = tmp&lt;br /&gt;
    tmp = cur&lt;br /&gt;
  end&lt;br /&gt;
  local h,b = node.hpack(start) -- ignore badness&lt;br /&gt;
  return h&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local tenpt = 10 * 2^16&lt;br /&gt;
---------------------------&lt;br /&gt;
-- page 1&lt;br /&gt;
---------------------------&lt;br /&gt;
local n,dest = mkdest() -- dest is needed for the link to this anchor&lt;br /&gt;
&lt;br /&gt;
add_to_page(n)&lt;br /&gt;
add_to_page(mkrule(2 * tenpt))&lt;br /&gt;
&lt;br /&gt;
-- The pagelist contains a pdf dest node (a link destination) and a rule of size 20pt x 20pt.&lt;br /&gt;
&lt;br /&gt;
shipout()&lt;br /&gt;
---------------------------&lt;br /&gt;
-- page 2&lt;br /&gt;
---------------------------&lt;br /&gt;
-- This is the page with the link to the anchor (dest) on page one. A&lt;br /&gt;
-- link consists of three nodes: a pdf_start_link, a pdf_end_link and and &lt;br /&gt;
-- action node that specifies the action to perform when the user clicks on&lt;br /&gt;
-- the link.&lt;br /&gt;
-- The pdf link must be inside a horizontal box, that&amp;#039;s why we hpack() it.&lt;br /&gt;
-- The link_attr (link attributes) is optional, here it draws a yellowish border&lt;br /&gt;
-- around the link.&lt;br /&gt;
local start_link = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_start_link&amp;quot;)&lt;br /&gt;
local end_link   = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_end_link&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
start_link.width     = tenpt&lt;br /&gt;
start_link.height    = tenpt / 2&lt;br /&gt;
start_link.depth     = tenpt / 2&lt;br /&gt;
start_link.link_attr = &amp;quot;/C [0.9 1 0] /Border [0 0 2]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
start_link.action = node.new(&amp;quot;action&amp;quot;)&lt;br /&gt;
start_link.action.action_type = 1&lt;br /&gt;
start_link.action.action_id   = dest&lt;br /&gt;
&lt;br /&gt;
local rule = mkrule(tenpt)&lt;br /&gt;
local hbox = hpack(start_link, rule, end_link)&lt;br /&gt;
add_to_page(hbox)&lt;br /&gt;
&lt;br /&gt;
-- This pagelist consists of an hbox whose contents is &amp;quot;start_link&amp;quot;,&lt;br /&gt;
-- the 10pt x 10pt rule and the &amp;quot;end_link&amp;quot; node. &lt;br /&gt;
&lt;br /&gt;
shipout()&lt;br /&gt;
---------------------------&lt;br /&gt;
&lt;br /&gt;
-- Just to show you that you can get some memory usage statistics:&lt;br /&gt;
print(string.format(&amp;quot;\nnode_mem_usage=%s&amp;quot;,status.node_mem_usage))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The idea is to create nodes, collect them in a list (here: pagelist) and use &amp;lt;tt&amp;gt;tex.shipout()&amp;lt;/tt&amp;gt; to put the page into the PDF.&lt;br /&gt;
&lt;br /&gt;
== And what about &amp;#039;&amp;#039;real&amp;#039;&amp;#039; content? ==&lt;br /&gt;
&lt;br /&gt;
Black squares won&amp;#039;t make anyone happy. So we need a typeset paragraph. For that we start with a single glyph and a glue first. A glyph node has this structure:&lt;br /&gt;
&lt;br /&gt;
[[File:Singleglyphnode.png]]&lt;br /&gt;
&lt;br /&gt;
whereas a glue is more complicated:&lt;br /&gt;
&lt;br /&gt;
[[File:Simplegluenode.png]]&lt;br /&gt;
&lt;br /&gt;
The glue item comes in pairs: a glue node and a glue_spec node. The information about the shrink/stretch values go into the glue_spec node. For example, the TeX glue &amp;lt;tt&amp;gt;2pt plus 1fill&amp;lt;/tt&amp;gt; has a width of 2*2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;, a stretch of 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt; and a stretch_order of 3. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local g = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g.font = font.current()&lt;br /&gt;
g.lang = tex.language&lt;br /&gt;
g.char = 86 -- V&lt;br /&gt;
&lt;br /&gt;
local hbox = node.hpack(g)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We create a glyph, pack it into an hbox (horizontal box), pack that hbox into a vbox (a vertical box) and write this box to the main vertical list. The char number (86 in the example above) is based on an internal encoding, so we have to keep an eye on what character is on what position. Now we do this for two glyphs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local g1 = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g1.font = font.current()&lt;br /&gt;
g1.lang = tex.language&lt;br /&gt;
g1.char = 86&lt;br /&gt;
&lt;br /&gt;
local g2 = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g2.font = font.current()&lt;br /&gt;
g2.lang = tex.language&lt;br /&gt;
g2.char = 97&lt;br /&gt;
&lt;br /&gt;
g1.next = g2&lt;br /&gt;
g2.prev = g1&lt;br /&gt;
&lt;br /&gt;
local hbox = node.hpack(g1)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pretty much the same as above. The glyphs g1 and g2 are chained together by setting the next and prev pointer to each other. If they were not connected, only glyph g1 gets into the hbox.&lt;br /&gt;
&lt;br /&gt;
If you take a close look at the PDF, you see that the two glyphs are too far away, a (negative) kern should be inserted. This can be done by inserting a kern-node manually or you can ask TeX to do that for you. The last lines of the example above should then read:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local head,tail,success = node.kerning(g1)&lt;br /&gt;
local hbox = node.hpack(head)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this approach you are able to put some glyphs into the PDF but you will run into problems when you want to create a whole paragraph. It is much easier to ask TeX to do the line breaking. The steps for paragraph creation are&lt;br /&gt;
&lt;br /&gt;
# put glyph nodes and glue nodes in a list (= chain them together with the prev/next pointers)&lt;br /&gt;
# add trailing infinite penalty and parfillskip&lt;br /&gt;
# call lang.hyphenate(), node.kerning() and node.ligaturing() to prepare the list for the linebreaking job&lt;br /&gt;
# call tex.linebreak()&lt;br /&gt;
&lt;br /&gt;
For the next task we want to create the following paragraph:&lt;br /&gt;
&lt;br /&gt;
[[File:Sample_paragraph.png|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We start with the small TeX stub as above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;myprogram.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and myprogram.lua ([https://gist.github.com/1063228 download]) defines a function &amp;lt;tt&amp;gt;mknodes()&amp;lt;/tt&amp;gt; that creates the list of nodes to be passed into the typesetter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function mknodes( text )&lt;br /&gt;
  local current_font = font.current()&lt;br /&gt;
  local font_parameters = font.getfont(current_font).parameters&lt;br /&gt;
  local n, head, last&lt;br /&gt;
  for s in string.utfvalues( text ) do&lt;br /&gt;
    local char = unicode.utf8.char(s)&lt;br /&gt;
    if unicode.utf8.match(char,&amp;quot;%s&amp;quot;) then&lt;br /&gt;
      -- its a space&lt;br /&gt;
      n = node.new(&amp;quot;glue&amp;quot;)&lt;br /&gt;
      n.spec = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
      n.spec.width   = font_parameters.space&lt;br /&gt;
      n.spec.shrink  = font_parameters.space_shrink&lt;br /&gt;
      n.spec.stretch = font_parameters.space_stretch&lt;br /&gt;
    else -- a glyph&lt;br /&gt;
      n = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
      n.font = current_font&lt;br /&gt;
      n.subtype = 1&lt;br /&gt;
      n.char = s&lt;br /&gt;
      n.lang = tex.language&lt;br /&gt;
      n.uchyph = 1&lt;br /&gt;
      n.left = tex.lefthyphenmin&lt;br /&gt;
      n.right = tex.righthyphenmin&lt;br /&gt;
    end&lt;br /&gt;
    if head then&lt;br /&gt;
      last.next = n&lt;br /&gt;
    else&lt;br /&gt;
      head = n&lt;br /&gt;
    end&lt;br /&gt;
    last = n&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  -- now add the final parts: a penalty and the parfillskip glue&lt;br /&gt;
  local penalty = node.new(&amp;quot;penalty&amp;quot;)&lt;br /&gt;
  penalty.penalty = 10000&lt;br /&gt;
&lt;br /&gt;
  local parfillskip = node.new(&amp;quot;glue&amp;quot;)&lt;br /&gt;
  parfillskip.spec = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
  parfillskip.spec.stretch = 2^16&lt;br /&gt;
  parfillskip.spec.stretch_order = 2&lt;br /&gt;
  &lt;br /&gt;
  last.next = penalty&lt;br /&gt;
  penalty.next = parfillskip&lt;br /&gt;
&lt;br /&gt;
  -- just to create the prev pointers for tex.linebreak&lt;br /&gt;
  node.slide(head)&lt;br /&gt;
  return head&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local txt = &amp;quot;A wonderful serenity has taken possession of my entire soul, ... like mine.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
tex.baselineskip = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
tex.baselineskip.width = 14 * 2^16&lt;br /&gt;
&lt;br /&gt;
local head = mknodes(txt)&lt;br /&gt;
lang.hyphenate(head)&lt;br /&gt;
head = node.kerning(head)&lt;br /&gt;
head = node.ligaturing(head)&lt;br /&gt;
&lt;br /&gt;
local vbox = tex.linebreak(head,{ hsize = tex.sp(&amp;quot;3in&amp;quot;)})&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(You can safely skip this section if you are not interested in the details.)&lt;br /&gt;
&lt;br /&gt;
What has happened in detail? We have created a list of glyph and glue nodes and fed those into the line breaking part of TeX which gave us the vbox back. This vbox contains horizontal lists glued together:&lt;br /&gt;
&lt;br /&gt;
[[File:Paragraph_with_boxes.png]]&lt;br /&gt;
&lt;br /&gt;
The dashed rectangle (vbox) should fit tight to the inner hboxes. It has a small offset just for demonstration purpose.&lt;br /&gt;
&lt;br /&gt;
To show you some of the nodes that TeX inserted for you, have a look at the following image:&lt;br /&gt;
&lt;br /&gt;
[[File:Nodes_in_sample_paragraph.png]]&lt;br /&gt;
&lt;br /&gt;
Here is an explanation of the nodes:&lt;br /&gt;
&lt;br /&gt;
# This is the dashed line in the image above. A paragraph is always vertical&lt;br /&gt;
# The first line. It has a width of three inches, a height and depth of together 8.888 pt&lt;br /&gt;
# The 20pt paragraph indent. This is the first item in the first line (note that the pointer comes from the head item of the node #2&lt;br /&gt;
# The first letter in the first line&lt;br /&gt;
# The interword glue.&lt;br /&gt;
# The second letter in the first line&lt;br /&gt;
# The clubpenalty&lt;br /&gt;
# The baselineskip minus the height of the hbox &amp;quot;above&amp;quot; (8.888pt + 5.111pt is approx. 14pt. The rounding error is due to the display of only few significant digits.) Note that TeX is in vertical mode, as it is the third item in the vbox (#1). &lt;br /&gt;
# The hbox of the second line&lt;br /&gt;
# The first letter of the second line&lt;br /&gt;
# A kern between the m and the y of the first word (second line)&lt;br /&gt;
# The last letter shown here&lt;br /&gt;
&lt;br /&gt;
There are many nodes created in the paragraph which are not shown here. A full view can be found in [[Media:Nodes_in_sample_paragraph_full.pdf|a separate PDF file]].&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=File:Nodes_in_sample_paragraph_full.pdf&amp;diff=133</id>
		<title>File:Nodes in sample paragraph full.pdf</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=File:Nodes_in_sample_paragraph_full.pdf&amp;diff=133"/>
		<updated>2011-07-04T12:44:17Z</updated>

		<summary type="html">&lt;p&gt;Patrick: lots of nodes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;lots of nodes&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=File:Nodes_in_sample_paragraph.png&amp;diff=132</id>
		<title>File:Nodes in sample paragraph.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=File:Nodes_in_sample_paragraph.png&amp;diff=132"/>
		<updated>2011-07-04T12:30:26Z</updated>

		<summary type="html">&lt;p&gt;Patrick: The nodes in the sample paragraph&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The nodes in the sample paragraph&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=File:Paragraph_with_boxes.png&amp;diff=131</id>
		<title>File:Paragraph with boxes.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=File:Paragraph_with_boxes.png&amp;diff=131"/>
		<updated>2011-07-04T11:34:29Z</updated>

		<summary type="html">&lt;p&gt;Patrick: A sample paragraph with hboxes and bounding box shown&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A sample paragraph with hboxes and bounding box shown&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=130</id>
		<title>TeX without TeX</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=130"/>
		<updated>2011-07-04T11:31:27Z</updated>

		<summary type="html">&lt;p&gt;Patrick: paragraph with tex.shipout()&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Use TeX&amp;#039;s power without TeX macros ==&lt;br /&gt;
&lt;br /&gt;
With LuaTeX you have access to most of TeX&amp;#039;s capabilities for creating PDF documents. Most of the [http://www.luatex.org/svn/trunk/manual/luatexref-t.pdf LuaTeX reference manual] is about this topic. &lt;br /&gt;
&lt;br /&gt;
The underlying idea is to create TeX&amp;#039;s internal data structure as TeX would do by transforming macros and primitives into something called nodes. These nodes are then transformed into instructions for the PDF file (PDF objects). So the following pages deal with node creation and the structures. &lt;br /&gt;
&lt;br /&gt;
Let&amp;#039;s start with a rule node. When you write &amp;lt;tt&amp;gt;\hrule width 20pt height 10pt depth 10pt &amp;lt;/tt&amp;gt; in TeX, a node of type rule will be created, which has three fields: height, depth and width. We can visualize this node by a simple box like this:&lt;br /&gt;
&lt;br /&gt;
[[File:rulenode.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r.width  = 20 * 65536&lt;br /&gt;
r.height = 10 * 65536&lt;br /&gt;
r.depth  = 10 * 65536&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some remarks: the size is in scaled points, and 65536 (=2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;) scaled points are 1 point, so 20pt becomes 20 * 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;. Not shown in the example are (among others) the next and prev fields. These fields hold a pointer (the node address) to the following and the previous nodes. A node that exist by itself has its prev and next fields set to nil.&lt;br /&gt;
&lt;br /&gt;
A slightly more complicated example is when you create two rules and pack then into a vertical box. This would look like this in plain TeX:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\vbox {\hrule width 20pt height 10pt depth 10pt&lt;br /&gt;
           \hrule width 20pt height 10pt depth 10pt }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would generate a node list like:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Rulenode2.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r1 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r1.width  = 20 * 65536&lt;br /&gt;
r1.height = 10 * 65536&lt;br /&gt;
r1.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r2 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r2.width  = 20 * 65536&lt;br /&gt;
r2.height = 10 * 65536&lt;br /&gt;
r2.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r1.next = r2&lt;br /&gt;
r2.prev = r1&lt;br /&gt;
&lt;br /&gt;
vbox = node.vpack(r1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result is a vbox containing the two rule nodes. The nodes are connected by their next and prev pointers, so the vbox contains them both. The size (width, height and depth) is adjusted automatically.&lt;br /&gt;
&lt;br /&gt;
This also applies to all other things you can put on a TeX page: glyphs, horizontal boxes, math, images, hyperlinks, glue .... For a complete list of the nodes, see the reference manual Chapter 8 &amp;quot;Nodes&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Beyond reports and articles ==&lt;br /&gt;
&lt;br /&gt;
Perhaps the question that comes into your mind is: why should I bother writing Lua code instead of TeX code? For many documents, including articles, reports and books, the classic way to create a PDF with TeX is to use LaTeX or ConTeXt. But there are applications that use TeX as an 100% automatic PDF generation software. If you want to create data sheets or product listings, your normal input is not a classic document, but most likely an Excel spreadsheet or an XML file, perhaps extracted from a database. You won&amp;#039;t have any TeX markup within these documents. So: if you don&amp;#039;t have TeX markup in these documents, you don&amp;#039;t need the TeX interpreter to read these files. More likely is an XML parser or a spreadsheet 2 ... converter.&lt;br /&gt;
&lt;br /&gt;
When you use regular LaTeX or ConTeXt code to put the contents of the database in your PDF (database publishing), you run into several problems:&lt;br /&gt;
&lt;br /&gt;
* Exact positioning of items on the page can be troublesome&lt;br /&gt;
* catcodes / command escapes are to be considered and surely get into your way&lt;br /&gt;
* TeX is no fun to program in (well it is, but only for some people) - calculations, tests, exception handling, control flow&lt;br /&gt;
* The packages that exist may reach their limit soon. You need a super flexible image-between-columns-with-parshape package? Write it yourself.&lt;br /&gt;
&lt;br /&gt;
With Lua you have a very decent programming language that &amp;#039;&amp;#039;is&amp;#039;&amp;#039; fun to program in. When you use the Lua interface to TeX, you have full control of what is happening, which is usually the level of control you need for high quality output.&lt;br /&gt;
&lt;br /&gt;
One approach is to create a stub TeX file and let Lua do the rest:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;myprogram.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The file &amp;lt;tt&amp;gt;myprogram.lua&amp;lt;/tt&amp;gt; then contains all the code to a) read the source file(s), b) extract the information and create the appropriate nodes and c) instruct TeX to create PDF pages from these nodes.&lt;br /&gt;
&lt;br /&gt;
In a future version of LuaTeX you will be able to run the Lua interpreter without the stub TeX file above.&lt;br /&gt;
&lt;br /&gt;
== A first example ==&lt;br /&gt;
&lt;br /&gt;
The example document given below creates two pages by using Lua code alone. You will learn how to access TeX&amp;#039;s boxes and counters from the Lua side, shipout a page into the PDF file, create horizontal and vertical boxes (hbox and vbox), create new nodes and manipulate the nodes links structure. The example covers the following node types: rule, whatsit, vlist, hlist and action.&lt;br /&gt;
&lt;br /&gt;
In the example code we use black squares as the contents of the pages and not normal text, because character handling takes more code and will be covered later on.&lt;br /&gt;
&lt;br /&gt;
Save the following file into &amp;lt;tt&amp;gt;myprogram.lua&amp;lt;/tt&amp;gt; and use the TeX stub from above (or get the source [https://raw.github.com/gist/1062041/d3de082e955f6535f3820742cef76fe9e50d5a6f/myprogram.lua here]).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
  -- this will hold the items that go onto the page&lt;br /&gt;
  local pagelist&lt;br /&gt;
 &lt;br /&gt;
  -- Call tex.shipout() with the contents of the pagelist&lt;br /&gt;
  function shipout()&lt;br /&gt;
&lt;br /&gt;
    local vbox,b = node.vpack(pagelist) -- we ignore the badness &amp;#039;b&amp;#039;&lt;br /&gt;
    tex.box[666] = vbox&lt;br /&gt;
    tex.shipout(666)&lt;br /&gt;
&lt;br /&gt;
    pagelist = nil&lt;br /&gt;
    &lt;br /&gt;
    -- Not strictly necessary. TeX holds the current page number in counter 0.&lt;br /&gt;
    -- TeX displays the contents of this counter when it puts a page into&lt;br /&gt;
    -- the pdf (tex.shipout()). If we don&amp;#039;t change the counter, TeX will&lt;br /&gt;
    -- display [1] [1], instead of [1] [2] for our two page document.&lt;br /&gt;
    tex.count[0] = tex.count[0] + 1&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
  function add_to_page( list )&lt;br /&gt;
    -- We attach the nodelist &amp;#039;list&amp;#039; to the end of the pagelist&lt;br /&gt;
    -- if pagelist doesn&amp;#039;t exist, &amp;#039;list&amp;#039; is our new pagelist&lt;br /&gt;
    -- if it exists, we go to the end with node.tail() and adjust&lt;br /&gt;
    -- the prev and next pointers, so list becomes part&lt;br /&gt;
    -- of pagelist.&lt;br /&gt;
    if not pagelist then pagelist = list&lt;br /&gt;
    else&lt;br /&gt;
      local tail = node.tail(pagelist)&lt;br /&gt;
      tail.next = list&lt;br /&gt;
      list.prev  = tail&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- This creates a new square rule and returns the pointer to it.&lt;br /&gt;
function mkrule( size )&lt;br /&gt;
  local r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
  r.width  = size &lt;br /&gt;
  r.height = size / 2&lt;br /&gt;
  r.depth  = size / 2&lt;br /&gt;
  return r&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
do&lt;br /&gt;
  local destcounter = 0&lt;br /&gt;
  -- Create a pdf anchor (dest object). It returns a whatsit node and the &lt;br /&gt;
  -- number of the anchor, so it can be used in a pdf link or an outline.&lt;br /&gt;
  function mkdest()&lt;br /&gt;
    destcounter = destcounter + 1&lt;br /&gt;
    local d = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_dest&amp;quot;)&lt;br /&gt;
    d.named_id = 0&lt;br /&gt;
    d.dest_id = destcounter&lt;br /&gt;
    d.dest_type = 3&lt;br /&gt;
&lt;br /&gt;
    return d, destcounter&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Take a list of nodes and put them into an hbox. The prev and next fields&lt;br /&gt;
-- of the nodes will be set automatically. Return a pointer to the hbox.&lt;br /&gt;
function hpack( ... )&lt;br /&gt;
  local start, tmp, cur&lt;br /&gt;
  start = select(1,...)&lt;br /&gt;
  tmp = start&lt;br /&gt;
  for i=2,select(&amp;quot;#&amp;quot;,...) do&lt;br /&gt;
    cur = select(i,...)&lt;br /&gt;
    tmp.next = cur&lt;br /&gt;
    cur.prev = tmp&lt;br /&gt;
    tmp = cur&lt;br /&gt;
  end&lt;br /&gt;
  local h,b = node.hpack(start) -- ignore badness&lt;br /&gt;
  return h&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local tenpt = 10 * 2^16&lt;br /&gt;
---------------------------&lt;br /&gt;
-- page 1&lt;br /&gt;
---------------------------&lt;br /&gt;
local n,dest = mkdest() -- dest is needed for the link to this anchor&lt;br /&gt;
&lt;br /&gt;
add_to_page(n)&lt;br /&gt;
add_to_page(mkrule(2 * tenpt))&lt;br /&gt;
&lt;br /&gt;
-- The pagelist contains a pdf dest node (a link destination) and a rule of size 20pt x 20pt.&lt;br /&gt;
&lt;br /&gt;
shipout()&lt;br /&gt;
---------------------------&lt;br /&gt;
-- page 2&lt;br /&gt;
---------------------------&lt;br /&gt;
-- This is the page with the link to the anchor (dest) on page one. A&lt;br /&gt;
-- link consists of three nodes: a pdf_start_link, a pdf_end_link and and &lt;br /&gt;
-- action node that specifies the action to perform when the user clicks on&lt;br /&gt;
-- the link.&lt;br /&gt;
-- The pdf link must be inside a horizontal box, that&amp;#039;s why we hpack() it.&lt;br /&gt;
-- The link_attr (link attributes) is optional, here it draws a yellowish border&lt;br /&gt;
-- around the link.&lt;br /&gt;
local start_link = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_start_link&amp;quot;)&lt;br /&gt;
local end_link   = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_end_link&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
start_link.width     = tenpt&lt;br /&gt;
start_link.height    = tenpt / 2&lt;br /&gt;
start_link.depth     = tenpt / 2&lt;br /&gt;
start_link.link_attr = &amp;quot;/C [0.9 1 0] /Border [0 0 2]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
start_link.action = node.new(&amp;quot;action&amp;quot;)&lt;br /&gt;
start_link.action.action_type = 1&lt;br /&gt;
start_link.action.action_id   = dest&lt;br /&gt;
&lt;br /&gt;
local rule = mkrule(tenpt)&lt;br /&gt;
local hbox = hpack(start_link, rule, end_link)&lt;br /&gt;
add_to_page(hbox)&lt;br /&gt;
&lt;br /&gt;
-- This pagelist consists of an hbox whose contents is &amp;quot;start_link&amp;quot;,&lt;br /&gt;
-- the 10pt x 10pt rule and the &amp;quot;end_link&amp;quot; node. &lt;br /&gt;
&lt;br /&gt;
shipout()&lt;br /&gt;
---------------------------&lt;br /&gt;
&lt;br /&gt;
-- Just to show you that you can get some memory usage statistics:&lt;br /&gt;
print(string.format(&amp;quot;\nnode_mem_usage=%s&amp;quot;,status.node_mem_usage))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The idea is to create nodes, collect them in a list (here: pagelist) and use &amp;lt;tt&amp;gt;tex.shipout()&amp;lt;/tt&amp;gt; to put the page into the PDF.&lt;br /&gt;
&lt;br /&gt;
== And what about &amp;#039;&amp;#039;real&amp;#039;&amp;#039; content? ==&lt;br /&gt;
&lt;br /&gt;
Black squares won&amp;#039;t make anyone happy. So we need a typeset paragraph. For that we start with a single glyph and a glue first. A glyph node has this structure:&lt;br /&gt;
&lt;br /&gt;
[[File:Singleglyphnode.png]]&lt;br /&gt;
&lt;br /&gt;
whereas a glue is more complicated:&lt;br /&gt;
&lt;br /&gt;
[[File:Simplegluenode.png]]&lt;br /&gt;
&lt;br /&gt;
The glue item comes in pairs: a glue node and a glue_spec node. The information about the shrink/stretch values go into the glue_spec node. For example, the TeX glue &amp;lt;tt&amp;gt;2pt plus 1fill&amp;lt;/tt&amp;gt; has a width of 2*2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;, a stretch of 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt; and a stretch_order of 3. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local g = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g.font = font.current()&lt;br /&gt;
g.lang = tex.language&lt;br /&gt;
g.char = 86 -- V&lt;br /&gt;
&lt;br /&gt;
local hbox = node.hpack(g)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We create a glyph, pack it into an hbox (horizontal box), pack that hbox into a vbox (a vertical box) and write this box to the main vertical list. The char number (86 in the example above) is based on an internal encoding, so we have to keep an eye on what character is on what position. Now we do this for two glyphs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local g1 = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g1.font = font.current()&lt;br /&gt;
g1.lang = tex.language&lt;br /&gt;
g1.char = 86&lt;br /&gt;
&lt;br /&gt;
local g2 = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g2.font = font.current()&lt;br /&gt;
g2.lang = tex.language&lt;br /&gt;
g2.char = 97&lt;br /&gt;
&lt;br /&gt;
g1.next = g2&lt;br /&gt;
g2.prev = g1&lt;br /&gt;
&lt;br /&gt;
local hbox = node.hpack(g1)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pretty much the same as above. The glyphs g1 and g2 are chained together by setting the next and prev pointer to each other. If they were not connected, only glyph g1 gets into the hbox.&lt;br /&gt;
&lt;br /&gt;
If you take a close look at the PDF, you see that the two glyphs are too far away, a (negative) kern should be inserted. This can be done by inserting a kern-node manually or you can ask TeX to do that for you. The last lines of the example above should then read:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local head,tail,success = node.kerning(g1)&lt;br /&gt;
local hbox = node.hpack(head)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this approach you are able to put some glyphs into the PDF but you will run into problems when you want to create a whole paragraph. It is much easier to ask TeX to do the line breaking. The steps for paragraph creation are&lt;br /&gt;
&lt;br /&gt;
# put glyph nodes and glue nodes in a list (= chain them together with the prev/next pointers)&lt;br /&gt;
# add trailing infinite penalty and parfillskip&lt;br /&gt;
# call lang.hyphenate(), node.kerning() and node.ligaturing() to prepare the list for the linebreaking job&lt;br /&gt;
# call tex.linebreak()&lt;br /&gt;
&lt;br /&gt;
For the next task we want to create the following paragraph:&lt;br /&gt;
&lt;br /&gt;
[[File:Sample_paragraph.png|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We start with the small TeX stub as above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;myprogram.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and myprogram.lua ([https://gist.github.com/1063228 download]) defines a function &amp;lt;tt&amp;gt;mknodes()&amp;lt;/tt&amp;gt; that creates the list of nodes to be passed into the typesetter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function mknodes( text )&lt;br /&gt;
  local current_font = font.current()&lt;br /&gt;
  local font_parameters = font.getfont(current_font).parameters&lt;br /&gt;
  local n, head, last&lt;br /&gt;
  for s in string.utfvalues( text ) do&lt;br /&gt;
    local char = unicode.utf8.char(s)&lt;br /&gt;
    if unicode.utf8.match(char,&amp;quot;%s&amp;quot;) then&lt;br /&gt;
      -- its a space&lt;br /&gt;
      n = node.new(&amp;quot;glue&amp;quot;)&lt;br /&gt;
      n.spec = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
      n.spec.width   = font_parameters.space&lt;br /&gt;
      n.spec.shrink  = font_parameters.space_shrink&lt;br /&gt;
      n.spec.stretch = font_parameters.space_stretch&lt;br /&gt;
    else -- a glyph&lt;br /&gt;
      n = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
      n.font = current_font&lt;br /&gt;
      n.subtype = 1&lt;br /&gt;
      n.char = s&lt;br /&gt;
      n.lang = tex.language&lt;br /&gt;
      n.uchyph = 1&lt;br /&gt;
      n.left = tex.lefthyphenmin&lt;br /&gt;
      n.right = tex.righthyphenmin&lt;br /&gt;
    end&lt;br /&gt;
    if head then&lt;br /&gt;
      last.next = n&lt;br /&gt;
    else&lt;br /&gt;
      head = n&lt;br /&gt;
    end&lt;br /&gt;
    last = n&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  -- now add the final parts: a penalty and the parfillskip glue&lt;br /&gt;
  local penalty = node.new(&amp;quot;penalty&amp;quot;)&lt;br /&gt;
  penalty.penalty = 10000&lt;br /&gt;
&lt;br /&gt;
  local parfillskip = node.new(&amp;quot;glue&amp;quot;)&lt;br /&gt;
  parfillskip.spec = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
  parfillskip.spec.stretch = 2^16&lt;br /&gt;
  parfillskip.spec.stretch_order = 2&lt;br /&gt;
  &lt;br /&gt;
  last.next = penalty&lt;br /&gt;
  penalty.next = parfillskip&lt;br /&gt;
&lt;br /&gt;
  -- just to create the prev pointers for tex.linebreak&lt;br /&gt;
  node.slide(head)&lt;br /&gt;
  return head&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local txt = &amp;quot;A wonderful serenity has taken possession of my entire soul, ... like mine.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
tex.baselineskip = node.new(&amp;quot;glue_spec&amp;quot;)&lt;br /&gt;
tex.baselineskip.width = 14 * 2^16&lt;br /&gt;
&lt;br /&gt;
local head = mknodes(txt)&lt;br /&gt;
lang.hyphenate(head)&lt;br /&gt;
head = node.kerning(head)&lt;br /&gt;
head = node.ligaturing(head)&lt;br /&gt;
&lt;br /&gt;
local vbox = tex.linebreak(head,{ hsize = tex.sp(&amp;quot;3in&amp;quot;)})&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=File:Sample_paragraph.png&amp;diff=129</id>
		<title>File:Sample paragraph.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=File:Sample_paragraph.png&amp;diff=129"/>
		<updated>2011-07-04T10:36:21Z</updated>

		<summary type="html">&lt;p&gt;Patrick: a simple paragraph&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;a simple paragraph&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=128</id>
		<title>TeX without TeX</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=128"/>
		<updated>2011-07-03T20:04:56Z</updated>

		<summary type="html">&lt;p&gt;Patrick: typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Use TeX&amp;#039;s power without TeX macros ==&lt;br /&gt;
&lt;br /&gt;
With LuaTeX you have access to most of TeX&amp;#039;s capabilities for creating PDF documents. Most of the [http://www.luatex.org/svn/trunk/manual/luatexref-t.pdf LuaTeX reference manual] is about this topic. &lt;br /&gt;
&lt;br /&gt;
The underlying idea is to create TeX&amp;#039;s internal data structure as TeX would do by transforming macros and primitives into something called nodes. These nodes are then transformed into instructions for the PDF file (PDF objects). So the following pages deal with node creation and the structures. &lt;br /&gt;
&lt;br /&gt;
Let&amp;#039;s start with a rule node. When you write &amp;lt;tt&amp;gt;\hrule width 20pt height 10pt depth 10pt &amp;lt;/tt&amp;gt; in TeX, a node of type rule will be created, which has three fields: height, depth and width. We can visualize this node by a simple box like this:&lt;br /&gt;
&lt;br /&gt;
[[File:rulenode.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r.width  = 20 * 65536&lt;br /&gt;
r.height = 10 * 65536&lt;br /&gt;
r.depth  = 10 * 65536&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some remarks: the size is in scaled points, and 65536 (=2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;) scaled points are 1 point, so 20pt becomes 20 * 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;. Not shown in the example are (among others) the next and prev fields. These fields hold a pointer (the node address) to the following and the previous nodes. A node that exist by itself has its prev and next fields set to nil.&lt;br /&gt;
&lt;br /&gt;
A slightly more complicated example is when you create two rules and pack then into a vertical box. This would look like this in plain TeX:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\vbox {\hrule width 20pt height 10pt depth 10pt&lt;br /&gt;
           \hrule width 20pt height 10pt depth 10pt }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would generate a node list like:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Rulenode2.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r1 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r1.width  = 20 * 65536&lt;br /&gt;
r1.height = 10 * 65536&lt;br /&gt;
r1.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r2 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r2.width  = 20 * 65536&lt;br /&gt;
r2.height = 10 * 65536&lt;br /&gt;
r2.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r1.next = r2&lt;br /&gt;
r2.prev = r1&lt;br /&gt;
&lt;br /&gt;
vbox = node.vpack(r1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result is a vbox containing the two rule nodes. The nodes are connected by their next and prev pointers, so the vbox contains them both. The size (width, height and depth) is adjusted automatically.&lt;br /&gt;
&lt;br /&gt;
This also applies to all other things you can put on a TeX page: glyphs, horizontal boxes, math, images, hyperlinks, glue .... For a complete list of the nodes, see the reference manual Chapter 8 &amp;quot;Nodes&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Beyond reports and articles ==&lt;br /&gt;
&lt;br /&gt;
Perhaps the question that comes into your mind is: why should I bother writing Lua code instead of TeX code? For many documents, including articles, reports and books, the classic way to create a PDF with TeX is to use LaTeX or ConTeXt. But there are applications that use TeX as an 100% automatic PDF generation software. If you want to create data sheets or product listings, your normal input is not a classic document, but most likely an Excel spreadsheet or an XML file, perhaps extracted from a database. You won&amp;#039;t have any TeX markup within these documents. So: if you don&amp;#039;t have TeX markup in these documents, you don&amp;#039;t need the TeX interpreter to read these files. More likely is an XML parser or a spreadsheet 2 ... converter.&lt;br /&gt;
&lt;br /&gt;
When you use regular LaTeX or ConTeXt code to put the contents of the database in your PDF (database publishing), you run into several problems:&lt;br /&gt;
&lt;br /&gt;
* Exact positioning of items on the page can be troublesome&lt;br /&gt;
* catcodes / command escapes are to be considered and surely get into your way&lt;br /&gt;
* TeX is no fun to program in (well it is, but only for some people) - calculations, tests, exception handling, control flow&lt;br /&gt;
* The packages that exist may reach their limit soon. You need a super flexible image-between-columns-with-parshape package? Write it yourself.&lt;br /&gt;
&lt;br /&gt;
With Lua you have a very decent programming language that &amp;#039;&amp;#039;is&amp;#039;&amp;#039; fun to program in. When you use the Lua interface to TeX, you have full control of what is happening, which is usually the level of control you need for high quality output.&lt;br /&gt;
&lt;br /&gt;
One approach is to create a stub TeX file and let Lua do the rest:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;myprogram.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The file &amp;lt;tt&amp;gt;myprogram.lua&amp;lt;/tt&amp;gt; then contains all the code to a) read the source file(s), b) extract the information and create the appropriate nodes and c) instruct TeX to create PDF pages from these nodes.&lt;br /&gt;
&lt;br /&gt;
In a future version of LuaTeX you will be able to run the Lua interpreter without the stub TeX file above.&lt;br /&gt;
&lt;br /&gt;
== A first example ==&lt;br /&gt;
&lt;br /&gt;
The example document given below creates two pages by using Lua code alone. You will learn how to access TeX&amp;#039;s boxes and counters from the Lua side, shipout a page into the PDF file, create horizontal and vertical boxes (hbox and vbox), create new nodes and manipulate the nodes links structure. The example covers the following node types: rule, whatsit, vlist, hlist and action.&lt;br /&gt;
&lt;br /&gt;
In the example code we use black squares as the contents of the pages and not normal text, because character handling takes more code and will be covered later on.&lt;br /&gt;
&lt;br /&gt;
Save the following file into &amp;lt;tt&amp;gt;myprogram.lua&amp;lt;/tt&amp;gt; and use the TeX stub from above (or get the source [https://raw.github.com/gist/1062041/d3de082e955f6535f3820742cef76fe9e50d5a6f/myprogram.lua here]).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
  -- this will hold the items that go onto the page&lt;br /&gt;
  local pagelist&lt;br /&gt;
 &lt;br /&gt;
  -- Call tex.shipout() with the contents of the pagelist&lt;br /&gt;
  function shipout()&lt;br /&gt;
&lt;br /&gt;
    local vbox,b = node.vpack(pagelist) -- we ignore the badness &amp;#039;b&amp;#039;&lt;br /&gt;
    tex.box[666] = vbox&lt;br /&gt;
    tex.shipout(666)&lt;br /&gt;
&lt;br /&gt;
    pagelist = nil&lt;br /&gt;
    &lt;br /&gt;
    -- Not strictly necessary. TeX holds the current page number in counter 0.&lt;br /&gt;
    -- TeX displays the contents of this counter when it puts a page into&lt;br /&gt;
    -- the pdf (tex.shipout()). If we don&amp;#039;t change the counter, TeX will&lt;br /&gt;
    -- display [1] [1], instead of [1] [2] for our two page document.&lt;br /&gt;
    tex.count[0] = tex.count[0] + 1&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
  function add_to_page( list )&lt;br /&gt;
    -- We attach the nodelist &amp;#039;list&amp;#039; to the end of the pagelist&lt;br /&gt;
    -- if pagelist doesn&amp;#039;t exist, &amp;#039;list&amp;#039; is our new pagelist&lt;br /&gt;
    -- if it exists, we go to the end with node.tail() and adjust&lt;br /&gt;
    -- the prev and next pointers, so list becomes part&lt;br /&gt;
    -- of pagelist.&lt;br /&gt;
    if not pagelist then pagelist = list&lt;br /&gt;
    else&lt;br /&gt;
      local tail = node.tail(pagelist)&lt;br /&gt;
      tail.next = list&lt;br /&gt;
      list.prev  = tail&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- This creates a new square rule and returns the pointer to it.&lt;br /&gt;
function mkrule( size )&lt;br /&gt;
  local r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
  r.width  = size &lt;br /&gt;
  r.height = size / 2&lt;br /&gt;
  r.depth  = size / 2&lt;br /&gt;
  return r&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
do&lt;br /&gt;
  local destcounter = 0&lt;br /&gt;
  -- Create a pdf anchor (dest object). It returns a whatsit node and the &lt;br /&gt;
  -- number of the anchor, so it can be used in a pdf link or an outline.&lt;br /&gt;
  function mkdest()&lt;br /&gt;
    destcounter = destcounter + 1&lt;br /&gt;
    local d = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_dest&amp;quot;)&lt;br /&gt;
    d.named_id = 0&lt;br /&gt;
    d.dest_id = destcounter&lt;br /&gt;
    d.dest_type = 3&lt;br /&gt;
&lt;br /&gt;
    return d, destcounter&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Take a list of nodes and put them into an hbox. The prev and next fields&lt;br /&gt;
-- of the nodes will be set automatically. Return a pointer to the hbox.&lt;br /&gt;
function hpack( ... )&lt;br /&gt;
  local start, tmp, cur&lt;br /&gt;
  start = select(1,...)&lt;br /&gt;
  tmp = start&lt;br /&gt;
  for i=2,select(&amp;quot;#&amp;quot;,...) do&lt;br /&gt;
    cur = select(i,...)&lt;br /&gt;
    tmp.next = cur&lt;br /&gt;
    cur.prev = tmp&lt;br /&gt;
    tmp = cur&lt;br /&gt;
  end&lt;br /&gt;
  local h,b = node.hpack(start) -- ignore badness&lt;br /&gt;
  return h&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local tenpt = 10 * 2^16&lt;br /&gt;
---------------------------&lt;br /&gt;
-- page 1&lt;br /&gt;
---------------------------&lt;br /&gt;
local n,dest = mkdest() -- dest is needed for the link to this anchor&lt;br /&gt;
&lt;br /&gt;
add_to_page(n)&lt;br /&gt;
add_to_page(mkrule(2 * tenpt))&lt;br /&gt;
&lt;br /&gt;
-- The pagelist contains a pdf dest node (a link destination) and a rule of size 20pt x 20pt.&lt;br /&gt;
&lt;br /&gt;
shipout()&lt;br /&gt;
---------------------------&lt;br /&gt;
-- page 2&lt;br /&gt;
---------------------------&lt;br /&gt;
-- This is the page with the link to the anchor (dest) on page one. A&lt;br /&gt;
-- link consists of three nodes: a pdf_start_link, a pdf_end_link and and &lt;br /&gt;
-- action node that specifies the action to perform when the user clicks on&lt;br /&gt;
-- the link.&lt;br /&gt;
-- The pdf link must be inside a horizontal box, that&amp;#039;s why we hpack() it.&lt;br /&gt;
-- The link_attr (link attributes) is optional, here it draws a yellowish border&lt;br /&gt;
-- around the link.&lt;br /&gt;
local start_link = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_start_link&amp;quot;)&lt;br /&gt;
local end_link   = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_end_link&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
start_link.width     = tenpt&lt;br /&gt;
start_link.height    = tenpt / 2&lt;br /&gt;
start_link.depth     = tenpt / 2&lt;br /&gt;
start_link.link_attr = &amp;quot;/C [0.9 1 0] /Border [0 0 2]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
start_link.action = node.new(&amp;quot;action&amp;quot;)&lt;br /&gt;
start_link.action.action_type = 1&lt;br /&gt;
start_link.action.action_id   = dest&lt;br /&gt;
&lt;br /&gt;
local rule = mkrule(tenpt)&lt;br /&gt;
local hbox = hpack(start_link, rule, end_link)&lt;br /&gt;
add_to_page(hbox)&lt;br /&gt;
&lt;br /&gt;
-- This pagelist consists of an hbox whose contents is &amp;quot;start_link&amp;quot;,&lt;br /&gt;
-- the 10pt x 10pt rule and the &amp;quot;end_link&amp;quot; node. &lt;br /&gt;
&lt;br /&gt;
shipout()&lt;br /&gt;
---------------------------&lt;br /&gt;
&lt;br /&gt;
-- Just to show you that you can get some memory usage statistics:&lt;br /&gt;
print(string.format(&amp;quot;\nnode_mem_usage=%s&amp;quot;,status.node_mem_usage))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The idea is to create nodes, collect them in a list (here: pagelist) and use &amp;lt;tt&amp;gt;tex.shipout()&amp;lt;/tt&amp;gt; to put the page into the PDF.&lt;br /&gt;
&lt;br /&gt;
== And what about &amp;#039;&amp;#039;real&amp;#039;&amp;#039; content? ==&lt;br /&gt;
&lt;br /&gt;
Black squares won&amp;#039;t make anyone happy. So we need a typeset paragraph. For that we start with a single glyph and a glue first. A glyph node has this structure:&lt;br /&gt;
&lt;br /&gt;
[[File:Singleglyphnode.png]]&lt;br /&gt;
&lt;br /&gt;
whereas a glue is more complicated:&lt;br /&gt;
&lt;br /&gt;
[[File:Simplegluenode.png]]&lt;br /&gt;
&lt;br /&gt;
The glue item comes in pairs: a glue node and a glue_spec node. The information about the shrink/stretch values go into the glue_spec node. For example, the TeX glue &amp;lt;tt&amp;gt;2pt plus 1fill&amp;lt;/tt&amp;gt; has a width of 2*2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;, a stretch of 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt; and a stretch_order of 3. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local g = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g.font = font.current()&lt;br /&gt;
g.lang = tex.language&lt;br /&gt;
g.char = 86 -- V&lt;br /&gt;
&lt;br /&gt;
local hbox = node.hpack(g)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We create a glyph, pack it into an hbox (horizontal box), pack that hbox into a vbox (a vertical box) and write this box to the main vertical list. The char number (86 in the example above) is based on an internal encoding, so we have to keep an eye on what character is on what position. Now we do this for two glyphs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local g1 = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g1.font = font.current()&lt;br /&gt;
g1.lang = tex.language&lt;br /&gt;
g1.char = 86&lt;br /&gt;
&lt;br /&gt;
local g2 = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g2.font = font.current()&lt;br /&gt;
g2.lang = tex.language&lt;br /&gt;
g2.char = 97&lt;br /&gt;
&lt;br /&gt;
g1.next = g2&lt;br /&gt;
g2.prev = g1&lt;br /&gt;
&lt;br /&gt;
local hbox = node.hpack(g1)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pretty much the same as above. The glyphs g1 and g2 are chained together by setting the next and prev pointer to each other, otherwise only glyph g1 gets into the hbox.&lt;br /&gt;
&lt;br /&gt;
If you take a close look at the PDF, you see that the two glyphs are too far away, a (negative) kern should be inserted. This can be done by inserting a kern-node manually or you can ask TeX to do that for you. The last lines of the example above should then read:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local head,tail,success = node.kerning(g1)&lt;br /&gt;
local hbox = node.hpack(head)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
(todo: glyph subtype, ligaturing)&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&lt;br /&gt;
Our paragraph consists of boxes of glue, glyphs and penalties. Luckily TeX will help us with most of the complicated stuff: the breaking of paragraphs into lines and adjusting the glue values. We only need to create the glyph nodes and the glue nodes between the words and . Let&amp;#039;s take a look &lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=127</id>
		<title>TeX without TeX</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=127"/>
		<updated>2011-07-03T09:50:24Z</updated>

		<summary type="html">&lt;p&gt;Patrick: typo (&amp;lt;/pre&amp;gt;)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Use TeX&amp;#039;s power without TeX macros ==&lt;br /&gt;
&lt;br /&gt;
With LuaTeX you have access to most of TeX&amp;#039;s capabilities for creating PDF documents. Most of the [http://www.luatex.org/svn/trunk/manual/luatexref-t.pdf LuaTeX reference manual] is about this topic. &lt;br /&gt;
&lt;br /&gt;
The underlying idea is to create TeX&amp;#039;s internal data structure as TeX would do by transforming macros and primitives into something called nodes. These nodes are then transformed into instructions for the PDF file (PDF objects). So the following pages deal with node creation and the structures. &lt;br /&gt;
&lt;br /&gt;
Let&amp;#039;s start with a rule node. When you write &amp;lt;tt&amp;gt;\hrule width 20pt height 10pt depth 10pt &amp;lt;/tt&amp;gt; in TeX, a node of type rule will be created, which has three fields: height, depth and width. We can visualize this node by a simple box like this:&lt;br /&gt;
&lt;br /&gt;
[[File:rulenode.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r.width  = 20 * 65536&lt;br /&gt;
r.height = 10 * 65536&lt;br /&gt;
r.depth  = 10 * 65536&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some remarks: the size is in scaled points, and 65536 (=2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;) scaled points are 1 point, so 20pt becomes 20 * 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;. Not shown in the example are (among others) the next and prev fields. These fields hold a pointer (the node address) to the following and the previous nodes. A node that exist by itself has its prev and next fields set to nil.&lt;br /&gt;
&lt;br /&gt;
A slightly more complicated example is when you create two rules and pack then into a vertical box. This would look like this in plain TeX:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\vbox {\hrule width 20pt height 10pt depth 10pt&lt;br /&gt;
           \hrule width 20pt height 10pt depth 10pt }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would generate a node list like:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Rulenode2.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r1 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r1.width  = 20 * 65536&lt;br /&gt;
r1.height = 10 * 65536&lt;br /&gt;
r1.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r2 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r2.width  = 20 * 65536&lt;br /&gt;
r2.height = 10 * 65536&lt;br /&gt;
r2.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r1.next = r2&lt;br /&gt;
r2.prev = r1&lt;br /&gt;
&lt;br /&gt;
vbox = node.vpack(r1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result is a vbox containing the two rule nodes. The nodes are connected by their next and prev pointers, so the vbox contains them both. The size (width, height and depth) is adjusted automatically.&lt;br /&gt;
&lt;br /&gt;
This also applies to all other things you can put on a TeX page: glyphs, horizontal boxes, math, images, hyperlinks, glue .... For a complete list of the nodes, see the reference manual Chapter 8 &amp;quot;Nodes&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Beyond reports and articles ==&lt;br /&gt;
&lt;br /&gt;
Perhaps the question that comes into your mind is: why should I bother writing Lua code instead of TeX code? For many documents, including articles, reports and books, the classic way to create a PDF with TeX is to use LaTeX or ConTeXt. But there are applications that use TeX as an 100% automatic PDF generation software. If you want to create data sheets or product listings, your normal input is not a classic document, but most likely an Excel spreadsheet or an XML file, perhaps extracted from a database. You won&amp;#039;t have any TeX markup within these documents. So: if you don&amp;#039;t have TeX markup in these documents, you don&amp;#039;t need the TeX interpreter to read these files. More likely is an XML parser or a spreadsheet 2 ... converter.&lt;br /&gt;
&lt;br /&gt;
When you use regular LaTeX or ConTeXt code to put the contents of the database in your PDF (database publishing), you run into several problems:&lt;br /&gt;
&lt;br /&gt;
* Exact positioning of items on the page can be troublesome&lt;br /&gt;
* catcodes / command escapes are to be considered and surely get into your way&lt;br /&gt;
* TeX is no fun to program in (well it is, but only for some people) - calculations, tests, exception handling, control flow&lt;br /&gt;
* The packages that exist may reach their limit soon. You need a super flexible image-between-columns-with-parshape package? Write it yourself.&lt;br /&gt;
&lt;br /&gt;
With Lua you have a very decent programming language that &amp;#039;&amp;#039;is&amp;#039;&amp;#039; fun to program in. When you use the Lua interface to TeX, you have full control of what is happening, which is usually the level of control you need for high quality output.&lt;br /&gt;
&lt;br /&gt;
One approach is to create a stub TeX file and let Lua do the rest:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;myprogram.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The file &amp;lt;tt&amp;gt;myprogram.lua&amp;lt;/tt&amp;gt; then contains all the code to a) read the source file(s), b) extract the information and create the appropriate nodes and c) instruct TeX to create PDF pages from these nodes.&lt;br /&gt;
&lt;br /&gt;
In a future version of LuaTeX you will be able to run the Lua interpreter without the stub TeX file above.&lt;br /&gt;
&lt;br /&gt;
== A first example ==&lt;br /&gt;
&lt;br /&gt;
The example document given below creates two pages by using Lua code alone. You will learn how to access TeX&amp;#039;s boxes and counters from the Lua side, shipout a page into the PDF file, create horizontal and vertical boxes (hbox and vbox), create new nodes and manipulate the nodes links structure. The example covers the following node types: rule, whatsit, vlist, hlist and action.&lt;br /&gt;
&lt;br /&gt;
In the example code we use black squares as the contents of the pages and not normal text, because character handling takes more code and will be covered later on.&lt;br /&gt;
&lt;br /&gt;
Save the following file into &amp;lt;tt&amp;gt;myprogram.lua&amp;lt;/tt&amp;gt; and use the TeX stub from above (or get the source [https://raw.github.com/gist/1062041/d3de082e955f6535f3820742cef76fe9e50d5a6f/myprogram.lua here]).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
  -- this will hold the items that go onto the page&lt;br /&gt;
  local pagelist&lt;br /&gt;
 &lt;br /&gt;
  -- Call tex.shipout() with the contents of the pagelist&lt;br /&gt;
  function shipout()&lt;br /&gt;
&lt;br /&gt;
    local vbox,b = node.vpack(pagelist) -- we ignore the badness &amp;#039;b&amp;#039;&lt;br /&gt;
    tex.box[666] = vbox&lt;br /&gt;
    tex.shipout(666)&lt;br /&gt;
&lt;br /&gt;
    pagelist = nil&lt;br /&gt;
    &lt;br /&gt;
    -- Not strictly necessary. TeX holds the current page number in counter 0.&lt;br /&gt;
    -- TeX displays the contents of this counter when it puts a page into&lt;br /&gt;
    -- the pdf (tex.shipout()). If we don&amp;#039;t change the counter, TeX will&lt;br /&gt;
    -- display [1] [1], instead of [1] [2] for our two page document.&lt;br /&gt;
    tex.count[0] = tex.count[0] + 1&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
  function add_to_page( list )&lt;br /&gt;
    -- We attach the nodelist &amp;#039;list&amp;#039; to the end of the pagelist&lt;br /&gt;
    -- if pagelist doesn&amp;#039;t exist, &amp;#039;list&amp;#039; is our new pagelist&lt;br /&gt;
    -- if it exists, we go to the end with node.tail() and adjust&lt;br /&gt;
    -- the prev and next pointers, so list becomes part&lt;br /&gt;
    -- of pagelist.&lt;br /&gt;
    if not pagelist then pagelist = list&lt;br /&gt;
    else&lt;br /&gt;
      local tail = node.tail(pagelist)&lt;br /&gt;
      tail.next = list&lt;br /&gt;
      list.prev  = tail&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- This creates a new square rule and returns the pointer to it.&lt;br /&gt;
function mkrule( size )&lt;br /&gt;
  local r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
  r.width  = size &lt;br /&gt;
  r.height = size / 2&lt;br /&gt;
  r.depth  = size / 2&lt;br /&gt;
  return r&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
do&lt;br /&gt;
  local destcounter = 0&lt;br /&gt;
  -- Create a pdf anchor (dest object). It returns a whatsit node and the &lt;br /&gt;
  -- number of the anchor, so it can be used in a pdf link or an outline.&lt;br /&gt;
  function mkdest()&lt;br /&gt;
    destcounter = destcounter + 1&lt;br /&gt;
    local d = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_dest&amp;quot;)&lt;br /&gt;
    d.named_id = 0&lt;br /&gt;
    d.dest_id = destcounter&lt;br /&gt;
    d.dest_type = 3&lt;br /&gt;
&lt;br /&gt;
    return d, destcounter&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Take a list of nodes and put them into an hbox. The prev and next fields&lt;br /&gt;
-- of the nodes will be set automatically. Return a pointer to the hbox.&lt;br /&gt;
function hpack( ... )&lt;br /&gt;
  local start, tmp, cur&lt;br /&gt;
  start = select(1,...)&lt;br /&gt;
  tmp = start&lt;br /&gt;
  for i=2,select(&amp;quot;#&amp;quot;,...) do&lt;br /&gt;
    cur = select(i,...)&lt;br /&gt;
    tmp.next = cur&lt;br /&gt;
    cur.prev = tmp&lt;br /&gt;
    tmp = cur&lt;br /&gt;
  end&lt;br /&gt;
  local h,b = node.hpack(start) -- ignore badness&lt;br /&gt;
  return h&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local tenpt = 10 * 2^16&lt;br /&gt;
---------------------------&lt;br /&gt;
-- page 1&lt;br /&gt;
---------------------------&lt;br /&gt;
local n,dest = mkdest() -- dest is needed for the link to this anchor&lt;br /&gt;
&lt;br /&gt;
add_to_page(n)&lt;br /&gt;
add_to_page(mkrule(2 * tenpt))&lt;br /&gt;
&lt;br /&gt;
-- The pagelist contains a pdf dest node (a link destination) and a rule of size 20pt x 20pt.&lt;br /&gt;
&lt;br /&gt;
shipout()&lt;br /&gt;
---------------------------&lt;br /&gt;
-- page 2&lt;br /&gt;
---------------------------&lt;br /&gt;
-- This is the page with the link to the anchor (dest) on page one. A&lt;br /&gt;
-- link consists of three nodes: a pdf_start_link, a pdf_end_link and and &lt;br /&gt;
-- action node that specifies the action to perform when the user clicks on&lt;br /&gt;
-- the link.&lt;br /&gt;
-- The pdf link must be inside a horizontal box, that&amp;#039;s why we hpack() it.&lt;br /&gt;
-- The link_attr (link attributes) is optional, here it draws a yellowish border&lt;br /&gt;
-- around the link.&lt;br /&gt;
local start_link = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_start_link&amp;quot;)&lt;br /&gt;
local end_link   = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_end_link&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
start_link.width     = tenpt&lt;br /&gt;
start_link.height    = tenpt / 2&lt;br /&gt;
start_link.depth     = tenpt / 2&lt;br /&gt;
start_link.link_attr = &amp;quot;/C [0.9 1 0] /Border [0 0 2]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
start_link.action = node.new(&amp;quot;action&amp;quot;)&lt;br /&gt;
start_link.action.action_type = 1&lt;br /&gt;
start_link.action.action_id   = dest&lt;br /&gt;
&lt;br /&gt;
local rule = mkrule(tenpt)&lt;br /&gt;
local hbox = hpack(start_link, rule, end_link)&lt;br /&gt;
add_to_page(hbox)&lt;br /&gt;
&lt;br /&gt;
-- This pagelist consists of an hbox whose contents is &amp;quot;start_link&amp;quot;,&lt;br /&gt;
-- the 10pt x 10pt rule and the &amp;quot;end_link&amp;quot; node. &lt;br /&gt;
&lt;br /&gt;
shipout()&lt;br /&gt;
---------------------------&lt;br /&gt;
&lt;br /&gt;
-- Just to show you that you can get some memory usage statistics:&lt;br /&gt;
print(string.format(&amp;quot;\nnode_mem_usage=%s&amp;quot;,status.node_mem_usage))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The idea is to create nodes, collect them in a list (here: pagelist) and use &amp;lt;tt&amp;gt;tex.shipout()&amp;lt;/tt&amp;gt; to put the page into the PDF.&lt;br /&gt;
&lt;br /&gt;
== And what about &amp;#039;&amp;#039;real&amp;#039;&amp;#039; content? ==&lt;br /&gt;
&lt;br /&gt;
Black squares won&amp;#039;t make anyone happy. So we need a typeset paragraph. For that we start with a single glyph and a glue first. A glyph node has this structure:&lt;br /&gt;
&lt;br /&gt;
[[File:Singleglyphnode.png]]&lt;br /&gt;
&lt;br /&gt;
whereas a glue is more complicated:&lt;br /&gt;
&lt;br /&gt;
[[File:Simplegluenode.png]]&lt;br /&gt;
&lt;br /&gt;
The glue item comes in pairs: a glue node and a glue_spec node. The information about the shrink/stretch values go into the glue_spec node. For example, the TeX glue &amp;lt;tt&amp;gt;2pt plus 1fill&amp;lt;/tt&amp;gt; has a width of 2*2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;, a stretch of 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt; and a stretch_order of 3. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local g = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g.font = font.current()&lt;br /&gt;
g.lang = tex.language&lt;br /&gt;
g.char = 86 -- V&lt;br /&gt;
&lt;br /&gt;
local hbox = node.hpack(g)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We create a glyph, pack it into an hbox (horizontal box), pack that hbox into a vbox (a vertical box) and write this box to the main vertical list. The char number (65 in the example above) is based on an internal encoding, so we have to keep an eye on what character is on what position. Now we do this for two glyphs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local g1 = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g1.font = font.current()&lt;br /&gt;
g1.lang = tex.language&lt;br /&gt;
g1.char = 86&lt;br /&gt;
&lt;br /&gt;
local g2 = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g2.font = font.current()&lt;br /&gt;
g2.lang = tex.language&lt;br /&gt;
g2.char = 97&lt;br /&gt;
&lt;br /&gt;
g1.next = g2&lt;br /&gt;
g2.prev = g1&lt;br /&gt;
&lt;br /&gt;
local hbox = node.hpack(g1)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pretty much the same as above. The glyphs g1 and g2 are chained together by setting the next and prev pointer to each other, otherwise only glyph g1 gets into the hbox.&lt;br /&gt;
&lt;br /&gt;
If you take a close look at the PDF, you see that the two glyphs are too far away, a (negative) kern should be inserted. This can be done by inserting a kern-node manually or you can ask TeX to do that for you. The last lines of the example above should then read:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local head,tail,success = node.kerning(g1)&lt;br /&gt;
local hbox = node.hpack(head)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
(todo: glyph subtype, ligaturing)&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&lt;br /&gt;
Our paragraph consists of boxes of glue, glyphs and penalties. Luckily TeX will help us with most of the complicated stuff: the breaking of paragraphs into lines and adjusting the glue values. We only need to create the glyph nodes and the glue nodes between the words and . Let&amp;#039;s take a look &lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=126</id>
		<title>TeX without TeX</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=126"/>
		<updated>2011-07-03T09:44:35Z</updated>

		<summary type="html">&lt;p&gt;Patrick: how to create a glyph node&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Use TeX&amp;#039;s power without TeX macros ==&lt;br /&gt;
&lt;br /&gt;
With LuaTeX you have access to most of TeX&amp;#039;s capabilities for creating PDF documents. Most of the [http://www.luatex.org/svn/trunk/manual/luatexref-t.pdf LuaTeX reference manual] is about this topic. &lt;br /&gt;
&lt;br /&gt;
The underlying idea is to create TeX&amp;#039;s internal data structure as TeX would do by transforming macros and primitives into something called nodes. These nodes are then transformed into instructions for the PDF file (PDF objects). So the following pages deal with node creation and the structures. &lt;br /&gt;
&lt;br /&gt;
Let&amp;#039;s start with a rule node. When you write &amp;lt;tt&amp;gt;\hrule width 20pt height 10pt depth 10pt &amp;lt;/tt&amp;gt; in TeX, a node of type rule will be created, which has three fields: height, depth and width. We can visualize this node by a simple box like this:&lt;br /&gt;
&lt;br /&gt;
[[File:rulenode.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r.width  = 20 * 65536&lt;br /&gt;
r.height = 10 * 65536&lt;br /&gt;
r.depth  = 10 * 65536&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some remarks: the size is in scaled points, and 65536 (=2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;) scaled points are 1 point, so 20pt becomes 20 * 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;. Not shown in the example are (among others) the next and prev fields. These fields hold a pointer (the node address) to the following and the previous nodes. A node that exist by itself has its prev and next fields set to nil.&lt;br /&gt;
&lt;br /&gt;
A slightly more complicated example is when you create two rules and pack then into a vertical box. This would look like this in plain TeX:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\vbox {\hrule width 20pt height 10pt depth 10pt&lt;br /&gt;
           \hrule width 20pt height 10pt depth 10pt }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would generate a node list like:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Rulenode2.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r1 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r1.width  = 20 * 65536&lt;br /&gt;
r1.height = 10 * 65536&lt;br /&gt;
r1.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r2 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r2.width  = 20 * 65536&lt;br /&gt;
r2.height = 10 * 65536&lt;br /&gt;
r2.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r1.next = r2&lt;br /&gt;
r2.prev = r1&lt;br /&gt;
&lt;br /&gt;
vbox = node.vpack(r1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result is a vbox containing the two rule nodes. The nodes are connected by their next and prev pointers, so the vbox contains them both. The size (width, height and depth) is adjusted automatically.&lt;br /&gt;
&lt;br /&gt;
This also applies to all other things you can put on a TeX page: glyphs, horizontal boxes, math, images, hyperlinks, glue .... For a complete list of the nodes, see the reference manual Chapter 8 &amp;quot;Nodes&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Beyond reports and articles ==&lt;br /&gt;
&lt;br /&gt;
Perhaps the question that comes into your mind is: why should I bother writing Lua code instead of TeX code? For many documents, including articles, reports and books, the classic way to create a PDF with TeX is to use LaTeX or ConTeXt. But there are applications that use TeX as an 100% automatic PDF generation software. If you want to create data sheets or product listings, your normal input is not a classic document, but most likely an Excel spreadsheet or an XML file, perhaps extracted from a database. You won&amp;#039;t have any TeX markup within these documents. So: if you don&amp;#039;t have TeX markup in these documents, you don&amp;#039;t need the TeX interpreter to read these files. More likely is an XML parser or a spreadsheet 2 ... converter.&lt;br /&gt;
&lt;br /&gt;
When you use regular LaTeX or ConTeXt code to put the contents of the database in your PDF (database publishing), you run into several problems:&lt;br /&gt;
&lt;br /&gt;
* Exact positioning of items on the page can be troublesome&lt;br /&gt;
* catcodes / command escapes are to be considered and surely get into your way&lt;br /&gt;
* TeX is no fun to program in (well it is, but only for some people) - calculations, tests, exception handling, control flow&lt;br /&gt;
* The packages that exist may reach their limit soon. You need a super flexible image-between-columns-with-parshape package? Write it yourself.&lt;br /&gt;
&lt;br /&gt;
With Lua you have a very decent programming language that &amp;#039;&amp;#039;is&amp;#039;&amp;#039; fun to program in. When you use the Lua interface to TeX, you have full control of what is happening, which is usually the level of control you need for high quality output.&lt;br /&gt;
&lt;br /&gt;
One approach is to create a stub TeX file and let Lua do the rest:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;myprogram.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The file &amp;lt;tt&amp;gt;myprogram.lua&amp;lt;/tt&amp;gt; then contains all the code to a) read the source file(s), b) extract the information and create the appropriate nodes and c) instruct TeX to create PDF pages from these nodes.&lt;br /&gt;
&lt;br /&gt;
In a future version of LuaTeX you will be able to run the Lua interpreter without the stub TeX file above.&lt;br /&gt;
&lt;br /&gt;
== A first example ==&lt;br /&gt;
&lt;br /&gt;
The example document given below creates two pages by using Lua code alone. You will learn how to access TeX&amp;#039;s boxes and counters from the Lua side, shipout a page into the PDF file, create horizontal and vertical boxes (hbox and vbox), create new nodes and manipulate the nodes links structure. The example covers the following node types: rule, whatsit, vlist, hlist and action.&lt;br /&gt;
&lt;br /&gt;
In the example code we use black squares as the contents of the pages and not normal text, because character handling takes more code and will be covered later on.&lt;br /&gt;
&lt;br /&gt;
Save the following file into &amp;lt;tt&amp;gt;myprogram.lua&amp;lt;/tt&amp;gt; and use the TeX stub from above (or get the source [https://raw.github.com/gist/1062041/d3de082e955f6535f3820742cef76fe9e50d5a6f/myprogram.lua here]).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
  -- this will hold the items that go onto the page&lt;br /&gt;
  local pagelist&lt;br /&gt;
 &lt;br /&gt;
  -- Call tex.shipout() with the contents of the pagelist&lt;br /&gt;
  function shipout()&lt;br /&gt;
&lt;br /&gt;
    local vbox,b = node.vpack(pagelist) -- we ignore the badness &amp;#039;b&amp;#039;&lt;br /&gt;
    tex.box[666] = vbox&lt;br /&gt;
    tex.shipout(666)&lt;br /&gt;
&lt;br /&gt;
    pagelist = nil&lt;br /&gt;
    &lt;br /&gt;
    -- Not strictly necessary. TeX holds the current page number in counter 0.&lt;br /&gt;
    -- TeX displays the contents of this counter when it puts a page into&lt;br /&gt;
    -- the pdf (tex.shipout()). If we don&amp;#039;t change the counter, TeX will&lt;br /&gt;
    -- display [1] [1], instead of [1] [2] for our two page document.&lt;br /&gt;
    tex.count[0] = tex.count[0] + 1&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
  function add_to_page( list )&lt;br /&gt;
    -- We attach the nodelist &amp;#039;list&amp;#039; to the end of the pagelist&lt;br /&gt;
    -- if pagelist doesn&amp;#039;t exist, &amp;#039;list&amp;#039; is our new pagelist&lt;br /&gt;
    -- if it exists, we go to the end with node.tail() and adjust&lt;br /&gt;
    -- the prev and next pointers, so list becomes part&lt;br /&gt;
    -- of pagelist.&lt;br /&gt;
    if not pagelist then pagelist = list&lt;br /&gt;
    else&lt;br /&gt;
      local tail = node.tail(pagelist)&lt;br /&gt;
      tail.next = list&lt;br /&gt;
      list.prev  = tail&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- This creates a new square rule and returns the pointer to it.&lt;br /&gt;
function mkrule( size )&lt;br /&gt;
  local r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
  r.width  = size &lt;br /&gt;
  r.height = size / 2&lt;br /&gt;
  r.depth  = size / 2&lt;br /&gt;
  return r&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
do&lt;br /&gt;
  local destcounter = 0&lt;br /&gt;
  -- Create a pdf anchor (dest object). It returns a whatsit node and the &lt;br /&gt;
  -- number of the anchor, so it can be used in a pdf link or an outline.&lt;br /&gt;
  function mkdest()&lt;br /&gt;
    destcounter = destcounter + 1&lt;br /&gt;
    local d = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_dest&amp;quot;)&lt;br /&gt;
    d.named_id = 0&lt;br /&gt;
    d.dest_id = destcounter&lt;br /&gt;
    d.dest_type = 3&lt;br /&gt;
&lt;br /&gt;
    return d, destcounter&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Take a list of nodes and put them into an hbox. The prev and next fields&lt;br /&gt;
-- of the nodes will be set automatically. Return a pointer to the hbox.&lt;br /&gt;
function hpack( ... )&lt;br /&gt;
  local start, tmp, cur&lt;br /&gt;
  start = select(1,...)&lt;br /&gt;
  tmp = start&lt;br /&gt;
  for i=2,select(&amp;quot;#&amp;quot;,...) do&lt;br /&gt;
    cur = select(i,...)&lt;br /&gt;
    tmp.next = cur&lt;br /&gt;
    cur.prev = tmp&lt;br /&gt;
    tmp = cur&lt;br /&gt;
  end&lt;br /&gt;
  local h,b = node.hpack(start) -- ignore badness&lt;br /&gt;
  return h&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local tenpt = 10 * 2^16&lt;br /&gt;
---------------------------&lt;br /&gt;
-- page 1&lt;br /&gt;
---------------------------&lt;br /&gt;
local n,dest = mkdest() -- dest is needed for the link to this anchor&lt;br /&gt;
&lt;br /&gt;
add_to_page(n)&lt;br /&gt;
add_to_page(mkrule(2 * tenpt))&lt;br /&gt;
&lt;br /&gt;
-- The pagelist contains a pdf dest node (a link destination) and a rule of size 20pt x 20pt.&lt;br /&gt;
&lt;br /&gt;
shipout()&lt;br /&gt;
---------------------------&lt;br /&gt;
-- page 2&lt;br /&gt;
---------------------------&lt;br /&gt;
-- This is the page with the link to the anchor (dest) on page one. A&lt;br /&gt;
-- link consists of three nodes: a pdf_start_link, a pdf_end_link and and &lt;br /&gt;
-- action node that specifies the action to perform when the user clicks on&lt;br /&gt;
-- the link.&lt;br /&gt;
-- The pdf link must be inside a horizontal box, that&amp;#039;s why we hpack() it.&lt;br /&gt;
-- The link_attr (link attributes) is optional, here it draws a yellowish border&lt;br /&gt;
-- around the link.&lt;br /&gt;
local start_link = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_start_link&amp;quot;)&lt;br /&gt;
local end_link   = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_end_link&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
start_link.width     = tenpt&lt;br /&gt;
start_link.height    = tenpt / 2&lt;br /&gt;
start_link.depth     = tenpt / 2&lt;br /&gt;
start_link.link_attr = &amp;quot;/C [0.9 1 0] /Border [0 0 2]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
start_link.action = node.new(&amp;quot;action&amp;quot;)&lt;br /&gt;
start_link.action.action_type = 1&lt;br /&gt;
start_link.action.action_id   = dest&lt;br /&gt;
&lt;br /&gt;
local rule = mkrule(tenpt)&lt;br /&gt;
local hbox = hpack(start_link, rule, end_link)&lt;br /&gt;
add_to_page(hbox)&lt;br /&gt;
&lt;br /&gt;
-- This pagelist consists of an hbox whose contents is &amp;quot;start_link&amp;quot;,&lt;br /&gt;
-- the 10pt x 10pt rule and the &amp;quot;end_link&amp;quot; node. &lt;br /&gt;
&lt;br /&gt;
shipout()&lt;br /&gt;
---------------------------&lt;br /&gt;
&lt;br /&gt;
-- Just to show you that you can get some memory usage statistics:&lt;br /&gt;
print(string.format(&amp;quot;\nnode_mem_usage=%s&amp;quot;,status.node_mem_usage))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The idea is to create nodes, collect them in a list (here: pagelist) and use &amp;lt;tt&amp;gt;tex.shipout()&amp;lt;/tt&amp;gt; to put the page into the PDF.&lt;br /&gt;
&lt;br /&gt;
== And what about &amp;#039;&amp;#039;real&amp;#039;&amp;#039; content? ==&lt;br /&gt;
&lt;br /&gt;
Black squares won&amp;#039;t make anyone happy. So we need a typeset paragraph. For that we start with a single glyph and a glue first. A glyph node has this structure:&lt;br /&gt;
&lt;br /&gt;
[[File:Singleglyphnode.png]]&lt;br /&gt;
&lt;br /&gt;
whereas a glue is more complicated:&lt;br /&gt;
&lt;br /&gt;
[[File:Simplegluenode.png]]&lt;br /&gt;
&lt;br /&gt;
The glue item comes in pairs: a glue node and a glue_spec node. The information about the shrink/stretch values go into the glue_spec node. For example, the TeX glue &amp;lt;tt&amp;gt;2pt plus 1fill&amp;lt;/tt&amp;gt; has a width of 2*2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;, a stretch of 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt; and a stretch_order of 3. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local g = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g.font = font.current()&lt;br /&gt;
g.lang = tex.language&lt;br /&gt;
g.char = 86 -- V&lt;br /&gt;
&lt;br /&gt;
local hbox = node.hpack(g)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We create a glyph, pack it into an hbox (horizontal box), pack that hbox into a vbox (a vertical box) and write this box to the main vertical list. The char number (65 in the example above) is based on an internal encoding, so we have to keep an eye on what character is on what position. Now we do this for two glyphs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local g1 = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g1.font = font.current()&lt;br /&gt;
g1.lang = tex.language&lt;br /&gt;
g1.char = 86&lt;br /&gt;
&lt;br /&gt;
local g2 = node.new(&amp;quot;glyph&amp;quot;)&lt;br /&gt;
g2.font = font.current()&lt;br /&gt;
g2.lang = tex.language&lt;br /&gt;
g2.char = 97&lt;br /&gt;
&lt;br /&gt;
g1.next = g2&lt;br /&gt;
g2.prev = g1&lt;br /&gt;
&lt;br /&gt;
local hbox = node.hpack(g1)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pretty much the same as above. The glyphs g1 and g2 are chained together by setting the next and prev pointer to each other, otherwise only glyph g1 gets into the hbox.&lt;br /&gt;
&lt;br /&gt;
If you take a close look at the PDF, you see that the two glyphs are too far away, a (negative) kern should be inserted. This can be done by inserting a kern-node manually or you can ask TeX to do that for you. The last lines of the example above should then read:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local head,tail,success = node.kerning(g1)&lt;br /&gt;
local hbox = node.hpack(head)&lt;br /&gt;
local vbox = node.vpack(hbox)&lt;br /&gt;
&lt;br /&gt;
node.write(vbox)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
(todo: glyph subtype, ligaturing)&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&lt;br /&gt;
Our paragraph consists of boxes of glue, glyphs and penalties. Luckily TeX will help us with most of the complicated stuff: the breaking of paragraphs into lines and adjusting the glue values. We only need to create the glyph nodes and the glue nodes between the words and . Let&amp;#039;s take a look &lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=File:Singleglyphnode.png&amp;diff=125</id>
		<title>File:Singleglyphnode.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=File:Singleglyphnode.png&amp;diff=125"/>
		<updated>2011-07-03T09:43:36Z</updated>

		<summary type="html">&lt;p&gt;Patrick: structure for a glyph node&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;structure for a glyph node&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=File:Simplegluenode.png&amp;diff=124</id>
		<title>File:Simplegluenode.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=File:Simplegluenode.png&amp;diff=124"/>
		<updated>2011-07-03T09:42:13Z</updated>

		<summary type="html">&lt;p&gt;Patrick: structure for glue /glue_spec nodes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;structure for glue /glue_spec nodes&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=123</id>
		<title>TeX without TeX</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=123"/>
		<updated>2011-07-02T20:18:45Z</updated>

		<summary type="html">&lt;p&gt;Patrick: remove unnecessary code&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Use TeX&amp;#039;s power without TeX macros ==&lt;br /&gt;
&lt;br /&gt;
With LuaTeX you have access to most of TeX&amp;#039;s capabilities for creating PDF documents. Most of the [http://www.luatex.org/svn/trunk/manual/luatexref-t.pdf LuaTeX reference manual] is about this topic. &lt;br /&gt;
&lt;br /&gt;
The underlying idea is to create TeX&amp;#039;s internal data structure as TeX would do by transforming macros and primitives into something called nodes. These nodes are then transformed into instructions for the PDF file (PDF objects). So the following pages deal with node creation and the structures. &lt;br /&gt;
&lt;br /&gt;
Let&amp;#039;s start with a rule node. When you write &amp;lt;tt&amp;gt;\hrule width 20pt height 10pt depth 10pt &amp;lt;/tt&amp;gt; in TeX, a node of type rule will be created, which has three fields: height, depth and width. We can visualize this node by a simple box like this:&lt;br /&gt;
&lt;br /&gt;
[[File:rulenode.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r.width  = 20 * 65536&lt;br /&gt;
r.height = 10 * 65536&lt;br /&gt;
r.depth  = 10 * 65536&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some remarks: the size is in scaled points, and 65536 (=2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;) scaled points are 1 point, so 20pt becomes 20 * 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;. Not shown in the example are (among others) the next and prev fields. These fields hold a pointer (the node address) to the following and the previous nodes. A node that exist by itself has its prev and next fields set to nil.&lt;br /&gt;
&lt;br /&gt;
A slightly more complicated example is when you create two rules and pack then into a vertical box. This would look like this in plain TeX:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\vbox {\hrule width 20pt height 10pt depth 10pt&lt;br /&gt;
           \hrule width 20pt height 10pt depth 10pt }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would generate a node list like:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Rulenode2.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r1 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r1.width  = 20 * 65536&lt;br /&gt;
r1.height = 10 * 65536&lt;br /&gt;
r1.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r2 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r2.width  = 20 * 65536&lt;br /&gt;
r2.height = 10 * 65536&lt;br /&gt;
r2.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r1.next = r2&lt;br /&gt;
r2.prev = r1&lt;br /&gt;
&lt;br /&gt;
vbox = node.vpack(r1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result is a vbox containing the two rule nodes. The nodes are connected by their next and prev pointers, so the vbox contains them both. The size (width, height and depth) is adjusted automatically.&lt;br /&gt;
&lt;br /&gt;
This also applies to all other things you can put on a TeX page: glyphs, horizontal boxes, math, images, hyperlinks, glue .... For a complete list of the nodes, see the reference manual Chapter 8 &amp;quot;Nodes&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Beyond reports and articles ==&lt;br /&gt;
&lt;br /&gt;
Perhaps the question that comes into your mind is: why should I bother writing Lua code instead of TeX code? For many documents, including articles, reports and books, the classic way to create a PDF with TeX is to use LaTeX or ConTeXt. But there are applications that use TeX as an 100% automatic PDF generation software. If you want to create data sheets or product listings, your normal input is not a classic document, but most likely an Excel spreadsheet or an XML file, perhaps extracted from a database. You won&amp;#039;t have any TeX markup within these documents. So: if you don&amp;#039;t have TeX markup in these documents, you don&amp;#039;t need the TeX interpreter to read these files. More likely is an XML parser or a spreadsheet 2 ... converter.&lt;br /&gt;
&lt;br /&gt;
When you use regular LaTeX or ConTeXt code to put the contents of the database in your PDF (database publishing), you run into several problems:&lt;br /&gt;
&lt;br /&gt;
* Exact positioning of items on the page can be troublesome&lt;br /&gt;
* catcodes / command escapes are to be considered and surely get into your way&lt;br /&gt;
* TeX is no fun to program in (well it is, but only for some people) - calculations, tests, exception handling, control flow&lt;br /&gt;
* The packages that exist may reach their limit soon. You need a super flexible image-between-columns-with-parshape package? Write it yourself.&lt;br /&gt;
&lt;br /&gt;
With Lua you have a very decent programming language that &amp;#039;&amp;#039;is&amp;#039;&amp;#039; fun to program in. When you use the Lua interface to TeX, you have full control of what is happening, which is usually the level of control you need for high quality output.&lt;br /&gt;
&lt;br /&gt;
One approach is to create a stub TeX file and let Lua do the rest:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;myprogram.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The file &amp;lt;tt&amp;gt;myprogram.lua&amp;lt;/tt&amp;gt; then contains all the code to a) read the source file(s), b) extract the information and create the appropriate nodes and c) instruct TeX to create PDF pages from these nodes.&lt;br /&gt;
&lt;br /&gt;
In a future version of LuaTeX you will be able to run the Lua interpreter without the stub TeX file above.&lt;br /&gt;
&lt;br /&gt;
== A first example ==&lt;br /&gt;
&lt;br /&gt;
The example document given below creates two pages by using Lua code alone. You will learn how to access TeX&amp;#039;s boxes and counters from the Lua side, shipout a page into the PDF file, create horizontal and vertical boxes (hbox and vbox), create new nodes and manipulate the nodes links structure. The example covers the following node types: rule, whatsit, vlist, hlist and action.&lt;br /&gt;
&lt;br /&gt;
In the example code we use black squares as the contents of the pages and not normal text, because character handling takes more code and will be covered later on.&lt;br /&gt;
&lt;br /&gt;
Save the following file into &amp;lt;tt&amp;gt;myprogram.lua&amp;lt;/tt&amp;gt; and use the TeX stub from above.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
  -- this will hold the items that go onto the page&lt;br /&gt;
  local pagelist&lt;br /&gt;
 &lt;br /&gt;
  -- Call tex.shipout() with the contents of the pagelist&lt;br /&gt;
  function shipout()&lt;br /&gt;
&lt;br /&gt;
    local vbox,b = node.vpack(pagelist) -- we ignore the badness &amp;#039;b&amp;#039;&lt;br /&gt;
    tex.box[666] = vbox&lt;br /&gt;
    tex.shipout(666)&lt;br /&gt;
&lt;br /&gt;
    pagelist = nil&lt;br /&gt;
    &lt;br /&gt;
    -- Not strictly necessary. TeX holds the current page number in counter 0.&lt;br /&gt;
    -- TeX displays the contents of this counter when it puts a page into&lt;br /&gt;
    -- the pdf (tex.shipout()). If we don&amp;#039;t change the counter, TeX will&lt;br /&gt;
    -- display [1] [1], instead of [1] [2] for our two page document.&lt;br /&gt;
    tex.count[0] = tex.count[0] + 1&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
  function add_to_page( list )&lt;br /&gt;
    -- We attach the nodelist &amp;#039;list&amp;#039; to the end of the pagelist&lt;br /&gt;
    -- if pagelist doesn&amp;#039;t exist, &amp;#039;list&amp;#039; is our new pagelist&lt;br /&gt;
    -- if it exists, we go to the end with node.tail() and adjust&lt;br /&gt;
    -- the prev and next pointers, so list becomes part&lt;br /&gt;
    -- of pagelist.&lt;br /&gt;
    if not pagelist then pagelist = list&lt;br /&gt;
    else&lt;br /&gt;
      local tail = node.tail(pagelist)&lt;br /&gt;
      tail.next = list&lt;br /&gt;
      list.prev  = tail&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- This creates a new square rule and returns the pointer to it.&lt;br /&gt;
function mkrule( size )&lt;br /&gt;
  local r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
  r.width  = size &lt;br /&gt;
  r.height = size / 2&lt;br /&gt;
  r.depth  = size / 2&lt;br /&gt;
  return r&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
do&lt;br /&gt;
  local destcounter = 0&lt;br /&gt;
  -- Create a pdf anchor (dest object). It returns a whatsit node and the &lt;br /&gt;
  -- number of the anchor, so it can be used in a pdf link or an outline.&lt;br /&gt;
  function mkdest()&lt;br /&gt;
    destcounter = destcounter + 1&lt;br /&gt;
    local d = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_dest&amp;quot;)&lt;br /&gt;
    d.named_id = 0&lt;br /&gt;
    d.dest_id = destcounter&lt;br /&gt;
    d.dest_type = 3&lt;br /&gt;
&lt;br /&gt;
    return d, destcounter&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Take a list of nodes and put them into an hbox. The prev and next fields&lt;br /&gt;
-- of the nodes will be set automatically. Return a pointer to the hbox.&lt;br /&gt;
function hpack( ... )&lt;br /&gt;
  local start, tmp, cur&lt;br /&gt;
  start = select(1,...)&lt;br /&gt;
  tmp = start&lt;br /&gt;
  for i=2,select(&amp;quot;#&amp;quot;,...) do&lt;br /&gt;
    cur = select(i,...)&lt;br /&gt;
    tmp.next = cur&lt;br /&gt;
    cur.prev = tmp&lt;br /&gt;
    tmp = cur&lt;br /&gt;
  end&lt;br /&gt;
  local h,b = node.hpack(start) -- ignore badness&lt;br /&gt;
  return h&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local tenpt = 10 * 2^16&lt;br /&gt;
---------------------------&lt;br /&gt;
-- page 1&lt;br /&gt;
---------------------------&lt;br /&gt;
local n,dest = mkdest() -- dest is needed for the link to this anchor&lt;br /&gt;
&lt;br /&gt;
add_to_page(n)&lt;br /&gt;
add_to_page(mkrule(2 * tenpt))&lt;br /&gt;
&lt;br /&gt;
-- The pagelist contains a pdf dest node (a link destination) and a rule of size 20pt x 20pt.&lt;br /&gt;
&lt;br /&gt;
shipout()&lt;br /&gt;
---------------------------&lt;br /&gt;
-- page 2&lt;br /&gt;
---------------------------&lt;br /&gt;
-- This is the page with the link to the anchor (dest) on page one. A&lt;br /&gt;
-- link consists of three nodes: a pdf_start_link, a pdf_end_link and and &lt;br /&gt;
-- action node that specifies the action to perform when the user clicks on&lt;br /&gt;
-- the link.&lt;br /&gt;
-- The pdf link must be inside a horizontal box, that&amp;#039;s why we hpack() it.&lt;br /&gt;
-- The link_attr (link attributes) is optional, here it draws a yellowish border&lt;br /&gt;
-- around the link.&lt;br /&gt;
local start_link = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_start_link&amp;quot;)&lt;br /&gt;
local end_link   = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_end_link&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
start_link.width     = tenpt&lt;br /&gt;
start_link.height    = tenpt / 2&lt;br /&gt;
start_link.depth     = tenpt / 2&lt;br /&gt;
start_link.link_attr = &amp;quot;/C [0.9 1 0] /Border [0 0 2]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
start_link.action = node.new(&amp;quot;action&amp;quot;)&lt;br /&gt;
start_link.action.action_type = 1&lt;br /&gt;
start_link.action.action_id   = dest&lt;br /&gt;
&lt;br /&gt;
local rule = mkrule(tenpt)&lt;br /&gt;
local hbox = hpack(start_link, rule, end_link)&lt;br /&gt;
add_to_page(hbox)&lt;br /&gt;
&lt;br /&gt;
-- This pagelist consists of an hbox whose contents is &amp;quot;start_link&amp;quot;,&lt;br /&gt;
-- the 10pt x 10pt rule and the &amp;quot;end_link&amp;quot; node. &lt;br /&gt;
&lt;br /&gt;
shipout()&lt;br /&gt;
---------------------------&lt;br /&gt;
&lt;br /&gt;
-- Just to show you that you can get some memory usage statistics:&lt;br /&gt;
print(string.format(&amp;quot;\nnode_mem_usage=%s&amp;quot;,status.node_mem_usage))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The idea is to create nodes, collect them in a list (here: pagelist) and use &amp;lt;tt&amp;gt;tex.shipout()&amp;lt;/tt&amp;gt; to put the page into the PDF.&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=122</id>
		<title>TeX without TeX</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=122"/>
		<updated>2011-07-02T19:09:35Z</updated>

		<summary type="html">&lt;p&gt;Patrick: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Use TeX&amp;#039;s power without TeX macros ==&lt;br /&gt;
&lt;br /&gt;
With LuaTeX you have access to most of TeX&amp;#039;s capabilities for creating PDF documents. Most of the [http://www.luatex.org/svn/trunk/manual/luatexref-t.pdf LuaTeX reference manual] is about this topic. &lt;br /&gt;
&lt;br /&gt;
The underlying idea is to create TeX&amp;#039;s internal data structure as TeX would do by transforming macros and primitives into something called nodes. These nodes are then transformed into instructions for the PDF file (PDF objects). So the following pages deal with node creation and the structures. &lt;br /&gt;
&lt;br /&gt;
Let&amp;#039;s start with a rule node. When you write &amp;lt;tt&amp;gt;\hrule width 20pt height 10pt depth 10pt &amp;lt;/tt&amp;gt; in TeX, a node of type rule will be created, which has three fields: height, depth and width. We can visualize this node by a simple box like this:&lt;br /&gt;
&lt;br /&gt;
[[File:rulenode.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r.width  = 20 * 65536&lt;br /&gt;
r.height = 10 * 65536&lt;br /&gt;
r.depth  = 10 * 65536&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some remarks: the size is in scaled points, and 65536 (=2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;) scaled points are 1 point, so 20pt becomes 20 * 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;. Not shown in the example are (among others) the next and prev fields. These fields hold a pointer (the node address) to the following and the previous nodes. A node that exist by itself has its prev and next fields set to nil.&lt;br /&gt;
&lt;br /&gt;
A slightly more complicated example is when you create two rules and pack then into a vertical box. This would look like this in plain TeX:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\vbox {\hrule width 20pt height 10pt depth 10pt&lt;br /&gt;
           \hrule width 20pt height 10pt depth 10pt }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would generate a node list like:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Rulenode2.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r1 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r1.width  = 20 * 65536&lt;br /&gt;
r1.height = 10 * 65536&lt;br /&gt;
r1.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r2 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r2.width  = 20 * 65536&lt;br /&gt;
r2.height = 10 * 65536&lt;br /&gt;
r2.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r1.next = r2&lt;br /&gt;
r2.prev = r1&lt;br /&gt;
&lt;br /&gt;
vbox = node.vpack(r1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result is a vbox containing the two rule nodes. The nodes are connected by their next and prev pointers, so the vbox contains them both. The size (width, height and depth) is adjusted automatically.&lt;br /&gt;
&lt;br /&gt;
This also applies to all other things you can put on a TeX page: glyphs, horizontal boxes, math, images, hyperlinks, glue .... For a complete list of the nodes, see the reference manual Chapter 8 &amp;quot;Nodes&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Beyond reports and articles ==&lt;br /&gt;
&lt;br /&gt;
Perhaps the question that comes into your mind is: why should I bother writing Lua code instead of TeX code? For many documents, including articles, reports and books, the classic way to create a PDF with TeX is to use LaTeX or ConTeXt. But there are applications that use TeX as an 100% automatic PDF generation software. If you want to create data sheets or product listings, your normal input is not a classic document, but most likely an Excel spreadsheet or an XML file, perhaps extracted from a database. You won&amp;#039;t have any TeX markup within these documents. So: if you don&amp;#039;t have TeX markup in these documents, you don&amp;#039;t need the TeX interpreter to read these files. More likely is an XML parser or a spreadsheet 2 ... converter.&lt;br /&gt;
&lt;br /&gt;
When you use regular LaTeX or ConTeXt code to put the contents of the database in your PDF (database publishing), you run into several problems:&lt;br /&gt;
&lt;br /&gt;
* Exact positioning of items on the page can be troublesome&lt;br /&gt;
* catcodes / command escapes are to be considered and surely get into your way&lt;br /&gt;
* TeX is no fun to program in (well it is, but only for some people) - calculations, tests, exception handling, control flow&lt;br /&gt;
* The packages that exist may reach their limit soon. You need a super flexible image-between-columns-with-parshape package? Write it yourself.&lt;br /&gt;
&lt;br /&gt;
With Lua you have a very decent programming language that &amp;#039;&amp;#039;is&amp;#039;&amp;#039; fun to program in. When you use the Lua interface to TeX, you have full control of what is happening, which is usually the level of control you need for high quality output.&lt;br /&gt;
&lt;br /&gt;
One approach is to create a stub TeX file and let Lua do the rest:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;myprogram.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The file &amp;lt;tt&amp;gt;myprogram.lua&amp;lt;/tt&amp;gt; then contains all the code to a) read the source file(s), b) extract the information and create the appropriate nodes and c) instruct TeX to create PDF pages from these nodes.&lt;br /&gt;
&lt;br /&gt;
In a future version of LuaTeX you will be able to run the Lua interpreter without the stub TeX file above.&lt;br /&gt;
&lt;br /&gt;
== A first example ==&lt;br /&gt;
&lt;br /&gt;
The example document given below creates two pages by using Lua code alone. You will learn how to access TeX&amp;#039;s boxes and counters from the Lua side, shipout a page into the PDF file, create horizontal and vertical boxes (hbox and vbox), create new nodes and manipulate the nodes links structure. The example covers the following node types: rule, whatsit, vlist, hlist and action.&lt;br /&gt;
&lt;br /&gt;
In the example code we use black squares as the contents of the pages and not normal text, because character handling takes more code and will be covered later on.&lt;br /&gt;
&lt;br /&gt;
Save the following file into &amp;lt;tt&amp;gt;myprogram.lua&amp;lt;/tt&amp;gt; and use the TeX stub from above.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
  -- this will hold the items that go onto the page&lt;br /&gt;
  local pagelist&lt;br /&gt;
  -- local counter = 1&lt;br /&gt;
&lt;br /&gt;
  -- Call tex.shipout() with the contents of the pagelist&lt;br /&gt;
  function shipout()&lt;br /&gt;
&lt;br /&gt;
    local vbox,b = node.vpack(pagelist) -- we ignore the badness &amp;#039;b&amp;#039;&lt;br /&gt;
    tex.box[666] = vbox&lt;br /&gt;
&lt;br /&gt;
    -- require(&amp;quot;viznodelist&amp;quot;)&lt;br /&gt;
    -- viznodelist.nodelist_visualize(vbox,string.format(&amp;quot;head%d.gv&amp;quot;,counter))&lt;br /&gt;
&lt;br /&gt;
    tex.shipout(666)&lt;br /&gt;
    pagelist = nil&lt;br /&gt;
    &lt;br /&gt;
    -- Not strictly necessary. TeX holds the current page number in counter 0.&lt;br /&gt;
    -- TeX displays the contents of this counter when it puts a page into&lt;br /&gt;
    -- the pdf (tex.shipout()). If we don&amp;#039;t change the counter, TeX will&lt;br /&gt;
    -- display [1] [1], instead of [1] [2] for our two page document.&lt;br /&gt;
    tex.count[0] = tex.count[0] + 1&lt;br /&gt;
&lt;br /&gt;
    -- counter = counter + 1&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  function add_to_page( list )&lt;br /&gt;
    -- We attach the nodelist &amp;#039;list&amp;#039; to the end of the pagelist&lt;br /&gt;
    -- if pagelist doesn&amp;#039;t exist, &amp;#039;list&amp;#039; is our new pagelist&lt;br /&gt;
    -- if it exists, we go to the end with node.tail() and adjust&lt;br /&gt;
    -- the prev and next pointers, so list becomes part&lt;br /&gt;
    -- of pagelist.&lt;br /&gt;
    if not pagelist then pagelist = list&lt;br /&gt;
    else&lt;br /&gt;
      local tail = node.tail(pagelist)&lt;br /&gt;
      tail.next = list&lt;br /&gt;
      list.prev  = tail&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- This creates a new square rule and returns the pointer to it.&lt;br /&gt;
function mkrule( size )&lt;br /&gt;
  local r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
  r.width  = size &lt;br /&gt;
  r.height = size / 2&lt;br /&gt;
  r.depth  = size / 2&lt;br /&gt;
  return r&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
do&lt;br /&gt;
  local destcounter = 0&lt;br /&gt;
  -- Create a pdf anchor (dest object). It returns a whatsit node and the &lt;br /&gt;
  -- number of the anchor, so it can be used in a pdf link or an outline.&lt;br /&gt;
  function mkdest()&lt;br /&gt;
    destcounter = destcounter + 1&lt;br /&gt;
    local d = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_dest&amp;quot;)&lt;br /&gt;
    d.named_id = 0&lt;br /&gt;
    d.dest_id = destcounter&lt;br /&gt;
    d.dest_type = 3&lt;br /&gt;
&lt;br /&gt;
    return d, destcounter&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Take a list of nodes and put them into an hbox. The prev and next fields&lt;br /&gt;
-- of the nodes will be set automatically. Return a pointer to the hbox.&lt;br /&gt;
function hpack( ... )&lt;br /&gt;
  local start, tmp, cur&lt;br /&gt;
  start = select(1,...)&lt;br /&gt;
  tmp = start&lt;br /&gt;
  for i=2,select(&amp;quot;#&amp;quot;,...) do&lt;br /&gt;
    cur = select(i,...)&lt;br /&gt;
    tmp.next = cur&lt;br /&gt;
    cur.prev = tmp&lt;br /&gt;
    tmp = cur&lt;br /&gt;
  end&lt;br /&gt;
  local h,b = node.hpack(start) -- ignore badness&lt;br /&gt;
  return h&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local tenpt = 10 * 2^16&lt;br /&gt;
---------------------------&lt;br /&gt;
-- page 1&lt;br /&gt;
---------------------------&lt;br /&gt;
local n,dest = mkdest() -- dest is needed for the link to this anchor&lt;br /&gt;
&lt;br /&gt;
add_to_page(n)&lt;br /&gt;
add_to_page(mkrule(2 * tenpt))&lt;br /&gt;
&lt;br /&gt;
-- The pagelist contains a pdf dest node (a link destination) and a rule of size 20pt x 20pt.&lt;br /&gt;
&lt;br /&gt;
shipout()&lt;br /&gt;
---------------------------&lt;br /&gt;
-- page 2&lt;br /&gt;
---------------------------&lt;br /&gt;
-- This is the page with the link to the anchor (dest) on page one. A&lt;br /&gt;
-- link consists of three nodes: a pdf_start_link, a pdf_end_link and and &lt;br /&gt;
-- action node that specifies the action to perform when the user clicks on&lt;br /&gt;
-- the link.&lt;br /&gt;
-- The pdf link must be inside a horizontal box, that&amp;#039;s why we hpack() it.&lt;br /&gt;
-- The link_attr (link attributes) is optional, here it draws a yellowish border&lt;br /&gt;
-- around the link.&lt;br /&gt;
local start_link = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_start_link&amp;quot;)&lt;br /&gt;
local end_link   = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_end_link&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
start_link.width     = tenpt&lt;br /&gt;
start_link.height    = tenpt / 2&lt;br /&gt;
start_link.depth     = tenpt / 2&lt;br /&gt;
start_link.link_attr = &amp;quot;/C [0.9 1 0] /Border [0 0 2]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
start_link.action = node.new(&amp;quot;action&amp;quot;)&lt;br /&gt;
start_link.action.action_type = 1&lt;br /&gt;
start_link.action.action_id   = dest&lt;br /&gt;
&lt;br /&gt;
local rule = mkrule(tenpt)&lt;br /&gt;
local hbox = hpack(start_link, rule, end_link)&lt;br /&gt;
add_to_page(hbox)&lt;br /&gt;
&lt;br /&gt;
-- This pagelist consists of an hbox whose contents is &amp;quot;start_link&amp;quot;,&lt;br /&gt;
-- the 10pt x 10pt rule and the &amp;quot;end_link&amp;quot; node. &lt;br /&gt;
&lt;br /&gt;
shipout()&lt;br /&gt;
---------------------------&lt;br /&gt;
&lt;br /&gt;
-- Just to show you that you can get some memory usage statistics:&lt;br /&gt;
print(string.format(&amp;quot;\nnode_mem_usage=%s&amp;quot;,status.node_mem_usage))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The idea is to create nodes, collect them in a list (here: pagelist) and use &amp;lt;tt&amp;gt;tex.shipout()&amp;lt;/tt&amp;gt; to put the page into the PDF.&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=121</id>
		<title>TeX without TeX</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=121"/>
		<updated>2011-07-02T19:07:34Z</updated>

		<summary type="html">&lt;p&gt;Patrick: Continue page on &amp;#039;notex&amp;#039;.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Use TeX&amp;#039;s power without TeX macros ==&lt;br /&gt;
&lt;br /&gt;
With LuaTeX you have access to most of TeX&amp;#039;s capabilities for creating PDF documents. Most of the [http://www.luatex.org/svn/trunk/manual/luatexref-t.pdf LuaTeX reference manual] is about this topic. &lt;br /&gt;
&lt;br /&gt;
The underlying idea is to create TeX&amp;#039;s internal data structure as TeX would do by transforming macros and primitives into something called nodes. These nodes are then transformed into instructions for the PDF file (PDF objects). So the following pages deal with node creation and the structures. &lt;br /&gt;
&lt;br /&gt;
Let&amp;#039;s start with a rule node. When you write &amp;lt;tt&amp;gt;\hrule width 20pt height 10pt depth 10pt &amp;lt;/tt&amp;gt; in TeX, a node of type rule will be created, which has three fields: height, depth and width. We can visualize this node by a simple box like this:&lt;br /&gt;
&lt;br /&gt;
[[File:rulenode.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r.width  = 20 * 65536&lt;br /&gt;
r.height = 10 * 65536&lt;br /&gt;
r.depth  = 10 * 65536&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some remarks: the size is in scaled points, and 65536 (=2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;) scaled points are 1 point, so 20pt becomes 20 * 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;. Not shown in the example are (among others) the next and prev fields. These fields hold a pointer (the node address) to the following and the previous nodes. A node that exist by itself has its prev and next fields set to nil.&lt;br /&gt;
&lt;br /&gt;
A slightly more complicated example is when you create two rules and pack then into a vertical box. This would look like this in plain TeX:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\vbox {\hrule width 20pt height 10pt depth 10pt&lt;br /&gt;
           \hrule width 20pt height 10pt depth 10pt }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would generate a node list like:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Rulenode2.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r1 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r1.width  = 20 * 65536&lt;br /&gt;
r1.height = 10 * 65536&lt;br /&gt;
r1.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r2 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r2.width  = 20 * 65536&lt;br /&gt;
r2.height = 10 * 65536&lt;br /&gt;
r2.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r1.next = r2&lt;br /&gt;
r2.prev = r1&lt;br /&gt;
&lt;br /&gt;
vbox = node.vpack(r1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result is a vbox containing the two rule nodes. The nodes are connected by their next and prev pointers, so the vbox contains them both. The size (width, height and depth) is adjusted automatically.&lt;br /&gt;
&lt;br /&gt;
This also applies to all other things you can put on a TeX page: glyphs, horizontal boxes, math, images, hyperlinks, glue .... For a complete list of the nodes, see the reference manual Chapter 8 &amp;quot;Nodes&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Beyond reports and articles ==&lt;br /&gt;
&lt;br /&gt;
Perhaps the question that comes into your mind is: why should I bother writing Lua code instead of TeX code? For many documents, including articles, reports and books, the classic way to create a PDF with TeX is to use LaTeX or ConTeXt. But there are applications that use TeX as an 100% automatic PDF generation software. If you want to create data sheets or product listings, your normal input is not a classic document, but most likely an Excel spreadsheet or an XML file, perhaps extracted from a database. You won&amp;#039;t have any TeX markup within these documents. So: if you don&amp;#039;t have TeX markup in these documents, you don&amp;#039;t need the TeX interpreter to read these files. More likely is an XML parser or a spreadsheet 2 ... converter.&lt;br /&gt;
&lt;br /&gt;
When you use regular LaTeX or ConTeXt code to put the contents of the database in your PDF (database publishing), you run into several problems:&lt;br /&gt;
&lt;br /&gt;
* Exact positioning of items on the page can be troublesome&lt;br /&gt;
* catcodes / command escapes are to be considered and surely get into your way&lt;br /&gt;
* TeX is no fun to program in (well it is, but only for some people) - calculations, tests, exception handling, control flow&lt;br /&gt;
* The packages that exist may reach their limit soon. You need a super flexible image-between-columns-with-parshape package? Write it yourself.&lt;br /&gt;
&lt;br /&gt;
With Lua you have a very decent programming language that &amp;#039;&amp;#039;is&amp;#039;&amp;#039; fun to program in. When you use the Lua interface to TeX, you have full control of what is happening, which is usually the level of control you need for high quality output.&lt;br /&gt;
&lt;br /&gt;
One approach is to create a stub TeX file and let Lua do the rest:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;myprogram.lua&amp;quot;)}&lt;br /&gt;
\end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The file &amp;lt;tt&amp;gt;myprogram.lua&amp;lt;/tt&amp;gt; then contains all the code to a) read the source file(s), b) extract the information and create the appropriate nodes and c) instruct TeX to create PDF pages from these nodes.&lt;br /&gt;
&lt;br /&gt;
In a future version of LuaTeX you will be able to run the Lua interpreter without the stub TeX file above.&lt;br /&gt;
&lt;br /&gt;
== A first (but simple) example ==&lt;br /&gt;
&lt;br /&gt;
The example document given below creates two pages by using Lua code alone. You will learn how to access TeX&amp;#039;s boxes and counters from the Lua side, shipout a page into the PDF file, create horizontal and vertical boxes (hbox and vbox), create new nodes and manipulate the nodes links structure. The example covers the following node types: rule, whatsit, vlist, hlist and action.&lt;br /&gt;
&lt;br /&gt;
In the example code we use black squares as the contents of the pages and not normal text, because character handling takes more code and will be covered later on.&lt;br /&gt;
&lt;br /&gt;
Save the following file into &amp;lt;tt&amp;gt;myprogram.lua&amp;lt;/tt&amp;gt; and use the TeX stub from above.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
  -- this will hold the items that go onto the page&lt;br /&gt;
  local pagelist&lt;br /&gt;
  -- local counter = 1&lt;br /&gt;
&lt;br /&gt;
  -- Call tex.shipout() with the contents of the pagelist&lt;br /&gt;
  function shipout()&lt;br /&gt;
&lt;br /&gt;
    local vbox,b = node.vpack(pagelist) -- we ignore the badness &amp;#039;b&amp;#039;&lt;br /&gt;
    tex.box[666] = vbox&lt;br /&gt;
&lt;br /&gt;
    -- require(&amp;quot;viznodelist&amp;quot;)&lt;br /&gt;
    -- viznodelist.nodelist_visualize(vbox,string.format(&amp;quot;head%d.gv&amp;quot;,counter))&lt;br /&gt;
&lt;br /&gt;
    tex.shipout(666)&lt;br /&gt;
    pagelist = nil&lt;br /&gt;
    &lt;br /&gt;
    -- Not strictly necessary. TeX holds the current page number in counter 0.&lt;br /&gt;
    -- TeX displays the contents of this counter when it puts a page into&lt;br /&gt;
    -- the pdf (tex.shipout()). If we don&amp;#039;t change the counter, TeX will&lt;br /&gt;
    -- display [1] [1], instead of [1] [2] for our two page document.&lt;br /&gt;
    tex.count[0] = tex.count[0] + 1&lt;br /&gt;
&lt;br /&gt;
    -- counter = counter + 1&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  function add_to_page( list )&lt;br /&gt;
    -- We attach the nodelist &amp;#039;list&amp;#039; to the end of the pagelist&lt;br /&gt;
    -- if pagelist doesn&amp;#039;t exist, &amp;#039;list&amp;#039; is our new pagelist&lt;br /&gt;
    -- if it exists, we go to the end with node.tail() and adjust&lt;br /&gt;
    -- the prev and next pointers, so list becomes part&lt;br /&gt;
    -- of pagelist.&lt;br /&gt;
    if not pagelist then pagelist = list&lt;br /&gt;
    else&lt;br /&gt;
      local tail = node.tail(pagelist)&lt;br /&gt;
      tail.next = list&lt;br /&gt;
      list.prev  = tail&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- This creates a new square rule and returns the pointer to it.&lt;br /&gt;
function mkrule( size )&lt;br /&gt;
  local r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
  r.width  = size &lt;br /&gt;
  r.height = size / 2&lt;br /&gt;
  r.depth  = size / 2&lt;br /&gt;
  return r&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
do&lt;br /&gt;
  local destcounter = 0&lt;br /&gt;
  -- Create a pdf anchor (dest object). It returns a whatsit node and the &lt;br /&gt;
  -- number of the anchor, so it can be used in a pdf link or an outline.&lt;br /&gt;
  function mkdest()&lt;br /&gt;
    destcounter = destcounter + 1&lt;br /&gt;
    local d = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_dest&amp;quot;)&lt;br /&gt;
    d.named_id = 0&lt;br /&gt;
    d.dest_id = destcounter&lt;br /&gt;
    d.dest_type = 3&lt;br /&gt;
&lt;br /&gt;
    return d, destcounter&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Take a list of nodes and put them into an hbox. The prev and next fields&lt;br /&gt;
-- of the nodes will be set automatically. Return a pointer to the hbox.&lt;br /&gt;
function hpack( ... )&lt;br /&gt;
  local start, tmp, cur&lt;br /&gt;
  start = select(1,...)&lt;br /&gt;
  tmp = start&lt;br /&gt;
  for i=2,select(&amp;quot;#&amp;quot;,...) do&lt;br /&gt;
    cur = select(i,...)&lt;br /&gt;
    tmp.next = cur&lt;br /&gt;
    cur.prev = tmp&lt;br /&gt;
    tmp = cur&lt;br /&gt;
  end&lt;br /&gt;
  local h,b = node.hpack(start) -- ignore badness&lt;br /&gt;
  return h&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local tenpt = 10 * 2^16&lt;br /&gt;
---------------------------&lt;br /&gt;
-- page 1&lt;br /&gt;
---------------------------&lt;br /&gt;
local n,dest = mkdest() -- dest is needed for the link to this anchor&lt;br /&gt;
&lt;br /&gt;
add_to_page(n)&lt;br /&gt;
add_to_page(mkrule(2 * tenpt))&lt;br /&gt;
&lt;br /&gt;
-- The pagelist contains a pdf dest node (a link destination) and a rule of size 20pt x 20pt.&lt;br /&gt;
&lt;br /&gt;
shipout()&lt;br /&gt;
---------------------------&lt;br /&gt;
-- page 2&lt;br /&gt;
---------------------------&lt;br /&gt;
-- This is the page with the link to the anchor (dest) on page one. A&lt;br /&gt;
-- link consists of three nodes: a pdf_start_link, a pdf_end_link and and &lt;br /&gt;
-- action node that specifies the action to perform when the user clicks on&lt;br /&gt;
-- the link.&lt;br /&gt;
-- The pdf link must be inside a horizontal box, that&amp;#039;s why we hpack() it.&lt;br /&gt;
-- The link_attr (link attributes) is optional, here it draws a yellowish border&lt;br /&gt;
-- around the link.&lt;br /&gt;
local start_link = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_start_link&amp;quot;)&lt;br /&gt;
local end_link   = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_end_link&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
start_link.width     = tenpt&lt;br /&gt;
start_link.height    = tenpt / 2&lt;br /&gt;
start_link.depth     = tenpt / 2&lt;br /&gt;
start_link.link_attr = &amp;quot;/C [0.9 1 0] /Border [0 0 2]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
start_link.action = node.new(&amp;quot;action&amp;quot;)&lt;br /&gt;
start_link.action.action_type = 1&lt;br /&gt;
start_link.action.action_id   = dest&lt;br /&gt;
&lt;br /&gt;
local rule = mkrule(tenpt)&lt;br /&gt;
local hbox = hpack(start_link, rule, end_link)&lt;br /&gt;
add_to_page(hbox)&lt;br /&gt;
&lt;br /&gt;
-- This pagelist consists of an hbox whose contents is &amp;quot;start_link&amp;quot;,&lt;br /&gt;
-- the 10pt x 10pt rule and the &amp;quot;end_link&amp;quot; node. &lt;br /&gt;
&lt;br /&gt;
shipout()&lt;br /&gt;
---------------------------&lt;br /&gt;
&lt;br /&gt;
-- Just to show you that you can get some memory usage statistics:&lt;br /&gt;
print(string.format(&amp;quot;\nnode_mem_usage=%s&amp;quot;,status.node_mem_usage))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The idea is to create nodes, collect them in a list (here: pagelist) and use &amp;lt;tt&amp;gt;tex.shipout()&amp;lt;/tt&amp;gt; to put the page into the PDF.&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=Help:Editing&amp;diff=120</id>
		<title>Help:Editing</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=Help:Editing&amp;diff=120"/>
		<updated>2011-07-02T18:46:07Z</updated>

		<summary type="html">&lt;p&gt;Patrick: Link to the mediwiki.org page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See [http://www.mediawiki.org/wiki/Help:Formatting the formatting page on the mediwiki.org site]&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=119</id>
		<title>TeX without TeX</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=119"/>
		<updated>2011-07-02T12:05:02Z</updated>

		<summary type="html">&lt;p&gt;Patrick: formatting the link to the reference manual&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Use TeX&amp;#039;s power without TeX macros ==&lt;br /&gt;
&lt;br /&gt;
With LuaTeX you have access to most of TeX&amp;#039;s capabilities for creating PDF documents. Most of the [http://www.luatex.org/svn/trunk/manual/luatexref-t.pdf LuaTeX reference manual] is about this topic. &lt;br /&gt;
&lt;br /&gt;
The underlying idea is to create TeX&amp;#039;s internal data structure as TeX would do by transforming macros and primitives into something called nodes. These nodes are then transformed into instructions for the PDF file (PDF objects). So the following pages deal with node creation and the structures. &lt;br /&gt;
&lt;br /&gt;
Let&amp;#039;s start with a rule node. When you write &amp;lt;tt&amp;gt;\hrule width 20pt height 10pt depth 10pt &amp;lt;/tt&amp;gt; in TeX, a node of type rule will be created, which has three fields: height, depth and width. We can visualize this node by a simple box like this:&lt;br /&gt;
&lt;br /&gt;
[[File:rulenode.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r.width  = 20 * 65536&lt;br /&gt;
r.height = 10 * 65536&lt;br /&gt;
r.depth  = 10 * 65536&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some remarks: the size is in scaled points, and 65536 (=2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;) scaled points are 1 point, so 20pt becomes 20 * 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;. Not shown in the example are (among others) the next and prev fields. These fields hold a pointer (the node address) to the following and the previous nodes. A node that exist by itself has its prev and next fields set to nil.&lt;br /&gt;
&lt;br /&gt;
A slightly more complicated example is when you create two rules and pack then into a vertical box. This would look like this in plain TeX:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\vbox {\hrule width 20pt height 10pt depth 10pt&lt;br /&gt;
           \hrule width 20pt height 10pt depth 10pt }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would generate a node list like:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Rulenode2.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r1 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r1.width  = 20 * 65536&lt;br /&gt;
r1.height = 10 * 65536&lt;br /&gt;
r1.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r2 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r2.width  = 20 * 65536&lt;br /&gt;
r2.height = 10 * 65536&lt;br /&gt;
r2.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r1.next = r2&lt;br /&gt;
r2.prev = r1&lt;br /&gt;
&lt;br /&gt;
vbox = node.vpack(r1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result is a vbox containing the two rule nodes. &lt;br /&gt;
&lt;br /&gt;
This also applies to all other things you can put on a TeX page: glyphs, horizontal boxes, math, images, hyperlinks, glue .... For a complete list of the nodes, see the reference manual Chapter 8 &amp;quot;Nodes&amp;quot;.&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=118</id>
		<title>TeX without TeX</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=118"/>
		<updated>2011-07-02T11:39:10Z</updated>

		<summary type="html">&lt;p&gt;Patrick: ^ -&amp;gt; sup&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Use TeX&amp;#039;s power without TeX macros ==&lt;br /&gt;
&lt;br /&gt;
With LuaTeX you have access to most of TeX&amp;#039;s capabilities for creating PDF documents. Most of the [[http://www.luatex.org/svn/trunk/manual/luatexref-t.pdf LuaTeX reference manual]] is about this topic. &lt;br /&gt;
&lt;br /&gt;
The underlying idea is to create TeX&amp;#039;s internal data structure as TeX would do by transforming macros and primitives into something called nodes. These nodes are then transformed into instructions for the PDF file (PDF objects). So the following pages deal with node creation and the structures. &lt;br /&gt;
&lt;br /&gt;
Let&amp;#039;s start with a rule node. When you write &amp;lt;tt&amp;gt;\hrule width 20pt height 10pt depth 10pt &amp;lt;/tt&amp;gt; in TeX, a node of type rule will be created, which has three fields: height, depth and width. We can visualize this node by a simple box like this:&lt;br /&gt;
&lt;br /&gt;
[[File:rulenode.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r.width  = 20 * 65536&lt;br /&gt;
r.height = 10 * 65536&lt;br /&gt;
r.depth  = 10 * 65536&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some remarks: the size is in scaled points, and 65536 (=2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;) scaled points are 1 point, so 20pt becomes 20 * 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;. Not shown in the example are (among others) the next and prev fields. These fields hold a pointer (the node address) to the following and the previous nodes. A node that exist by itself has its prev and next fields set to nil.&lt;br /&gt;
&lt;br /&gt;
A slightly more complicated example is when you create two rules and pack then into a vertical box. This would look like this in plain TeX:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\vbox {\hrule width 20pt height 10pt depth 10pt&lt;br /&gt;
           \hrule width 20pt height 10pt depth 10pt }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would generate a node list like:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Rulenode2.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r1 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r1.width  = 20 * 65536&lt;br /&gt;
r1.height = 10 * 65536&lt;br /&gt;
r1.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r2 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r2.width  = 20 * 65536&lt;br /&gt;
r2.height = 10 * 65536&lt;br /&gt;
r2.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r1.next = r2&lt;br /&gt;
r2.prev = r1&lt;br /&gt;
&lt;br /&gt;
vbox = node.vpack(r1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result is a vbox containing the two rule nodes. &lt;br /&gt;
&lt;br /&gt;
This also applies to all other things you can put on a TeX page: glyphs, horizontal boxes, math, images, hyperlinks, glue .... For a complete list of the nodes, see the reference manual Chapter 8 &amp;quot;Nodes&amp;quot;.&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=117</id>
		<title>TeX without TeX</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=TeX_without_TeX&amp;diff=117"/>
		<updated>2011-07-02T11:11:38Z</updated>

		<summary type="html">&lt;p&gt;Patrick: Started page on TeX without TeX&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Use TeX&amp;#039;s power without TeX macros ==&lt;br /&gt;
&lt;br /&gt;
With LuaTeX you have access to most of TeX&amp;#039;s capabilities for creating PDF documents. Most of the [[http://www.luatex.org/svn/trunk/manual/luatexref-t.pdf LuaTeX reference manual]] is about this topic. &lt;br /&gt;
&lt;br /&gt;
The underlying idea is to create TeX&amp;#039;s internal data structure as TeX would do by transforming macros and primitives into something called nodes. These nodes are then transformed into instructions for the PDF file (PDF objects). So the following pages deal with node creation and the structures. &lt;br /&gt;
&lt;br /&gt;
Let&amp;#039;s start with a rule node. When you write &amp;lt;tt&amp;gt;\hrule width 20pt height 10pt depth 10pt &amp;lt;/tt&amp;gt; in TeX, a node of type rule will be created, which has three fields: height, depth and width. We can visualize this node by a simple box like this:&lt;br /&gt;
&lt;br /&gt;
[[File:rulenode.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r.width  = 20 * 65536&lt;br /&gt;
r.height = 10 * 65536&lt;br /&gt;
r.depth  = 10 * 65536&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some remarks: the size is in scaled points, and 65536 (=2^16) scaled points are 1 point, so 20pt becomes 20 * 2^16. Not shown in the example are (among others) the next and prev fields. These fields hold a pointer (the node address) to the following and the previous nodes. A node that exist by itself has its prev and next fields set to nil.&lt;br /&gt;
&lt;br /&gt;
A slightly more complicated example is when you create two rules and pack then into a vertical box. This would look like this in plain TeX:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\vbox {\hrule width 20pt height 10pt depth 10pt&lt;br /&gt;
           \hrule width 20pt height 10pt depth 10pt }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would generate a node list like:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Rulenode2.png]]&lt;br /&gt;
&lt;br /&gt;
The same can be done directly in Lua:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r1 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r1.width  = 20 * 65536&lt;br /&gt;
r1.height = 10 * 65536&lt;br /&gt;
r1.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r2 = node.new(&amp;quot;rule&amp;quot;)&lt;br /&gt;
r2.width  = 20 * 65536&lt;br /&gt;
r2.height = 10 * 65536&lt;br /&gt;
r2.depth  = 10 * 65536&lt;br /&gt;
&lt;br /&gt;
r1.next = r2&lt;br /&gt;
r2.prev = r1&lt;br /&gt;
&lt;br /&gt;
vbox = node.vpack(r1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result is a vbox containing the two rule nodes. &lt;br /&gt;
&lt;br /&gt;
This also applies to all other things you can put on a TeX page: glyphs, horizontal boxes, math, images, hyperlinks, glue .... For a complete list of the nodes, see the reference manual Chapter 8 &amp;quot;Nodes&amp;quot;.&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=File:Rulenode2.png&amp;diff=116</id>
		<title>File:Rulenode2.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=File:Rulenode2.png&amp;diff=116"/>
		<updated>2011-07-02T11:07:26Z</updated>

		<summary type="html">&lt;p&gt;Patrick: vlist/rule/rule node visualized&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;vlist/rule/rule node visualized&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=File:Rulenode.png&amp;diff=115</id>
		<title>File:Rulenode.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=File:Rulenode.png&amp;diff=115"/>
		<updated>2011-07-02T10:54:48Z</updated>

		<summary type="html">&lt;p&gt;Patrick: uploaded a new version of &amp;amp;quot;File:Rulenode.png&amp;amp;quot;: Smaller size&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;simple rule node&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=File:Rulenode.png&amp;diff=114</id>
		<title>File:Rulenode.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=File:Rulenode.png&amp;diff=114"/>
		<updated>2011-07-02T09:45:01Z</updated>

		<summary type="html">&lt;p&gt;Patrick: simple rule node&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;simple rule node&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=Main_Page&amp;diff=113</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=Main_Page&amp;diff=113"/>
		<updated>2011-07-02T09:27:49Z</updated>

		<summary type="html">&lt;p&gt;Patrick: /* Some articles */ Link to TeX without TeX&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Welcome to the LuaTeX wiki ==&lt;br /&gt;
&lt;br /&gt;
This is a wiki for [http://www.luatex.org LuaTeX], a typesetting engine derived from &lt;br /&gt;
[http://en.wikipedia.org/wiki/TeX TeX] that includes [http://www.lua.org Lua] as an embedded scripting language.&lt;br /&gt;
&lt;br /&gt;
See [[Special:Allpages|all the articles]] or the [[Special:Recentchanges|recent changes]].&lt;br /&gt;
&lt;br /&gt;
* [http://www.mediawiki.org/wiki/Help:Formatting How to edit wiki pages]&lt;br /&gt;
* [[Bug tracking|Bug tracking]]: Mantis [http://tracker.luatex.org bug tracker]&lt;br /&gt;
&lt;br /&gt;
== Some articles ==&lt;br /&gt;
&lt;br /&gt;
* [[Documentation and help]] points to other online resources (manuals, mailing list, etc.) related to LuaTeX.&lt;br /&gt;
* [[Writing Lua in TeX]] explains how to write Lua code in a TeX document (and back).&lt;br /&gt;
* [[Attributes]] introduces LuaTeX&amp;#039;s thrilling new concept.&lt;br /&gt;
* Pages on callbacks:&lt;br /&gt;
** [[Callbacks]] introduces callbacks and how to use them.&lt;br /&gt;
** There is a page on the [[Post linebreak filter|&amp;lt;tt&amp;gt;post_linebreak_filter&amp;lt;/tt&amp;gt;]] callback, explaining and illustrating it with a couple of examples. The [[Show the hyphenation points]] article is another example of use.&lt;br /&gt;
** The page on [[process input buffer|the &amp;lt;tt&amp;gt;process_input_buffer&amp;lt;/tt&amp;gt; callback]] illustrates how to read documents with non-UTF-8 encoding, and how to write TeX with lightweight markup instead of the usual commands.&lt;br /&gt;
** Another callback is [[show error hook|&amp;lt;tt&amp;gt;show_error_hook&amp;lt;/tt&amp;gt;]], which lets you enliven your error messages!&lt;br /&gt;
** You can fake XeTeX&amp;#039;s interchar tokens with the [[token filter|&amp;lt;tt&amp;gt;token_filter&amp;lt;/tt&amp;gt;]].&lt;br /&gt;
* [[TeX without TeX]] is about using TeX&amp;#039;s functionality (typesetting, pdf writing) only using Lua code (no &amp;lt;tt&amp;gt;\TeX&amp;lt;/tt&amp;gt; macros).&lt;br /&gt;
&lt;br /&gt;
== From the old bluwiki.com ==&lt;br /&gt;
&lt;br /&gt;
(Mostly by and thanks to [http://omega.enstb.org/yannis/ Yannis Haralambous])&lt;br /&gt;
&lt;br /&gt;
* An example of code [[traversing TeX nodes]] before an horizontal list goes through the line breaking engine;&lt;br /&gt;
* An example of code [[traversing tokens]] just before execution or expansion;&lt;br /&gt;
* you want to [[explore the table obtained from a TrueType font]], loaded by &amp;lt;tt&amp;gt;font.read_ttf&amp;lt;/tt&amp;gt;;&lt;br /&gt;
* you want to [[explore the internal font table]] of a pre-loaded font or of a font you have loaded by &amp;lt;tt&amp;gt;\font&amp;lt;/tt&amp;gt; and then used for at least one glyph;&lt;br /&gt;
* how to [[use a TrueType font]] without going through a TFM or a OFM file;&lt;br /&gt;
* how to do &amp;lt;i&amp;gt;kinsoku&amp;lt;/i&amp;gt; ([[Japanese and more generally CJK typesetting]]);&lt;br /&gt;
* you want a newline in your log file or on the terminal? add &amp;lt;tt&amp;gt;\string\n&amp;lt;/tt&amp;gt; to your string;&lt;br /&gt;
* you want to [[sort a token list]];&lt;br /&gt;
* you want to [[split a comma-separated list]];&lt;br /&gt;
* you want to [[encrypt your document using ROT13]];&lt;br /&gt;
* you want to [[typeset non-TeX files by converting them using Lua code]];&lt;br /&gt;
* example code to [[mirror characters with Bidi_Mirrored property]];&lt;br /&gt;
* using mplib to write [[metapost with LuaTeX]]&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=User:Patrick&amp;diff=61</id>
		<title>User:Patrick</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=User:Patrick&amp;diff=61"/>
		<updated>2011-01-11T16:09:18Z</updated>

		<summary type="html">&lt;p&gt;Patrick: Link to luatex.de&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;LuaTeX addict. Contact me at patrick &amp;lt;at&amp;gt; gundla &amp;lt;dot&amp;gt; ch.&lt;br /&gt;
&lt;br /&gt;
If you can read german, see more LuaTeX stuff at http://www.luatex.de.&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=Show_the_hyphenation_points&amp;diff=60</id>
		<title>Show the hyphenation points</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=Show_the_hyphenation_points&amp;diff=60"/>
		<updated>2011-01-11T15:35:07Z</updated>

		<summary type="html">&lt;p&gt;Patrick: show the disc nodes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This LaTeX example adds a function to the &amp;lt;tt&amp;gt;post_linebreak_filter&amp;lt;/tt&amp;gt; callback. The function iterates through all the nodes in the paragraph (and descends into the vlist and hlist nodes) and inserts a small rule where the discretionary nodes are.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\documentclass[12pt,a4paper]{scrartcl}&lt;br /&gt;
\usepackage[english]{babel}&lt;br /&gt;
\usepackage{blindtext}&lt;br /&gt;
\usepackage{fontspec}&lt;br /&gt;
\directlua{&lt;br /&gt;
show_hyph = function(head)&lt;br /&gt;
  while head do&lt;br /&gt;
    if head.id == 0 or head.id == 1 then % hlist, vlist&lt;br /&gt;
      show_hyph(head.list) % should be head.head in a newer luatex than 0.64&lt;br /&gt;
    elseif head.id == 7 then             % disc&lt;br /&gt;
      local n = node.new(&amp;quot;whatsit&amp;quot;,&amp;quot;pdf_literal&amp;quot;)&lt;br /&gt;
      n.mode = 0&lt;br /&gt;
      n.data = &amp;quot;q 0.3 w 0 2 m 0 7 l S Q&amp;quot;&lt;br /&gt;
      n.next = head.next&lt;br /&gt;
      n.prev = head&lt;br /&gt;
      head.next = n&lt;br /&gt;
      head = n&lt;br /&gt;
    end&lt;br /&gt;
  head = head.next&lt;br /&gt;
  end&lt;br /&gt;
  return true&lt;br /&gt;
end&lt;br /&gt;
luatexbase.add_to_callback(&amp;quot;post_linebreak_filter&amp;quot;,show_hyph,&amp;quot;show_hyph&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
\begin{document}&lt;br /&gt;
\begin{minipage}{5cm}&lt;br /&gt;
\blindtext&lt;br /&gt;
\end{minipage}&lt;br /&gt;
\end{document}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=Writing_Lua_in_TeX&amp;diff=50</id>
		<title>Writing Lua in TeX</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=Writing_Lua_in_TeX&amp;diff=50"/>
		<updated>2010-12-27T19:04:29Z</updated>

		<summary type="html">&lt;p&gt;Patrick: Undo revision 49 by 89.162.236.186 (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Embedding Lua code in a TeX document =&lt;br /&gt;
&lt;br /&gt;
Although it is simpler to put Lua code in Lua files, from time to time one may want or need to go Lua in the middle of a document. To this end, LuaTeX has two commands: &amp;lt;tt&amp;gt;\directlua&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;\latelua&amp;lt;/tt&amp;gt;. They work the same, except &amp;lt;tt&amp;gt;\latelua&amp;lt;/tt&amp;gt; is processed when the page where it appears is shipped out, whereas &amp;lt;tt&amp;gt;\directlua&amp;lt;/tt&amp;gt; is processed at once; the distinction is immaterial here, and what is said of &amp;lt;tt&amp;gt;\directlua&amp;lt;/tt&amp;gt; also applies to &amp;lt;tt&amp;gt;\latelua&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;\directlua&amp;lt;/tt&amp;gt; can be called in three ways:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua {&amp;lt;lua code&amp;gt;}&lt;br /&gt;
\directlua name {&amp;lt;name&amp;gt;} {&amp;lt;lua code&amp;gt;}&lt;br /&gt;
\directlua &amp;lt;number&amp;gt; {&amp;lt;lua code&amp;gt;}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Those three ways are equivalent when it comes to process &amp;lt;tt&amp;gt;&amp;lt;lua code&amp;gt;&amp;lt;/tt&amp;gt;, but in the second case processing will occur in a chunk named &amp;lt;tt&amp;gt;&amp;lt;name&amp;gt;&amp;lt;/tt&amp;gt;, and in the third it will occur in a chunk whose name is the entry &amp;lt;tt&amp;gt;&amp;lt;number&amp;gt;&amp;lt;/tt&amp;gt; in the table &amp;lt;tt&amp;gt;lua.name&amp;lt;/tt&amp;gt;. The difference manifests itself only when errors occur, in which case the name of the chunk, if any, is reported.&lt;br /&gt;
&lt;br /&gt;
Each call to &amp;lt;tt&amp;gt;\directlua&amp;lt;/tt&amp;gt;, named or not, is processed in a separate chunk. That means that any &amp;lt;tt&amp;gt;local&amp;lt;/tt&amp;gt; variable is defined for this call only and is lost afterward. Hence:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{&lt;br /&gt;
  one = 1&lt;br /&gt;
  local two = 2&lt;br /&gt;
}&lt;br /&gt;
\directlua{&lt;br /&gt;
  texio.write_nl(type(one))&lt;br /&gt;
  texio.write_nl(type(two))&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will report &amp;lt;tt&amp;gt;number&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;nil&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;texio.write_nl&amp;lt;/tt&amp;gt; writes to the log file). On the other hand, Lua code is completely insensitive to TeX&amp;#039;s grouping mechanism. In other words, calling &amp;lt;tt&amp;gt;\directlua&amp;lt;/tt&amp;gt; between &amp;lt;tt&amp;gt;\bgroup&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;\egroup&amp;lt;/tt&amp;gt; doesn&amp;#039;t affect the code to be processed.&lt;br /&gt;
&lt;br /&gt;
= TeX catcodes in Lua =&lt;br /&gt;
&lt;br /&gt;
By default, the code passed to &amp;lt;tt&amp;gt;\directlua&amp;lt;/tt&amp;gt; is treated as normal TeX input and only then sent to the Lua interpreter. This may lead to unwanted results and must be acknowledged.&lt;br /&gt;
&lt;br /&gt;
== Expansion ==&lt;br /&gt;
&lt;br /&gt;
As with any other special, the code in &amp;lt;tt&amp;gt;\directlua&amp;lt;/tt&amp;gt; (and the &amp;lt;tt&amp;gt;&amp;lt;name&amp;gt;&amp;lt;/tt&amp;gt;, if specifed) is fully expanded. This means that macros can be safely passed to &amp;lt;tt&amp;gt;\directlua&amp;lt;/tt&amp;gt; if one wants their values, but that they should also be properly escaped when needed. For instance:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\def\macro{1}&lt;br /&gt;
\directlua{&lt;br /&gt;
  myvar = \macro&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defines &amp;lt;tt&amp;gt;myvar&amp;lt;/tt&amp;gt; as the number &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;. To store the control sequence &amp;lt;tt&amp;gt;\macro&amp;lt;/tt&amp;gt; instead, another course of action is needed: see the [[#Backslash|section on backslash]] below.&lt;br /&gt;
&lt;br /&gt;
== Line ends ==&lt;br /&gt;
&lt;br /&gt;
When TeX reads a file, it normally turns line ends into spaces. That means that what looks like several lines is actually fed to the Lua interpreter as one big line. For instance:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{&lt;br /&gt;
  myvar = 1&lt;br /&gt;
  anothervar = 2&lt;br /&gt;
  onelastvar = 3&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
amounts to the following, if it were written in a separate Lua file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
myvar = 1 anothervar = 2 onelastvar = 3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That is perfectly legitimate, but strange things might happen. First, TeX macros gobble spaces as usual. Hence:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\def\macro{1}&lt;br /&gt;
\directlua{&lt;br /&gt;
  myvar = \macro&lt;br /&gt;
  anothervar = 2&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will be fed to the interpreter as&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
myvar = 1anothervar = 2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which is not legitimate at all. Second, the Lua comment &amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt; will affect everything to the end of the &amp;lt;tt&amp;gt;\directlua&amp;lt;/tt&amp;gt; call. That is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{&lt;br /&gt;
  myvar = 1&lt;br /&gt;
--  anothervar = 2&lt;br /&gt;
  onelastvar = 3&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will be processed as&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
myvar = 1 -- anothervar = 2 onelastvar = 3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which works but only defines &amp;lt;tt&amp;gt;myvar&amp;lt;/tt&amp;gt;. Third, when reporting error, the Lua interpreter will always mention the line number as 1, since it processes one big line only; that isn&amp;#039;t extremely useful when the code is large.&lt;br /&gt;
&lt;br /&gt;
The solution is to set &amp;lt;tt&amp;gt;\endlinechar=10&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;\catcode`\^^M=12&amp;lt;/tt&amp;gt;. In both cases, line ends will be preserved and the code will be processed as it is input.&lt;br /&gt;
&lt;br /&gt;
== Special characters ==&lt;br /&gt;
&lt;br /&gt;
In TeX, some characters have a special behavior. That must be taken into account when writing Lua code: one must change their catcodes beforehand if one wants to handle them as Lua would, as has just been done for line ends. That means that &amp;lt;tt&amp;gt;\directlua&amp;lt;/tt&amp;gt;, as such, is clearly insufficient to write any extended chunk of code. It is thus better to devise a special macro that sets the catcodes to the appropriate values, reads the Lua code, feeds it to &amp;lt;tt&amp;gt;\directlua&amp;lt;/tt&amp;gt;, and restores the catcodes. The following code does the job:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\def\luacode{%&lt;br /&gt;
  \bgroup&lt;br /&gt;
  \catcode`\{=12&lt;br /&gt;
  \catcode`\}=12&lt;br /&gt;
  \catcode`\^^M=12&lt;br /&gt;
  \catcode`\#=12&lt;br /&gt;
  \catcode`\~=12&lt;br /&gt;
  \catcode`\%=12&lt;br /&gt;
  \doluacode&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
\bgroup&lt;br /&gt;
\catcode`\^^M=12 %&lt;br /&gt;
\long\gdef\doluacode#1^^M#2\endluacode{\directlua{#2}\egroup}%&lt;br /&gt;
\egroup&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that not all special characters are set to normal (catcode 12) characters; that is explained for each below. Note also that &amp;lt;tt&amp;gt;\doluacode&amp;lt;/tt&amp;gt;, internally called by &amp;lt;tt&amp;gt;\luacode&amp;lt;/tt&amp;gt;, is defined to get rid of anything up to the line end, and then pass anything up to &amp;lt;tt&amp;gt;\endluacode&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;\directlua&amp;lt;/tt&amp;gt;. Discarding what follows &amp;lt;tt&amp;gt;\luacode&amp;lt;/tt&amp;gt; is important, otherwise a simple code as&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\luacode&lt;br /&gt;
myvar = 1&lt;br /&gt;
\endluacode&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
would actually create two lines, the first being empty; it is annoying because errors are then reported with the wrong line number (i.e. any error in this one-line code would be reported to happen on line 2).&lt;br /&gt;
&lt;br /&gt;
However, the rest of the line after &amp;lt;tt&amp;gt;\luacode&amp;lt;/tt&amp;gt; could also be processed, instead of discarded, to manage special effects (e.g. specifying a chunk&amp;#039;s name, storing the code in a control sequence, or even setting which catcodes should be changed or not).&lt;br /&gt;
&lt;br /&gt;
=== Backslash ===&lt;br /&gt;
&lt;br /&gt;
The backslash in TeX is used to form control sequences. In the definition of &amp;lt;tt&amp;gt;\luacode&amp;lt;/tt&amp;gt; above, it isn&amp;#039;t changed and thus behaves as usual. It allows commands to be passed and expanded to the Lua code. Anyway a backslash in Lua is also an escape character in strings. Hence, if one wants to store the name of a macro in Lua code, the following won&amp;#039;t work:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\luacode&lt;br /&gt;
myvar = &amp;quot;\noexpand\macro&amp;quot;&lt;br /&gt;
\endluacode&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
because to the Lua interpreter the string is made of &amp;lt;tt&amp;gt;\m&amp;lt;/tt&amp;gt; followed by &amp;lt;tt&amp;gt;acro&amp;lt;/tt&amp;gt;; since &amp;lt;tt&amp;gt;\m&amp;lt;/tt&amp;gt; is not defined in Lua, the string is read as &amp;lt;tt&amp;gt;macro&amp;lt;/tt&amp;gt;, but in other circumstances strange things might happen: for instance, &amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt; is a newline. The proper way to pass a macro verbatim is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\luacode&lt;br /&gt;
myvar = &amp;quot;\noexpand\\macro&amp;quot;&lt;br /&gt;
\endluacode&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which Lua will correctly read as&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
myvar = &amp;quot;\\macro&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with the backslash escaped to represent itself. Another solution is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
myvar = [[\noexpand\macro]]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;tt&amp;gt;myvar&amp;lt;/tt&amp;gt; will be defined with a trailing space, i.e. as &amp;lt;tt&amp;gt;&amp;quot;\macro &amp;quot;&amp;lt;/tt&amp;gt;, because of TeX&amp;#039;s habit to append a trailing space to unexpanded (or unexpandable) control sequences.&lt;br /&gt;
&lt;br /&gt;
=== Braces ===&lt;br /&gt;
&lt;br /&gt;
One may want to define a string in Lua which contains unbalanced braces, i.e.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\luacode&lt;br /&gt;
myvar = &amp;quot;{&amp;quot;&lt;br /&gt;
\endluacode&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the braces&amp;#039; catcodes hadn&amp;#039;t been changed beforehand, that would be impossible. Note, however, that this means that one can&amp;#039;t feed arguments to commands in the usual way. I.e. the following will produce nothing good:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\luacode&lt;br /&gt;
myvar = &amp;quot;\dosomething{\macro}&amp;quot;&lt;br /&gt;
\endluacode&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;\dosomething&amp;lt;/tt&amp;gt; will be expanded with the left brace (devoid of its usual delimiter-ness) as its argument, and the rest of the line might produce chaos. Thus, one may also choose not to change the catcodes of braces, depending on how &amp;lt;tt&amp;gt;\luacode&amp;lt;/tt&amp;gt; is most likely to be used. Note that strings with unbalanced braces can still be defined, even if braces have their usual catcodes, thanks to the following trick:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\luacode&lt;br /&gt;
myvar = &amp;quot;{&amp;quot; -- }&lt;br /&gt;
\endluacode&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the code is passed to &amp;lt;tt&amp;gt;\directlua&amp;lt;/tt&amp;gt;, braces are balanced because the Lua comment means nothing to TeX; when passed to the Lua interpreter, on the other hand, the right brace is ignored.&lt;br /&gt;
&lt;br /&gt;
=== Hash and comment ===&lt;br /&gt;
&lt;br /&gt;
The hash sign &amp;lt;tt&amp;gt;#&amp;lt;/tt&amp;gt; in Lua is the length operator: prefixed to a string or table variable, it returns its length. If its catcode weren&amp;#039;t taken care of, LuaTeX would pass to &amp;lt;tt&amp;gt;\directlua&amp;lt;/tt&amp;gt; a double hash for each hash, i.e. each &amp;lt;tt&amp;gt;#&amp;lt;/tt&amp;gt; would be turned into &amp;lt;tt&amp;gt;##&amp;lt;/tt&amp;gt;. That is normal TeX behavior, but unwanted here.&lt;br /&gt;
&lt;br /&gt;
As for the commen sign &amp;lt;tt&amp;gt;%&amp;lt;/tt&amp;gt;, it is useful in Lua when manipulating strings. If it weren&amp;#039;t escaped it would discard parts of the code when TeX reads it, and a mutilated version of the input would be passed to the Lua interpreter. In turn, discarding a line by commenting it in &amp;lt;tt&amp;gt;\luacode&amp;lt;/tt&amp;gt; should be done with the Lua comment &amp;lt;tt&amp;gt;--&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Active characters ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;~&amp;lt;/tt&amp;gt; character is generally active and used as a no-break space in TeX. It it were passed as is to &amp;lt;tt&amp;gt;\directlua&amp;lt;/tt&amp;gt;, it would expand to uninterpretable control sequences, whereas in Lua it is used to form the unequal operator &amp;lt;tt&amp;gt;~=&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Other possible active characters should be taken care of, but which characters are active is unpredictable; punctuation marks might be so to accommodate special spacing, as with LaTeX&amp;#039;s &amp;#039;&amp;#039;babel&amp;#039;&amp;#039; package, but such tricks are unlikely to survive in LuaTeX (cleaner methods exist that add a space before punctuation marks when necessary).&lt;br /&gt;
&lt;br /&gt;
=== Other characters ===&lt;br /&gt;
&lt;br /&gt;
When processing verbatim text in TeX, one generally also changes the catcodes of &amp;lt;tt&amp;gt;$&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;&amp;amp;&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;^&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt; and the space character, because they too are special. When passed to the Lua interpreter, though, their usual catcodes won&amp;#039;t do any harm, that is why they are left unmodified here.&lt;br /&gt;
&lt;br /&gt;
== \luaescapestring ==&lt;br /&gt;
&lt;br /&gt;
Although it can&amp;#039;t do all of what&amp;#039;s been explained, the &amp;lt;tt&amp;gt;\luaescapestring&amp;lt;/tt&amp;gt; command might be useful in some cases: it expands its argument (which must be enclosed in &amp;#039;&amp;#039;real&amp;#039;&amp;#039; braces) fully, then modify it so that dangerous characters are escaped: backslashes, hashes, quotes and line ends. For instance:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\def\macro{&amp;quot;\noexpand\foo&amp;quot;}&lt;br /&gt;
\luacode&lt;br /&gt;
myvar = &amp;quot;\luaescapestring{\macro}&amp;quot;&lt;br /&gt;
\endluacode&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will be passed to Lua as&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
myvar = &amp;quot;\&amp;quot;\\foo \&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
so that &amp;lt;tt&amp;gt;myvar&amp;lt;/tt&amp;gt; is defined as &amp;lt;tt&amp;gt;&amp;quot;\foo &amp;quot;&amp;lt;/tt&amp;gt;, with the quotes as parts of it. Note that the trailing space after &amp;lt;tt&amp;gt;\foo&amp;lt;/tt&amp;gt; still happens.&lt;br /&gt;
&lt;br /&gt;
= From Lua to TeX =&lt;br /&gt;
&lt;br /&gt;
Inside Lua code, one can pass strings to be processed by TeX with the functions &amp;lt;tt&amp;gt;tex.print()&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;tex.sprint()&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;tex.tprint()&amp;lt;/tt&amp;gt;. All such calls are processed at the end of a &amp;lt;tt&amp;gt;\directlua&amp;lt;/tt&amp;gt; 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.&lt;br /&gt;
&lt;br /&gt;
== tex.print() ==&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;tt&amp;gt;newline&amp;lt;/tt&amp;gt; when processing it (i.e. leading spaces are skipped). Hence the two equivalent calls:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tex.print(&amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;)&lt;br /&gt;
tex.print({&amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
are both interpreted by TeX as would the following two lines:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
a&lt;br /&gt;
b&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thus `a b&amp;#039; is produced, since line ends normally produce a space.&lt;br /&gt;
&lt;br /&gt;
The function can also take an optional number as its first argument; it is interpreted as referring to a catcode table (as defined by &amp;lt;tt&amp;gt;\initcatcodetable&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;\savecatcodetable&amp;lt;/tt&amp;gt;), and each line is processed by TeX with that catcode regime. For instance (note that with such a minimal catcode table, braces don&amp;#039;t even have their usual values):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\bgroup&lt;br /&gt;
\initcatcodetable1&lt;br /&gt;
\catcode`\_=0&lt;br /&gt;
\savecatcodetable1&lt;br /&gt;
\egroup&lt;br /&gt;
&lt;br /&gt;
\directlua{tex.print(1, &amp;quot;_TeX&amp;quot;)}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The string will be read with &amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt; as an escape character, and thus interpreted as the command commonly known as &amp;lt;tt&amp;gt;\TeX&amp;lt;/tt&amp;gt;. The catcode regime holds only for the strings passed to &amp;lt;tt&amp;gt;tex.print()&amp;lt;/tt&amp;gt; and the rest of the document isn&amp;#039;t affected.&lt;br /&gt;
&lt;br /&gt;
If the optional number is &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt;, 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 &amp;lt;tt&amp;gt;-2&amp;lt;/tt&amp;gt;, then the strings are read as if the result of &amp;lt;tt&amp;gt;\detokenize&amp;lt;/tt&amp;gt;: all characters have catcode 12 (i.e. `other&amp;#039;, characters that have no function beside representing themselves), except space, which has catcode 10 (as usual).&lt;br /&gt;
&lt;br /&gt;
== tex.sprint() ==&lt;br /&gt;
&lt;br /&gt;
Like &amp;lt;tt&amp;gt;tex.print()&amp;lt;/tt&amp;gt;, 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 &amp;lt;tt&amp;gt;tex.print()&amp;lt;/tt&amp;gt;, 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&amp;#039;t skipped, no end-of-line character is added and trailing spaces aren&amp;#039;t ignored. Thus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tex.sprint(&amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is interpreted by TeX as&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ab&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
without any space inbetween.&lt;br /&gt;
&lt;br /&gt;
== tex.tprint() ==&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;tt&amp;gt;tex.sprint()&amp;lt;/tt&amp;gt;. Thus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tex.tprint({1, &amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;}, {&amp;quot;c&amp;quot;, &amp;quot;d&amp;quot;})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is equivalent to&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tex.sprint(1, &amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;)&lt;br /&gt;
tex.sprint(&amp;quot;c&amp;quot;, &amp;quot;d&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= The expansion of \directlua =&lt;br /&gt;
&lt;br /&gt;
A call to &amp;lt;tt&amp;gt;\directlua&amp;lt;/tt&amp;gt; is fully expandable; i.e. it can be used in contexts where full expansion is required, as in:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\csname\directlua{tex.print(&amp;quot;TeX&amp;quot;)}\endcsname&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which is a somewhat convoluted way of saying &amp;lt;tt&amp;gt;\TeX&amp;lt;/tt&amp;gt;. 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 &amp;lt;tt&amp;gt;\edef&amp;lt;/tt&amp;gt; by TeX&amp;#039;s traditional means. I.e. the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\edef\macro{\count1=5}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defines &amp;lt;tt&amp;gt;\macro&amp;lt;/tt&amp;gt; as &amp;lt;tt&amp;gt;\count1=5&amp;lt;/tt&amp;gt; but doesn&amp;#039;t perform the assignment (the &amp;lt;tt&amp;gt;\edef&amp;lt;/tt&amp;gt; does nothing more than a simple &amp;lt;tt&amp;gt;\def&amp;lt;/tt&amp;gt;). After the definition, the value of &amp;lt;tt&amp;gt;\count1&amp;lt;/tt&amp;gt; hasn&amp;#039;t changed. The same is not true, though, if such an assigment is made with Lua code. The following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\edef\macro{\directlua{tex.count[1] = 5}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defines &amp;lt;tt&amp;gt;\macro&amp;lt;/tt&amp;gt; emptily (since nothing remains after &amp;lt;tt&amp;gt;\directlua&amp;lt;/tt&amp;gt; has been processed) &amp;#039;&amp;#039;and&amp;#039;&amp;#039; sets count 1 to 5. Since such a behavior is totally unexpected in normal TeX, one should be wary when using &amp;lt;tt&amp;gt;\directlua&amp;lt;/tt&amp;gt; in such contexts.&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=Traversing_tokens&amp;diff=41</id>
		<title>Traversing tokens</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=Traversing_tokens&amp;diff=41"/>
		<updated>2010-12-08T08:40:14Z</updated>

		<summary type="html">&lt;p&gt;Patrick: minor correction&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Traversing (or tracing) tokens =&lt;br /&gt;
&lt;br /&gt;
Add the following where you want to start tracing tokens:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{&lt;br /&gt;
callback.register(&amp;#039;token_filter&amp;#039;,&lt;br /&gt;
function()&lt;br /&gt;
	t = token.get_next()&lt;br /&gt;
	if (t[3]==0) then&lt;br /&gt;
	texio.write_nl(&amp;#039;term and log&amp;#039;, &amp;#039;CHAR TOKEN char=&amp;#039; .. unicode.utf8.char(t[2]) .. &amp;#039; catcode=&amp;#039; .. t[1])&lt;br /&gt;
	else&lt;br /&gt;
	texio.write_nl(&amp;#039;term and log&amp;#039;, &amp;#039;CSEQ TOKEN name=&amp;#039; .. token.command_name(t) .. &amp;#039; code=&amp;#039; .. t[1] .. &amp;#039; id=&amp;#039; .. t[3])&lt;br /&gt;
	end&lt;br /&gt;
	return t&lt;br /&gt;
end )&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The anonymous function reads tokens using &amp;lt;tt&amp;gt;token.get_next()&amp;lt;/tt&amp;gt;, processes them, and then supplies them (or different ones) to TeX by its &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; value. The function unicode.utf8.char reads a numeric value and produces a UTF-8 character. For all functions in the &amp;lt;b&amp;gt;string&amp;lt;/b&amp;gt; library of lua you have the equivalents functions in the &amp;lt;b&amp;gt;unicode.utf8&amp;lt;/b&amp;gt; library which is loaded by luatex.&lt;br /&gt;
&lt;br /&gt;
When I apply this to file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\font\x=omlgc&lt;br /&gt;
\x VAT bl? bla bla bla &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I get the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
This is luaTeX, Version 3.141592-snapshot-2007062922 (Web2C 7.5.6) (format= 2007.6.25)  4 JUL 2007 00:14&lt;br /&gt;
**&amp;amp;plain test&lt;br /&gt;
(&lt;br /&gt;
CHAR TOKEN char=  catcode=10&lt;br /&gt;
CSEQ TOKEN name=register code=93 id=1115710&lt;br /&gt;
CSEQ TOKEN name=expand_after code=118 id=1114234&lt;br /&gt;
CHAR TOKEN char== catcode=12&lt;br /&gt;
CHAR TOKEN char=o catcode=11&lt;br /&gt;
CHAR TOKEN char=o catcode=11&lt;br /&gt;
CHAR TOKEN char=m catcode=11&lt;br /&gt;
CHAR TOKEN char=l catcode=11&lt;br /&gt;
CHAR TOKEN char=g catcode=11&lt;br /&gt;
CHAR TOKEN char=c catcode=11&lt;br /&gt;
CHAR TOKEN char=  catcode=10&lt;br /&gt;
CSEQ TOKEN name=def_font code=92 id=1114234&lt;br /&gt;
CSEQ TOKEN name=def_font code=92 id=1114234&lt;br /&gt;
CSEQ TOKEN name=def_font code=92 id=1114234&lt;br /&gt;
CSEQ TOKEN name=def_font code=92 id=1114234&lt;br /&gt;
CSEQ TOKEN name=def_font code=92 id=1114234&lt;br /&gt;
CHAR TOKEN char=V catcode=11&lt;br /&gt;
CHAR TOKEN char=V catcode=11&lt;br /&gt;
CHAR TOKEN char=A catcode=11&lt;br /&gt;
CHAR TOKEN char=T catcode=11&lt;br /&gt;
CHAR TOKEN char=  catcode=10&lt;br /&gt;
CHAR TOKEN char=b catcode=11&lt;br /&gt;
CHAR TOKEN char=l catcode=11&lt;br /&gt;
CHAR TOKEN char=? catcode=12&lt;br /&gt;
CHAR TOKEN char=  catcode=10&lt;br /&gt;
CHAR TOKEN char=b catcode=11&lt;br /&gt;
CHAR TOKEN char=l catcode=11&lt;br /&gt;
CHAR TOKEN char=a catcode=11&lt;br /&gt;
CHAR TOKEN char=  catcode=10&lt;br /&gt;
CHAR TOKEN char=b catcode=11&lt;br /&gt;
CHAR TOKEN char=l catcode=11&lt;br /&gt;
CHAR TOKEN char=a catcode=11&lt;br /&gt;
CHAR TOKEN char=  catcode=10&lt;br /&gt;
CHAR TOKEN char=b catcode=11&lt;br /&gt;
CHAR TOKEN char=l catcode=11&lt;br /&gt;
CHAR TOKEN char=a catcode=11&lt;br /&gt;
CHAR TOKEN char=  catcode=10&lt;br /&gt;
CSEQ TOKEN name=par_end code=13 id=1114870&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you wondering why the letters o and V appear twice, here are the answers I received from Taco:&lt;br /&gt;
&lt;br /&gt;
=== why do I get the o character token twice?===&lt;br /&gt;
&lt;br /&gt;
This is because of how the filename scanning works: it has&lt;br /&gt;
to pre-scan the first character to decide between the two&lt;br /&gt;
allowed syntaxes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  \font\f=omlgc&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
and&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  \font\f={omlgc}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== why do I get the V character token twice? ===&lt;br /&gt;
&lt;br /&gt;
Because it is a character encoutered in vmode. TeX switches&lt;br /&gt;
to hmode, then re-reads the character.&lt;br /&gt;
&lt;br /&gt;
[[User:Yannis.Haralambous|Yannis]] 04:40, 4 July 2007 (EDT)&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=User:Patrick&amp;diff=40</id>
		<title>User:Patrick</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=User:Patrick&amp;diff=40"/>
		<updated>2010-12-08T08:23:47Z</updated>

		<summary type="html">&lt;p&gt;Patrick: User page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;LuaTeX addict. Contact me at patrick &amp;lt;at&amp;gt; gundla &amp;lt;dot&amp;gt; ch.&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=Explore_the_table_obtained_from_a_TrueType_font&amp;diff=39</id>
		<title>Explore the table obtained from a TrueType font</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=Explore_the_table_obtained_from_a_TrueType_font&amp;diff=39"/>
		<updated>2010-12-08T08:22:10Z</updated>

		<summary type="html">&lt;p&gt;Patrick: forgot macro&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Define the following macro in your TeX file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\def\studyttffont#1{\directlua{&lt;br /&gt;
function printtable (ind,tableau,prof)&lt;br /&gt;
  local k,l&lt;br /&gt;
  texio.write_nl(string.rep(&amp;quot;...&amp;quot;,prof) .. ind .. &amp;quot; -&amp;gt; {&amp;quot;)&lt;br /&gt;
  prof=prof+1&lt;br /&gt;
  for k,l in pairs(tableau) do &lt;br /&gt;
    if (type(l)==&amp;quot;table&amp;quot;) then&lt;br /&gt;
      printtable(k,l,prof)&lt;br /&gt;
    else&lt;br /&gt;
      texio.write_nl(string.rep(&amp;quot;...&amp;quot;,prof) .. k .. &amp;quot; -&amp;gt; &amp;quot; .. tostring(l))&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  texio.write_nl(string.rep(&amp;quot;...&amp;quot;,prof-1) .. &amp;quot;}&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
filename = kpse.find_file(&amp;quot;#1&amp;quot;,&amp;quot;truetype fonts&amp;quot;)&lt;br /&gt;
ttffont  = fontloader.to_table(fontloader.open(filename))&lt;br /&gt;
printtable(&amp;quot;#1&amp;quot;,ttffont,0)&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and call it giving the name of the font you want to explore (the font must be in some directory known by kpse). Here is what you get for the &amp;quot;Gentium&amp;quot; font (strongly truncated, otherwise it would be too long for wiki):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
(&lt;br /&gt;
gentium -&amp;gt; {&lt;br /&gt;
...mark_class_cnt -&amp;gt; 0&lt;br /&gt;
...glyphs -&amp;gt; {&lt;br /&gt;
......1 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 0&lt;br /&gt;
............2 -&amp;gt; 0&lt;br /&gt;
............3 -&amp;gt; 0&lt;br /&gt;
............4 -&amp;gt; 0&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; .null&lt;br /&gt;
.........unicodeenc -&amp;gt; 0&lt;br /&gt;
.........width -&amp;gt; 0&lt;br /&gt;
......}&lt;br /&gt;
......2 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 0&lt;br /&gt;
............2 -&amp;gt; 0&lt;br /&gt;
............3 -&amp;gt; 0&lt;br /&gt;
............4 -&amp;gt; 0&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; nonmarkingreturn&lt;br /&gt;
.........unicodeenc -&amp;gt; 12&lt;br /&gt;
.........width -&amp;gt; 451&lt;br /&gt;
......}&lt;br /&gt;
......3 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 0&lt;br /&gt;
............2 -&amp;gt; 0&lt;br /&gt;
............3 -&amp;gt; 0&lt;br /&gt;
............4 -&amp;gt; 0&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; space&lt;br /&gt;
.........unicodeenc -&amp;gt; 32&lt;br /&gt;
.........width -&amp;gt; 451&lt;br /&gt;
......}&lt;br /&gt;
......4 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 154&lt;br /&gt;
............2 -&amp;gt; -40&lt;br /&gt;
............3 -&amp;gt; 391&lt;br /&gt;
............4 -&amp;gt; 1480&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; exclam&lt;br /&gt;
.........unicodeenc -&amp;gt; 33&lt;br /&gt;
.........width -&amp;gt; 557&lt;br /&gt;
......}&lt;br /&gt;
......5 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 160&lt;br /&gt;
............2 -&amp;gt; 813&lt;br /&gt;
............3 -&amp;gt; 711&lt;br /&gt;
............4 -&amp;gt; 1480&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; quotedbl&lt;br /&gt;
.........unicodeenc -&amp;gt; 34&lt;br /&gt;
.........width -&amp;gt; 870&lt;br /&gt;
......}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explanation: the &amp;lt;tt&amp;gt;glyphs&amp;lt;/tt&amp;gt; table is indexed by glyph indexes. Each glyph index maps to a bounding box, a potential (PostScript) name, a potential Unicode character, and to its width. Bounding box and width are given in font units.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
......6 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 87&lt;br /&gt;
............2 -&amp;gt; 127&lt;br /&gt;
............3 -&amp;gt; 982&lt;br /&gt;
............4 -&amp;gt; 1292&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; numbersign&lt;br /&gt;
.........unicodeenc -&amp;gt; 35&lt;br /&gt;
.........width -&amp;gt; 961&lt;br /&gt;
......}&lt;br /&gt;
......7 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 88&lt;br /&gt;
............2 -&amp;gt; -174&lt;br /&gt;
............3 -&amp;gt; 862&lt;br /&gt;
............4 -&amp;gt; 1384&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; dollar&lt;br /&gt;
.........unicodeenc -&amp;gt; 36&lt;br /&gt;
.........width -&amp;gt; 961&lt;br /&gt;
......}&lt;br /&gt;
......8 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 76&lt;br /&gt;
............2 -&amp;gt; -34&lt;br /&gt;
............3 -&amp;gt; 1337&lt;br /&gt;
............4 -&amp;gt; 1237&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; percent&lt;br /&gt;
.........unicodeenc -&amp;gt; 37&lt;br /&gt;
.........width -&amp;gt; 1413&lt;br /&gt;
......}&lt;br /&gt;
......9 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 80&lt;br /&gt;
............2 -&amp;gt; -30&lt;br /&gt;
............3 -&amp;gt; 1346&lt;br /&gt;
............4 -&amp;gt; 1450&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; ampersand&lt;br /&gt;
.........unicodeenc -&amp;gt; 38&lt;br /&gt;
.........width -&amp;gt; 1366&lt;br /&gt;
......}&lt;br /&gt;
......10 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 160&lt;br /&gt;
............2 -&amp;gt; 813&lt;br /&gt;
............3 -&amp;gt; 352&lt;br /&gt;
............4 -&amp;gt; 1480&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; quotesingle&lt;br /&gt;
.........unicodeenc -&amp;gt; 39&lt;br /&gt;
.........width -&amp;gt; 512&lt;br /&gt;
......}&lt;br /&gt;
......11 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 121&lt;br /&gt;
............2 -&amp;gt; -315&lt;br /&gt;
............3 -&amp;gt; 610&lt;br /&gt;
............4 -&amp;gt; 1600&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; parenleft&lt;br /&gt;
.........unicodeenc -&amp;gt; 40&lt;br /&gt;
.........possub -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; {&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............type -&amp;gt; substitution&lt;br /&gt;
...............subs -&amp;gt; {&lt;br /&gt;
..................variant -&amp;gt; parenright&lt;br /&gt;
...............}&lt;br /&gt;
...............script_lang_index -&amp;gt; 1&lt;br /&gt;
...............tag -&amp;gt; rtla&lt;br /&gt;
............}&lt;br /&gt;
.........}&lt;br /&gt;
.........width -&amp;gt; 649&lt;br /&gt;
......}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we have the special case of a glyph which has an attached OpenType transformation. In this case it is a (simple) substitution from the GSUB table. This substitution should happen when we are in the script+language combination indexed by number 1, and the OpenType which calls it is &amp;lt;tt&amp;gt;rtla&amp;lt;/tt&amp;gt;, also known as �Right-to-left alternates�. The glyph �parenleft� is substituted by the glyph �parenright�.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
......12 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 41&lt;br /&gt;
............2 -&amp;gt; -315&lt;br /&gt;
............3 -&amp;gt; 530&lt;br /&gt;
............4 -&amp;gt; 1600&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; parenright&lt;br /&gt;
.........unicodeenc -&amp;gt; 41&lt;br /&gt;
.........possub -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; {&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............type -&amp;gt; substitution&lt;br /&gt;
...............subs -&amp;gt; {&lt;br /&gt;
..................variant -&amp;gt; parenleft&lt;br /&gt;
...............}&lt;br /&gt;
...............script_lang_index -&amp;gt; 1&lt;br /&gt;
...............tag -&amp;gt; rtla&lt;br /&gt;
............}&lt;br /&gt;
.........}&lt;br /&gt;
.........width -&amp;gt; 649&lt;br /&gt;
......}&lt;br /&gt;
......13 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 70&lt;br /&gt;
............2 -&amp;gt; 709&lt;br /&gt;
............3 -&amp;gt; 846&lt;br /&gt;
............4 -&amp;gt; 1561&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; asterisk&lt;br /&gt;
.........unicodeenc -&amp;gt; 42&lt;br /&gt;
.........width -&amp;gt; 915&lt;br /&gt;
......}&lt;br /&gt;
......14 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 61&lt;br /&gt;
............2 -&amp;gt; 205&lt;br /&gt;
............3 -&amp;gt; 778&lt;br /&gt;
............4 -&amp;gt; 920&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; plus&lt;br /&gt;
.........unicodeenc -&amp;gt; 43&lt;br /&gt;
.........width -&amp;gt; 840&lt;br /&gt;
......}&lt;br /&gt;
......15 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 88&lt;br /&gt;
............2 -&amp;gt; -305&lt;br /&gt;
............3 -&amp;gt; 391&lt;br /&gt;
............4 -&amp;gt; 230&lt;br /&gt;
.........}&lt;br /&gt;
.........kerns -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; quotedblright&lt;br /&gt;
...............off -&amp;gt; -220&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............2 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; quoteright&lt;br /&gt;
...............off -&amp;gt; -220&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; comma&lt;br /&gt;
.........unicodeenc -&amp;gt; 44&lt;br /&gt;
.........width -&amp;gt; 469&lt;br /&gt;
......}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we have some kernings: the �comma� glyph gets kerned by -220 units when in front of �quoteright� or �quotedblright�.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
......16 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 61&lt;br /&gt;
............2 -&amp;gt; 455&lt;br /&gt;
............3 -&amp;gt; 629&lt;br /&gt;
............4 -&amp;gt; 569&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; hyphen&lt;br /&gt;
.........unicodeenc -&amp;gt; 45&lt;br /&gt;
.........width -&amp;gt; 690&lt;br /&gt;
......}&lt;br /&gt;
......17 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 131&lt;br /&gt;
............2 -&amp;gt; -40&lt;br /&gt;
............3 -&amp;gt; 369&lt;br /&gt;
............4 -&amp;gt; 236&lt;br /&gt;
.........}&lt;br /&gt;
.........kerns -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; quotedblright&lt;br /&gt;
...............off -&amp;gt; -220&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............2 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; quoteright&lt;br /&gt;
...............off -&amp;gt; -220&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; period&lt;br /&gt;
.........unicodeenc -&amp;gt; 46&lt;br /&gt;
.........width -&amp;gt; 469&lt;br /&gt;
......}&lt;br /&gt;
......18 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 49&lt;br /&gt;
............2 -&amp;gt; -335&lt;br /&gt;
............3 -&amp;gt; 909&lt;br /&gt;
............4 -&amp;gt; 1600&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; slash&lt;br /&gt;
.........unicodeenc -&amp;gt; 47&lt;br /&gt;
.........width -&amp;gt; 961&lt;br /&gt;
......}&lt;br /&gt;
......19 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 76&lt;br /&gt;
............2 -&amp;gt; -30&lt;br /&gt;
............3 -&amp;gt; 885&lt;br /&gt;
............4 -&amp;gt; 1235&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; zero&lt;br /&gt;
.........unicodeenc -&amp;gt; 48&lt;br /&gt;
.........width -&amp;gt; 961&lt;br /&gt;
......}&lt;br /&gt;
......20 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 139&lt;br /&gt;
............2 -&amp;gt; 0&lt;br /&gt;
............3 -&amp;gt; 840&lt;br /&gt;
............4 -&amp;gt; 1245&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; one&lt;br /&gt;
.........unicodeenc -&amp;gt; 49&lt;br /&gt;
.........width -&amp;gt; 961&lt;br /&gt;
......}&lt;br /&gt;
......21 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 98&lt;br /&gt;
............2 -&amp;gt; 0&lt;br /&gt;
............3 -&amp;gt; 836&lt;br /&gt;
............4 -&amp;gt; 1235&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; two&lt;br /&gt;
.........unicodeenc -&amp;gt; 50&lt;br /&gt;
.........width -&amp;gt; 961&lt;br /&gt;
......}&lt;br /&gt;
......22 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 68&lt;br /&gt;
............2 -&amp;gt; -30&lt;br /&gt;
............3 -&amp;gt; 825&lt;br /&gt;
............4 -&amp;gt; 1235&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; three&lt;br /&gt;
.........unicodeenc -&amp;gt; 51&lt;br /&gt;
.........width -&amp;gt; 961&lt;br /&gt;
......}&lt;br /&gt;
......23 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 55&lt;br /&gt;
............2 -&amp;gt; 0&lt;br /&gt;
............3 -&amp;gt; 874&lt;br /&gt;
............4 -&amp;gt; 1245&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; four&lt;br /&gt;
.........unicodeenc -&amp;gt; 52&lt;br /&gt;
.........width -&amp;gt; 961&lt;br /&gt;
......}&lt;br /&gt;
......24 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 78&lt;br /&gt;
............2 -&amp;gt; -30&lt;br /&gt;
............3 -&amp;gt; 836&lt;br /&gt;
............4 -&amp;gt; 1223&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; five&lt;br /&gt;
.........unicodeenc -&amp;gt; 53&lt;br /&gt;
.........width -&amp;gt; 961&lt;br /&gt;
......}&lt;br /&gt;
......25 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 111&lt;br /&gt;
............2 -&amp;gt; -30&lt;br /&gt;
............3 -&amp;gt; 881&lt;br /&gt;
............4 -&amp;gt; 1249&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; six&lt;br /&gt;
.........unicodeenc -&amp;gt; 54&lt;br /&gt;
.........width -&amp;gt; 961&lt;br /&gt;
......}&lt;br /&gt;
......26 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 104&lt;br /&gt;
............2 -&amp;gt; -30&lt;br /&gt;
............3 -&amp;gt; 885&lt;br /&gt;
............4 -&amp;gt; 1204&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; seven&lt;br /&gt;
.........unicodeenc -&amp;gt; 55&lt;br /&gt;
.........width -&amp;gt; 961&lt;br /&gt;
......}&lt;br /&gt;
......27 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 94&lt;br /&gt;
............2 -&amp;gt; -30&lt;br /&gt;
............3 -&amp;gt; 864&lt;br /&gt;
............4 -&amp;gt; 1235&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; eight&lt;br /&gt;
.........unicodeenc -&amp;gt; 56&lt;br /&gt;
.........width -&amp;gt; 961&lt;br /&gt;
......}&lt;br /&gt;
......28 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 100&lt;br /&gt;
............2 -&amp;gt; -43&lt;br /&gt;
............3 -&amp;gt; 870&lt;br /&gt;
............4 -&amp;gt; 1235&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; nine&lt;br /&gt;
.........unicodeenc -&amp;gt; 57&lt;br /&gt;
.........width -&amp;gt; 961&lt;br /&gt;
......}&lt;br /&gt;
......29 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 131&lt;br /&gt;
............2 -&amp;gt; -40&lt;br /&gt;
............3 -&amp;gt; 369&lt;br /&gt;
............4 -&amp;gt; 961&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; colon&lt;br /&gt;
.........unicodeenc -&amp;gt; 58&lt;br /&gt;
.........width -&amp;gt; 469&lt;br /&gt;
......}&lt;br /&gt;
......30 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 88&lt;br /&gt;
............2 -&amp;gt; -305&lt;br /&gt;
............3 -&amp;gt; 391&lt;br /&gt;
............4 -&amp;gt; 961&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; semicolon&lt;br /&gt;
.........unicodeenc -&amp;gt; 59&lt;br /&gt;
.........width -&amp;gt; 469&lt;br /&gt;
......}&lt;br /&gt;
......31 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 61&lt;br /&gt;
............2 -&amp;gt; 256&lt;br /&gt;
............3 -&amp;gt; 838&lt;br /&gt;
............4 -&amp;gt; 899&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; less&lt;br /&gt;
.........unicodeenc -&amp;gt; 60&lt;br /&gt;
.........possub -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; {&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............type -&amp;gt; substitution&lt;br /&gt;
...............subs -&amp;gt; {&lt;br /&gt;
..................variant -&amp;gt; greater&lt;br /&gt;
...............}&lt;br /&gt;
...............script_lang_index -&amp;gt; 1&lt;br /&gt;
...............tag -&amp;gt; rtla&lt;br /&gt;
............}&lt;br /&gt;
.........}&lt;br /&gt;
.........width -&amp;gt; 899&lt;br /&gt;
......}&lt;br /&gt;
......32 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 61&lt;br /&gt;
............2 -&amp;gt; 354&lt;br /&gt;
............3 -&amp;gt; 838&lt;br /&gt;
............4 -&amp;gt; 768&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; equal&lt;br /&gt;
.........unicodeenc -&amp;gt; 61&lt;br /&gt;
.........width -&amp;gt; 899&lt;br /&gt;
......}&lt;br /&gt;
......33 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 61&lt;br /&gt;
............2 -&amp;gt; 256&lt;br /&gt;
............3 -&amp;gt; 838&lt;br /&gt;
............4 -&amp;gt; 899&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; greater&lt;br /&gt;
.........unicodeenc -&amp;gt; 62&lt;br /&gt;
.........possub -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; {&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............type -&amp;gt; substitution&lt;br /&gt;
...............subs -&amp;gt; {&lt;br /&gt;
..................variant -&amp;gt; less&lt;br /&gt;
...............}&lt;br /&gt;
...............script_lang_index -&amp;gt; 1&lt;br /&gt;
...............tag -&amp;gt; rtla&lt;br /&gt;
............}&lt;br /&gt;
.........}&lt;br /&gt;
.........width -&amp;gt; 899&lt;br /&gt;
......}&lt;br /&gt;
......34 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 80&lt;br /&gt;
............2 -&amp;gt; -40&lt;br /&gt;
............3 -&amp;gt; 807&lt;br /&gt;
............4 -&amp;gt; 1480&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; question&lt;br /&gt;
.........unicodeenc -&amp;gt; 63&lt;br /&gt;
.........width -&amp;gt; 887&lt;br /&gt;
......}&lt;br /&gt;
......35 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 70&lt;br /&gt;
............2 -&amp;gt; -375&lt;br /&gt;
............3 -&amp;gt; 1583&lt;br /&gt;
............4 -&amp;gt; 1333&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; at&lt;br /&gt;
.........unicodeenc -&amp;gt; 64&lt;br /&gt;
.........width -&amp;gt; 1653&lt;br /&gt;
......}&lt;br /&gt;
......36 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 0&lt;br /&gt;
............2 -&amp;gt; 0&lt;br /&gt;
............3 -&amp;gt; 1198&lt;br /&gt;
............4 -&amp;gt; 1317&lt;br /&gt;
.........}&lt;br /&gt;
.........kerns -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; quotedblright&lt;br /&gt;
...............off -&amp;gt; -200&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............2 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; quoteright&lt;br /&gt;
...............off -&amp;gt; -200&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............3 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; y&lt;br /&gt;
...............off -&amp;gt; -100&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............4 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; w&lt;br /&gt;
...............off -&amp;gt; -80&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............5 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; v&lt;br /&gt;
...............off -&amp;gt; -100&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............6 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; Y&lt;br /&gt;
...............off -&amp;gt; -180&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............7 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; W&lt;br /&gt;
...............off -&amp;gt; -120&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............8 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; V&lt;br /&gt;
...............off -&amp;gt; -160&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............9 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; U&lt;br /&gt;
...............off -&amp;gt; -80&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............10 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; T&lt;br /&gt;
...............off -&amp;gt; -100&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............11 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; Q&lt;br /&gt;
...............off -&amp;gt; -30&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............12 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; O&lt;br /&gt;
...............off -&amp;gt; -30&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............13 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; G&lt;br /&gt;
...............off -&amp;gt; -30&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............14 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; C&lt;br /&gt;
...............off -&amp;gt; -30&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; A&lt;br /&gt;
.........unicodeenc -&amp;gt; 65&lt;br /&gt;
.........width -&amp;gt; 1219&lt;br /&gt;
......}&lt;br /&gt;
......37 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 41&lt;br /&gt;
............2 -&amp;gt; -14&lt;br /&gt;
............3 -&amp;gt; 1016&lt;br /&gt;
............4 -&amp;gt; 1290&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; B&lt;br /&gt;
.........unicodeenc -&amp;gt; 66&lt;br /&gt;
.........width -&amp;gt; 1126&lt;br /&gt;
......}&lt;br /&gt;
......38 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 70&lt;br /&gt;
............2 -&amp;gt; -30&lt;br /&gt;
............3 -&amp;gt; 1018&lt;br /&gt;
............4 -&amp;gt; 1290&lt;br /&gt;
.........}&lt;br /&gt;
.........kerns -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; A&lt;br /&gt;
...............off -&amp;gt; -60&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; C&lt;br /&gt;
.........unicodeenc -&amp;gt; 67&lt;br /&gt;
.........width -&amp;gt; 1098&lt;br /&gt;
......}&lt;br /&gt;
......39 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 41&lt;br /&gt;
............2 -&amp;gt; 0&lt;br /&gt;
............3 -&amp;gt; 1124&lt;br /&gt;
............4 -&amp;gt; 1290&lt;br /&gt;
.........}&lt;br /&gt;
.........kerns -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; Y&lt;br /&gt;
...............off -&amp;gt; -60&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............2 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; W&lt;br /&gt;
...............off -&amp;gt; -20&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............3 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; V&lt;br /&gt;
...............off -&amp;gt; 40&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............4 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; A&lt;br /&gt;
...............off -&amp;gt; -60&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; D&lt;br /&gt;
.........unicodeenc -&amp;gt; 68&lt;br /&gt;
.........width -&amp;gt; 1214&lt;br /&gt;
......}&lt;br /&gt;
&lt;br /&gt;
another 35,850 lines of code&lt;br /&gt;
&lt;br /&gt;
...}&lt;br /&gt;
...fontstyle_id -&amp;gt; 0&lt;br /&gt;
...units_per_em -&amp;gt; 2048&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2,048 units per em means that to obtain TeX quads we need to divide by that number. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...glyphcnt -&amp;gt; 1699&lt;br /&gt;
...gasp_cnt -&amp;gt; 3&lt;br /&gt;
...weight -&amp;gt; Book&lt;br /&gt;
...pfminfo -&amp;gt; {&lt;br /&gt;
......vlinegap -&amp;gt; 0&lt;br /&gt;
......os2_subyoff -&amp;gt; 1200&lt;br /&gt;
......hheadascent_add -&amp;gt; 1&lt;br /&gt;
......os2_strikeypos -&amp;gt; 512&lt;br /&gt;
......hhead_descent -&amp;gt; -565&lt;br /&gt;
......os2_typolinegap -&amp;gt; 90&lt;br /&gt;
......typodescent_add -&amp;gt; 1&lt;br /&gt;
......weight -&amp;gt; 400&lt;br /&gt;
......hhead_ascent -&amp;gt; 1759&lt;br /&gt;
......os2_strikeysize -&amp;gt; 102&lt;br /&gt;
......panose_set -&amp;gt; 1&lt;br /&gt;
......os2_breakchar -&amp;gt; 0&lt;br /&gt;
......pfmset -&amp;gt; 1&lt;br /&gt;
......os2_typoascent -&amp;gt; -88&lt;br /&gt;
......winascent_add -&amp;gt; 1&lt;br /&gt;
......firstchar -&amp;gt; 32&lt;br /&gt;
......os2_capheight -&amp;gt; 0&lt;br /&gt;
......windescent_add -&amp;gt; 1&lt;br /&gt;
......vheadset -&amp;gt; 0&lt;br /&gt;
......os2_subxsize -&amp;gt; 856&lt;br /&gt;
......os2_xheight -&amp;gt; 0&lt;br /&gt;
......os2_supxoff -&amp;gt; 0&lt;br /&gt;
......hheaddescent_add -&amp;gt; 1&lt;br /&gt;
......os2_defaultchar -&amp;gt; 0&lt;br /&gt;
......linegap -&amp;gt; 45&lt;br /&gt;
......os2_family_class -&amp;gt; 0&lt;br /&gt;
......os2_vendor -&amp;gt; SIL &lt;br /&gt;
......os2_supyoff -&amp;gt; 1200&lt;br /&gt;
......os2_winascent -&amp;gt; 1759&lt;br /&gt;
......os2_subysize -&amp;gt; 856&lt;br /&gt;
......avgwidth -&amp;gt; 845&lt;br /&gt;
......os2_subxoff -&amp;gt; 0&lt;br /&gt;
......os2_supysize -&amp;gt; 856&lt;br /&gt;
......os2_windescent -&amp;gt; 565&lt;br /&gt;
......os2_typodescent -&amp;gt; -69&lt;br /&gt;
......hheadset -&amp;gt; 1&lt;br /&gt;
......fstype -&amp;gt; 0&lt;br /&gt;
......os2_supxsize -&amp;gt; 856&lt;br /&gt;
......lastchar -&amp;gt; 64260&lt;br /&gt;
......panose -&amp;gt; {&lt;br /&gt;
.........serifstyle -&amp;gt; Any&lt;br /&gt;
.........armstyle -&amp;gt; Any&lt;br /&gt;
.........contrast -&amp;gt; Medium&lt;br /&gt;
.........familytype -&amp;gt; Text and Display&lt;br /&gt;
.........proportion -&amp;gt; Modern&lt;br /&gt;
.........strokevariation -&amp;gt; Any&lt;br /&gt;
.........weight -&amp;gt; Book&lt;br /&gt;
.........xheight -&amp;gt; Constant/Large&lt;br /&gt;
.........midline -&amp;gt; Any&lt;br /&gt;
.........letterform -&amp;gt; Normal/Contact&lt;br /&gt;
......}&lt;br /&gt;
......width -&amp;gt; 5&lt;br /&gt;
......pfmfamily -&amp;gt; 17&lt;br /&gt;
......subsuper_set -&amp;gt; 1&lt;br /&gt;
......typoascent_add -&amp;gt; 1&lt;br /&gt;
...}&lt;br /&gt;
...fullname -&amp;gt; GentiumAlt&lt;br /&gt;
...map -&amp;gt; {&lt;br /&gt;
......map -&amp;gt; {&lt;br /&gt;
.........32 -&amp;gt; 3&lt;br /&gt;
.........33 -&amp;gt; 4&lt;br /&gt;
.........34 -&amp;gt; 5&lt;br /&gt;
.........35 -&amp;gt; 6&lt;br /&gt;
.........36 -&amp;gt; 7&lt;br /&gt;
.........37 -&amp;gt; 8&lt;br /&gt;
.........38 -&amp;gt; 9&lt;br /&gt;
.........39 -&amp;gt; 10&lt;br /&gt;
.........40 -&amp;gt; 11&lt;br /&gt;
&lt;br /&gt;
another 1,679 lines&lt;br /&gt;
&lt;br /&gt;
.........65764 -&amp;gt; 1688&lt;br /&gt;
.........65765 -&amp;gt; 1689&lt;br /&gt;
.........65766 -&amp;gt; 1690&lt;br /&gt;
.........65767 -&amp;gt; 1691&lt;br /&gt;
.........65768 -&amp;gt; 1692&lt;br /&gt;
.........65769 -&amp;gt; 1693&lt;br /&gt;
.........65770 -&amp;gt; 1694&lt;br /&gt;
.........65771 -&amp;gt; 1695&lt;br /&gt;
.........65772 -&amp;gt; 1696&lt;br /&gt;
.........65773 -&amp;gt; 1697&lt;br /&gt;
.........65774 -&amp;gt; 1698&lt;br /&gt;
......}&lt;br /&gt;
......enc -&amp;gt; {&lt;br /&gt;
.........1 -&amp;gt; {&lt;br /&gt;
............has_2byte -&amp;gt; 1&lt;br /&gt;
............char_max -&amp;gt; 0&lt;br /&gt;
............only_1byte -&amp;gt; 0&lt;br /&gt;
............is_unicodebmp -&amp;gt; 1&lt;br /&gt;
............char_cnt -&amp;gt; 65536&lt;br /&gt;
............high_page -&amp;gt; 0&lt;br /&gt;
............has_1byte -&amp;gt; 0&lt;br /&gt;
............low_page -&amp;gt; 0&lt;br /&gt;
............builtin -&amp;gt; 1&lt;br /&gt;
............enc_name -&amp;gt; UnicodeBmp&lt;br /&gt;
............hidden -&amp;gt; 1&lt;br /&gt;
.........}&lt;br /&gt;
.........2 -&amp;gt; {&lt;br /&gt;
............has_2byte -&amp;gt; 0&lt;br /&gt;
............char_max -&amp;gt; 0&lt;br /&gt;
............only_1byte -&amp;gt; 0&lt;br /&gt;
............is_original -&amp;gt; 1&lt;br /&gt;
............char_cnt -&amp;gt; 0&lt;br /&gt;
............high_page -&amp;gt; 0&lt;br /&gt;
............has_1byte -&amp;gt; 0&lt;br /&gt;
............low_page -&amp;gt; 0&lt;br /&gt;
............builtin -&amp;gt; 1&lt;br /&gt;
............enc_name -&amp;gt; Original&lt;br /&gt;
............hidden -&amp;gt; 1&lt;br /&gt;
.........}&lt;br /&gt;
.........3 -&amp;gt; {&lt;br /&gt;
............has_2byte -&amp;gt; 0&lt;br /&gt;
............char_max -&amp;gt; 0&lt;br /&gt;
............only_1byte -&amp;gt; 0&lt;br /&gt;
............char_cnt -&amp;gt; 0&lt;br /&gt;
............is_custom -&amp;gt; 1&lt;br /&gt;
............has_1byte -&amp;gt; 0&lt;br /&gt;
............low_page -&amp;gt; 0&lt;br /&gt;
............builtin -&amp;gt; 1&lt;br /&gt;
............enc_name -&amp;gt; Custom&lt;br /&gt;
............high_page -&amp;gt; 0&lt;br /&gt;
............hidden -&amp;gt; 1&lt;br /&gt;
.........}&lt;br /&gt;
.........4 -&amp;gt; {&lt;br /&gt;
............has_2byte -&amp;gt; 0&lt;br /&gt;
............char_max -&amp;gt; 0&lt;br /&gt;
............only_1byte -&amp;gt; 1&lt;br /&gt;
............char_cnt -&amp;gt; 256&lt;br /&gt;
............high_page -&amp;gt; 0&lt;br /&gt;
............has_1byte -&amp;gt; 1&lt;br /&gt;
............low_page -&amp;gt; 0&lt;br /&gt;
............builtin -&amp;gt; 1&lt;br /&gt;
............enc_name -&amp;gt; TeX-Base-Encoding&lt;br /&gt;
............unicode -&amp;gt; {&lt;br /&gt;
...............1 -&amp;gt; 729&lt;br /&gt;
...............2 -&amp;gt; 64257&lt;br /&gt;
...............3 -&amp;gt; 64258&lt;br /&gt;
...............4 -&amp;gt; 8260&lt;br /&gt;
...............5 -&amp;gt; 733&lt;br /&gt;
...............6 -&amp;gt; 321&lt;br /&gt;
...............7 -&amp;gt; 322&lt;br /&gt;
...............8 -&amp;gt; 731&lt;br /&gt;
&lt;br /&gt;
another 238 lines&lt;br /&gt;
&lt;br /&gt;
...............247 -&amp;gt; 247&lt;br /&gt;
...............248 -&amp;gt; 248&lt;br /&gt;
...............249 -&amp;gt; 249&lt;br /&gt;
...............250 -&amp;gt; 250&lt;br /&gt;
...............251 -&amp;gt; 251&lt;br /&gt;
...............252 -&amp;gt; 252&lt;br /&gt;
...............253 -&amp;gt; 253&lt;br /&gt;
...............254 -&amp;gt; 254&lt;br /&gt;
...............255 -&amp;gt; 255&lt;br /&gt;
...............0 -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............hidden -&amp;gt; 1&lt;br /&gt;
.........}&lt;br /&gt;
......}&lt;br /&gt;
......backmax -&amp;gt; 1699&lt;br /&gt;
......enccount -&amp;gt; 65775&lt;br /&gt;
......encmax -&amp;gt; 65775&lt;br /&gt;
......backmap -&amp;gt; {&lt;br /&gt;
.........1 -&amp;gt; 65537&lt;br /&gt;
.........2 -&amp;gt; 65538&lt;br /&gt;
.........3 -&amp;gt; 32&lt;br /&gt;
.........4 -&amp;gt; 33&lt;br /&gt;
.........5 -&amp;gt; 34&lt;br /&gt;
.........6 -&amp;gt; 35&lt;br /&gt;
.........7 -&amp;gt; 36&lt;br /&gt;
.........8 -&amp;gt; 37&lt;br /&gt;
.........9 -&amp;gt; 38&lt;br /&gt;
.........10 -&amp;gt; 39&lt;br /&gt;
.........11 -&amp;gt; 40&lt;br /&gt;
.........12 -&amp;gt; 41&lt;br /&gt;
.........13 -&amp;gt; 42&lt;br /&gt;
&lt;br /&gt;
another 1,679 lines&lt;br /&gt;
&lt;br /&gt;
.........1693 -&amp;gt; 65769&lt;br /&gt;
.........1694 -&amp;gt; 65770&lt;br /&gt;
.........1695 -&amp;gt; 65771&lt;br /&gt;
.........1696 -&amp;gt; 65772&lt;br /&gt;
.........1697 -&amp;gt; 65773&lt;br /&gt;
.........1698 -&amp;gt; 65774&lt;br /&gt;
.........0 -&amp;gt; 65536&lt;br /&gt;
......}&lt;br /&gt;
...}&lt;br /&gt;
...italicangle -&amp;gt; 0&lt;br /&gt;
...strokedfont -&amp;gt; 0&lt;br /&gt;
...cidinfo -&amp;gt; {&lt;br /&gt;
......supplement -&amp;gt; 0&lt;br /&gt;
......version -&amp;gt; 0&lt;br /&gt;
...}&lt;br /&gt;
...familyname -&amp;gt; GentiumAlt&lt;br /&gt;
...script_lang -&amp;gt; {&lt;br /&gt;
......1 -&amp;gt; {&lt;br /&gt;
.........script -&amp;gt; latn&lt;br /&gt;
.........langs -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; dflt&lt;br /&gt;
.........}&lt;br /&gt;
......}&lt;br /&gt;
...}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The table &amp;lt;tt&amp;gt;script_lang&amp;lt;/tt&amp;gt; contains scripts and languages. Here we have script &amp;lt;tt&amp;gt;latn&amp;lt;/tt&amp;gt; (Latin) with default language.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...upos -&amp;gt; -48&lt;br /&gt;
...version -&amp;gt; 1.01; 2003; initial SIL release&lt;br /&gt;
...glyphmax -&amp;gt; 1699&lt;br /&gt;
...names -&amp;gt; {&lt;br /&gt;
......1 -&amp;gt; {&lt;br /&gt;
.........lang -&amp;gt; English (US)&lt;br /&gt;
.........names -&amp;gt; {&lt;br /&gt;
............designerurl -&amp;gt; http://www.sil.org/~gaultney&lt;br /&gt;
............venderurl -&amp;gt; http://www.sil.org/&lt;br /&gt;
............compatfull -&amp;gt; GentiumAlt&lt;br /&gt;
............trademark -&amp;gt; Gentium is a trademark of SIL International.&lt;br /&gt;
............license -&amp;gt; This font is the property of SIL International. It is distributed as copyrighted freeware. You may use this software without any charge and may distribute it, as is, to others. Commercial distribution of this software is restricted &lt;br /&gt;
without prior written permission. If you wish to distribute this software commercially, contact SIL for details on obtaining a license. You may not rent or lease the software, nor may you modify, adapt, translate, reverse engineer, decompile, or disassemb&lt;br /&gt;
le the software. You may not make derivative fonts from this software. THE SOFTWARE AND RELATED FILES ARE PROVIDED &amp;quot;AS IS&amp;quot; AND WITHOUT WARRANTY OF ANY KIND.&lt;br /&gt;
............fullname -&amp;gt; GentiumAlt&lt;br /&gt;
............preffamilyname -&amp;gt; GentiumAlt&lt;br /&gt;
............designer -&amp;gt; J. Victor Gaultney&lt;br /&gt;
............copyright -&amp;gt; Copyright (c) SIL International 2003. All rights reserved.&lt;br /&gt;
............version -&amp;gt; Version 1.01; 2003; initial SIL release&lt;br /&gt;
............prefmodifiers -&amp;gt; Regular&lt;br /&gt;
............family -&amp;gt; GentiumAlt&lt;br /&gt;
............postscriptname -&amp;gt; GentiumAlt&lt;br /&gt;
............subfamily -&amp;gt; Regular&lt;br /&gt;
............uniqueid -&amp;gt; SIL: GentiumAlt: 2003&lt;br /&gt;
.........}&lt;br /&gt;
......}&lt;br /&gt;
...}&lt;br /&gt;
...gentags -&amp;gt; {&lt;br /&gt;
......tt_cur -&amp;gt; 0&lt;br /&gt;
...}&lt;br /&gt;
...modificationtime -&amp;gt; 1063146346&lt;br /&gt;
...fontname -&amp;gt; GentiumAlt&lt;br /&gt;
...changed -&amp;gt; 0&lt;br /&gt;
...vertical_origin -&amp;gt; 0&lt;br /&gt;
...table_version -&amp;gt; 0.1&lt;br /&gt;
...hasvmetrics -&amp;gt; 0&lt;br /&gt;
...creationtime -&amp;gt; 1032220800&lt;br /&gt;
...order2 -&amp;gt; 1&lt;br /&gt;
...head_optimized_for_cleartype -&amp;gt; 0&lt;br /&gt;
...strokewidth -&amp;gt; 0&lt;br /&gt;
...design_range_bottom -&amp;gt; 0&lt;br /&gt;
...design_size -&amp;gt; 0&lt;br /&gt;
...design_range_top -&amp;gt; 0&lt;br /&gt;
...sli_cnt -&amp;gt; 1&lt;br /&gt;
...macstyle -&amp;gt; -1&lt;br /&gt;
...ttf_tables -&amp;gt; {&lt;br /&gt;
......1 -&amp;gt; {&lt;br /&gt;
.........len -&amp;gt; 32&lt;br /&gt;
.........data -&amp;gt; &lt;br /&gt;
.........maxlen -&amp;gt; 0&lt;br /&gt;
.........tag -&amp;gt; maxp&lt;br /&gt;
......}&lt;br /&gt;
...}&lt;br /&gt;
...copyright -&amp;gt; Copyright (c) SIL International 2003. All rights reserved.&lt;br /&gt;
...os2_version -&amp;gt; 1&lt;br /&gt;
...gasp_version -&amp;gt; 0&lt;br /&gt;
...uni_interp -&amp;gt; none&lt;br /&gt;
...uwidth -&amp;gt; 14&lt;br /&gt;
...weight_width_slope_only -&amp;gt; 0&lt;br /&gt;
...descent -&amp;gt; 410&lt;br /&gt;
...ascent -&amp;gt; 1638&lt;br /&gt;
...uniqueid -&amp;gt; 0&lt;br /&gt;
} )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=Explore_the_table_obtained_from_a_TrueType_font&amp;diff=38</id>
		<title>Explore the table obtained from a TrueType font</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=Explore_the_table_obtained_from_a_TrueType_font&amp;diff=38"/>
		<updated>2010-12-08T08:21:18Z</updated>

		<summary type="html">&lt;p&gt;Patrick: fontforge -&amp;gt; fontloader&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Define the following macro in your TeX file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function printtable (ind,tableau,prof)&lt;br /&gt;
  local k,l&lt;br /&gt;
  texio.write_nl(string.rep(&amp;quot;...&amp;quot;,prof) .. ind .. &amp;quot; -&amp;gt; {&amp;quot;)&lt;br /&gt;
  prof=prof+1&lt;br /&gt;
  for k,l in pairs(tableau) do &lt;br /&gt;
    if (type(l)==&amp;quot;table&amp;quot;) then&lt;br /&gt;
      printtable(k,l,prof)&lt;br /&gt;
    else&lt;br /&gt;
      texio.write_nl(string.rep(&amp;quot;...&amp;quot;,prof) .. k .. &amp;quot; -&amp;gt; &amp;quot; .. tostring(l))&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  texio.write_nl(string.rep(&amp;quot;...&amp;quot;,prof-1) .. &amp;quot;}&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
filename = kpse.find_file(&amp;quot;#1&amp;quot;,&amp;quot;truetype fonts&amp;quot;)&lt;br /&gt;
ttffont  = fontloader.to_table(fontloader.open(filename))&lt;br /&gt;
printtable(&amp;quot;#1&amp;quot;,ttffont,0)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and call it giving the name of the font you want to explore (the font must be in some directory known by kpse). Here is what you get for the &amp;quot;Gentium&amp;quot; font (strongly truncated, otherwise it would be too long for wiki):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
(&lt;br /&gt;
gentium -&amp;gt; {&lt;br /&gt;
...mark_class_cnt -&amp;gt; 0&lt;br /&gt;
...glyphs -&amp;gt; {&lt;br /&gt;
......1 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 0&lt;br /&gt;
............2 -&amp;gt; 0&lt;br /&gt;
............3 -&amp;gt; 0&lt;br /&gt;
............4 -&amp;gt; 0&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; .null&lt;br /&gt;
.........unicodeenc -&amp;gt; 0&lt;br /&gt;
.........width -&amp;gt; 0&lt;br /&gt;
......}&lt;br /&gt;
......2 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 0&lt;br /&gt;
............2 -&amp;gt; 0&lt;br /&gt;
............3 -&amp;gt; 0&lt;br /&gt;
............4 -&amp;gt; 0&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; nonmarkingreturn&lt;br /&gt;
.........unicodeenc -&amp;gt; 12&lt;br /&gt;
.........width -&amp;gt; 451&lt;br /&gt;
......}&lt;br /&gt;
......3 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 0&lt;br /&gt;
............2 -&amp;gt; 0&lt;br /&gt;
............3 -&amp;gt; 0&lt;br /&gt;
............4 -&amp;gt; 0&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; space&lt;br /&gt;
.........unicodeenc -&amp;gt; 32&lt;br /&gt;
.........width -&amp;gt; 451&lt;br /&gt;
......}&lt;br /&gt;
......4 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 154&lt;br /&gt;
............2 -&amp;gt; -40&lt;br /&gt;
............3 -&amp;gt; 391&lt;br /&gt;
............4 -&amp;gt; 1480&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; exclam&lt;br /&gt;
.........unicodeenc -&amp;gt; 33&lt;br /&gt;
.........width -&amp;gt; 557&lt;br /&gt;
......}&lt;br /&gt;
......5 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 160&lt;br /&gt;
............2 -&amp;gt; 813&lt;br /&gt;
............3 -&amp;gt; 711&lt;br /&gt;
............4 -&amp;gt; 1480&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; quotedbl&lt;br /&gt;
.........unicodeenc -&amp;gt; 34&lt;br /&gt;
.........width -&amp;gt; 870&lt;br /&gt;
......}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explanation: the &amp;lt;tt&amp;gt;glyphs&amp;lt;/tt&amp;gt; table is indexed by glyph indexes. Each glyph index maps to a bounding box, a potential (PostScript) name, a potential Unicode character, and to its width. Bounding box and width are given in font units.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
......6 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 87&lt;br /&gt;
............2 -&amp;gt; 127&lt;br /&gt;
............3 -&amp;gt; 982&lt;br /&gt;
............4 -&amp;gt; 1292&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; numbersign&lt;br /&gt;
.........unicodeenc -&amp;gt; 35&lt;br /&gt;
.........width -&amp;gt; 961&lt;br /&gt;
......}&lt;br /&gt;
......7 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 88&lt;br /&gt;
............2 -&amp;gt; -174&lt;br /&gt;
............3 -&amp;gt; 862&lt;br /&gt;
............4 -&amp;gt; 1384&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; dollar&lt;br /&gt;
.........unicodeenc -&amp;gt; 36&lt;br /&gt;
.........width -&amp;gt; 961&lt;br /&gt;
......}&lt;br /&gt;
......8 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 76&lt;br /&gt;
............2 -&amp;gt; -34&lt;br /&gt;
............3 -&amp;gt; 1337&lt;br /&gt;
............4 -&amp;gt; 1237&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; percent&lt;br /&gt;
.........unicodeenc -&amp;gt; 37&lt;br /&gt;
.........width -&amp;gt; 1413&lt;br /&gt;
......}&lt;br /&gt;
......9 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 80&lt;br /&gt;
............2 -&amp;gt; -30&lt;br /&gt;
............3 -&amp;gt; 1346&lt;br /&gt;
............4 -&amp;gt; 1450&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; ampersand&lt;br /&gt;
.........unicodeenc -&amp;gt; 38&lt;br /&gt;
.........width -&amp;gt; 1366&lt;br /&gt;
......}&lt;br /&gt;
......10 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 160&lt;br /&gt;
............2 -&amp;gt; 813&lt;br /&gt;
............3 -&amp;gt; 352&lt;br /&gt;
............4 -&amp;gt; 1480&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; quotesingle&lt;br /&gt;
.........unicodeenc -&amp;gt; 39&lt;br /&gt;
.........width -&amp;gt; 512&lt;br /&gt;
......}&lt;br /&gt;
......11 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 121&lt;br /&gt;
............2 -&amp;gt; -315&lt;br /&gt;
............3 -&amp;gt; 610&lt;br /&gt;
............4 -&amp;gt; 1600&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; parenleft&lt;br /&gt;
.........unicodeenc -&amp;gt; 40&lt;br /&gt;
.........possub -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; {&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............type -&amp;gt; substitution&lt;br /&gt;
...............subs -&amp;gt; {&lt;br /&gt;
..................variant -&amp;gt; parenright&lt;br /&gt;
...............}&lt;br /&gt;
...............script_lang_index -&amp;gt; 1&lt;br /&gt;
...............tag -&amp;gt; rtla&lt;br /&gt;
............}&lt;br /&gt;
.........}&lt;br /&gt;
.........width -&amp;gt; 649&lt;br /&gt;
......}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we have the special case of a glyph which has an attached OpenType transformation. In this case it is a (simple) substitution from the GSUB table. This substitution should happen when we are in the script+language combination indexed by number 1, and the OpenType which calls it is &amp;lt;tt&amp;gt;rtla&amp;lt;/tt&amp;gt;, also known as �Right-to-left alternates�. The glyph �parenleft� is substituted by the glyph �parenright�.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
......12 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 41&lt;br /&gt;
............2 -&amp;gt; -315&lt;br /&gt;
............3 -&amp;gt; 530&lt;br /&gt;
............4 -&amp;gt; 1600&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; parenright&lt;br /&gt;
.........unicodeenc -&amp;gt; 41&lt;br /&gt;
.........possub -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; {&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............type -&amp;gt; substitution&lt;br /&gt;
...............subs -&amp;gt; {&lt;br /&gt;
..................variant -&amp;gt; parenleft&lt;br /&gt;
...............}&lt;br /&gt;
...............script_lang_index -&amp;gt; 1&lt;br /&gt;
...............tag -&amp;gt; rtla&lt;br /&gt;
............}&lt;br /&gt;
.........}&lt;br /&gt;
.........width -&amp;gt; 649&lt;br /&gt;
......}&lt;br /&gt;
......13 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 70&lt;br /&gt;
............2 -&amp;gt; 709&lt;br /&gt;
............3 -&amp;gt; 846&lt;br /&gt;
............4 -&amp;gt; 1561&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; asterisk&lt;br /&gt;
.........unicodeenc -&amp;gt; 42&lt;br /&gt;
.........width -&amp;gt; 915&lt;br /&gt;
......}&lt;br /&gt;
......14 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 61&lt;br /&gt;
............2 -&amp;gt; 205&lt;br /&gt;
............3 -&amp;gt; 778&lt;br /&gt;
............4 -&amp;gt; 920&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; plus&lt;br /&gt;
.........unicodeenc -&amp;gt; 43&lt;br /&gt;
.........width -&amp;gt; 840&lt;br /&gt;
......}&lt;br /&gt;
......15 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 88&lt;br /&gt;
............2 -&amp;gt; -305&lt;br /&gt;
............3 -&amp;gt; 391&lt;br /&gt;
............4 -&amp;gt; 230&lt;br /&gt;
.........}&lt;br /&gt;
.........kerns -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; quotedblright&lt;br /&gt;
...............off -&amp;gt; -220&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............2 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; quoteright&lt;br /&gt;
...............off -&amp;gt; -220&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; comma&lt;br /&gt;
.........unicodeenc -&amp;gt; 44&lt;br /&gt;
.........width -&amp;gt; 469&lt;br /&gt;
......}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we have some kernings: the �comma� glyph gets kerned by -220 units when in front of �quoteright� or �quotedblright�.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
......16 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 61&lt;br /&gt;
............2 -&amp;gt; 455&lt;br /&gt;
............3 -&amp;gt; 629&lt;br /&gt;
............4 -&amp;gt; 569&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; hyphen&lt;br /&gt;
.........unicodeenc -&amp;gt; 45&lt;br /&gt;
.........width -&amp;gt; 690&lt;br /&gt;
......}&lt;br /&gt;
......17 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 131&lt;br /&gt;
............2 -&amp;gt; -40&lt;br /&gt;
............3 -&amp;gt; 369&lt;br /&gt;
............4 -&amp;gt; 236&lt;br /&gt;
.........}&lt;br /&gt;
.........kerns -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; quotedblright&lt;br /&gt;
...............off -&amp;gt; -220&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............2 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; quoteright&lt;br /&gt;
...............off -&amp;gt; -220&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; period&lt;br /&gt;
.........unicodeenc -&amp;gt; 46&lt;br /&gt;
.........width -&amp;gt; 469&lt;br /&gt;
......}&lt;br /&gt;
......18 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 49&lt;br /&gt;
............2 -&amp;gt; -335&lt;br /&gt;
............3 -&amp;gt; 909&lt;br /&gt;
............4 -&amp;gt; 1600&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; slash&lt;br /&gt;
.........unicodeenc -&amp;gt; 47&lt;br /&gt;
.........width -&amp;gt; 961&lt;br /&gt;
......}&lt;br /&gt;
......19 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 76&lt;br /&gt;
............2 -&amp;gt; -30&lt;br /&gt;
............3 -&amp;gt; 885&lt;br /&gt;
............4 -&amp;gt; 1235&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; zero&lt;br /&gt;
.........unicodeenc -&amp;gt; 48&lt;br /&gt;
.........width -&amp;gt; 961&lt;br /&gt;
......}&lt;br /&gt;
......20 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 139&lt;br /&gt;
............2 -&amp;gt; 0&lt;br /&gt;
............3 -&amp;gt; 840&lt;br /&gt;
............4 -&amp;gt; 1245&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; one&lt;br /&gt;
.........unicodeenc -&amp;gt; 49&lt;br /&gt;
.........width -&amp;gt; 961&lt;br /&gt;
......}&lt;br /&gt;
......21 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 98&lt;br /&gt;
............2 -&amp;gt; 0&lt;br /&gt;
............3 -&amp;gt; 836&lt;br /&gt;
............4 -&amp;gt; 1235&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; two&lt;br /&gt;
.........unicodeenc -&amp;gt; 50&lt;br /&gt;
.........width -&amp;gt; 961&lt;br /&gt;
......}&lt;br /&gt;
......22 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 68&lt;br /&gt;
............2 -&amp;gt; -30&lt;br /&gt;
............3 -&amp;gt; 825&lt;br /&gt;
............4 -&amp;gt; 1235&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; three&lt;br /&gt;
.........unicodeenc -&amp;gt; 51&lt;br /&gt;
.........width -&amp;gt; 961&lt;br /&gt;
......}&lt;br /&gt;
......23 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 55&lt;br /&gt;
............2 -&amp;gt; 0&lt;br /&gt;
............3 -&amp;gt; 874&lt;br /&gt;
............4 -&amp;gt; 1245&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; four&lt;br /&gt;
.........unicodeenc -&amp;gt; 52&lt;br /&gt;
.........width -&amp;gt; 961&lt;br /&gt;
......}&lt;br /&gt;
......24 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 78&lt;br /&gt;
............2 -&amp;gt; -30&lt;br /&gt;
............3 -&amp;gt; 836&lt;br /&gt;
............4 -&amp;gt; 1223&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; five&lt;br /&gt;
.........unicodeenc -&amp;gt; 53&lt;br /&gt;
.........width -&amp;gt; 961&lt;br /&gt;
......}&lt;br /&gt;
......25 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 111&lt;br /&gt;
............2 -&amp;gt; -30&lt;br /&gt;
............3 -&amp;gt; 881&lt;br /&gt;
............4 -&amp;gt; 1249&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; six&lt;br /&gt;
.........unicodeenc -&amp;gt; 54&lt;br /&gt;
.........width -&amp;gt; 961&lt;br /&gt;
......}&lt;br /&gt;
......26 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 104&lt;br /&gt;
............2 -&amp;gt; -30&lt;br /&gt;
............3 -&amp;gt; 885&lt;br /&gt;
............4 -&amp;gt; 1204&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; seven&lt;br /&gt;
.........unicodeenc -&amp;gt; 55&lt;br /&gt;
.........width -&amp;gt; 961&lt;br /&gt;
......}&lt;br /&gt;
......27 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 94&lt;br /&gt;
............2 -&amp;gt; -30&lt;br /&gt;
............3 -&amp;gt; 864&lt;br /&gt;
............4 -&amp;gt; 1235&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; eight&lt;br /&gt;
.........unicodeenc -&amp;gt; 56&lt;br /&gt;
.........width -&amp;gt; 961&lt;br /&gt;
......}&lt;br /&gt;
......28 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 100&lt;br /&gt;
............2 -&amp;gt; -43&lt;br /&gt;
............3 -&amp;gt; 870&lt;br /&gt;
............4 -&amp;gt; 1235&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; nine&lt;br /&gt;
.........unicodeenc -&amp;gt; 57&lt;br /&gt;
.........width -&amp;gt; 961&lt;br /&gt;
......}&lt;br /&gt;
......29 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 131&lt;br /&gt;
............2 -&amp;gt; -40&lt;br /&gt;
............3 -&amp;gt; 369&lt;br /&gt;
............4 -&amp;gt; 961&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; colon&lt;br /&gt;
.........unicodeenc -&amp;gt; 58&lt;br /&gt;
.........width -&amp;gt; 469&lt;br /&gt;
......}&lt;br /&gt;
......30 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 88&lt;br /&gt;
............2 -&amp;gt; -305&lt;br /&gt;
............3 -&amp;gt; 391&lt;br /&gt;
............4 -&amp;gt; 961&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; semicolon&lt;br /&gt;
.........unicodeenc -&amp;gt; 59&lt;br /&gt;
.........width -&amp;gt; 469&lt;br /&gt;
......}&lt;br /&gt;
......31 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 61&lt;br /&gt;
............2 -&amp;gt; 256&lt;br /&gt;
............3 -&amp;gt; 838&lt;br /&gt;
............4 -&amp;gt; 899&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; less&lt;br /&gt;
.........unicodeenc -&amp;gt; 60&lt;br /&gt;
.........possub -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; {&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............type -&amp;gt; substitution&lt;br /&gt;
...............subs -&amp;gt; {&lt;br /&gt;
..................variant -&amp;gt; greater&lt;br /&gt;
...............}&lt;br /&gt;
...............script_lang_index -&amp;gt; 1&lt;br /&gt;
...............tag -&amp;gt; rtla&lt;br /&gt;
............}&lt;br /&gt;
.........}&lt;br /&gt;
.........width -&amp;gt; 899&lt;br /&gt;
......}&lt;br /&gt;
......32 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 61&lt;br /&gt;
............2 -&amp;gt; 354&lt;br /&gt;
............3 -&amp;gt; 838&lt;br /&gt;
............4 -&amp;gt; 768&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; equal&lt;br /&gt;
.........unicodeenc -&amp;gt; 61&lt;br /&gt;
.........width -&amp;gt; 899&lt;br /&gt;
......}&lt;br /&gt;
......33 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 61&lt;br /&gt;
............2 -&amp;gt; 256&lt;br /&gt;
............3 -&amp;gt; 838&lt;br /&gt;
............4 -&amp;gt; 899&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; greater&lt;br /&gt;
.........unicodeenc -&amp;gt; 62&lt;br /&gt;
.........possub -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; {&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............type -&amp;gt; substitution&lt;br /&gt;
...............subs -&amp;gt; {&lt;br /&gt;
..................variant -&amp;gt; less&lt;br /&gt;
...............}&lt;br /&gt;
...............script_lang_index -&amp;gt; 1&lt;br /&gt;
...............tag -&amp;gt; rtla&lt;br /&gt;
............}&lt;br /&gt;
.........}&lt;br /&gt;
.........width -&amp;gt; 899&lt;br /&gt;
......}&lt;br /&gt;
......34 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 80&lt;br /&gt;
............2 -&amp;gt; -40&lt;br /&gt;
............3 -&amp;gt; 807&lt;br /&gt;
............4 -&amp;gt; 1480&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; question&lt;br /&gt;
.........unicodeenc -&amp;gt; 63&lt;br /&gt;
.........width -&amp;gt; 887&lt;br /&gt;
......}&lt;br /&gt;
......35 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 70&lt;br /&gt;
............2 -&amp;gt; -375&lt;br /&gt;
............3 -&amp;gt; 1583&lt;br /&gt;
............4 -&amp;gt; 1333&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; at&lt;br /&gt;
.........unicodeenc -&amp;gt; 64&lt;br /&gt;
.........width -&amp;gt; 1653&lt;br /&gt;
......}&lt;br /&gt;
......36 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 0&lt;br /&gt;
............2 -&amp;gt; 0&lt;br /&gt;
............3 -&amp;gt; 1198&lt;br /&gt;
............4 -&amp;gt; 1317&lt;br /&gt;
.........}&lt;br /&gt;
.........kerns -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; quotedblright&lt;br /&gt;
...............off -&amp;gt; -200&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............2 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; quoteright&lt;br /&gt;
...............off -&amp;gt; -200&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............3 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; y&lt;br /&gt;
...............off -&amp;gt; -100&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............4 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; w&lt;br /&gt;
...............off -&amp;gt; -80&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............5 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; v&lt;br /&gt;
...............off -&amp;gt; -100&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............6 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; Y&lt;br /&gt;
...............off -&amp;gt; -180&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............7 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; W&lt;br /&gt;
...............off -&amp;gt; -120&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............8 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; V&lt;br /&gt;
...............off -&amp;gt; -160&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............9 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; U&lt;br /&gt;
...............off -&amp;gt; -80&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............10 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; T&lt;br /&gt;
...............off -&amp;gt; -100&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............11 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; Q&lt;br /&gt;
...............off -&amp;gt; -30&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............12 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; O&lt;br /&gt;
...............off -&amp;gt; -30&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............13 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; G&lt;br /&gt;
...............off -&amp;gt; -30&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............14 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; C&lt;br /&gt;
...............off -&amp;gt; -30&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; A&lt;br /&gt;
.........unicodeenc -&amp;gt; 65&lt;br /&gt;
.........width -&amp;gt; 1219&lt;br /&gt;
......}&lt;br /&gt;
......37 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 41&lt;br /&gt;
............2 -&amp;gt; -14&lt;br /&gt;
............3 -&amp;gt; 1016&lt;br /&gt;
............4 -&amp;gt; 1290&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; B&lt;br /&gt;
.........unicodeenc -&amp;gt; 66&lt;br /&gt;
.........width -&amp;gt; 1126&lt;br /&gt;
......}&lt;br /&gt;
......38 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 70&lt;br /&gt;
............2 -&amp;gt; -30&lt;br /&gt;
............3 -&amp;gt; 1018&lt;br /&gt;
............4 -&amp;gt; 1290&lt;br /&gt;
.........}&lt;br /&gt;
.........kerns -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; A&lt;br /&gt;
...............off -&amp;gt; -60&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; C&lt;br /&gt;
.........unicodeenc -&amp;gt; 67&lt;br /&gt;
.........width -&amp;gt; 1098&lt;br /&gt;
......}&lt;br /&gt;
......39 -&amp;gt; {&lt;br /&gt;
.........boundingbox -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; 41&lt;br /&gt;
............2 -&amp;gt; 0&lt;br /&gt;
............3 -&amp;gt; 1124&lt;br /&gt;
............4 -&amp;gt; 1290&lt;br /&gt;
.........}&lt;br /&gt;
.........kerns -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; Y&lt;br /&gt;
...............off -&amp;gt; -60&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............2 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; W&lt;br /&gt;
...............off -&amp;gt; -20&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............3 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; V&lt;br /&gt;
...............off -&amp;gt; 40&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............4 -&amp;gt; {&lt;br /&gt;
...............char -&amp;gt; A&lt;br /&gt;
...............off -&amp;gt; -60&lt;br /&gt;
...............flags -&amp;gt; 0&lt;br /&gt;
...............sli -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
.........}&lt;br /&gt;
.........name -&amp;gt; D&lt;br /&gt;
.........unicodeenc -&amp;gt; 68&lt;br /&gt;
.........width -&amp;gt; 1214&lt;br /&gt;
......}&lt;br /&gt;
&lt;br /&gt;
another 35,850 lines of code&lt;br /&gt;
&lt;br /&gt;
...}&lt;br /&gt;
...fontstyle_id -&amp;gt; 0&lt;br /&gt;
...units_per_em -&amp;gt; 2048&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2,048 units per em means that to obtain TeX quads we need to divide by that number. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...glyphcnt -&amp;gt; 1699&lt;br /&gt;
...gasp_cnt -&amp;gt; 3&lt;br /&gt;
...weight -&amp;gt; Book&lt;br /&gt;
...pfminfo -&amp;gt; {&lt;br /&gt;
......vlinegap -&amp;gt; 0&lt;br /&gt;
......os2_subyoff -&amp;gt; 1200&lt;br /&gt;
......hheadascent_add -&amp;gt; 1&lt;br /&gt;
......os2_strikeypos -&amp;gt; 512&lt;br /&gt;
......hhead_descent -&amp;gt; -565&lt;br /&gt;
......os2_typolinegap -&amp;gt; 90&lt;br /&gt;
......typodescent_add -&amp;gt; 1&lt;br /&gt;
......weight -&amp;gt; 400&lt;br /&gt;
......hhead_ascent -&amp;gt; 1759&lt;br /&gt;
......os2_strikeysize -&amp;gt; 102&lt;br /&gt;
......panose_set -&amp;gt; 1&lt;br /&gt;
......os2_breakchar -&amp;gt; 0&lt;br /&gt;
......pfmset -&amp;gt; 1&lt;br /&gt;
......os2_typoascent -&amp;gt; -88&lt;br /&gt;
......winascent_add -&amp;gt; 1&lt;br /&gt;
......firstchar -&amp;gt; 32&lt;br /&gt;
......os2_capheight -&amp;gt; 0&lt;br /&gt;
......windescent_add -&amp;gt; 1&lt;br /&gt;
......vheadset -&amp;gt; 0&lt;br /&gt;
......os2_subxsize -&amp;gt; 856&lt;br /&gt;
......os2_xheight -&amp;gt; 0&lt;br /&gt;
......os2_supxoff -&amp;gt; 0&lt;br /&gt;
......hheaddescent_add -&amp;gt; 1&lt;br /&gt;
......os2_defaultchar -&amp;gt; 0&lt;br /&gt;
......linegap -&amp;gt; 45&lt;br /&gt;
......os2_family_class -&amp;gt; 0&lt;br /&gt;
......os2_vendor -&amp;gt; SIL &lt;br /&gt;
......os2_supyoff -&amp;gt; 1200&lt;br /&gt;
......os2_winascent -&amp;gt; 1759&lt;br /&gt;
......os2_subysize -&amp;gt; 856&lt;br /&gt;
......avgwidth -&amp;gt; 845&lt;br /&gt;
......os2_subxoff -&amp;gt; 0&lt;br /&gt;
......os2_supysize -&amp;gt; 856&lt;br /&gt;
......os2_windescent -&amp;gt; 565&lt;br /&gt;
......os2_typodescent -&amp;gt; -69&lt;br /&gt;
......hheadset -&amp;gt; 1&lt;br /&gt;
......fstype -&amp;gt; 0&lt;br /&gt;
......os2_supxsize -&amp;gt; 856&lt;br /&gt;
......lastchar -&amp;gt; 64260&lt;br /&gt;
......panose -&amp;gt; {&lt;br /&gt;
.........serifstyle -&amp;gt; Any&lt;br /&gt;
.........armstyle -&amp;gt; Any&lt;br /&gt;
.........contrast -&amp;gt; Medium&lt;br /&gt;
.........familytype -&amp;gt; Text and Display&lt;br /&gt;
.........proportion -&amp;gt; Modern&lt;br /&gt;
.........strokevariation -&amp;gt; Any&lt;br /&gt;
.........weight -&amp;gt; Book&lt;br /&gt;
.........xheight -&amp;gt; Constant/Large&lt;br /&gt;
.........midline -&amp;gt; Any&lt;br /&gt;
.........letterform -&amp;gt; Normal/Contact&lt;br /&gt;
......}&lt;br /&gt;
......width -&amp;gt; 5&lt;br /&gt;
......pfmfamily -&amp;gt; 17&lt;br /&gt;
......subsuper_set -&amp;gt; 1&lt;br /&gt;
......typoascent_add -&amp;gt; 1&lt;br /&gt;
...}&lt;br /&gt;
...fullname -&amp;gt; GentiumAlt&lt;br /&gt;
...map -&amp;gt; {&lt;br /&gt;
......map -&amp;gt; {&lt;br /&gt;
.........32 -&amp;gt; 3&lt;br /&gt;
.........33 -&amp;gt; 4&lt;br /&gt;
.........34 -&amp;gt; 5&lt;br /&gt;
.........35 -&amp;gt; 6&lt;br /&gt;
.........36 -&amp;gt; 7&lt;br /&gt;
.........37 -&amp;gt; 8&lt;br /&gt;
.........38 -&amp;gt; 9&lt;br /&gt;
.........39 -&amp;gt; 10&lt;br /&gt;
.........40 -&amp;gt; 11&lt;br /&gt;
&lt;br /&gt;
another 1,679 lines&lt;br /&gt;
&lt;br /&gt;
.........65764 -&amp;gt; 1688&lt;br /&gt;
.........65765 -&amp;gt; 1689&lt;br /&gt;
.........65766 -&amp;gt; 1690&lt;br /&gt;
.........65767 -&amp;gt; 1691&lt;br /&gt;
.........65768 -&amp;gt; 1692&lt;br /&gt;
.........65769 -&amp;gt; 1693&lt;br /&gt;
.........65770 -&amp;gt; 1694&lt;br /&gt;
.........65771 -&amp;gt; 1695&lt;br /&gt;
.........65772 -&amp;gt; 1696&lt;br /&gt;
.........65773 -&amp;gt; 1697&lt;br /&gt;
.........65774 -&amp;gt; 1698&lt;br /&gt;
......}&lt;br /&gt;
......enc -&amp;gt; {&lt;br /&gt;
.........1 -&amp;gt; {&lt;br /&gt;
............has_2byte -&amp;gt; 1&lt;br /&gt;
............char_max -&amp;gt; 0&lt;br /&gt;
............only_1byte -&amp;gt; 0&lt;br /&gt;
............is_unicodebmp -&amp;gt; 1&lt;br /&gt;
............char_cnt -&amp;gt; 65536&lt;br /&gt;
............high_page -&amp;gt; 0&lt;br /&gt;
............has_1byte -&amp;gt; 0&lt;br /&gt;
............low_page -&amp;gt; 0&lt;br /&gt;
............builtin -&amp;gt; 1&lt;br /&gt;
............enc_name -&amp;gt; UnicodeBmp&lt;br /&gt;
............hidden -&amp;gt; 1&lt;br /&gt;
.........}&lt;br /&gt;
.........2 -&amp;gt; {&lt;br /&gt;
............has_2byte -&amp;gt; 0&lt;br /&gt;
............char_max -&amp;gt; 0&lt;br /&gt;
............only_1byte -&amp;gt; 0&lt;br /&gt;
............is_original -&amp;gt; 1&lt;br /&gt;
............char_cnt -&amp;gt; 0&lt;br /&gt;
............high_page -&amp;gt; 0&lt;br /&gt;
............has_1byte -&amp;gt; 0&lt;br /&gt;
............low_page -&amp;gt; 0&lt;br /&gt;
............builtin -&amp;gt; 1&lt;br /&gt;
............enc_name -&amp;gt; Original&lt;br /&gt;
............hidden -&amp;gt; 1&lt;br /&gt;
.........}&lt;br /&gt;
.........3 -&amp;gt; {&lt;br /&gt;
............has_2byte -&amp;gt; 0&lt;br /&gt;
............char_max -&amp;gt; 0&lt;br /&gt;
............only_1byte -&amp;gt; 0&lt;br /&gt;
............char_cnt -&amp;gt; 0&lt;br /&gt;
............is_custom -&amp;gt; 1&lt;br /&gt;
............has_1byte -&amp;gt; 0&lt;br /&gt;
............low_page -&amp;gt; 0&lt;br /&gt;
............builtin -&amp;gt; 1&lt;br /&gt;
............enc_name -&amp;gt; Custom&lt;br /&gt;
............high_page -&amp;gt; 0&lt;br /&gt;
............hidden -&amp;gt; 1&lt;br /&gt;
.........}&lt;br /&gt;
.........4 -&amp;gt; {&lt;br /&gt;
............has_2byte -&amp;gt; 0&lt;br /&gt;
............char_max -&amp;gt; 0&lt;br /&gt;
............only_1byte -&amp;gt; 1&lt;br /&gt;
............char_cnt -&amp;gt; 256&lt;br /&gt;
............high_page -&amp;gt; 0&lt;br /&gt;
............has_1byte -&amp;gt; 1&lt;br /&gt;
............low_page -&amp;gt; 0&lt;br /&gt;
............builtin -&amp;gt; 1&lt;br /&gt;
............enc_name -&amp;gt; TeX-Base-Encoding&lt;br /&gt;
............unicode -&amp;gt; {&lt;br /&gt;
...............1 -&amp;gt; 729&lt;br /&gt;
...............2 -&amp;gt; 64257&lt;br /&gt;
...............3 -&amp;gt; 64258&lt;br /&gt;
...............4 -&amp;gt; 8260&lt;br /&gt;
...............5 -&amp;gt; 733&lt;br /&gt;
...............6 -&amp;gt; 321&lt;br /&gt;
...............7 -&amp;gt; 322&lt;br /&gt;
...............8 -&amp;gt; 731&lt;br /&gt;
&lt;br /&gt;
another 238 lines&lt;br /&gt;
&lt;br /&gt;
...............247 -&amp;gt; 247&lt;br /&gt;
...............248 -&amp;gt; 248&lt;br /&gt;
...............249 -&amp;gt; 249&lt;br /&gt;
...............250 -&amp;gt; 250&lt;br /&gt;
...............251 -&amp;gt; 251&lt;br /&gt;
...............252 -&amp;gt; 252&lt;br /&gt;
...............253 -&amp;gt; 253&lt;br /&gt;
...............254 -&amp;gt; 254&lt;br /&gt;
...............255 -&amp;gt; 255&lt;br /&gt;
...............0 -&amp;gt; 0&lt;br /&gt;
............}&lt;br /&gt;
............hidden -&amp;gt; 1&lt;br /&gt;
.........}&lt;br /&gt;
......}&lt;br /&gt;
......backmax -&amp;gt; 1699&lt;br /&gt;
......enccount -&amp;gt; 65775&lt;br /&gt;
......encmax -&amp;gt; 65775&lt;br /&gt;
......backmap -&amp;gt; {&lt;br /&gt;
.........1 -&amp;gt; 65537&lt;br /&gt;
.........2 -&amp;gt; 65538&lt;br /&gt;
.........3 -&amp;gt; 32&lt;br /&gt;
.........4 -&amp;gt; 33&lt;br /&gt;
.........5 -&amp;gt; 34&lt;br /&gt;
.........6 -&amp;gt; 35&lt;br /&gt;
.........7 -&amp;gt; 36&lt;br /&gt;
.........8 -&amp;gt; 37&lt;br /&gt;
.........9 -&amp;gt; 38&lt;br /&gt;
.........10 -&amp;gt; 39&lt;br /&gt;
.........11 -&amp;gt; 40&lt;br /&gt;
.........12 -&amp;gt; 41&lt;br /&gt;
.........13 -&amp;gt; 42&lt;br /&gt;
&lt;br /&gt;
another 1,679 lines&lt;br /&gt;
&lt;br /&gt;
.........1693 -&amp;gt; 65769&lt;br /&gt;
.........1694 -&amp;gt; 65770&lt;br /&gt;
.........1695 -&amp;gt; 65771&lt;br /&gt;
.........1696 -&amp;gt; 65772&lt;br /&gt;
.........1697 -&amp;gt; 65773&lt;br /&gt;
.........1698 -&amp;gt; 65774&lt;br /&gt;
.........0 -&amp;gt; 65536&lt;br /&gt;
......}&lt;br /&gt;
...}&lt;br /&gt;
...italicangle -&amp;gt; 0&lt;br /&gt;
...strokedfont -&amp;gt; 0&lt;br /&gt;
...cidinfo -&amp;gt; {&lt;br /&gt;
......supplement -&amp;gt; 0&lt;br /&gt;
......version -&amp;gt; 0&lt;br /&gt;
...}&lt;br /&gt;
...familyname -&amp;gt; GentiumAlt&lt;br /&gt;
...script_lang -&amp;gt; {&lt;br /&gt;
......1 -&amp;gt; {&lt;br /&gt;
.........script -&amp;gt; latn&lt;br /&gt;
.........langs -&amp;gt; {&lt;br /&gt;
............1 -&amp;gt; dflt&lt;br /&gt;
.........}&lt;br /&gt;
......}&lt;br /&gt;
...}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The table &amp;lt;tt&amp;gt;script_lang&amp;lt;/tt&amp;gt; contains scripts and languages. Here we have script &amp;lt;tt&amp;gt;latn&amp;lt;/tt&amp;gt; (Latin) with default language.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...upos -&amp;gt; -48&lt;br /&gt;
...version -&amp;gt; 1.01; 2003; initial SIL release&lt;br /&gt;
...glyphmax -&amp;gt; 1699&lt;br /&gt;
...names -&amp;gt; {&lt;br /&gt;
......1 -&amp;gt; {&lt;br /&gt;
.........lang -&amp;gt; English (US)&lt;br /&gt;
.........names -&amp;gt; {&lt;br /&gt;
............designerurl -&amp;gt; http://www.sil.org/~gaultney&lt;br /&gt;
............venderurl -&amp;gt; http://www.sil.org/&lt;br /&gt;
............compatfull -&amp;gt; GentiumAlt&lt;br /&gt;
............trademark -&amp;gt; Gentium is a trademark of SIL International.&lt;br /&gt;
............license -&amp;gt; This font is the property of SIL International. It is distributed as copyrighted freeware. You may use this software without any charge and may distribute it, as is, to others. Commercial distribution of this software is restricted &lt;br /&gt;
without prior written permission. If you wish to distribute this software commercially, contact SIL for details on obtaining a license. You may not rent or lease the software, nor may you modify, adapt, translate, reverse engineer, decompile, or disassemb&lt;br /&gt;
le the software. You may not make derivative fonts from this software. THE SOFTWARE AND RELATED FILES ARE PROVIDED &amp;quot;AS IS&amp;quot; AND WITHOUT WARRANTY OF ANY KIND.&lt;br /&gt;
............fullname -&amp;gt; GentiumAlt&lt;br /&gt;
............preffamilyname -&amp;gt; GentiumAlt&lt;br /&gt;
............designer -&amp;gt; J. Victor Gaultney&lt;br /&gt;
............copyright -&amp;gt; Copyright (c) SIL International 2003. All rights reserved.&lt;br /&gt;
............version -&amp;gt; Version 1.01; 2003; initial SIL release&lt;br /&gt;
............prefmodifiers -&amp;gt; Regular&lt;br /&gt;
............family -&amp;gt; GentiumAlt&lt;br /&gt;
............postscriptname -&amp;gt; GentiumAlt&lt;br /&gt;
............subfamily -&amp;gt; Regular&lt;br /&gt;
............uniqueid -&amp;gt; SIL: GentiumAlt: 2003&lt;br /&gt;
.........}&lt;br /&gt;
......}&lt;br /&gt;
...}&lt;br /&gt;
...gentags -&amp;gt; {&lt;br /&gt;
......tt_cur -&amp;gt; 0&lt;br /&gt;
...}&lt;br /&gt;
...modificationtime -&amp;gt; 1063146346&lt;br /&gt;
...fontname -&amp;gt; GentiumAlt&lt;br /&gt;
...changed -&amp;gt; 0&lt;br /&gt;
...vertical_origin -&amp;gt; 0&lt;br /&gt;
...table_version -&amp;gt; 0.1&lt;br /&gt;
...hasvmetrics -&amp;gt; 0&lt;br /&gt;
...creationtime -&amp;gt; 1032220800&lt;br /&gt;
...order2 -&amp;gt; 1&lt;br /&gt;
...head_optimized_for_cleartype -&amp;gt; 0&lt;br /&gt;
...strokewidth -&amp;gt; 0&lt;br /&gt;
...design_range_bottom -&amp;gt; 0&lt;br /&gt;
...design_size -&amp;gt; 0&lt;br /&gt;
...design_range_top -&amp;gt; 0&lt;br /&gt;
...sli_cnt -&amp;gt; 1&lt;br /&gt;
...macstyle -&amp;gt; -1&lt;br /&gt;
...ttf_tables -&amp;gt; {&lt;br /&gt;
......1 -&amp;gt; {&lt;br /&gt;
.........len -&amp;gt; 32&lt;br /&gt;
.........data -&amp;gt; &lt;br /&gt;
.........maxlen -&amp;gt; 0&lt;br /&gt;
.........tag -&amp;gt; maxp&lt;br /&gt;
......}&lt;br /&gt;
...}&lt;br /&gt;
...copyright -&amp;gt; Copyright (c) SIL International 2003. All rights reserved.&lt;br /&gt;
...os2_version -&amp;gt; 1&lt;br /&gt;
...gasp_version -&amp;gt; 0&lt;br /&gt;
...uni_interp -&amp;gt; none&lt;br /&gt;
...uwidth -&amp;gt; 14&lt;br /&gt;
...weight_width_slope_only -&amp;gt; 0&lt;br /&gt;
...descent -&amp;gt; 410&lt;br /&gt;
...ascent -&amp;gt; 1638&lt;br /&gt;
...uniqueid -&amp;gt; 0&lt;br /&gt;
} )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=Main_Page&amp;diff=37</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=Main_Page&amp;diff=37"/>
		<updated>2010-12-07T21:28:43Z</updated>

		<summary type="html">&lt;p&gt;Patrick: Link corrected&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Welcome to the LuaTeX wiki ==&lt;br /&gt;
&lt;br /&gt;
This is a wiki for [http://www.luatex.org LuaTeX], a typesetting engine derived from &lt;br /&gt;
[http://en.wikipedia.org/wiki/TeX TeX] that includes [http://www.lua.org Lua] as an embedded scripting language.&lt;br /&gt;
&lt;br /&gt;
We are [[Special:Recentchanges|currently editing]] [[Special:Allpages|{{NUMBEROFARTICLES}}]] articles.&lt;br /&gt;
&lt;br /&gt;
* [http://www.mediawiki.org/wiki/Help:Formatting How to edit wiki pages]&lt;br /&gt;
* [[Bug tracking|Bug tracking]]: Mantis [http://tracker.luatex.org bug tracker]&lt;br /&gt;
&lt;br /&gt;
== Getting help ==&lt;br /&gt;
&lt;br /&gt;
* There are two mailing lists related to LuaTeX, [http://tug.org/mailman/listinfo/luatex one for general discussions and questions about LuaTeX (&amp;quot;luatex users&amp;quot;)] and [http://www.ntg.nl/mailman/listinfo/dev-luatex one more related to the development of LuaTeX (&amp;quot;dev-luatex&amp;quot;)]&lt;br /&gt;
* There is also [http://www.tug.org/mailman/listinfo/lualatex-dev a LuaLaTeX (LaTeX with LuaTeX) mailing list].&lt;br /&gt;
* [http://tex.stackexchange.com/ tex.stackexchange.com] is a q&amp;amp;a site for questions related to TeX, and you can ask (and answer) LuaTeX related questions there.&lt;br /&gt;
* The [http://www.luatex.org/svn/trunk/manual/luatexref-t.pdf online reference manual (pdf)] describes every aspect of LuaTeX, but is rather technical and concise.&lt;br /&gt;
&lt;br /&gt;
== Some topics from the old wiki at bluwiki.com ==&lt;br /&gt;
&lt;br /&gt;
(Thanks to [http://omega.enstb.org/yannis/ Yannis Haralambous])&lt;br /&gt;
&lt;br /&gt;
* An example of code [[traversing TeX nodes]] before an horizontal list goes through the line breaking engine;&lt;br /&gt;
* An example of code [[traversing tokens]] just before execution or expansion;&lt;br /&gt;
* you want to [[explore the table obtained from a TrueType font]], loaded by &amp;lt;tt&amp;gt;font.read_ttf&amp;lt;/tt&amp;gt;;&lt;br /&gt;
* you want to [[explore the internal font table]] of a pre-loaded font or of a font you have loaded by &amp;lt;tt&amp;gt;\font&amp;lt;/tt&amp;gt; and then used for at least one glyph;&lt;br /&gt;
* how to [[use a TrueType font]] without going through a TFM or a OFM file;&lt;br /&gt;
* how to do &amp;lt;i&amp;gt;kinsoku&amp;lt;/i&amp;gt; ([[Japanese and more generally CJK typesetting]]);&lt;br /&gt;
* you want a newline in your log file or on the terminal? add &amp;lt;tt&amp;gt;\string\n&amp;lt;/tt&amp;gt; to your string;&lt;br /&gt;
* you want to [[sort a token list]];&lt;br /&gt;
* you want to [[split a comma-separated list]];&lt;br /&gt;
* you want to [[encrypt your document using ROT13]];&lt;br /&gt;
* you want to [[typeset non-TeX files by converting them using Lua code]];&lt;br /&gt;
* example code to [[mirror characters with Bidi_Mirrored property]];&lt;br /&gt;
* using mplib to write [[metapost with LuaTeX]]&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=Talk:Metapost_with_LuaTeX&amp;diff=36</id>
		<title>Talk:Metapost with LuaTeX</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=Talk:Metapost_with_LuaTeX&amp;diff=36"/>
		<updated>2010-12-07T21:27:34Z</updated>

		<summary type="html">&lt;p&gt;Patrick: Link to old location&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Old location: http://luatex.bluwiki.com/go/Metapost_with_LuaTeX&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=Metapost_with_LuaTeX&amp;diff=35</id>
		<title>Metapost with LuaTeX</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=Metapost_with_LuaTeX&amp;diff=35"/>
		<updated>2010-12-07T21:27:15Z</updated>

		<summary type="html">&lt;p&gt;Patrick: Copied from the old bluwiki.com luatex wiki&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Writing directly some metapost code is now possible in LuaTeX, through MPLib. It only works in pdf mode.&lt;br /&gt;
&lt;br /&gt;
To get it working, you will need three files: [http://source.contextgarden.net/tex/context/base/supp-mpl.lua supp-mpl.lua] and [http://source.contextgarden.net/tex/context/base/supp-mpl.tex supp-mpl.tex] (you need to copy/paste them) from the ConTeXt distribution, and a stupid .sty file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\NeedsTeXFormat{LaTeX2e}&lt;br /&gt;
\ProvidesPackage{mplib}&lt;br /&gt;
&lt;br /&gt;
\input supp-mpl.tex&lt;br /&gt;
&lt;br /&gt;
\directlua0{dofile(kpse.find_file(&amp;quot;formathack.lua&amp;quot;))}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And create a file formathack.lua containing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local preamble = [[&lt;br /&gt;
input %s ; dump ;&lt;br /&gt;
]]&lt;br /&gt;
metapost.make = function (name, mem_name)&lt;br /&gt;
    local mpx = mplib.new {&lt;br /&gt;
        ini_version = true,&lt;br /&gt;
        find_file = metapost.finder,&lt;br /&gt;
        job_name =  name}&lt;br /&gt;
    if mpx then&lt;br /&gt;
        local result = mpx:execute(string.format(preamble,name))&lt;br /&gt;
        mpx:finish()&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
function replacesuffix(filename, suffix)&lt;br /&gt;
  return (string.gsub(filename,&amp;quot;%.[%a%d]+$&amp;quot;,&amp;quot;&amp;quot;)) .. &amp;quot;.&amp;quot; .. suffix&lt;br /&gt;
end&lt;br /&gt;
metapost.load = function (name)&lt;br /&gt;
    local mpx = mplib.new {&lt;br /&gt;
            ini_version = false,&lt;br /&gt;
            mem_name = replacesuffix(name,&amp;quot;mem&amp;quot;),&lt;br /&gt;
            find_file = finder&lt;br /&gt;
        }&lt;br /&gt;
    local result&lt;br /&gt;
    if not mpx then&lt;br /&gt;
        metapost.make(name)&lt;br /&gt;
        metapost.report(&amp;quot;creating %s.mem&amp;quot;, name)&lt;br /&gt;
        mpx = mplib.new {&lt;br /&gt;
            ini_version = false,&lt;br /&gt;
            mem_name = replacesuffix(name,&amp;quot;mem&amp;quot;),&lt;br /&gt;
            find_file = finder&lt;br /&gt;
        }&lt;br /&gt;
    end&lt;br /&gt;
    if not mpx then&lt;br /&gt;
        result = { status = 99, error = &amp;quot;out of memory&amp;quot;}&lt;br /&gt;
    end&lt;br /&gt;
    return mpx, result&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have all four files, the following example should work:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\mplibcode&lt;br /&gt;
beginfig(1);&lt;br /&gt;
pickup pencircle xscaled 5 rotated 30;&lt;br /&gt;
draw unitsquare scaled 20 withcmykcolor (0.3,0.4,0.6,0);&lt;br /&gt;
endfig;&lt;br /&gt;
\endmplibcode &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
as well as any metapost code.&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=Talk:Mirror_characters_with_Bidi_Mirrored_property&amp;diff=34</id>
		<title>Talk:Mirror characters with Bidi Mirrored property</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=Talk:Mirror_characters_with_Bidi_Mirrored_property&amp;diff=34"/>
		<updated>2010-12-07T21:23:52Z</updated>

		<summary type="html">&lt;p&gt;Patrick: Link to old location&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Old location: http://luatex.bluwiki.com/go/Mirror_characters_with_Bidi_Mirrored_property&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=Mirror_characters_with_Bidi_Mirrored_property&amp;diff=33</id>
		<title>Mirror characters with Bidi Mirrored property</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=Mirror_characters_with_Bidi_Mirrored_property&amp;diff=33"/>
		<updated>2010-12-07T21:23:34Z</updated>

		<summary type="html">&lt;p&gt;Patrick: Copied from the old bluwiki.com luatex wiki&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This example code for mirroring characters that has Bidi_Mirrored property (as defined by Unicode) in RTL contexts. It uses characters.data table defined in [http://source.contextgarden.net/tex/context/base/char-def.lua char-def.lua] file from ConTeXt distribution to get character properties.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
dofile(&amp;quot;char-def.lua&amp;quot;) -- character definition table&lt;br /&gt;
&lt;br /&gt;
local function mirror(hlist)&lt;br /&gt;
  local rtl = false&lt;br /&gt;
  if tex.textdir == &amp;quot;TRT&amp;quot; then&lt;br /&gt;
    rtl = true&lt;br /&gt;
  elseif tex.textdir == &amp;quot;TLT&amp;quot; then&lt;br /&gt;
    rtl = false&lt;br /&gt;
  end&lt;br /&gt;
  for n in node.traverse(hlist) do&lt;br /&gt;
    if n.id == node.id(&amp;#039;hlist&amp;#039;) then&lt;br /&gt;
      mirror(n.list)&lt;br /&gt;
    end&lt;br /&gt;
    if n.id == node.id(&amp;quot;whatsit&amp;quot;) and n.subtype == 7 then&lt;br /&gt;
      if n.dir == &amp;quot;+TRT&amp;quot; or n.dir == &amp;quot;-TLT&amp;quot; then&lt;br /&gt;
        rtl = true&lt;br /&gt;
      elseif n.dir == &amp;quot;-TRT&amp;quot; or n.dir == &amp;quot;+TLT&amp;quot; then&lt;br /&gt;
        rtl = false&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if n.id == node.id(&amp;#039;glyph&amp;#039;) then&lt;br /&gt;
      if rtl then&lt;br /&gt;
      local char = n.char&lt;br /&gt;
      local mirror = characters.data[char].mirror&lt;br /&gt;
        if mirror then&lt;br /&gt;
          n.char = mirror&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
callback.register(&amp;#039;pre_linebreak_filter&amp;#039;,&lt;br /&gt;
  function(h)&lt;br /&gt;
     mirror(h)&lt;br /&gt;
     return true&lt;br /&gt;
  end&lt;br /&gt;
  )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\directlua{dofile(&amp;quot;mirror.lua&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
(Left to right) {\textdir TRT (RIGHT TO LEFT)}&lt;br /&gt;
&lt;br /&gt;
\textdir TRT&lt;br /&gt;
&lt;br /&gt;
RIGHT [TO] LEFT (TEXT)&lt;br /&gt;
&lt;br /&gt;
\textdir TLT&lt;br /&gt;
&lt;br /&gt;
left [to] right (text)&lt;br /&gt;
\bye&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--khaledhosny&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=Talk:Typeset_non-TeX_files_by_converting_them_using_Lua_code&amp;diff=32</id>
		<title>Talk:Typeset non-TeX files by converting them using Lua code</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=Talk:Typeset_non-TeX_files_by_converting_them_using_Lua_code&amp;diff=32"/>
		<updated>2010-12-07T21:21:37Z</updated>

		<summary type="html">&lt;p&gt;Patrick: Link to old location&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Old location: http://luatex.bluwiki.com/go/Typeset_non-TeX_files_by_converting_them_using_Lua_code&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=Typeset_non-TeX_files_by_converting_them_using_Lua_code&amp;diff=31</id>
		<title>Typeset non-TeX files by converting them using Lua code</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=Typeset_non-TeX_files_by_converting_them_using_Lua_code&amp;diff=31"/>
		<updated>2010-12-07T21:21:16Z</updated>

		<summary type="html">&lt;p&gt;Patrick: Copied from the old bluwiki.com luatex wiki&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The following code example demonstrates how to use the file reading callback and coroutines to convert a non-TeX file into TeX code which is then typeset.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First the Lua code (&amp;quot;Preprocessor.lua&amp;quot;):&lt;br /&gt;
&lt;br /&gt;
  local function readFile(fn)&lt;br /&gt;
  	local file = assert(io.open(fn, &amp;quot;r&amp;quot;))&lt;br /&gt;
  	local contents = file:read(&amp;quot;*a&amp;quot;)&lt;br /&gt;
  	file:close()&lt;br /&gt;
  	return contents&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  local function processInputFile(contents)&lt;br /&gt;
  	-- Preamble&lt;br /&gt;
  	coroutine.yield(&amp;quot;\\pdfoutput=1 &amp;quot;)&lt;br /&gt;
  	&lt;br /&gt;
  	-- Process the file: Return each line&lt;br /&gt;
  	for line in contents:gmatch(&amp;quot;(.-)[\n\r]&amp;quot;) do&lt;br /&gt;
  		coroutine.yield(line)&lt;br /&gt;
  	end&lt;br /&gt;
  	&lt;br /&gt;
  	-- Postamble&lt;br /&gt;
  	coroutine.yield(&amp;quot;\\bye&amp;quot;)&lt;br /&gt;
  	&lt;br /&gt;
  	-- Done&lt;br /&gt;
  	coroutine.yield(nil)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  callback.register(&amp;quot;open_read_file&amp;quot;, function(fileName)&lt;br /&gt;
  	local contents = readFile(fileName)&lt;br /&gt;
  	return {&lt;br /&gt;
  		reader = coroutine.wrap(function()&lt;br /&gt;
  			processInputFile(contents .. &amp;quot;\n&amp;quot;)&lt;br /&gt;
  		end)&lt;br /&gt;
  	}&lt;br /&gt;
  end)&lt;br /&gt;
&lt;br /&gt;
Then a small test file (&amp;quot;Preprocessor.txt&amp;quot;):&lt;br /&gt;
&lt;br /&gt;
  Hello World1&lt;br /&gt;
  &lt;br /&gt;
  Hello World2&lt;br /&gt;
  &lt;br /&gt;
  Paragraph 3,&lt;br /&gt;
  continuing right now&lt;br /&gt;
  and going on over&lt;br /&gt;
  four lines&lt;br /&gt;
&lt;br /&gt;
And finally the bash shell script to tie everything together (&amp;quot;Preprocessor.sh&amp;quot;):&lt;br /&gt;
&lt;br /&gt;
  luatex -fmt=luatex --jobname=Preprocessor &amp;#039;\directlua0{dofile(&amp;quot;Preprocessor.lua&amp;quot;)}\input Preprocessor.txt&amp;#039;&lt;br /&gt;
&lt;br /&gt;
As you can see, the file to be converted is simply read using &amp;quot;\input&amp;quot; and then converted&lt;br /&gt;
in the Lua function &amp;quot;processInputFile&amp;quot;. By using coroutines, we can pretend to convert the file&lt;br /&gt;
in one go, when really we are supplying it line by line to LuaTeX.&lt;br /&gt;
&lt;br /&gt;
It would of course be possible to check the file type/extension inside the &amp;quot;open_read_file&amp;quot; callback and perform different conversions (or none at all if a TeX file) depending on the&lt;br /&gt;
file type, i.e. to typeset source code.&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=Talk:Encrypt_your_document_using_ROT13&amp;diff=30</id>
		<title>Talk:Encrypt your document using ROT13</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=Talk:Encrypt_your_document_using_ROT13&amp;diff=30"/>
		<updated>2010-12-07T21:20:12Z</updated>

		<summary type="html">&lt;p&gt;Patrick: Link to old location&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Old location: http://luatex.bluwiki.com/go/Encrypt_your_document_using_ROT13&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.luatex.org/index.php?title=Encrypt_your_document_using_ROT13&amp;diff=29</id>
		<title>Encrypt your document using ROT13</title>
		<link rel="alternate" type="text/html" href="https://wiki.luatex.org/index.php?title=Encrypt_your_document_using_ROT13&amp;diff=29"/>
		<updated>2010-12-07T21:19:47Z</updated>

		<summary type="html">&lt;p&gt;Patrick: Copied from the old bluwiki.com luatex wiki&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The following PlainTeX code example uses the ligaturing callback to &amp;quot;encrypt&amp;quot; the document using ROT13-&amp;quot;encryption&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  %&amp;amp;luatex&lt;br /&gt;
  &lt;br /&gt;
  % Notes:&lt;br /&gt;
  % &lt;br /&gt;
  % -	Hyphenation is applied before rotating.&lt;br /&gt;
  % -	Ligaturing is performed after rotating.&lt;br /&gt;
  &lt;br /&gt;
  \pdfoutput=1&lt;br /&gt;
  \begingroup&lt;br /&gt;
  \catcode`\%=12&lt;br /&gt;
  \directlua0{&lt;br /&gt;
  	callback.register(&amp;#039;ligaturing&amp;#039;, function(head)&lt;br /&gt;
  		for v in node.traverse_id(33, head) do&lt;br /&gt;
  			if v.subtype == 1 then&lt;br /&gt;
  				local c = v.char&lt;br /&gt;
  				if c &amp;gt;= 65 and c &amp;lt;= 90 then&lt;br /&gt;
  					v.char = (c - 65 + 13) % 26 + 65&lt;br /&gt;
  				elseif c &amp;gt;= 97 and c &amp;lt;= 122 then&lt;br /&gt;
  					v.char = (c - 97 + 13) % 26 + 97&lt;br /&gt;
  				end&lt;br /&gt;
  			end&lt;br /&gt;
  		end&lt;br /&gt;
  		node.ligaturing(head)&lt;br /&gt;
  	end)&lt;br /&gt;
  }&lt;br /&gt;
  \endgroup&lt;br /&gt;
  &lt;br /&gt;
  % Hello World; fi -- fl -- ffl -- ffi -- enough with the ligatures!&lt;br /&gt;
  % Better do some kerning instead: AV&lt;br /&gt;
  &lt;br /&gt;
  Uryyb Jbeyq; sv -- sy -- ssy -- ssv -- rabhtu jvgu gur yvtngherf!&lt;br /&gt;
  Orggre qb fbzr xreavat vafgrnq: NI&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  \bye&lt;/div&gt;</summary>
		<author><name>Patrick</name></author>
		
	</entry>
</feed>