--- /dev/null
+;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*-
+;;;; *************************************************************************
+;;;; FILE IDENTIFICATION
+;;;;
+;;;; Name: lml.cl
+;;;; Purpose: Lisp Markup Language functions
+;;;; Programmer: Kevin M. Rosenberg
+;;;; Date Started: Aug 2002
+;;;;
+;;;; $Id: base.lisp,v 1.1 2002/12/29 09:10:41 kevin Exp $
+;;;;
+;;;; This file, part of LML, is Copyright (c) 2002 by Kevin M. Rosenberg
+;;;;
+;;;; LML users are granted the rights to distribute and use this software
+;;;; as governed by the terms of the GNU General Public License v2
+;;;; (http://www.gnu.org/licenses/gpl.html)
+;;;; *************************************************************************
+
+(declaim (optimize (debug 3) (speed 3) (safety 3) (compilation-speed 0)))
+(in-package :lml)
+
+(defun html4-prologue-string ()
+ "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">")
+
+(defun xml-prologue-string ()
+ "<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"yes\"?>")
+
+(defun xhtml-prologue-string ()
+ "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">")
+
+(defvar *print-spaces* nil)
+(defvar *indent* 0)
+(defun reset-indent ()
+ (setq *indent* 0))
+
+(defun lml-print (str &rest args)
+ (when (streamp *html-output*)
+ (when *print-spaces* (indent-spaces *indent* *html-output*))
+ (if args
+ (apply #'format *html-output* str args)
+ (princ str *html-output*))
+ (when *print-spaces* (format *html-output* "~%"))
+ (values)))
+
+(defmacro lml-line (str &rest args)
+ `(lml-print ,str ,@args))
+
+(defun lml-print-date (date)
+ (lml-print (date-string date)))
+
+(defmacro lml-exec-body (&body forms)
+ `(progn
+ ,@(mapcar
+ #'(lambda (form)
+ (etypecase form
+ (string
+ `(lml-print ,form))
+ (number
+ `(lml-print "~D" ,form))
+ (symbol
+ (when form
+ `(lml-print (string-downcase (symbol-name ,form)))))
+ (cons
+ form)))
+ forms)))
+
+(defmacro with-attr-string (tag attr-string &body body)
+ (let ((attr (gensym)))
+ `(let ((,attr ,attr-string))
+ (lml-print "<~(~A~)~A>" ',tag
+ (if (and (stringp ,attr) (plusp (length ,attr)))
+ (format nil "~A" ,attr)
+ ""))
+ (incf *indent*)
+ (lml-exec-body ,@body)
+ (decf *indent*)
+ (lml-print "</~(~A~)>" ',tag))))
+
+(defun one-keyarg-string (key value)
+ "Return attribute string for keys"
+ (format nil "~(~A~)=\"~A\"" key
+ (typecase value
+ (symbol
+ (string-downcase (symbol-name value)))
+ (string
+ value)
+ (t
+ (eval value)))))
+
+(defmacro with-keyargs (tag keyargs &body body)
+ (let ((attr (gensym))
+ (kv (gensym)))
+ `(progn
+ (let ((,attr '()))
+ (dolist (,kv ',keyargs)
+ (awhen (cadr ,kv)
+ (push (one-keyarg-string (car ,kv) it) ,attr)))
+ (with-attr-string ,tag (list-to-spaced-string (nreverse ,attr)) ,@body)))))
+
+(defmacro with (tag &rest args)
+ (let ((body '())
+ (keyargs '())
+ (n (length args)))
+ (do ((i 0 (1+ i)))
+ ((> i (1- n)))
+ (let ((arg (nth i args))
+ (value (when (< (1+ i) n)
+ (nth (1+ i) args))))
+ (if (keyword-symbol? arg)
+ (progn
+ (push (list arg value) keyargs)
+ (incf i))
+ (push arg body))))
+ `(with-keyargs ,tag ,keyargs ,@(nreverse body))))
+
+
+(defmacro keyargs-string (&rest args)
+ "Returns a string of attributes and values. Result contains a leading space."
+ (let ((keyarg-list '()))
+ (loop for ( name val ) on args by #'cddr
+ do
+ (when val
+ (push (one-keyarg-string name val) keyarg-list)))
+ (list-to-spaced-string (nreverse keyarg-list))))
+
+
+(defmacro xhtml-prologue ()
+ `(progn
+ (lml-print "~A~%" (xml-prologue-string))
+ (lml-print "~A~%" (xhtml-prologue-string))))
+
+(defmacro link (dest &body body)
+ `(with a :href ,dest ,@body))
+
+(defmacro link-c (class dest &body body)
+ `(with a :href ,dest :class ,class ,@body))
+
+(defmacro img (dest &key class id alt style width height align)
+ (let ((attr
+ (eval `(keyargs-string :class ,class :id ,id :alt ,alt :style ,style
+ :width ,width :height ,height :align ,align))))
+ `(lml-print ,(format nil "<img src=\"~A\"~A />" dest attr))))
+
+(defmacro input (&key name class id type style size maxlength value checked)
+ (let ((attr
+ (eval `(keyargs-string :name ,name :class ,class :id ,id :style ,style
+ :size ,size :maxlength ,maxlength :value ,value
+ :type ,type :checked ,checked))))
+ `(lml-print ,(format nil "<input~A />" attr))))
+
+(defmacro meta (name content)
+ `(with meta :name ,name :content ,content))
+
+(defmacro meta-key (&key name content http-equiv)
+ `(with meta :name ,name :content ,content :http-equiv ,http-equiv))
+
+(defmacro br ()
+ `(lml-print "<br />"))
+
+(defmacro hr ()
+ `(lml-print "<hr />"))
+
+(defmacro lml-tag-macro (tag)
+ `(progn
+ (defmacro ,tag (&body body)
+ `(with ,',tag ,@body))
+ (export ',tag)))
+
+(defmacro lml-tag-class-macro (tag)
+ (let ((name (intern (format nil "~A-~A" tag :c))))
+ `(progn
+ (defmacro ,name (&body body)
+ `(with ,',tag :class ,(car body) ,@(cdr body)))
+ (export ',name))))
+
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (defparameter *macro-list*
+ '(a div span h1 h2 h3 h4 h5 h6 i b p li ul ol table tbody td tr body head
+ html title pre tt u dl dt dd kbd code form))
+ (export '(link link-c br hr img input meta meta-key))
+ (export *macro-list*))
+
+(loop for i in *macro-list*
+ do
+ (eval `(lml-tag-macro ,i))
+ (eval `(lml-tag-class-macro ,i)))
+
+(defmacro print-page (title &body body)
+ `(html
+ (head
+ (title ,title))
+ (body ,@body)))
+
+(defmacro page (out-file &body body)
+ `(with-open-file (*html-output*
+ (lml-file-name ,out-file :output)
+ :direction :output
+ :if-exists :supersede)
+ (xhtml-prologue)
+ (html :xmlns "http://www.w3.org/1999/xhtml"
+ ,@body)))
+
+(defun new-string ()
+ (make-array 1024 :fill-pointer 0 :adjustable t :element-type 'character))
+
+(set-macro-character #\[
+ #'(lambda (stream char)
+ (declare (ignore char))
+ (let ((forms '())
+ (curr-string (new-string))
+ (paren-level 0)
+ (got-comma nil))
+ (declare (type fixnum paren-level))
+ (do ((ch (read-char stream t nil t) (read-char stream t nil t)))
+ ((eql ch #\]))
+ (if got-comma
+ (if (eql ch #\()
+ ;; Starting top-level ,(
+ (progn
+ #+cmu
+ (setf curr-string (coerce curr-string `(simple-array character (*))))
+
+ (push `(lml-print ,curr-string) forms)
+ (setq curr-string (new-string))
+ (setq got-comma nil)
+ (vector-push #\( curr-string)
+ (do ((ch (read-char stream t nil t) (Read-char stream t nil t)))
+ ((and (eql ch #\)) (zerop paren-level)))
+ (when (eql ch #\])
+ (format *trace-output* "Syntax error reading #\]")
+ (return nil))
+ (case ch
+ (#\(
+ (incf paren-level))
+ (#\)
+ (decf paren-level)))
+ (vector-push-extend ch curr-string))
+ (vector-push-extend #\) curr-string)
+ (let ((eval-string (read-from-string curr-string))
+ (res (gensym)))
+ (push
+ `(let ((,res ,eval-string))
+ (when ,res
+ (lml-print ,res)))
+ forms))
+ (setq curr-string (new-string)))
+ ;; read comma, then non #\( char
+ (progn
+ (unless (eql ch #\,)
+ (setq got-comma nil))
+ (vector-push-extend #\, curr-string) ;; push previous command
+ (vector-push-extend ch curr-string)))
+ ;; previous character is not a comma
+ (if (eql ch #\,)
+ (setq got-comma t)
+ (progn
+ (setq got-comma nil)
+ (vector-push-extend ch curr-string)))))
+
+ #+cmu
+ (setf curr-string (coerce curr-string `(simple-array character (*))))
+
+ (push `(lml-print ,curr-string) forms)
+ `(progn ,@(nreverse forms)))))
+
+
+cl-lml (1.7.6-1) unstable; urgency=low
+
+ * Add checked to input macro
+
+ -- Kevin M. Rosenberg <kmr@debian.org> Sun, 29 Dec 2002 02:10:21 -0700
+
cl-lml (1.7.5-1) unstable; urgency=low
* Add support for OpenMCL
;;;; Programmer: Kevin M. Rosenberg
;;;; Date Started: Aug 2002
;;;;
-;;;; $Id: lml.asd,v 1.11 2002/11/08 16:51:40 kevin Exp $
+;;;; $Id: lml.asd,v 1.12 2002/12/29 09:10:41 kevin Exp $
;;;;
;;;; This file, part of LML, is Copyright (c) 2002 by Kevin M. Rosenberg
;;;;
((:file "package")
(:file "utils" :depends-on ("package"))
(:file "files" :depends-on ("utils"))
- (:file "lml" :depends-on ("files"))
- (:file "stdsite" :depends-on ("lml"))
- (:file "downloads" :depends-on ("lml"))
+ (:file "base" :depends-on ("files"))
+ (:file "stdsite" :depends-on ("base"))
+ (:file "downloads" :depends-on ("base"))
))
+++ /dev/null
-;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*-
-;;;; *************************************************************************
-;;;; FILE IDENTIFICATION
-;;;;
-;;;; Name: lml.cl
-;;;; Purpose: Lisp Markup Language functions
-;;;; Programmer: Kevin M. Rosenberg
-;;;; Date Started: Aug 2002
-;;;;
-;;;; $Id: lml.lisp,v 1.6 2002/11/25 18:59:20 kevin Exp $
-;;;;
-;;;; This file, part of LML, is Copyright (c) 2002 by Kevin M. Rosenberg
-;;;;
-;;;; LML users are granted the rights to distribute and use this software
-;;;; as governed by the terms of the GNU General Public License v2
-;;;; (http://www.gnu.org/licenses/gpl.html)
-;;;; *************************************************************************
-
-(declaim (optimize (debug 3) (speed 3) (safety 3) (compilation-speed 0)))
-(in-package :lml)
-
-(defun html4-prologue-string ()
- "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">")
-
-(defun xml-prologue-string ()
- "<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"yes\"?>")
-
-(defun xhtml-prologue-string ()
- "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">")
-
-(defvar *print-spaces* nil)
-(defvar *indent* 0)
-(defun reset-indent ()
- (setq *indent* 0))
-
-(defun lml-print (str &rest args)
- (when (streamp *html-output*)
- (when *print-spaces* (indent-spaces *indent* *html-output*))
- (if args
- (apply #'format *html-output* str args)
- (princ str *html-output*))
- (when *print-spaces* (format *html-output* "~%"))
- (values)))
-
-(defmacro lml-line (str &rest args)
- `(lml-print ,str ,@args))
-
-(defun lml-print-date (date)
- (lml-print (date-string date)))
-
-(defmacro lml-exec-body (&body forms)
- `(progn
- ,@(mapcar
- #'(lambda (form)
- (etypecase form
- (string
- `(lml-print ,form))
- (number
- `(lml-print "~D" ,form))
- (symbol
- (when form
- `(lml-print (string-downcase (symbol-name ,form)))))
- (cons
- form)))
- forms)))
-
-(defmacro with-attr-string (tag attr-string &body body)
- (let ((attr (gensym)))
- `(let ((,attr ,attr-string))
- (lml-print "<~(~A~)~A>" ',tag
- (if (and (stringp ,attr) (plusp (length ,attr)))
- (format nil "~A" ,attr)
- ""))
- (incf *indent*)
- (lml-exec-body ,@body)
- (decf *indent*)
- (lml-print "</~(~A~)>" ',tag))))
-
-(defun one-keyarg-string (key value)
- "Return attribute string for keys"
- (format nil "~(~A~)=\"~A\"" key
- (typecase value
- (symbol
- (string-downcase (symbol-name value)))
- (string
- value)
- (t
- (eval value)))))
-
-(defmacro with-keyargs (tag keyargs &body body)
- (let ((attr (gensym))
- (kv (gensym)))
- `(progn
- (let ((,attr '()))
- (dolist (,kv ',keyargs)
- (awhen (cadr ,kv)
- (push (one-keyarg-string (car ,kv) it) ,attr)))
- (with-attr-string ,tag (list-to-spaced-string (nreverse ,attr)) ,@body)))))
-
-(defmacro with (tag &rest args)
- (let ((body '())
- (keyargs '())
- (n (length args)))
- (do ((i 0 (1+ i)))
- ((> i (1- n)))
- (let ((arg (nth i args))
- (value (when (< (1+ i) n)
- (nth (1+ i) args))))
- (if (keyword-symbol? arg)
- (progn
- (push (list arg value) keyargs)
- (incf i))
- (push arg body))))
- `(with-keyargs ,tag ,keyargs ,@(nreverse body))))
-
-
-(defmacro keyargs-string (&rest args)
- "Returns a string of attributes and values. Result contains a leading space."
- (let ((keyarg-list '()))
- (loop for ( name val ) on args by #'cddr
- do
- (when val
- (push (one-keyarg-string name val) keyarg-list)))
- (list-to-spaced-string (nreverse keyarg-list))))
-
-
-(defmacro xhtml-prologue ()
- `(progn
- (lml-print "~A~%" (xml-prologue-string))
- (lml-print "~A~%" (xhtml-prologue-string))))
-
-(defmacro link (dest &body body)
- `(with a :href ,dest ,@body))
-
-(defmacro link-c (class dest &body body)
- `(with a :href ,dest :class ,class ,@body))
-
-(defmacro img (dest &key class id alt style width height align)
- (let ((attr
- (eval `(keyargs-string :class ,class :id ,id :alt ,alt :style ,style
- :width ,width :height ,height :align ,align))))
- `(lml-print ,(format nil "<img src=\"~A\"~A />" dest attr))))
-
-(defmacro input (&key name class id type style size maxlength value)
- (let ((attr
- (eval `(keyargs-string :name ,name :class ,class :id ,id :style ,style
- :size ,size :maxlength ,maxlength :value ,value
- :type ,type))))
- `(lml-print ,(format nil "<input~A />" attr))))
-
-(defmacro meta (name content)
- `(with meta :name ,name :content ,content))
-
-(defmacro meta-key (&key name content http-equiv)
- `(with meta :name ,name :content ,content :http-equiv ,http-equiv))
-
-(defmacro br ()
- `(lml-print "<br />"))
-
-(defmacro hr ()
- `(lml-print "<hr />"))
-
-(defmacro lml-tag-macro (tag)
- `(progn
- (defmacro ,tag (&body body)
- `(with ,',tag ,@body))
- (export ',tag)))
-
-(defmacro lml-tag-class-macro (tag)
- (let ((name (intern (format nil "~A-~A" tag :c))))
- `(progn
- (defmacro ,name (&body body)
- `(with ,',tag :class ,(car body) ,@(cdr body)))
- (export ',name))))
-
-(eval-when (:compile-toplevel :load-toplevel :execute)
- (defparameter *macro-list*
- '(a div span h1 h2 h3 h4 h5 h6 i b p li ul ol table tbody td tr body head
- html title pre tt u dl dt dd kbd code form))
- (export '(link link-c br hr img input meta meta-key))
- (export *macro-list*))
-
-(loop for i in *macro-list*
- do
- (eval `(lml-tag-macro ,i))
- (eval `(lml-tag-class-macro ,i)))
-
-(defmacro print-page (title &body body)
- `(html
- (head
- (title ,title))
- (body ,@body)))
-
-(defmacro page (out-file &body body)
- `(with-open-file (*html-output*
- (lml-file-name ,out-file :output)
- :direction :output
- :if-exists :supersede)
- (xhtml-prologue)
- (html :xmlns "http://www.w3.org/1999/xhtml"
- ,@body)))
-
-(defun new-string ()
- (make-array 1024 :fill-pointer 0 :adjustable t :element-type 'character))
-
-(set-macro-character #\[
- #'(lambda (stream char)
- (declare (ignore char))
- (let ((forms '())
- (curr-string (new-string))
- (paren-level 0)
- (got-comma nil))
- (declare (type fixnum paren-level))
- (do ((ch (read-char stream t nil t) (read-char stream t nil t)))
- ((eql ch #\]))
- (if got-comma
- (if (eql ch #\()
- ;; Starting top-level ,(
- (progn
- #+cmu
- (setf curr-string (coerce curr-string `(simple-array character (*))))
-
- (push `(lml-print ,curr-string) forms)
- (setq curr-string (new-string))
- (setq got-comma nil)
- (vector-push #\( curr-string)
- (do ((ch (read-char stream t nil t) (Read-char stream t nil t)))
- ((and (eql ch #\)) (zerop paren-level)))
- (when (eql ch #\])
- (format *trace-output* "Syntax error reading #\]")
- (return nil))
- (case ch
- (#\(
- (incf paren-level))
- (#\)
- (decf paren-level)))
- (vector-push-extend ch curr-string))
- (vector-push-extend #\) curr-string)
- (let ((eval-string (read-from-string curr-string))
- (res (gensym)))
- (push
- `(let ((,res ,eval-string))
- (when ,res
- (lml-print ,res)))
- forms))
- (setq curr-string (new-string)))
- ;; read comma, then non #\( char
- (progn
- (unless (eql ch #\,)
- (setq got-comma nil))
- (vector-push-extend #\, curr-string) ;; push previous command
- (vector-push-extend ch curr-string)))
- ;; previous character is not a comma
- (if (eql ch #\,)
- (setq got-comma t)
- (progn
- (setq got-comma nil)
- (vector-push-extend ch curr-string)))))
-
- #+cmu
- (setf curr-string (coerce curr-string `(simple-array character (*))))
-
- (push `(lml-print ,curr-string) forms)
- `(progn ,@(nreverse forms)))))
-
-