<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>Hi all,</div><div><br></div><div>I just released a package onto PLaneT:</div><div><br></div><div>"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:</div><div><br></div><div>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.</div><div><br></div><div>Cheers,</div><div><br></div><div>-- Dave</div><div><br></div><div>==== FEATURES ====</div><div><br></div><div>Assemble blocks of XML and Javascript using a convenient macro syntax rather than more traditional lists, quasiquotes and unquotes:</div><div><br></div><div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> (xml (p "Paragraph 1")</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> ,(if condition </span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> (xml (p "Paragraph 2")</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> (p "Paragraph 3"))</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> (xml))</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> (p "Paragraph 4"))</span></font></div></div><div><br></div><div>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:</div><div><br></div><div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px; "> (xml (div (!raw ,block-of-text)))</span></font></div><div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px; "> (xml (div (!cdata ,block-of-text)))</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"><br></span></font></div></div></div><div>XML syntax correctly deals with many browser idiosyncrasies such as incorrect parsing of singleton elements:</div><div><br></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> (xml (br)) ==> <br /></span></font></div><div></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> (xml (td)) ==> <td></td></span></font></div><div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> (xml (script)) ==> <script></script></span></font></div><div><br></div></div><div>XML output is pre-rendered as properly quoted strings at macro expansion time, saving time when serving your pages:</div><div><br></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> (define name "Dave")</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> (xml (div (@ [id "hello"]) "Hello " ,name ))</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"><br></span></font></div><div><span class="Apple-style-span" style="font-family: Monaco; font-size: 11px; "> --> </span></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"><br></span></font></div><div><span class="Apple-style-span" style="font-family: Monaco; font-size: 11px; "> #(struct:block (#(struct:raw ("<div id=\"hello\">Hello "))</span></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> #(struct:atom "Dave")</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> #(struct:raw ("</div>"))))</span></font></div><div><br></div><div>Quote and quasiquote style splicing for XML and Javascript statements:</div><div><br></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> (js (for ((var [x 0]) (< x 10) (= x (+ x 1)))</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> ,@(list (js (alert (+ "X = " x)))</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> (js (= (!index someArray x) (* x x)))</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> (js (alert (+ "Array value = " (!index someArray x)))))))</span></font></div><div><br></div><div>Javascript can be rendered in compact or indented formats (using the Dave Herman's pretty printing functionality in javascript.plt):</div><div><br></div><div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> (display</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> (javascript->pretty-string</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> (js (function sayHello ()</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> (alert "Hello, world!")))))</span></font></div></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> --></span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"><br></span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> function sayHello() {</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> alert("Hello, world!");</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> }</span></font></div><div><br></div><div>Javascript is correctly rendered in single- or multi-line format when it is embedded inside XML.</div><div><br></div><div>And much much more...</div><div><br></div><div>==== EXAMPLE ====</div><div><br></div><div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;">#lang scheme</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"><br></span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;">(require (planet untyped/mirrors/mirrors)</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> (planet untyped/instaservlet/instaservlet))</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"><br></span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;">(go! (lambda (request)</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> (make-html-response</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> (xml ,xhtml-1.0-transitional-doctype</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> (html (@ [xmlns "<a href="http://www.w3.org/1999/xhtml">http://www.w3.org/1999/xhtml</a>"] [lang "en"])</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> (title "Hello world")</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> (meta (@ [htp-equiv "Content-Type"] [content "text/html; charset=utf-8"]))</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> (script (@ [type "text/javascript"])</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> (!raw "\n// <![CDATA[\n")</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> (!raw ,(js (function sayHello (name)</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> (alert (+ "Hello, " name)))))</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> (!raw "\n// ]]>\n")))</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> (body (h1 "Hello world")</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> (p (label (@ [for "name-field"])</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> "Enter your name: ")</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> (input (@ [id "name-field"]</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> [type "text"]</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> [size 20]</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> [onchange ,(js (sayHello (!dot this value)))]))))))))</span></font></div><div><br></div><div><br></div></div></body></html>