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


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


Graham Fawcett



(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.

Multiple expressions can be passed to (hart) and (hart->string): there is an implicit (let: () ...) enclosing the expressions (see let: below).

Keyword expressions

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

These are like their Scheme counterparts, 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 list of Hart expressions, 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 list of Hart expressions.

Formatting keywords

[syntax] (raw: . expr)

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

[syntax] (text: . exprs) or (t: . exprs)

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

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

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

[syntax] (scheme: . exprs)

The Scheme expressions are evaluated. If they produce output, that output will be inserted into the HTML.


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.

Optional Attributes

An attribute whose value evaluates to #f will be omitted from the HTML output. This provides a mechanism for specifying optional attributes.

Utility functions

[procedure] (hart-html-escape string)

A fast, basic HTML-escaping routine.



hart is licensed under the BSD License. Copyright (C) 2008 Graham Fawcett <>