doc.txt

WebIt! Reference Manual

_WebIt!_ Reference Manual
=========================

Version: WebIt! 2.0
Last update: 24 April 2005

WebIt! is a framework for manipulating XML in Scheme. The main features of WebIt! 
are: an XML pattern matching system based on that of Scheme's syntax-rules and 
syntax-case macro systems, and a macro-style transformation system. An Abstract 
Data Type (ADT) for manipulating the XML Infoset is also provided. (The concrete 
representation of XML used by WebIt!, internally, is SXML.) Lastly, an embedding 
in Scheme of Cascading Stylesheets (CSS) is provided.


Part I

Module "xml.ss"

1 Defining XML Element and Attribute Types
------------------------------------------

1.1 _define-element_
--------------------

syntax

The grammar for the define-element syntax is:
  element-definition ::= (define-element (element-tag namespace-uri))
                       | (define-element (element-tag #f))
                       | (define-element element-tag)

element-tag must be a symbol. If present, namespace uri is a string 
containing a uri.

define-element introduces the following bindings:
  - element-tag: a constructor function for the element type defined by define-element.
  - element-tag?: a predicate function for the element type defined by define-element.

The example below defines an element 'group':
  (define-element group)

The code fragment below illustrates the use of both the constructor group and 
the predicate group.
  (group? "test") ; ==> #f
  (group? (group "body")) ; ==> #t

1.2 _define-attribute_
----------------------

syntax

The grammar for the define-attribute syntax is:
  attribute-definition ::= (define-attribute (attribute-tag namespace-uri))
                         | (define-attribute (attribute-tag #f))
                         | (define-attribute attribute-tag)

attribute-tag must be a symbol. If present, namespace uri is a string containing a uri.

define-attribute introduces the following bindings:
  - attribute-tag:: a keyword used for construction of the the attribute
    defined by define-attribute.
  - attribute-tag?: a predicate function, taking an element as its argument. 
    If the element contains the attribute 'attribute-tag', the value of the 
    attribute is returned. Otherwise #f.

The example below defines an attribute 'label':
  (define-attribute label)

The code fragment below illustrates the use of both the constructor label: 
and the predicate label?.
  (label? (group "body")) ; ==> #f
  (label? (group label: "a" "body")) ; ==> "a"

2 Pattern Matching of XML
-------------------------

2.1 _xml-match_
---------------

syntax

xml-match provides pattern matching of XML nodes. The pattern notation is 
based on that of Scheme's syntax-rules/syntax-case macro systems.

The grammar for the xml-match syntax is given below:
  match-form ::= (xml-match input-expression
                   clause+)

  clause ::= [node-pattern action-expression+]
           | [node-pattern (guard expression*) action-expression+]

  node-pattern ::= literal-pattern
                 | pat-var-or-cata
                 | element-pattern
                 | list-pattern

  literal-pattern ::= string
                    | character
                    | number
                    | #t
                    | #f

  attribute-pattern ::= attribute-keyword attr-val-pattern

  attr-val-pattern ::= literal-pattern
                     | pat-var-or-cata
                     | (pat-var-or-cata default-value-expr)

  element-pattern ::= (tag-symbol attribute-pattern*)
                    | (tag-symbol attribute-pattern* nodeset-pattern)
                    | (tag-symbol attribute-pattern*
                                  nodeset-pattern . pat-var-or-cata)

  list-pattern ::= (list nodeset-pattern)
                 | (list nodeset-pattern . pat-var-or-cata)
                 | (list)

  nodeset-pattern ::= node-pattern
                    | node-pattern ...
                    | node-pattern nodeset-pattern
                    | node-pattern ... nodeset-pattern

  pat-var-or-cata ::= (unquote var-symbol)
                    | (unquote [var-symbol*])
                    | (unquote [cata-expression -> var-symbol*])


Within a list or element body pattern, ellipses may appear only once, but may 
be followed by zero or more node patterns.

Guard expressions cannot refer to the return values of catamorphisms.

Ellipses in the output expressions must appear only in an expression context; 
ellipses are not allowed in a syntactic form.

The sections below illustrate specific aspects of the xml-match pattern matcher.

Matching XML Elements
---------------------

The example below illustrates the pattern matching of an XML element:
(xml-match (e i: 1 3 4 5)
  [(e i: ,d ,a ,b ,c) (list d a b c)]
  [,otherwise #f])


The element and attribute tags used in patterns are the element and attribute 
constructors created by define-element and define-attribute. Each clause in 
xml-match contains two parts: a pattern and one or more expressions which are 
evaluated if the pattern is successfully match.

Pattern variables are must be "unquoted" in the pattern. The above expression 
binds d to 1, a to 3, b to 4, and c to 5.

Matching Nodesets
-----------------

A nodeset pattern is designated by a list in the pattern, beginning the 
identifier list. The example below illustrates matching a nodeset.
(xml-match '("i" "j" "k" "l" "m")
  [(list ,a ,b ,c ,d ,e)
   (list (h4:p a) (h4:p b) (h4:p c) (h4:p d) (h4:p e))])


This example wraps each nodeset item in an HTML paragraph element.

Matching the 'Rest' of a Nodeset

Matching the 'rest' of a nodeset is achieved by using a ". rest)" pattern at 
the end of an element or nodeset pattern.

This is illustrated in the example below:
(xml-match (e 3 (f 4 5 6) 7)
  [(e ,a (f . ,y) ,d)
   (list a y d)])


The above expression returns (3 (4 5 6) 7).

Ellipses in Patterns
--------------------

As in syntax-rules, ellipses may be used to specify a repeated pattern. Note 
that the pattern "item ..." specifies zero-or-more matches of the pattern "item".

The use of ellipses in a pattern is illustrated in the code fragment below, 
where nested ellipses are used to match the children of repeated instances 
of an 'a' element, within an element 'd'.
(define x (d (a 1 2 3) (a 4 5) (a 6 7 8) (a 9 10)))

(xml-match x
  [(d (a ,b ...) ...)
   (list (list b ...) ...)])


The above expression returns a value of ((1 2 3) (4 5) (6 7 8) (9 10)).

Default Values in Attribute Patterns
------------------------------------

It is possible to specify a default value for an attribute which is used 
if the attribute is not present in the element being matched. This is 
illustrated in the following example:
(xml-match (e 3 4 5)
  [(e z: (,d 1) ,a ,b ,c) (list d a b c)])


The value 1 is used when the attribute 'z' is absent from the element 'e'.

Guards in Patterns
------------------

Guards may be added to a pattern clause via the guard keyword. A guard 
expression may include zero or more expressions which are evaluated 
only if the pattern is matched. The body of the clause is only evaluated 
if the guard expressions evaluate to #t.

The use of guard expressions is illustrated below:
(xml-match '(a 2 3)
  ((a ,n) (guard (number? n)) n)
  ((a ,m ,n) (guard (number? m) (number? n)) (+ m n)))

Catamorphisms
-------------

The example below illustrates the use of explicit recursion within an 
xml-match form. This example implements a simple calculator for the basic 
arithmetic operations, which are represented by the XML elements plus, 
minus, times, and div.
(define simple-eval
  (lambda (x)
    (xml-match x
      [,i (guard (integer? i)) i]
      [(plus ,x ,y) (+ (simple-eval x) (simple-eval y))]
      [(times ,x ,y) (* (simple-eval x) (simple-eval y))]
      [(minus ,x ,y) (- (simple-eval x) (simple-eval y))]
      [(div ,x ,y) (/ (simple-eval x) (simple-eval y))]
      [,otherwise (error "simple-eval: invalid expression" x)])))


Using the catamorphism feature of xml-match , a more concise version of 
simple-eval can be written. The pattern ,[x] recusively invokes the 
pattern matcher on the value bound in this position.
(define simple-eval
  (lambda (x)
    (xml-match x
      [,i (guard (integer? i)) i]
      [(plus ,[x] ,[y]) (+ x y)]
      [(times ,[x] ,[y]) (* x y)]
      [(minus ,[x] ,[y]) (- x y)]
      [(div ,[x] ,[y]) (/ x y)]
      [,otherwise (error "simple-eval: invalid expression" x)])))


Named-Catamorphisms
-------------------

It is also possible to explicitly name the operator in the 'cata' 
position. Where ,[id*] recurs to the top of the current xml-match, 
,[cata -> id*] recurs to cata. cata must evaluate to a procedure which 
takes one argument, and returns as many values as there are 
identifiers following ->.

Named catamorphism patterns allow processing to be split into 
multiple, mutually recursive procedures. This is illustrated in the 
example below: a transformation that formats a "TV Guide" into HTML.
(define (tv-guide->html g)
  (define (cast-list cl)
    (xml-match cl
      [(CastList (CastMember (Character (Name ,ch)) (Actor (Name ,a))) ...)
       (h4:div (h4:ul (h4:li ch ": " a) ...))]))
  (define (prog p)
    (xml-match p
      [(Program (Start ,start-time) (Duration ,dur) (Series ,series-title)
                (Description . ,desc))
       (h4:div (h4:p start-time
                     (h4:br) series-title
                     (h4:br) desc))]
      [(Program (Start ,start-time) (Duration ,dur) (Series ,series-title)
                (Description . ,desc)
                ,[cast-list -> cl])
       (h4:div (h4:p start-time
                     (h4:br) series-title
                     (h4:br) desc)
               cl)]))
  (xml-match g
    [(TVGuide start: ,start-date
              end: ,end-date
              (Channel (Name ,nm) ,[prog -> p] ...) ...)
     (h4:html (h4:head (h4:title "TV Guide"))
              (h4:body (h4:h1 "TV Guide")
                       (h4:div (h4:h2 nm) p ...) ...))]))


Ellipses in Quasiquote'd Output
-------------------------------

Within the body of an xml-match form, a slightly extended version of 
quasiquote is provided, which allows the use of ellipses. This is 
illustrated in the example below.
(xml-match '(e 3 4 5 6 7)
  [(e ,i ... 6 7) `("start" ,(list 'wrap i) ... "end")]
  [,otherwise #f])


The general pattern is that `(something ,i ...) is rewritten as `(something ,@i).

2.2 _xml-match-let_ and _xml-match-let*_
----------------------------------------

syntax

The xml-match-let and xml-match-let* forms generalize the let and let* 
forms of Scheme to allow an XML pattern in the binding position, rather 
than a simple variable.

For example, the expression below:
(xml-match-let ([(a ,i ,j) '(a 1 2)])
  (+ i j))


binds the variables i and j to 1 and 2 in the XML value given.

The syntax for these forms is given below:
(xml-match-let ([pat expr] ...) expression0 expression ...)
(xml-match-let* ([pat expr] ...) expression0 expression ...)


3 XML Transformation
--------------------

3.1 _stylesheet_
----------------

syntax

A stylesheet is a set of rules for transformation of XML. The 
stylesheet syntax allows one to intermix a sequence of xml-micro's, 
xml-macro's, and top-level Scheme expressions.

The grammar for stylesheet is given below:
stylesheet-form ::= (stylesheet body-item*)

body-item ::= xml-micro-form
            | xml-macro-form
            | top-level-sceheme-expression


A stylesheet form evaluates to a stylesheet object.

The semantics of top-level definitions within a stylesheet is identical 
to that of PLT Scheme's units.

3.2 _xml-micro_
---------------

syntax

An xml-micro performs a single transformation of its argument. The result of 
this transformation is not further "expanded".

The grammar for xml-micro is:
micro-form ::= (xml-micro trigger-tag
                 expression)

trigger-tag ::= element-tag
              | *text*
              | *data*

The expression in an xml-micro must evaluate to a function of which 
takes an XML node as its argument, and (generally) returns a node or 
nodeset.

3.3 _xml-macro_
---------------

syntax

An xml-macro performs a transformation of its argument; the result 
of this transformation further "expanded" until no further 
transformations are possible.

The grammar for xml-macro is:
macro-form ::= (xml-macro trigger-tag
                 expression)

trigger-tag ::= element-tag
              | *text*
              | *data*

The expression in an xml-macro must evaluate to a function of which 
takes an XML node as its argument, and returns a node or nodeset.

No further transformations of a node are possible when no more xml-micros 
or xml-macros are triggered by that node under the stylesheet being applied.

3.4 stylesheet->expander
------------------------

function
> _stylesheet->expander_ :: stylesheet -> (function node -> node))

This function converts a stylesheet to an expander function. The 
return-result may be applied to an XML node to apply the stylesheet's 
transformations.

3.5 _compound-stylesheet_
-------------------------

syntax

This form is used to combine multiple stylesheets. The result of 
evaluating a compound-stylesheet is a new stylesheet object.

The grammar for a compound-stylesheet is given below:
compound-ss-form ::= (compound-stylesheet expression+)

Each expression must evaluate to a stylesheet object.

3.6 Example
-----------

The example below is a complete working stylesheet which translates a 
collection of poetry into HTML. The 'micro' for the poem element 
formats a poem into HTML. The 'macro' for the book element creates a 
skeletal HTML document, with a new contents element which contains 
both a table of contents element and the poems to be formatted. The 
'micro' for the contents element formats the table of contents and 
uses xml-expand to invoke the expander on each of the poems.

poetry->html is bound to the result of applying stylesheet->expander 
to the stylesheet, producing a function which takes a single argument: 
the poetry book element.

(define poetry->html
  (stylesheet->expander
   (stylesheet
     
     (define-element toc)
     (define-element contents)
     
     (xml-micro poem
       (lambda (x)
         (xml-match x
           [(poem title: ,t poet: ,a tag: ,m
                  (stanza (line ,l1) (line ,l) ...) ...)
            (h4:div (h4:p) (h4:a h4:name: m) (h4:strong t) (h4:br) (h4:em a)
                    (list (h4:p) l1 (list (h4:br) l) ...) ...)])))
     
     (xml-micro contents
       (lambda (x)
         (xml-match x
           [(contents (toc (poem title: ,t poet: ,a tag: ,m . ,rest) ...) ,p* ...)
            (h4:div (h4:p) "Table of Contents:"
                    (h4:ul
                     (h4:li (h4:a h4:href: (string-append "#" m) t)) ...)
                    (xml-expand p*) ...)])))
     
     (xml-macro book
       (lambda (x)
         (xml-match x
           [(book title: ,bt ,p* ...)
            (h4:html
             (h4:head (h4:title bt))
             (h4:body
              (h4:h1 bt)
              (contents (toc p* ...)
                        p* ...)))])))
     
     )))


4 Output Functions
------------------

4.1 write-xml
-------------

function
> _write-xml_ :: node [port] -> void

This function is used to write XML nodes to port, if given, or to 
current-output-port.

4.2 display-xml
---------------

function
> _display-xml_ :: node [port] -> void

This function is used to write XML nodes to port, if given, or 
to current-output-port. Unlike write-xml, this function introduces 
additional whitespace indentation for nested elements. The primary 
purpose is debugging. For correct XML output, write-xml should be used.

4.3 servlet-result
------------------

function
> _servlet-result_ :: node -> list-of-strings

This function may be used in servlets to convert XML to a 
list-of-strings for sending to a web browser.

5 XML Infoset Mapping
---------------------

WebIt! implements an abstract datatype for the XML Infoset, in 
terms of the API described in this section. The concrete datatype 
used by this API is SXML.

5.1 Normalized and Non-Normalized SXML
--------------------------------------

5.1.1 _normalized-sxml_
-----------------------

parameter

By default, WebIt! functions and syntax can process non-normalized 
SXML. However, there is a performance penalty for this. normalized-sxml 
may be used to restrict WebIt! to processing a particular style of 
normalized SXML. The default value of #f enables processing of 
non-normalized SXML. Set this parameter to #t to restrict WebIt! 
to normalized SXML.

5.2 Constructing and Analyzing XML Document Nodes
-------------------------------------------------

5.2.1 make-xml-document
-----------------------

function
> _make-xml-document_ :: list-of-nodes -> xml-document

This function construction a document node from a list of nodes. The 
list should include exactly one xml-element node.

5.2.2 xml-document?
-------------------

function
> _xml-document?_ :: node -> boolean

Returns #t if its argument is an xml-document node, otherwise #f.

5.2.3 xml-document-dtd-info
---------------------------

function
> _xml-document-dtd-info_ :: xml-document -> xml-dtd-info

Returns the document's xml-dtd-info, if one is present, otherwise #f.

5.2.4 xml-document-content
--------------------------

function
> _xml-document-content_ :: xml-document -> xml-element

Returns the document's root element.

5.2.5 xml-document-body
-----------------------

function
> _xml-document-content_ :: xml-document -> nodeset

Returns a list of the document's body nodes.

5.3 Constructing and Analyzing XML Element Nodes
------------------------------------------------

5.3.1 make-xml-element
----------------------

function
> _make-xml-element_ :: tag attribute-list node-list -> xml-element

The element tag is a symbol.

The attribute-list is a list of attribute nodes: a list of an 
attribute tag and a string, number or boolean.

A node-list is a (possibly null) list of XML nodes.

5.3.2 make-xml-element/ns
-------------------------

function
> _make-xml-element/ns_ :: tag ns-list attribute-list node-list -> xml-element

The element tag, tag, is a symbol.

ns-list is a list of namespace bindings. Each namespace binding 
is a list of a namespace uri (string) and a prefix (symbol).

The attribute-list is a list of attribute nodes: a list of 
an attribute tag and a string, number or boolean.

A node-list is a (possibly null) list of XML nodes.

5.3.3 xml-element?
------------------

function
> _xml-element?_ :: node -> boolean

Returns #t if its argument is an xml-element node, otherwise #f.

5.3.4 xml-element-tag
---------------------

function
> _xml-element-tag_ :: xml-element -> symbol

Returns the tag (symbol) of an element node. This tag is either 
the local name of the element (for locally named element), or 
the concatenation of the namespace URI to which the element belongs 
and the element's local name, separated by a colon.

5.3.5 xml-element-local-name
----------------------------

function
> _xml-element-local-name_ :: xml-element -> symbol

Returns the local-name (symbol) of an element node.

5.3.6 xml-element-ns-uri
------------------------

function
> _xml-element-local-name_ :: xml-element -> symbol

Returns the namespace URI to which the element belongs, #f.

5.3.7 xml-element-ns-list
-------------------------

function
> _xml-element-ns-list_ :: xml-element -> (listof xml-namespace-binding)

Returns a list of namespace prefix bindings associated with this element.

5.3.8 xml-element-attributes
----------------------------

function
> _xml-element-attributes_ :: xml-element -> (listof xml-attribute)

Returns a list of attributes of this element.

5.3.9 xml-element-contents
--------------------------

function
> _xml-element-contents_ :: xml-element -> (listof node)

Returns a nodeset of the children of this element.

5.4 Constructing and Analyzing XML Attribute Nodes
--------------------------------------------------

5.4.1 make-xml-attribute
------------------------

function
> _make-xml-attribute_ :: tag value -> (list-of symbol string|number|boolean)

The attribute tag is a symbol.

The value of an attribute may be a string, number or boolean.

5.4.2 xml-attribute-tag
-----------------------

function
> _xml-attribute-tag_ :: xml-attribute -> symbol

Returns the tag (symbol) of an attribute node. This tag is either 
the local name of the attribute (for locally named attributes), or 
the concatenation of the namespace URI to which the attribute 
belongs and the attribute's local name, separated by a colon.

5.4.3 xml-attribute-local-name
------------------------------

function
> _xml-attribute-local-name_ :: xml-attribute -> symbol

Returns the local-name (symbol) of an attribute node.

5.4.4 xml-attribute-ns-uri
--------------------------

function
> _xml-attribute-local-name_ :: xml-attribute -> symbol

Returns the namespace URI to which the attribute belongs, #f.

5.4.5 xml-attribute-value
-------------------------

function
> _xml-attribute-value_ :: xml-attribute -> string|number|boolean

Returns the value of an attribute node.

5.5 Constructing and Analyzing XML Comment Nodes
------------------------------------------------

5.5.1 make-xml-comment
----------------------

function
> _make-xml-comment_ :: string -> xml-comment

This function constructs an xml-comment object with its 
argument as the comment text.

5.5.2 xml-comment?
------------------

function
> _xml-comment?_ :: node -> boolean

This function returns #t if its argument is an xml-comment, 
otherwise #f.

5.5.3 xml-comment-text
----------------------

function
> _xml-comment-text_ :: xml-comment -> string

Returns the text of an xml-comment node.

5.6 Constructing and Analyzing XML Processing Instruction Nodes
---------------------------------------------------------------

5.6.1 make-xml-pi
-----------------

function
> _make-xml-pi_ :: symbol string -> xml-pi

This function has to arguments: a PI target (symbol) and PI text 
(a string). Returns a new xml-pi object.

5.6.2 xml-pi?
-------------

function
> _xml-pi?_ :: node -> boolean

This function returns #t if its argument is an xml-comment, otherwise #f.

5.6.3 xml-pi-target
-------------------

function
> _xml-pi-target_ :: xml-pi -> symbol

This function returns it's argument's PI target.

5.6.4 xml-pi-text
-----------------

function
> _xml-pi-text_ :: xml-pi -> symbol

This function returns it's argument's PI text.

5.7 Constructing and Analyzing XML Entity Nodes
-----------------------------------------------

5.7.1 make-xml-entity
---------------------

function
> _make-xml-entity_ :: string string -> xml-entity

This function takes two arguments of type string: a public-id and 
a system-id, and a returns a new xml-entity object.

5.7.2 xml-entity?
-----------------

function
> _xml-entity?_ :: node -> boolean

This function returns #t if its argument is an xml-entity, otherwise #f.

5.7.3 xml-entity-public-id
--------------------------

function
> _xml-entity-public-id_ :: xml-entity -> string

This function returns it's argument's public-id.

5.7.4 xml-entity-system-id
--------------------------

function
> _xml-entity-system-id_ :: xml-entity -> string

This function returns it's argument's system-id.

5.8 Constructing and Analyzing XML Namespace Binding Nodes
----------------------------------------------------------

5.8.1 make-xml-ns-binding
-------------------------

function
> _make-xml-ns-binding_ :: symbol string -> (list symbol string)

This function takes two arguments: a namespace prefix (symbol) 
and a namespace URI (string), and returns a new namespace prefix 
binding.

5.8.2 xml-ns-binding-prefix
---------------------------

function
> _xml-ns-binding-prefix_ :: (list symbol string) -> symbol

This function returns the namespace prefix from its argument.

5.8.3 xml-ns-binding-ns-url
---------------------------

function
> _xml-ns-binding-ns-url_ :: (list symbol string) -> string

This function returns the namespace URI from its argument.

5.9 Constructing and Analyzing DTD Information Nodes
----------------------------------------------------

5.9.1 make-xml-dtd-info
-----------------------

function
> _make-xml-dtd-info_ :: symbol string -> xml-dtd-info

This function takes two arguments: a name (symbol) and a system 
(string). Returns a new xml-dtd-info object.

5.9.2 xml-dtd-info?
-------------------

function
> _xml-dtd-info?_ :: node -> boolean

This function returns #t if its argument is an xml-dtd-info or 
xml-dtd-info/public object, otherwise #f.

5.9.3 xml-dtd-info-name
-----------------------

function
> _xml-dtd-info-name_ :: xml-dtd-info -> symbol

This function returns it's argument's name field.

5.9.4 xml-dtd-info-system
-------------------------

function
> _xml-dtd-info-system_ :: xml-dtd-info -> string

This function returns it's argument's system field.

5.9.5 make-xml-dtd-info/public
------------------------------

function
> _make-xml-dtd-info/public_ :: symbol string string -> xml-dtd-info/public

This function takes three arguments: a name (symbol), a system 
(string), and a public (string). Returns a new xml-dtd-info/public 
object.

5.9.6 xml-dtd-info/public?
--------------------------

function
> _xml-dtd-info/public?_ :: node -> boolean

This function returns #t if its argument is an xml-dtd-info/public, 
otherwise #f.

5.9.7 xml-dtd-info/public-public
--------------------------------

function
> _xml-dtd-info/public-public_ :: xml-dtd-info/public -> string

This function returns it's argument's public field.

5.10 Miscellaneous
------------------

5.10.1 nodeset?
---------------

function
> _nodeset?_ :: any -> boolean

This function returns #t if its argument is a list which does not 
begin with a symbol, otherwise #f.

5.10.2 has-attribute?
---------------------

function
> _has-attribute?_ :: symbol (listof xml-attribute) -> (xml-attribute | #f)

This function searches a list of attributes for the for the requested 
attribute. Returns the matching attribute, otherwise #f.

5.10.3 _bind-namespaces_
------------------------

syntax

This form is used to introduce namespace prefix bindings, and to 
attach these bindings to an xml-element object.

The grammar for bind-namespaces is:
(bind-namespaces ([prefix-symbol uri-string] ...)
   expression)

Expression must evaluate to an xml-element. bind-namespaces returns 
a new xml-element object, with the new namespace prefix bindings.

6 Deprecated Functions and Syntax
---------------------------------

The following functions and syntax are deprecated as of WebIt! 2.0. 
These are still available in the current build, but will be removed 
in a future release.
 - xml-rules: use xml-match, xml-match-let, xml-match-let* instead.
 - xml-case: use xml-match, xml-match-let, xml-match-let* instead.
 - xml-element-print-tag: use xml-element-local-name instead.
 - xml-element-target-ns: use xml-element-ns-uri instead.
 - xml-attribute-print-tag: use xml-attribute-local-name instead.
 - xml-attribute-target-ns: use xml-attribute-ns-uri instead.

Part II

Module "css.html"

7 _css_
-------

syntax

Below is the grammar for the css form:
 external-css-stylesheet ::= (css import-clause* rule+)
 internal-css-stylesheet ::= (css/html import-clause* rule+)
 
 import-clause ::= ( import string )
 
 rule ::= ( complex-selector css-avp+ )
 
 complex-selector ::= single-selector |
                      grouping-selector
 
 simple-selector ::= symbol |
                     (class symbol) |
                     (class symbol symbol) | -- (class <type> <class>)
                     (pclass symbol) |
                     (pclass symbol symbol) | -- (pclass <type> <pseudo-class>)
                     (id symbol) | 
                     (id symbol symbol) -- (id <type> <id>)
 
 path-selector ::= ( // simple-selector+ )
 
 single-selector ::= simple-selector |
                     path-selector
 
 grouping-selector ::= ( single-selector+ )
 
 css-avp ::= ( symbol scheme-expression ) |
             (! (symbol scheme-expression))

Note 1: scheme-expression must evaluate to a string

Note 2: internal-css-stylesheet translates to
( style  type:  "text/css"  ( css  import-clause*  rule+ ))


What follows is a basic example illustrating webIt!'s embedding 
off CSS in Scheme. this example creates a simple HTML document 
which uses an external CSS stylesheet. The CSS stylesheet is used 
to color the background navy, and set different text fragments 
yellow, white, and red.

(require (lib "xml.ss" "webit") (lib "html.ss" "webit") (lib "css.ss" "webit"))

The css syntax creates a CSS stylesheet. Informally, css takes a 
list of rules, each of which consists of a selector and a property 
list. In the first rule, for example, the selector is body, and the 
property list includes settings for font-family, font-size, and 
background-color.

(define ex-css
  (css
   (body
    (font-family "sans-serif")
    (font-size "12pt")
    (background-color "navy"))
   (p (color "white"))
   (p.ex (color "red"))
   (h1 (color "yellow"))))


This creates the following stylesheet:
  body {
    font-family: sans-serif;
    font-size: 12pt;
    background-color: navy;
  }
  p {
    color: white;
  }
  p.ex {
    color: red;
  }
  h1 {
    color: yellow;
  }
(define ex
  (h4:html
    (h4:head (css-link "a.css") (h4:title "Stylesheet Example"))
    (h4:body
      (h4:h1 "Stylesheet Example; this text is yellow")
      (h4:p "This text is white")
      (h4:p h4:class: "ex" "This text is red"))))

(write-xml ex-css (open-output-port "a.css"))

(write-xml ex (open-output-port "a.html"))


In the HTML above, we can see the use of the css-link form, which takes 
a single argument, the URL of the external stylesheeet. This form is 
simply shorthand for the construction of the following HTML:
(h4:link h4:rel: "stylesheet" h4:href: "a.css" h4:type: "text/css")


The sections below describe in more detail the construction of CSS 
stylesheets in Webit!.

Simple selectors, Classes, and Pseudo-classes
---------------------------------------------

The simplest form is the simple selector:
   p { color: white; }

The simple selector is just a symbol that is the element type to which  
this style property applies. This is written as:
(css (p (color "white")))


Classes
-------

Elements can also be selected by "class", that is, by the value of the  
HTML "class" attribute:
   .ex {color: red;}

This is written as:
(css (.ex (color "red")))


This is a convenient notation--and one which is supported  by PLT. But not 
all Scheme's support symbols which begin with a ".".  This example can 
also be written in a more verbose form:
(css ((class ex) (color "red")))


A selector can also be written with both an element type and a class.
   p.ex {color: red; }

This is written as:
(css (p.ex (color "red")))


or, in the verbose notation:
(css ((class p ex) (color "red")))


Using PLT's "infix" notation, this last can also be written as:
(css ((p . class . ex) (color "red"))))

if that is to one's taste.

Pseudo-classes
--------------

Pseudo-classes are supported in a similar manner.  One can color a 
visited link "lime":
   a:visited { color: lime; }

which is written as:
(css (a:visited (color "lime")))


or, in the verbose notation:
(css ((pclass a visited) (color "lime")))


or
(css ((a . pclass . visited) (color "lime"))))

As with classes, a selector may include only a pseudo-class:
   :visited { color: lime; }

which is written as:
(css (:visited (color "lime")))


or as
(css ((pclass visited) (color "lime")))


Combining Classes and Pseudo-classes
------------------------------------

Lastly, classes and pseudo-classes can be combined:
   a.external:visited { color: blue; }

which is written as:
(css (a.external:visited (color "blue")))


or
(css ((pclass (class a external) visited) (color "blue")))


This selector, without the element type, can also be used:
   .external:visited { color: blue; }

which is written as:
(css (.external:visited (color "blue")))


or
(css ((pclass (class external) visited) (color "blue")))


Id as a Selector
----------------

One may attach unique "identifiers" to HTML elements, using the id  
attribute. The value of an id attribute may be used as a selector as well.

To match the following paragraph tag:
   <p id=z98y>Wide text</p>

the following style rule can be defined:
   #z98y { letter-spacing: 0.3em; }

This would be written as:
(css ((id z98y) (letter-spacing "0.3em")))


(In principle, "(id z98y)" can also be written as the symbol "|#z98y|".)

Id's may also be combined with an element type in a selector:
   h1#z98y {letter-spacing: 0.5em; }

written as:
(css ((id h1 z98y) (letter-spacing "0.5em")))


or
(css ((id h1 z98y) (letter-spacing "0.5em")))


Contextual Selectors
--------------------

CSS allows one to specify that a "style" applies only to selected  
elements, in a _context_. For example, if I want to color emphasized  
text red, but only within an h1 element, this can be written as:
   h1 em { color: red; }

which, in the WebIt! embedding, is given as:
(css ((// h1 em) (color "red")))


The keyword "//" is used to suggest a similarity of a contextual  
specifier with a "path expression" (as in XPath/SXPath).

The "steps" in a contextual specifier can be an element type, class,  
pseudo-class, an id, or a combination of these.

Grouping Selectors
------------------

To avoid duplicating style descriptions, selectors may be grouped  
together. Any of the above kinds of selectors may be grouped, as  
shown below, where a simple selector (an element type) and a contextual  
selector are grouped:
    h1, h2 b, h2, em { color: red; }

The grouping "operator" is just a list:
(css ((h1 (// h2 b) (// h2 em)) (color "red")))


Importing a stylesheet
----------------------

A stylesheet may import another stylesheet:
    @import url(http://somewhere/a.css)

This is written as
(css (import "http://somewhere/a.css") ...)


Any such import forms must appear at the beginning of a CSS stylesheet,  
before any "style rules".

Marking a Property "Important"
------------------------------

CSS allows designers to increase the "weights" of some property 
declarations:
    p { font-size: 12pt ! important;
        font-style: italic;
      }

This can be written in Scheme as:
(css (p (! (font-size "12pt")) (font-style "italic")))


Part III

Module "scm-markup.html"

8 scm->html
-----------

function
> _scm->html_ :: string -> xml-element

This function is used to perform syntax coloring of a Scheme expression 
to be included inline within a paragraph. The string argument is parsed 
into tokens and marked up in HTML. CSS is used to control font selection 
and coloring. Returns a an xml-element consisting of the HTML markup.

9 scm-prog->html
----------------

function
> _scm-prog->html_ :: string -> xml-element

This function is used to perform syntax coloring of a Scheme program which 
is included as the body of an HTML "pre" tag. The string argument is parsed 
into tokens and marked up in HTML. CSS is used to control font selection 
and coloring. Returns a an xml-element consisting of the HTML markup.

10 Controlling Font Selection and Coloring
------------------------------------------

This section describes the CSS selectors used to control font and color 
styling of marked-up Scheme code.

The CSS selectors used for syntax coloring are:

.scheme
The base style for Scheme code

.scheme .keyword
Scheme syntactic keywords

.scheme .builtin
Scheme built-in functions

.scheme .variable
Scheme variables

.scheme .global
Scheme global variables

.scheme .selfeval
Self-evaluating expressions

.scheme .comment
Scheme comments

.scheme .schemeresponse
Scheme REPL responses