;;;; Programmer: Kevin M. Rosenberg
;;;; Date Started: Aug 2002
;;;;
-;;;; $Id: lml.cl,v 1.1 2002/09/16 01:13:49 kevin Exp $
+;;;; $Id: lml.cl,v 1.13 2002/09/16 10:18:19 kevin Exp $
;;;;
;;;; This file, part of LML, is Copyright (c) 2002 by Kevin M. Rosenberg
;;;;
(declaim (optimize (debug 3) (speed 3) (safety 1) (compilation-speed 0)))
(in-package :lml)
-(defconstant +html4-prologue-string+
- (format nil
- "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">~%"))
+(defun html4-prologue-string ()
+ "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">")
-(defconstant +xml-prologue-string+
- (format nil
- "<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"yes\"?>~%"))
+(defun xml-prologue-string ()
+ "<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"yes\"?>")
-(defconstant +xhtml-prologue-string+
- (format nil
- "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">~%"))
+(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)
(defmacro xhtml-prologue ()
`(progn
- (lml-print +xml-prologue-string+)
- (lml-print +xhtml-prologue-string+)))
+ (lml-print "~A~%" (xml-prologue-string))
+ (lml-print "~A~%" (xhtml-prologue-string))))
(defmacro link (dest &body body)
`(with a :href ,dest ,@body))
(defmacro br ()
`(lml-print "<br />"))
+(defmacro hr ()
+ `(lml-print "<hr />"))
+
(defmacro lml-tag-macro (tag)
`(progn
(defmacro ,tag (&body body)
(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 img input meta meta-key))
+ (export '(link link-c br hr img input meta meta-key))
(export *macro-list*))
(loop for i in *macro-list*
(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))
+ (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
+ (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)))))
+ (push `(lml-print ,curr-string) forms)
+ `(progn ,@(nreverse forms)))))
+
+