[plt-scheme] ANN: Mirrors.plt

From: Dave Gurnell (d.j.gurnell at gmail.com)
Date: Sun May 11 05:12:05 EDT 2008

Hi all,

I just released a package onto PLaneT:

"Mirrors" is a package for programatically assembling and rendering  
blocks XML and Javascript in Web applications. Future support for CSS  
is also planned. An abbreviated feature list and an example web  
application follow:

I've built a couple of libraries and applications on top of Mirrors  
now and I find it to be a quite convenient way of producing XML and  
Javascript output. Having said that, I have no doubt there are a few  
bugs and wrinkles that need ironing out. Please let me know if you  
have any suggestions for improvement.

Cheers,

-- Dave

==== FEATURES ====

Assemble blocks of XML and Javascript using a convenient macro syntax  
rather than more traditional lists, quasiquotes and unquotes:

     (xml (p "Paragraph 1")
          ,(if condition
               (xml (p "Paragraph 2")
                    (p "Paragraph 3"))
               (xml))
          (p "Paragraph 4"))

Use "raw" blocks in XML output to send text to the browser in a pure,  
unquoted form, or use "cdata" forms to explicitly insert CDATA tags in  
XML output:

     (xml (div (!raw ,block-of-text)))
     (xml (div (!cdata ,block-of-text)))

XML syntax correctly deals with many browser idiosyncrasies such as  
incorrect parsing of singleton elements:

     (xml (br))     ==> <br />
     (xml (td))     ==> <td></td>
     (xml (script)) ==> <script></script>

XML output is pre-rendered as properly quoted strings at macro  
expansion time, saving time when serving your pages:

     (define name "Dave")
     (xml (div (@ [id "hello"]) "Hello " ,name ))

    -->

     #(struct:block (#(struct:raw ("<div id=\"hello\">Hello "))
                     #(struct:atom "Dave")
                     #(struct:raw ("</div>"))))

Quote and quasiquote style splicing for XML and Javascript statements:

     (js (for ((var [x 0]) (< x 10) (= x (+ x 1)))
              ,@(list (js (alert (+ "X = " x)))
                      (js (= (!index someArray x) (* x x)))
                      (js (alert (+ "Array value = " (!index someArray  
x)))))))

Javascript can be rendered in compact or indented formats (using the  
Dave Herman's pretty printing functionality in javascript.plt):

     (display
      (javascript->pretty-string
       (js (function sayHello ()
             (alert "Hello, world!")))))
    -->

     function sayHello() {
         alert("Hello, world!");
     }

Javascript is correctly rendered in single- or multi-line format when  
it is embedded inside XML.

And much much more...

==== EXAMPLE ====

#lang scheme

(require (planet untyped/mirrors/mirrors)
          (planet untyped/instaservlet/instaservlet))

(go! (lambda (request)
        (make-html-response
         (xml ,xhtml-1.0-transitional-doctype
              (html (@ [xmlns "http://www.w3.org/1999/xhtml"] [lang  
"en"])
                    (title "Hello world")
                    (meta (@ [htp-equiv "Content-Type"] [content "text/ 
html; charset=utf-8"]))
                    (script (@ [type "text/javascript"])
                            (!raw "\n// <![CDATA[\n")
                            (!raw ,(js (function sayHello (name)
                                         (alert (+ "Hello, " name)))))
                            (!raw "\n// ]]>\n")))
              (body (h1 "Hello world")
                    (p (label (@ [for "name-field"])
                              "Enter your name: ")
                       (input (@ [id   "name-field"]
                                 [type "text"]
                                 [size 20]
                                 [onchange ,(js (sayHello (!dot this  
value)))]))))))))


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20080511/ba0bbdb8/attachment.html>

Posted on the users mailing list.