Using Speakhtml
An Introduction
Niklas Olmes niklas@noxa.de
http://faith.eu.org/
May 18 2003
Abstract:
This paper gives a short introduction to Speakhtml, a HTML generator
written in Scheme. Speakhtml provides easy to use hooks to make use of
Scheme in generating any type of static content with arbitrary
complexity. Although using the Scheme programming language gives you
great power in designing HTML, it is perfectly possible generating
Websites without using or even knowing Scheme. This paper is divided
into two sections. The first one serves as a tutorial to Speakhtml.
You will need some fundamental knowledge in HTML to understand it. If
you don't, perhaps consider learning basic HTML first. The second
section is about using Scheme in Speakhtml.
_________________________________________________________________
Tutorial
This section will show you how a Speakhtml file looks like and how the
generator is invocated.
Generally, a Speakhtml file contains a '(' and a closing ')'. Further
on in this paper we will call any construct with '(' at the beginning
and ')' at the end a list. Note that a file containing only '()' would
not be valid, since for the Speakhtml parser it contains no data at
all. The simplest possible valid Speakhtml file would be a file only
containing:
(("Hello, World"))
As you will have noticed, the data ("Hello World") is within a list.
One can say that a Speakhtml file is one file containing a list of one
or more lists.
The given example above would be legal in Speakhtml, but it is not yet
a valid HTML page. To make it a valid one, we will have to introduce
and use HTML elements in Speakhtml. The generator includes all HTML4
loose elements by default, which are defined in html4-loose.scm. To
use a HTML element, prefix the name with '!' and put the result at the
beginning of a list with optional contents appended.
((!html (!head (!title "Title goes here"))
(!body ("Hello, World"))))
Example above shows a valid HTML "Hello, World" page. We used the
,
, and tag. Speakhtml will render this to:
[..]
Title goes here
Hello, World
The advantage in using lists instead of the HTML tag notation should
be obvious to experienced authors. If not, consider complex
table-in-table structures for example.
So how do we tell Speakhtml to generate our "Hello, World"? If you're
using the Guile interpreter or any interpreter that is able to give
over command line arguments, you may simply do:
$ ./speakhtml.scm file-to-parse
this would output the rendered result to the console. There is no file
option, so redirect output to a file (> hello.html).
We haven't talked about strings (text to display) yet. Generally, you
have to enclose text in "" and put it in a list. ("Hello, World")
would be a string in Speakhtml. Inside of tags it is possible to use
"" only, like in (!b "Hello, World") or (!td "Foo!"). You are allowed
to use multiple strings in one tag, of course:
("The quick brown" (!i "fox") "jumps over the" (!b "lazy" "dog"))
Another aspect we left out until yet are attributes. These are
implemented in Speakhtml as vectors. A vector may look like:
#(name value)
or
#((name value))
for just one attribut, or:
#((name value)
(name2 value2)
...)
for multiple attributes. Attributes have to follow directly after the
tag name, i.e.:
(!body #((text black)
(link "#0c0c0c"))
...)
You might have wondered about the vector used in the example above. We
did not use string form there. For text, black, and link this is
perfectly ok, since Speakhtml automatically converts this labels to
strings, as it automatically converts numbers to strings. So why are
"" around '#0c0c0c'? This is definately not text, it is a special
form. It uses the character #, which would be not allowed if not put
into string form via "". You should be reminded that depending on your
Scheme interpreter, case is not expected to be preserved. So you
should use explicit string form whenever case matters.
Automatical conversion to string form is included for convenience.
Feel free to use it--or not use it. It is up to you.
Complex example:
((@d (define author "Your Name your.name@address"))
(!html (!head (!meta #((http-equiv "Content-Type")
(content "text/html; charset=iso-8859-1")))
(@p `(!meta #((name author)
(content ,author))))
(!title "Put title here"))
(!body #(text black)
(!h1 "Title")
(!div #(align center)
("The quick brown fox jumps" (!i "over")
"the lazy dog")
(!ul
(!li "quick")
(!li "brown")
(!li "lazy"))))))
If you are curious what @d and @p mean read the next section about the
Scheme hooks.
_________________________________________________________________
Taking Advantage of Speakhtml with Scheme
Don't worry. You actually won't have to program in Scheme. But you
may. The last example in the first section shows two special
constructs, @d and @p.
What do they do?
(@d lis) evaluates the Scheme list lis
(@d (define author "blah")) would give variable author the value
"blah".
(@p lis) parses the list lis after evaluating it
(@p `(,author)) would result in parsing ("blah")
` stands for (quasiquote) and , for (unqoute). We used them here to
construct a list with variable author expanded. So ,author evaluates
variable author, which results in "blah". In Scheme, there is another
qoute, ' (quote). In ' , has no effect, but it has, if ' is in a `,
since every , in a surrounding ` is evaluated.
There are more special forms with @ prefix in Speakhtml, which are
listed here:
(@d lis) evaluates the Scheme list lis
(@e lis) evaluates the Scheme list lis and displays converted result
(@p lis) evaluates the Scheme list lis and parses it afterwards
(@use "file")
(@load "file") load and execute Scheme file file
(@input "file") load Speakhtml file file and parse it
(@cmt string) create a comment with string string
We will now take a look at the @use/@load directive. It allows you to
load a whole Scheme file into the underlying Scheme interpreter. This
gives you incredible power in to what you can do with Speakhtml. You
may run entire programs within Speakhtml and let the results of the
program be parsed by Speakhtml. To allow this, you may call following
functions implemented by Speakhtml within Scheme:
(parse lis) let Speakhtml parse lis as if it appeared in a Speakhtml
file
(convert x) try to convert x (whatever it is) into a string
(comment string) create a comment with string string
Additionally, Speakhtml provides the constant FILE, which is a string
containing the name of the current Speakhtml file processed.
Example of a Scheme function for Speakhtml:
(define (mypage title date content)
(parse `(!html (!head (!title ,title))
(!body
(!h1 ,title)
,content
(!p)
(!b "Last change:" ,date)))))
Put above function mypage into a file and include it in your Speakhtml
files with (@use "file") and use it with @d:
((@use "mypage.scm")
(@d (mypage "Title of Page" "Last Date of Modification"
'("Content of Page"))))
As you can see, not even one HTML tag is used in the Speakhtml file.
It is perfectly possible to hide HTML by using Speakhtml.
For more elaborated examples in using Speakhtml see sources on
http://faith.eu.org/
#EOF