<div>We have a PS program split across a dozen or so Lisp files and a</div><div>"compiler" (really just a build script in the form of a CL function)</div><div>that processes each file by binding *PARENSCRIPT-STREAM*, reading in</div>

<div>PS forms from the top level of the file, and calling PS* on them to</div><div>create a .js file. Then a second script assembles the component .js</div><div>files into a big one, which is the entire client program. That thing</div>

<div>is given a SHA1 hash as part of its name so it can be browser-cached</div><div>forever.</div><div><br></div><div>This setup has proven pretty good. It's simple. It works somewhat like</div><div>ASDF so it feels natural in a CL environment. It only recompiles</div>

<div>individual js files when they change, so the round trip from editing</div><div>PS code to refreshing the page in the browser is reasonably fast.</div><div><br></div><div>Another advantage is for debugging. When browsers, even bad ones,</div>

<div>report an error, they provide the line number at which the error</div><div>occurred. Because the big .js file is named with a SHA1 hash, it's</div><div>very quick to go back to Emacs, open the precise version of the</div>

<div>program that's producing the error (ido-mode makes this particularly</div><div>quick as one only needs to type in 4 or 5 characters) and M-g M-g to</div><div>the offending line number. This is so much easier than having to open</div>

<div>the script in some horrible dinky client-side tool (even the</div><div>not-so-bad ones like Firebug) and scroll around.</div><div><br></div><div>As I said, pretty simple. Before this we had a more complicated</div><div>

approach that didn't work nearly as well.</div><div><br></div><div>Daniel</div><div><br></div><br><div class="gmail_quote">On Sat, Jan 8, 2011 at 2:44 PM, Jon Rosebaugh <span dir="ltr"><<a href="mailto:chairos@gmail.com">chairos@gmail.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">As I said in the subject, I'm working on a JS-only (no server-side<br>
code) HTML5 webapp in Parenscript with jQuery. I have extensive JS<br>
experience, but I'm really new to Common Lisp.<br>
<br>
I wanted a setup where I could edit a Parenscript file, hit save, then<br>
hit refresh in my browser and immediately see the new code, just as if<br>
I were working in Javascript. I built a little server using<br>
Hunchentoot and cl-who that runs ps-compile-file on my parenscript<br>
source file as needed. This works fairly well, but maybe is not the<br>
best way to accomplish this.<br>
<br>
However, there's a problem; I wanted to use parenscript functions<br>
without the namespace, so I defined a package in serve.lisp that uses<br>
parenscript, then put (in-package :innkeeper) at the top of my<br>
parenscript file. This doesn't work properly in the 2.2 release of<br>
Parenscript (which is what Quicklisp provides). It _does_ work in the<br>
git repo version (as of commit<br>
0e01e555f404a7dcb8befb7587288c38abf526c2), but it's annoying to not be<br>
able to use Quicklisp for everything.<br>
<br>
Once I have a release version I'll want to come up with some lisp<br>
program that compiles the parenscript to javascript, minifies it, and<br>
sticks it in an also-minified html file from cl-who, so the whole<br>
thing is compiled down to a single file. I'd appreciate any<br>
best-practice tips on that too.<br>
<br>
Just in case my description was unclear, here's what I think are the<br>
relevant bits. If needed, I can provide the entire files off-list.<br>
<br>
; relevant bits of serve.lisp<br>
(defpackage "INNKEEPER"<br>
  (:use "COMMON-LISP" "HUNCHENTOOT" "CL-WHO" "PARENSCRIPT")<br>
  (:export :start-innserver :stop-innserver))<br>
<br>
(in-package :innkeeper)<br>
<br>
(define-easy-handler (jsgen :uri "/innkeeper.js") ()<br>
  (setf (content-type*) "application/javascript")<br>
  (ps-compile-file "/Users/jon/code/innkeeper/innkeeper.lisp"))<br>
<br>
; beginning (and a few representative lines) of innkeeper.lisp<br>
<br>
(in-package :innkeeper)<br>
<br>
(defmacro immediate (&body body)<br>
  `((lambda () ,@body)))<br>
<br>
(var *inn*<br>
     (create<br>
             setup (lambda () ((@ ($ "#top-tabs") tabs)))))<br>
<br>
(j-query #'(@ *inn* setup))<br>
<br>
_______________________________________________<br>
parenscript-devel mailing list<br>
<a href="mailto:parenscript-devel@common-lisp.net">parenscript-devel@common-lisp.net</a><br>
<a href="http://common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel" target="_blank">http://common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel</a><br>
</blockquote></div><br>