r5195: *** empty log message ***
[lml.git] / 2 / htmlgen.lisp
index 3740158331e7eae39a9c17c4e42322dca9a0b6b3..62a99e9733de03c80236c3b8c6d2d3f010f2b5e4 100644 (file)
@@ -1,26 +1,24 @@
 ;; -*- mode: common-lisp; package: lml2 -*-
 ;;
-;; $Id: htmlgen.lisp,v 1.4 2003/06/24 16:30:05 kevin Exp $
+;; $Id: htmlgen.lisp,v 1.9 2003/06/24 20:20:12 kevin Exp $
 ;;
 ;; copyright (c) 1986-2000 Franz Inc, Berkeley, CA 
 ;; copyright (c) 2003 Kevin Rosenberg
 ;;
 ;; Main changes from Allegro version:
-;;    - Support XHTML
-;;    - lowercase symbol names
+;;    - Support XHTML end tags
+;;    - lowercase symbol names for attributes
+;;    - Add custom tags such as :jscript, :insert-file, :nbsp
 ;;
 ;; This code is free software; you can redistribute it and/or
 ;; modify it under the terms of the version 2.1 of
 ;; the GNU Lesser General Public License as published by 
-;; the Free Software Foundation, as clarified by the AllegroServe
-;; prequel found in license-allegroserve.txt.
+;; the Free Software Foundation, as clarified by the LLGPL
 
 
 (in-package #:lml2)
 
 
-;; html generation
-
 (defstruct (html-process (:type list) (:constructor
                                       make-html-process (key has-inverse
                                                              macro special
 
 (defmacro html-out-stream-check (stream)
   ;; ensure that a real stream is passed to this function
-  `(let ((.str. ,stream))
-     (if* (not (streamp .str.))
-       then (error "html-stream must be passed a stream object, not ~s"
-                   .str.))
-     .str.))
+  (let ((s (gensym)))
+  `(let ((,s ,stream))
+     (unless (streamp ,s)
+       (error "html-stream must be passed a stream object, not ~s" ,s))
+    ,s)))
 
 
 (defmacro html-stream (stream &rest forms)
 (defun html-body-key-form (string-code has-inv args body)
   ;; do what's needed to handle given keywords in the args
   ;; then do the body
-  (if* (and args (atom args))
-     then ; single arg 
-         (return-from html-body-key-form
-           (case args
-             (:set (if* has-inv
-                        then `(write-string  ,(format nil "<~a>" string-code)
-                               *html-stream*)
-                        else `(write-string  ,(format nil "<~a />" string-code)
-                               *html-stream*)))
-             (:unset (if* has-inv
-                          then `(write-string  ,(format nil "</~a>" string-code)
-                                 *html-stream*)))
-             (t (error "illegal arg ~s to ~s" args string-code)))))
+  (when (and args (atom args))
+    ;; single arg 
+    (return-from html-body-key-form
+      (case args
+       (:set (if* has-inv
+                  then `(write-string  ,(format nil "<~a>" string-code)
+                         *html-stream*)
+                  else `(write-string  ,(format nil "<~a />" string-code)
+                         *html-stream*)))
+       (:unset (if* has-inv
+                    then `(write-string  ,(format nil "</~a>" string-code)
+                           *html-stream*)))
+       (t (error "illegal arg ~s to ~s" args string-code)))))
   
-  (if* (not (evenp (length args)))
-       then (warn "arg list ~s isn't even" args))
+  (unless (evenp (length args))
+    (warn "arg list ~s isn't even" args))
   
   
   (if* args
 (def-special-html :insert-file
     (named-function html-nbsp-function
       (lambda (ent args argsp body)
-       (declare (ignore ent argsp))
+       (declare (ignore ent args argsp))
        (unless body
          (error "must have a body with :insert-file"))
-       `(lml-load-path (car ,args) *html-stream*)))
+       `(progn ,@(mapcar #'(lambda (bod)
+                             `(lml-load-path ,bod))
+                         body))))
   
   (named-function html-nbsp-print-function
+    (lambda (ent cmd args form subst unknown stream)
+      (declare (ignore ent unknown subst stream args))
+      (assert (eql 2 (length form)))
+      (if (eq cmd :full)
+         (lml-load-path (cadr form))
+         (error ":insert-file must be given an argument")))))
+
+
+(def-special-html :write-string
+    (named-function html-write-string-function
+      (lambda (ent args argsp body)
+       (declare (ignore ent args argsp))
+       `(progn ,@(mapcar #'(lambda (bod)
+                             `(write-string ,bod *html-stream*))
+                         body))))
+  
+  (named-function html-write-string-print-function
     (lambda (ent cmd args form subst unknown stream)
       (declare (ignore args ent unknown subst))
-      (if* (eq cmd :full)
-          then (lml-load-path (car args))
-          else (error ":insert-file must be given an argument")))))
+      (assert (eql 2 (length form)))
+      (if (eq cmd :full)
+         (write-string (cadr form) stream)
+         (error ":write-string must be given an argument")))))
+
+(def-special-html :write-char
+    (named-function html-write-char-function
+      (lambda (ent args argsp body)
+       (declare (ignore ent args argsp))
+       `(progn ,@(mapcar #'(lambda (bod)
+                             `(write-char ,bod *html-stream*))
+                         body))))
+  
+  (named-function html-write-char-print-function
+    (lambda (ent cmd args form subst unknown stream)
+      (declare (ignore args ent unknown subst))
+      (assert (eql 2 (length form)))
+      (if (eq cmd :full)
+         (write-char (cadr form) stream)
+         (error ":write-char must be given an argument")))))