For Development HEAD DRAFTSearch (procedure/syntax/module):

12.71 text.html-lite - Simple HTML document construction

Module: text.html-lite

Provides procedures to construct an HTML document easily. For example, you can construct an HTML table by the following code:

(html:table
  (html:tr (html:th "Item No") (html:th "Quantity"))
  (html:tr (html:td 1) (html:td 120))
  (html:tr (html:td 2) (html:td 30))
  (html:tr (html:td 3) (html:td 215)))

See the description of html:element below for details.

This module does little check for the constructed html documents, such as whether the attributes are valid, and whether the content of the element matches DTD. It does not provide a feature to parse the html document neither. Hence the name ‘lite’.

Function: html-escape
Function: html-escape-string string

{text.html-lite} Escapes the “unsafe” characters in HTML. html-escape reads input string from the current input port and writes the result to the current output port. html-escape-string takes the input from string and returns the result in a string.

Function: html-doctype :key type

{text.html-lite} Returns a doctype declaration for an HTML document. type can be either one of the followings (default is :html-4.01-strict).

:html-4.01-strict, :html-4.01, :strict

HTML 4.01 Strict DTD

:html-4.01-transitional, :transitional

HTML 4.01 Transitional DTD

:html-4.01-frameset, :frameset

HTML 4.01 Frameset DTD

:xhtml-1.0-strict, :xhtml-1.0

XHTML 1.0 Strict DTD

:xhtml-1.0-transitional

XHTML 1.0 Transitional DTD

:xhtml-1.0-frameset

XHTML 1.0 Frameset DTD

:xhtml-1.1

XHTML 1.1 DTD

Function: html:element args

{text.html-lite} Construct an HTML element element. Right now, the following elements are provided. (The elements defined in HTML 4.01 DTD, http://www.w3.org/TR/html4/sgml/dtd.html).

a        abbr       acronym    address     area      b
base     bdo        big        blockquote  body      br
button   caption    cite       code        col       colgroup
dd       del        dfn        div         dl        dt
em       fieldset   form       frame       frameset
h1       h2         h3         h4          h5        h6
head     hr         html       i           iframe    img
input    ins        kbd        label       legend    li
link     map        meta       noframes    noscript  object
ol       optgroup   option     p           param     pre
q        samp       script     select      small     span
strong   style      sub        sup         table     tbody
td       textarea   tfoot      th          thead     title
tr       tt         ul         var

The result of these functions is a tree of text segments, which can be written out to a port by write-tree or can be converted to a string by tree->string (see text.tree - Lazy text construction).

You can specify attributes of the element by using a keyword-value notation before the actual content.

(tree->string (html:a :href "http://foo/bar" "foobar"))
  ⇒
  "<a href=\"http://foo/bar\">foobar</a\n>"

(tree->string
  (html:table :width "100%" :cellpadding 0 "content here"))
  ⇒
  "<table width=\"100%\" cellpadding=\"0\">content here</table\n>"

The boolean value given to the attribute has a special meaning. If #t is given, the attribute is rendered without a value. If #f is given, the attribute is not rendered.

(tree->string (html:table :border #t))
  ⇒ "<table border></table\n>"

(tree->string (html:table :border #f))
  ⇒ "<table></table\n>"

Special characters in attribute values are escaped by the function, but the ones in the content are not. It is caller’s responsibility to escape them.

The functions signal an error if a content is given to the HTML element that doesn’t take a content. They do not check if the given attribute is valid, neither if the given content is valid for the element.

Note: You might have noticed that these procedures insert a newline before > of the closing tag. That is, the rendered HTML would look like this:

<table><tr><td>foo</td
><td>bar</td
></tr
></table
>

We intentionally avoid inserting newlines after the closing tag, since it depends on the surrounding context whether the newline is significant or not. We may be able to insert newlines after the elements directly below a <head> element, for example, but we cannot in a <p> element, without affecting the content.

There are three possible solutions: (1) not to insert newlines at all, (2) to insert newlines within tags, and (3) to insert newlines only at the safe position. The first one creates one long line of HTML, and although it is still valid HTML, it is inconvenient to handle it with line-oriented tools. The third one requires the rendering routine to be aware of DTD. So we took the second approach.



For Development HEAD DRAFTSearch (procedure/syntax/module):
DRAFT