easily embedding html into Lisp

From: Andreas Thiele (nospam6329_at_nospam.com)
Date: 09/15/04


Date: Wed, 15 Sep 2004 12:32:48 +0200

I'd like to introduce a simple approach of embedding html into Lisp.

Let's consider the following call to format

(format nil "~{ ~a ~}" '(1 2 3))

which produces " 1 2 3 " as output. This formatting capability can be used
to achive
a very simple embedding of html into Lisp.

Let's assume we already have three functions 'table 'tr and 'td. Our html
code to
make a table then might look like

(table :cellpadding 0 :cellspacing 5
  (tr (td "hello") (td "world")))

producing

<table cellpadding="0"
cellspacing="5"><tr><td>hello</td><td>world</td></tr></table>

I assume html tags can be described liked

<tag-name attribute1=value1 ... > content </tag-name>

So function 'table exspects a cons of a property list and the content as
parameters.
With the following helper function 'split-attribs

(defun split-attribs (lst)
  (let (attribs rest key value)
    (loop
      (if (zerop (length lst)) (return))
      (unless (keywordp (car lst)) (return))
      (setf key (string-downcase (pop lst)))
      (setf value (pop lst))
      (if value
        (push (format nil " ~a=\"~a\"" key value) attribs)
        (push (format nil " ~a" key) attribs)))
    (values (reverse attribs) lst)))

the function 'table could be

(defun table (&rest text)
  (multiple-value-bind (attribs rest)
      (split-attribs text)
    (format nil "<table~{~a~}>~{~a~}</table>~%" attribs rest)))

Now let's go one step ahead. For each html tag there has to be such a
function
definition. With the following macro we might generate these functions

(defun tag-format-string (tag)
  (concatenate 'string "<" tag "~{~a~}>~{~a~}</" tag ">~%"))

(defmacro deftag (name)
  (let ((f (tag-format-string (string-downcase (symbol-name name)))))
    `(defun ,name (&rest text)
       (multiple-value-bind (attribs rest)
           (split-attribs text)
         (format nil ,f attribs rest)))))

Thus defining our three functions 'table 'tr and 'td would reduce to

(deftag table)
(deftag tr)
(deftag td)

So the whole html thing can be reduced to approx. 60 lines of code, if we
consider
each 'deftag a line :-)

When talking about html I must mention Kevin Rosenberg's LML package at
http://lml.b9.com

I am interested in your criticism to my approach. With some slight
extensions (short tags
i.e. <br> ((no closing tag </br>)) and LF suppression) I use it to generate
html pages from Lisp.

Andreas



Relevant Pages

  • Re: UI, Lisp, CLOS, MVC, design
    ... Then I just handle one URL and drive my app framework the same as I do any cells framework, parsing the event and dispatching it appropriately to the moused widget or to the keyboard focus, which is tracked Lisp-side. ... I have a CLOS class for each HTML tag, slots for each attribute, exact same as for CelTk. ... The wicked cool thing is that after it matures one can forget one is programming anything other than Lisp, tho we understand the classes and slots map onto tags and attributes and we still need to provide reasonable values thereto. ...
    (comp.lang.lisp)
  • Re: macro and cl-who help
    ... Lisp, but... ... you back into the "walking forms as HTML data" mode, ... This would have been extensible with user-defined tags, ... HTML tags are macros can be functions: ...
    (comp.lang.lisp)
  • Re: Future of LISP. Alternative to XML. Web 3.0?
    ... rather than directly replacing HTML for Web pages. ... S-expr are more concise and easy to parse than XML. ... For today LISP ...
    (comp.lang.lisp)
  • Re: Lisp for the Twenty First Century: audio talk
    ... this is a high quality audio recording of about ... web know how and extremely poor web presentation of his lisp products. ... words of text slapped onto one single html page. ... if you pass tech geeker's webpages into HTML ...
    (comp.lang.lisp)
  • Re: Lisp for the Twenty First Century: audio talk
    ... this is a high quality audio recording of about ... web know how and extremely poor web presentation of his lisp products. ... words of text slapped onto one single html page. ... if you pass tech geeker's webpages into HTML ...
    (comp.lang.lisp)