![]() |
Programming in Lua | ![]() |
Part I. The Language Chapter 10. Complete Examples |
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.
First, we define an auxiliary function for writing formatted text (we already saw this function in Section 5.2):
function fwrite (fmt, ...) return io.write(string.format(fmt, unpack(arg))) end
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:
function entry0 (o) N=N + 1 local title = o.title or '(no title)' fwrite('<LI><A HREF="#%d">%s</A>\n', N, title) endIf
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') endFinally, 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:
BEGIN() N = 0 entry = entry0 fwrite('<UL>\n') dofile('db.lua') fwrite('</UL>\n') N = 0 entry = entry1 dofile('db.lua') END()
Copyright © 2003-2004 Roberto Ierusalimschy. All rights reserved. |
![]() |
![]() |