From: Kevin M. Rosenberg Date: Sun, 29 Dec 2002 09:10:41 +0000 (+0000) Subject: r3691: *** empty log message *** X-Git-Tag: v2.5.5~124 X-Git-Url: http://git.kpe.io/?p=lml.git;a=commitdiff_plain;h=9c9a88110167cb4727f04677192fd7afd4c8b00f r3691: *** empty log message *** --- diff --git a/base.lisp b/base.lisp new file mode 100644 index 0000000..85a5911 --- /dev/null +++ b/base.lisp @@ -0,0 +1,266 @@ +;;;; -*- 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 () + "") + +(defun xml-prologue-string () + "") + +(defun xhtml-prologue-string () + "") + +(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 "" ',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 "" 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 "" 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 "
")) + +(defmacro hr () + `(lml-print "
")) + +(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))))) + + diff --git a/debian/changelog b/debian/changelog index d38ca92..c256bc5 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +cl-lml (1.7.6-1) unstable; urgency=low + + * Add checked to input macro + + -- Kevin M. Rosenberg Sun, 29 Dec 2002 02:10:21 -0700 + cl-lml (1.7.5-1) unstable; urgency=low * Add support for OpenMCL diff --git a/lml.asd b/lml.asd index 0304634..6efe339 100644 --- a/lml.asd +++ b/lml.asd @@ -7,7 +7,7 @@ ;;;; 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 ;;;; @@ -34,8 +34,8 @@ ((: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")) )) diff --git a/lml.lisp b/lml.lisp deleted file mode 100644 index a98ced9..0000000 --- a/lml.lisp +++ /dev/null @@ -1,266 +0,0 @@ -;;;; -*- 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 () - "") - -(defun xml-prologue-string () - "") - -(defun xhtml-prologue-string () - "") - -(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 "" ',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 "" 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 "" 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 "
")) - -(defmacro hr () - `(lml-print "
")) - -(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))))) - -