This first edition was written for Lua 5.0. While still largely relevant for later versions, there are some differences.The third edition targets Lua 5.2 and is available at Amazon and other bookstores.By buying the book, you also help to support the Lua project.

The Lua site keeps a database containing
a sample of projects around the world that use Lua.
We represent each entry in the database by a constructor
in an auto-documented way,
as the following example shows:

entry{
title = "Tecgraf",
org = "Computer Graphics Technology Group, PUC-Rio",
url = "http://www.tecgraf.puc-rio.br/",
contact = "Waldemar Celes",
description = [[
TeCGraf is the result of a partnership between PUC-Rio,
the Pontifical Catholic University of Rio de Janeiro,
and <A HREF="http://www.petrobras.com.br/">PETROBRAS</A>,
the Brazilian Oil Company.
TeCGraf is Lua's birthplace,
and the language has been used there since 1993.
Currently, more than thirty programmers in TeCGraf use
Lua regularly; they have written more than two hundred
thousand lines of code, distributed among dozens of
final products.]]
}

The interesting thing about this representation is that a file with
a sequence of such entries is a Lua program,
which does a sequence of calls to a function entry,
using the tables as the call arguments.

Our goal is to write a program that shows that data in HTML,
so that it becomes the web page http://www.lua.org/uses.html.
Because there are many projects,
the final page first shows a list of all project titles,
and then shows the details of each project.
The result of the program is something like this:

<HTML>
<HEAD><TITLE>Projects using Lua</TITLE></HEAD>
<BODY BGCOLOR="#FFFFFF">
Here are brief descriptions of some projects around the
world that use <A HREF="home.html">Lua</A>.
<BR>
<UL>
<LI><A HREF="#1">TeCGraf</A>
<LI> ...
</UL>
<H3>
<A NAME="1" HREF="http://www.tecgraf.puc-rio.br/">TeCGraf</A>
<BR>
<SMALL><EM>Computer Graphics Technology Group,
PUC-Rio</EM></SMALL>
</H3>
TeCGraf is the result of a partnership between
...
distributed among dozens of final products.<P>
Contact: Waldemar Celes
<A NAME="2"></A><HR>
...
</BODY></HTML>

To read the data,
all the program has to do is to give a proper definition for entry,
and then run the data file as a program (with dofile).
Note that we have to traverse all the entries twice,
first for the title list, and again for the project descriptions.
A first approach would be to collect all entries in an array.
However, because Lua compiles so fast,
there is a second attractive solution:
run the data file twice,
each time with a different definition for entry.
We follow this approach in the next program.

The BEGIN function simply writes the page header,
which is always the same:

function BEGIN()
io.write([[
<HTML>
<HEAD><TITLE>Projects using Lua</TITLE></HEAD>
<BODY BGCOLOR="#FFFFFF">
Here are brief descriptions of some projects around the
world that use <A HREF="home.html">Lua</A>.
<BR>
]])
end

The first definition for entry writes each title project as a list item.
The argument o will be the table describing the project:

If o.title is nil (that is, the field was not provided),
the function uses a fixed string "(no title)".

The second definition writes all useful data about a project.
It is a little more complex,
because all items are optional.

function entry1 (o)
N=N + 1
local title = o.title or o.org or 'org'
fwrite('<HR>\n<H3>\n')
local href = ''
if o.url then
href = string.format(' HREF="%s"', o.url)
end
fwrite('<A NAME="%d"%s>%s</A>\n', N, href, title)
if o.title and o.org then
fwrite('<BR>\n<SMALL><EM>%s</EM></SMALL>', o.org)
end
fwrite('\n</H3>\n')
if o.description then
fwrite('%s', string.gsub(o.description,
'\n\n\n*', '<P>\n'))
fwrite('<P>\n')
end
if o.email then
fwrite('Contact: <A HREF="mailto:%s">%s</A>\n',
o.email, o.contact or o.email)
elseif o.contact then
fwrite('Contact: %s\n', o.contact)
end
end

(To avoid conflict with HTML, which uses double quotes,
we used only single quotes in this program.)
The last function closes the page:

function END()
fwrite('</BODY></HTML>\n')
end

Finally, the main program starts the page,
runs the data file with the first definition for entry
(entry0) to create the list of titles,
then runs the data file again with the second definition for entry,
and closes the page: