<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;">&nbsp;&nbsp; &nbsp;(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;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; ,(if condition&nbsp;</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(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;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (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;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(xml))</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; (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; ">&nbsp;&nbsp; &nbsp;(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; ">&nbsp;&nbsp; &nbsp;(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;">&nbsp;&nbsp; &nbsp;(xml (br)) &nbsp; &nbsp; ==> &lt;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;">&nbsp;&nbsp; &nbsp;(xml (td)) &nbsp; &nbsp; ==> &lt;td>&lt;/td></span></font></div><div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;">&nbsp;&nbsp; &nbsp;(xml (script)) ==> &lt;script>&lt;/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;">&nbsp;&nbsp; &nbsp;(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;">&nbsp;&nbsp; &nbsp;(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; ">&nbsp;&nbsp; -->&nbsp;</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; ">&nbsp;&nbsp; &nbsp;#(struct:block (#(struct:raw ("&lt;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;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;#(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;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;#(struct:raw ("&lt;/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;">&nbsp;&nbsp; &nbsp;(js (for ((var [x 0]) (&lt; 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;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ,@(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;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (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;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;(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;">&nbsp;&nbsp; &nbsp;(display</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;">&nbsp;&nbsp; &nbsp; (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;">&nbsp;&nbsp; &nbsp; &nbsp;(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;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(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;">&nbsp;&nbsp; --></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;">&nbsp;&nbsp; &nbsp;function sayHello() {</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;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;">&nbsp;&nbsp; &nbsp;}</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;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; (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;">&nbsp;&nbsp; &nbsp; &nbsp; (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;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;(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;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (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;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (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;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (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;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (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;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (!raw "\n// &lt;![CDATA[\n")</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (!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;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(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;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (!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;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (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;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (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;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "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;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(input (@ [id &nbsp; "name-field"]</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[type "text"]</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[size 20]</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[onchange ,(js (sayHello (!dot this value)))]))))))))</span></font></div><div><br></div><div><br></div></div></body></html>