release
authorDavid Lichteblau <david@lichteblau.com>
Sat, 4 Apr 2009 09:39:48 +0000 (4 11:39 +0200)
committerDavid Lichteblau <david@radon.(none)>
Sat, 4 Apr 2009 09:48:08 +0000 (4 11:48 +0200)
dist.sh [new file with mode: 0755]
doc/GNUmakefile
doc/example.xml [new file with mode: 0644]
doc/index.xml
doc/index.xsl

diff --git a/dist.sh b/dist.sh
new file mode 100755 (executable)
index 0000000..17f00cd
--- /dev/null
+++ b/dist.sh
@@ -0,0 +1,49 @@
+#!/bin/sh -e
+set -x
+
+cd $(dirname $0)
+home=$(pwd)
+name=$(basename $home)
+name_and_date=${name}-$(date --iso)
+
+TMPDIR=`mktemp -d /tmp/dist.XXXXXXXXXX`
+cleanup() {
+    cd
+    rm -rf $TMPDIR
+}
+trap cleanup exit
+
+make -C doc
+
+git tag -f $name_and_date
+git archive --prefix=$name_and_date/ $name_and_date | \
+    ( cd $TMPDIR && tar xvf - )
+
+# fixme: manually generated for now
+# echo '(progn (load "doc/atdoc.lisp") (quit))' | clbuild lisp 
+
+rsync -a doc $TMPDIR/$name_and_date
+
+cd $TMPDIR
+
+tgz=$TMPDIR/${name_and_date}.tgz
+tar czf $tgz $name_and_date
+gpg -b -a $tgz
+
+mkdir -p ~/clnet/project/xuriella/public_html/
+
+rsync -av \
+    $name_and_date/doc/ \
+    ~/clnet/project/xuriella/public_html/
+
+rsync $tgz $tgz.asc ~/clnet/project/xuriella/public_html/download/
+
+rm -f ~/clnet/project/xuriella/public_html/download/xuriella.tar.gz 
+rm -f ~/clnet/project/xuriella/public_html/download/xuriella.tar.gz.asc
+
+ln -sf ${name_and_date}.tgz ~/clnet/project/xuriella/public_html/download/xuriella.tar.gz
+ln -sf ${name_and_date}.tgz.asc ~/clnet/project/xuriella/public_html/download/xuriella.tar.gz.asc
+
+echo done
+exit 0
+rsync -av ~/clnet/project dlichteblau@common-lisp.net:/
index 28a6a83..21f6b78 100644 (file)
@@ -1,9 +1,10 @@
 USER=dlichteblau
 
-all: index.html installation.html
+all: index.html installation.html example.html
 
 %.html: %.xml index.xsl
        xsltproc index.xsl $< >$@.tmp
+       rm $@
        mv $@.tmp $@
        chmod -w $@
 
diff --git a/doc/example.xml b/doc/example.xml
new file mode 100644 (file)
index 0000000..8a0e715
--- /dev/null
@@ -0,0 +1,141 @@
+<page title="Xuriella XSLT Example">
+  <p>Example using XSLT in a Hunchentoot handler to deliver an HTML page</p>
+
+  <h3>Overview</h3>
+
+  <p>
+    Suppose you're writing a web application (say,
+    using <a href="">Hunchentoot</a>), and you would like to show
+    directory contents.
+  </p>
+  <p>
+    We do that in two steps, strictly separating the programmer-written
+    Lisp code from the XSLT stylesheet that a web designer might want to
+    tweak afterwards:
+  </p>
+  <p>
+    <ul>
+      <li>
+       First we call CL:DIRECTORY, and build a small in-memory XML
+       document listing the files.
+      </li>
+      <li>
+       In the main step, the run that XML document through an XSL
+       stylesheet to generate HTML.
+      </li>
+    </ul>
+  </p>
+
+  <h3>Hunchentoot setup</h3>
+  <p>
+    The example requires hunchentoot and xuriella:
+  </p>
+  <pre style="background-color: #eeeeee; border: 1px solid #cccccc;">
+(asdf:operate 'asdf:load-op :hunchentoot)
+(asdf:operate 'asdf:load-op :xuriella)
+</pre>
+
+  <p>
+    Let's start hunchentoot and register a handler for the example first:
+  </p>
+  <pre style="background-color: #eeeeee; border: 1px solid #cccccc;">
+(push (tbnl:create-prefix-dispatcher "/show-directory" 'show-directory)
+      tbnl:*dispatch-table*)
+(tbnl:start-server :port 4242)
+</pre>
+
+  <h3>Utility functions</h3>
+  <p>
+    Since we might want to write many different handlers using
+    stylesheets, we factor
+    the APPLY-STYLESHEET call out into a convenient macro WITH-STYLESHEET.
+    Its body is expected to provide XML, which it will send through the
+    stylesheet and return the result as a string.
+  </p>
+  <p>
+    Note the use of WITH-XML-OUTPUT and STP:MAKE-BUILDER to build the
+    intermediate XML as an in-memory document using STP.
+  </p>
+  <p>
+    (In real-world code, we could optimize this a little by compiling the
+    stylesheet ahead of time using PARSE-STYLESHEET, and building a cache out
+    of stylesheet objects in a hash table somewhere.)
+  </p>
+  <pre style="background-color: #eeeeee; border: 1px solid #cccccc;">
+(defmacro with-stylesheet ((stylesheet-pathname) &amp;body body)
+  `(invoke-with-stylesheet (lambda () ,@body) ,stylesheet-pathname))
+
+(defun invoke-with-stylesheet (fn stylesheet-pathname)
+  (xuriella:apply-stylesheet (pathname stylesheet-pathname)
+                             (cxml:with-xml-output (stp:make-builder)
+                               (funcall fn))))
+</pre>
+
+  <h3>Building the temporary XML</h3>
+  <p>
+    Now for the handler calling DIRECTORY.   We want our XML to look like
+    this:
+    <pre>
+    &lt;directory namestring="/home/jrhacker/">
+      &lt;file>hello-world.lisp&lt;/file>
+      &lt;file>mbox&lt;/file>
+      ...
+    &lt;/directory></pre>
+    which we can generate easily using WITH-ELEMENT and DOLIST:
+  </p>
+  <pre style="background-color: #eeeeee; border: 1px solid #cccccc;">
+(defun show-directory ()
+  (<b>with-stylesheet</b> ("directory.xsl")
+    (<b>cxml:with-element "directory"</b>
+      (let ((directory (user-homedir-pathname)))
+       (cxml:attribute "namestring" (namestring directory))
+       (<b>dolist (file (directory (merge-pathnames "*.*" directory)))</b>
+         (<b>cxml:with-element "file"</b>
+           (cxml:text (enough-namestring file directory))))))))
+  </pre>
+
+  <h3>An XSL stylesheet as a template</h3>
+  <p>
+    Finally, the XSL stylesheet that turns this into HTML for us.  Note
+    the xsl:version on the root element, which marks the literal result
+    element used as a stylesheet.
+  </p>
+  <p>
+    Since &lt;html> is the root element, the stylesheet processor will
+    turn on its HTML output method automatically, and generate HTML 4
+    rather than XML.  (Powered by Closure HTML.)
+  </p>
+  <p>
+    To keep the example short and simple, our HTML is not very fancy.
+  </p>
+  <pre style="background-color: #eeeeee; border: 1px solid #cccccc;">
+&lt;html xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+      xsl:version="1.0">
+  &lt;head>
+    &lt;title>
+      &lt;xsl:value-of select="/directory/@namestring"/>
+    &lt;/title>
+  &lt;/head>
+
+  &lt;body>
+    &lt;h1>
+      Index of &lt;xsl:value-of select="/directory/@namestring"/>
+    &lt;/h1>
+    
+    &lt;ul>
+      &lt;xsl:for-each select="/directory/file">
+       &lt;li>
+         &lt;xsl:value-of select="."/>
+       &lt;/li>
+      &lt;/xsl:for-each>
+    &lt;/ul>
+  &lt;/body>
+&lt;/html>
+</pre>
+
+  <h3>Try it!</h3>
+  <p>
+    That's it.  If you open <tt>http://localhost:4242/show-directory</tt>
+    in a browser, you should see a listing of your home directory.
+  </p>
+</page>
index 7a03f17..3f40492 100644 (file)
@@ -28,8 +28,8 @@
   </ul>
 
   <h3>Recent Changes</h3>
-  <p><b>2007-xx-yy</b></p>
+  <p><b>2009-04-04</b></p>
   <ul>
-    <li>not released yet; work in progress</li>
+    <li>initial public release</li>
   </ul>
 </page>
index 287911c..1e11eeb 100644 (file)
@@ -94,8 +94,7 @@
            </ul>
          </li>
          <li>
-           <a href="examples.html"><strike>Examples</strike></a>
-           (to be written)
+           <a href="example.html">Example</a>
            <br/>&#160;
          </li>
          <li>