You are looking at historical revision 2742 of this page. It may differ significantly from its current revision.


The hart egg provides an SXML-inspired syntax for HTML generation.

(Sorry, documentation is a bit sparse at the moment.)


hart is licensed under the BSD License.


Graham Fawcett



Canonical Usage

(use hart)
(define people '((Fred 25) (Mary 33)))
(hart (html (head (title "People"))
            (body (h1 (fmt: "A list of ~a people" (length people)))
                  (if: (null? people)
                       (h2 "No people!")
                       (ol (for: ((name email age) people)
                             (li (a (@ (href (conc "mailto:" email)))
                                    (text: name))
                                 (fmt: ", who is ~a years old." age))))))))

which produces

<h1>A list of 2 people</h1>
<ol><li><a href="">Fred</a>, who is 25 years old.</li>
<li><a href="">Mary</a>, who is 33 years old.</li>


[syntax] (hart hart-expr)
[syntax] (hart->string hart-expr)

Compiles hart-expr, an expression in the Hart syntax. In short, Hart is SXML syntax plus a set of "keyword expressions" which handle flow-control, iteration, escaping, etc.

(hart) outputs to (current-output-port) and returns an undefined value. (hart->string) returns a string value.

Keyword expressions

In future releases, users will be able to extend the keyword-expression syntax with their own forms. Until then, the following forms are available:

[syntax] (if: expr hart-true hart-false)
[syntax] (when: expr hart-true*)
[syntax] (unless: expr hart-false*)

Like an (if) expression, except hart-true and hart-false are expressions in Hart syntax.

[syntax] (for: (iter-expr list-or-vec) hart-body*)

A looping construct. The iter-expr is a match-expression which is matched to each successive value in list-or-vec. Hart-body is a Hart expression which is evaluated for each value of iter-expr.

[syntax] (let: let-forms hart-body*)
[syntax] (let*: let-forms hart-body*)
[syntax] (letrec: let-forms hart-body*)

Like a (let ...) expression, but hart-body is a Hart expression.

Formatting keywords

[syntax] (raw: expr*)

The Scheme expressions (not Hart!) are evaluated to strings and outputted, without HTML/XML escaping.

[syntax] (text: expr*) or (t: expr*)

The expressions are evaluated to strings, HTML-escaped, and outputted.

[syntax] (fmt: format-string args*)

The result of (format format-string args*) is HTML-escaped and outputted.

On Attributes

Note that attributes (such as the "href" in an A tag) are of the form (name value), where "name" is a string or symbol, and "value" is a Scheme expression (literal or otherwise). No escaping is done on these expressions at the current time. Also there isn't yet support for adding arbitrary attributes.