logo Lua

Using the Weave library

Archive magazine published a two part article, Weaving Your Website, by Harriet Bazley in May and June of 2002, describing a program I had written, which I had called Weave. Its purpose was to ease the task of producing a website. Over the years I often used Weave, in a variety of versions, to make websites for myself and for others. I have just produced version four. It is much simpler and easier to use than the original, though the principles have not changed.

The website scene, on the other hand, has. The browser wars were in full swing, and HTML was being distorted from its original purpose by the tug of rival factions, anxious to prevent the standard falling to the arms of others. The World Wide Web Consortium eventually put a stop to this nonsense by introducing Cascading Style Sheets, which rendered most HTML tags irrelevant. This development brought about a rethink of Weave along more abstract lines. Another change has been the rise of client-side scripting, notably Javascript. Unfortunately RISC OS was not able to keep up with this.

Despite that, if you do want to create a static website on your computer, for uploading later, but you want to avoid lots of tiresome detail, here is how you use Weave to do it. Some versions of Weave were separate programs, but version four is just a Lua library. In other words to create the HTML files you write a Lua program.

Here is just about the simplest example:

local BEGIN, PATH in require "weave"
local mypage = BEGIN "Example"
mypage "Hello World"
mypage:END (PATH (arg[0]) .. "HW_Ex/html")
Running this produces an HTML file, HW_Ex/html, with the title "Example" in the same directory as the file containing the program, displaying the time-honoured phrase. But it also contains all the salad that HTML files require, which is not apparent in the Weave code here. Too boring? Let us dress it up slightly:
local BEGIN, PATH, TAG, CLASS in require "weave"
local mypage = BEGIN ("Example", "mystyle.css")
mypage {
        TAG.h1 ( ) "Hello World";
        TAG.hr (CLASS "dotted") ( );
        TAG.div (CLASS "contents") { --------
        [[An old song.]];
        TAG.pre (CLASS "verse") [[
There was a Jolly miller once, lived on the banks of Dee,
He danced and sang from morn to night,
No man more blithe than he.]];
                                 };--------
       }
mypage:END (PATH (arg[0]) .. "HW_Ex/html")
This uses a CSS stylefile, "mystyle.css", defining the classes "dotted" for horizontal rules (hr), "contents" for divisions (div) and "verse" for preformatted sections (pre). The braces { } enclose lists, each item terminated by a semi-colon ; . The double square brackets [[ ]] enclose text. Note that tags are followed by a pair of arguments. The first is for the text that follows the tag's label in the opening part, which I call the "attributes", the second for the text that comes between the opening and closing tags. The ( ) following TAG.h1 means that no extra text comes in the opening tag. The next ( ) occurs because hr is a monotag - it has no closing part.

The variable "mypage" denotes the webpage object created by BEGIN. The body of this page is assigned to it by the statement

   mypage (body)
In Lua, arguments to a function are usually enclosed in parentheses. But if there is only one argument, and that is a literal string "..." or literal text [[...]] or a literal list {...}, then the parentheses can be omitted, as above. Compound expressions, or variables, need the parentheses.

Webpage objects come with an END "method", which writes them out to file. So the creation of a webpage comes in three phases:

          BEGIN -> assign contents -> END    
There is nothing to stop you creating lots of different webpages in the same program, and interleaving the commands for each. Indeed, it is sometimes convenient to define parametrized webpages, and to put the whole business inside a for-loop.

In Lua strings are immutable objects. Shuffling strings in memory, and concatenating them, is to be avoided at all costs. Weave is efficient because it keeps strings as separate pieces, writing them out to file in the right order. Technically, the data structure used here is the "rope". A rope is either a string or a list of ropes. Only when they meet in the target file do the pieces of string get to rub elbows.

To use Weave you need to know what HTML tags to use, and some CSS. You do not really need to know much about Lua to use Weave beyond double square brackets for text, braces and semicolons for lists, and TAG for defining functions that enclose within tags.

The point of the exercise? To embed HTML, a language lacking variables or means of abstraction, into a richer one.

Weave