X-Git-Url: http://git.kpe.io/?a=blobdiff_plain;f=base.lisp;h=4a03e71632aa245ba6cd35bccd957a553d3bad60;hb=b2d601fcc40acb08a61cb3607f4455bfbd3126fc;hp=5c2f88737630cb196207619d59747789e59b088f;hpb=7c195b8519f680bcb64b02645e4110cb7082d914;p=lml.git diff --git a/base.lisp b/base.lisp index 5c2f887..4a03e71 100644 --- a/base.lisp +++ b/base.lisp @@ -7,7 +7,7 @@ ;;;; Programmer: Kevin M. Rosenberg ;;;; Date Started: Aug 2002 ;;;; -;;;; $Id: base.lisp,v 1.3 2003/01/04 20:42:02 kevin Exp $ +;;;; $Id: base.lisp,v 1.11 2003/02/17 06:48:46 kevin Exp $ ;;;; ;;;; This file, part of LML, is Copyright (c) 2002 by Kevin M. Rosenberg ;;;; @@ -26,14 +26,14 @@ "") (defun xhtml-prologue-string () - "") + "") (defvar *print-spaces* nil) (defvar *indent* 0) (defun reset-indent () (setq *indent* 0)) -(defun lml-print (str &rest args) +(defun lml-format (str &rest args) (when (streamp *html-output*) (when *print-spaces* (indent-spaces *indent* *html-output*)) (if args @@ -42,11 +42,17 @@ (when *print-spaces* (format *html-output* "~%")) (values))) -(defmacro lml-line (str &rest args) - `(lml-print ,str ,@args)) +(defun lml-princ (s) + (princ s *html-output*)) + +(defun lml-print (s) + (format *html-output* "~A~%" s)) + +(defun lml-write-char (char) + (write-char char *html-output)) (defun lml-print-date (date) - (lml-print (date-string date))) + (lml-princ (date-string date))) (defmacro lml-exec-body (&body forms) `(progn @@ -54,12 +60,12 @@ #'(lambda (form) (etypecase form (string - `(lml-print ,form)) + `(lml-princ ,form)) (number - `(lml-print "~D" ,form)) + `(lml-format "~D" ,form)) (symbol (when form - `(lml-print ,form))) + `(lml-princ ,form))) (cons form))) forms))) @@ -67,14 +73,22 @@ (defmacro with-attr-string (tag attr-string &body body) (let ((attr (gensym))) `(let ((,attr ,attr-string)) - (lml-print "<~(~A~)~A>" ',tag + (lml-format "<~(~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)))) + (lml-format "" ',tag)))) + +(defmacro with-no-endtag-attr-string (tag attr-string) + (let ((attr (gensym))) + `(let ((,attr ,attr-string)) + (lml-format "<~(~A~) ~A />" ',tag + (if (and (stringp ,attr) (plusp (length ,attr))) + (format nil "~A" ,attr) + ""))))) (defun one-keyarg-string (key value) "Return attribute string for keys" @@ -97,6 +111,16 @@ (push (one-keyarg-string (car ,kv) it) ,attr))) (with-attr-string ,tag (list-to-spaced-string (nreverse ,attr)) ,@body))))) +(defmacro with-no-endtag-keyargs (tag keyargs) + (let ((attr (gensym)) + (kv (gensym))) + `(progn + (let ((,attr '())) + (dolist (,kv ,keyargs) + (awhen (cdr ,kv) + (push (one-keyarg-string (car ,kv) it) ,attr))) + (with-no-endtag-attr-string ,tag (list-to-spaced-string (nreverse ,attr))))))) + (defmacro bind-one-keyarg (keyarg) `(list ,(car keyarg) ,(cdr keyarg))) @@ -140,54 +164,54 @@ (setq keyargs (nreverse keyargs)) (setq body (nreverse body)) `(let ((,bound-keyargs ,(macroexpand `(bind-all-keyargs ,keyargs)))) - ,(macroexpand `(with-keyargs ,tag ,bound-keyargs ,@body))))) - + ,(macroexpand `(with-keyargs ,tag ,bound-keyargs ,@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 with-no-endtag (tag &rest args) + "Return a list of keyargs body of LML form" + (let ((keyargs '()) + (bound-keyargs (gensym))) + (do* ((n (length args)) + (i 0 (+ 2 i)) + (arg (nth i args) (nth i args)) + (value (when (< (1+ i) n) + (nth (1+ i) args)) + (when (< (1+ i) n) + (nth (1+ i) args)))) + ((or (not (keyword-symbol? arg)) + (>= i n))) + (push (cons arg value) keyargs)) + (setq keyargs (nreverse keyargs)) + `(let ((,bound-keyargs ,(macroexpand `(bind-all-keyargs ,keyargs)))) + ,(macroexpand `(with-no-endtag-keyargs ,tag ,bound-keyargs))))) (defmacro xhtml-prologue () `(progn - (lml-print "~A~%" (xml-prologue-string)) - (lml-print "~A~%" (xhtml-prologue-string)))) + (lml-format "~A~%" (xml-prologue-string)) + (lml-format "~A~%" (xhtml-prologue-string)))) -(defmacro link (dest &body body) +(defmacro alink (dest &body body) `(with a :href ,dest ,@body)) -(defmacro link-c (class dest &body body) +(defmacro alink-c (class dest &body body) `(with a :href ,dest :class (quote ,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 img (dest &rest args) + `(with-no-endtag img :src ,dest ,@args)) -(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 input (&rest args) + `(with-no-endtag input ,@args)) -(defmacro meta (name content) - `(with meta :name ,name :content ,content)) +(defmacro link (&rest args) + `(with-no-endtag link ,@args)) -(defmacro meta-key (&key name content http-equiv) - `(with meta :name ,name :content ,content :http-equiv ,http-equiv)) +(defmacro meta (&rest args) + `(with-no-endtag meta ,@args)) -(defmacro br () - `(lml-print "
")) +(defmacro br (&rest args) + `(with-no-endtag br ,@args)) -(defmacro hr () - `(lml-print "
")) +(defmacro hr (&rest args) + `(with-no-endtag hr ,@args)) (defmacro lml-tag-macro (tag) `(progn @@ -204,9 +228,9 @@ (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)) + '(a div span h1 h2 h3 h4 h5 h6 i b p li ul ol table tbody td th tr body head + html title pre tt u dl dt dd kbd code form textarea)) + (export '(alink alink br hr img input meta link meta-key)) (export *macro-list*)) (loop for i in *macro-list* @@ -249,7 +273,7 @@ #+cmu (setf curr-string (coerce curr-string `(simple-array character (*)))) - (push `(lml-print ,curr-string) forms) + (push `(lml-princ ,curr-string) forms) (setq curr-string (new-string)) (setq got-comma nil) (vector-push #\( curr-string) @@ -270,7 +294,7 @@ (push `(let ((,res ,eval-string)) (when ,res - (lml-print ,res))) + (lml-princ ,res))) forms)) (setq curr-string (new-string))) ;; read comma, then non #\( char @@ -289,7 +313,7 @@ #+cmu (setf curr-string (coerce curr-string `(simple-array character (*)))) - (push `(lml-print ,curr-string) forms) + (push `(lml-princ ,curr-string) forms) `(progn ,@(nreverse forms)))))