Including static HTML snippets in Weblocks

Generating your HTML directly in Lisp with CL-WHO (or some other HTML generation toolkit) is effective.
However, sometimes you need to include HTML from external sources, for example when you want HTML writers to provide page elements.

Here’s a widget for Weblocks that will create a widget from static HTML:

(in-package :weblocks)
 
(export '(static-html make-static-html-from-file
          with-widget-header render-widget-body))
 
(defwidget static-html (widget)
  ((html :type string :accessor html :initarg :html :initform ""))
  (:documentation "Represents a piece of static HTML body mark-up."))
 
(defmethod with-widget-header ((widget static-html) body-fn &rest args &key
                                                    prewidget-body-fn postwidget-body-fn &allow-other-keys)
    (apply body-fn widget args))
 
(defmethod render-widget-body ((widget static-html) &rest args)
  (format *weblocks-output-stream* "~A~_" (html widget)))
 
(defun make-static-html-from-file (file)
  "Create a static-html widget representing the mark-up in “file”."
  (with-open-file (input file :direction :input)
    (let ((data (make-string (file-length input))))
      (read-sequence data input)
      (make-instance 'static-html :html data))))

The Lisp paste is at http://paste.lisp.org/display/54023.

Sending mails in Common Lisp

Just a quickie that might be useful for people new to CL.

Install CL-SMTP if you don’t have it yet:

(asdf-install:install 'cl-smtp)

You’re now able to load it into your Lisp core at any time:

(asdf:oos 'asdf:load-op 'cl-smtp)

And use it, either interactively (HOST is your SMTP server, e.g. localhost):

(cl-smtp:send-email "HOST" "from@foo.com" "recipient@bar.com"
                    "SUBJECT" "BODY")

or non-interactively:

(handler-case
  (prog1 t
    (cl-smtp:send-email "HOST" "from@foo.com" "recipient@bar.com"
                        "SUBJECT" "BODY"))
  (error (msg) (format t "Could not send mail: ~A~%" msg) nil))

We need the prog1 because send-email always returns nil, even on success.
With the above, the whole expression will return true on success, which lets us decide afterwards whether we were able to hand our message to the mail server.

cl-i18n 0.4 released

If it continues like this, we will be at 1.0 soon. ;)

Vilson Vieira has added translation resource merging and has refactored the code base in a nice way.

I also put up my darcs repository at http://viridian-project.de/~sky/cl-i18n/ so you can provide patches against it if you want to contribute.

Adding accessiblity warnings to HTML-generating Lisp code

Image objects in HTML should have at least an ALT attribute for text browsers and screen readers, so let’s automate the checking:

(asdf:oos 'asdf:load-op 'cl-who)
 
(defmacro demand-image-attrs (img want-attrs have-attrs)
  "Check an image's accessiblity information for completeness."
  (let ((missing-attrs (gensym)))
    `(let* ((,missing-attrs (loop for attr in ,want-attrs
                                 when (not (find attr ,have-attrs))
                                 collect attr)))
       (unless (null ,missing-attrs)
         (warn "image ~S is missing the following attributes: ~{~A~^, ~}" ,img ,missing-attrs))))
 
(defmacro render-image (src &rest attrs)
  "Produce HTML code from an image location."
  (declare (type string src))
  `(demand-image-attrs src (list :alt :title) attrs)
  `(cl-who:with-html-output (*standard-output*)
     (:img :src ,src ,@attrs)))
 
CL-USER> (render-image "cat.png" :title "Tom")
WARNING: image "cat.png" is missing the following attributes: ALT
"<img src='cat.png' title='Tom' />"

Simple and effective.

Methods of customizing CLOS objects

CLOS objects provided by other people, for example as parts of libraries, are always a generalization of the concept they represent. What are the ways in which we can model our own objects, with their peculiar presets?

Suppose this simplified class from a layman’s biological classification library:

(in-package :bio)
 
(defclass flower (plant)
  ((stem-color :initform nil)
   (petal-color :initform nil)))

Suppose further that accessors and initargs are named like the slots themselves.

Now let’s try to model a white rose; green stem, white petals. What choices do we have?

Class specialization

The next best thing:

(defclass white-rose (flower)
  ((bio::stem-color :initform 'green)
   (bio::petal-color :initform 'white)))
 
(make-instance 'white-rose)

Watch out for package scoping when overriding slots!
This is a little bit ugly because we have to override the protection of the “bio“ package.
Also, any additional slot arguments (accessors, initargs) defined in some parent class are probably lost.
But instantiation is really clean, simple and straight-forward. As an added bonus you can customize the class beyond presets for existing slots: new slots are easily added.

See the comments section for a better version of this approach.

Constructor function

This method uses a simple function setting up the general object in a customized way and returning it:

(defun make-white-rose ()
  (make-instance 'flower :stem-color 'green :petal-color 'white))

Nice and without package lock intrusion, but not as obvious as class specialization.

initialize-instance :after-method

This is a variation on the first method. It might seem a bit intimidating, but works suprisingly well.

(defclass white-rose (flower) ())
 
(defmethod initialize-instance :after ((self white-rose))
  (setf (stem-color self) 'green)
  (setf (petal-color self) 'white))

initialize-instance gets called after make-instance to initialize the slots of the new object. We provide an :after method so the built-in method can do its housekeeping beforehand (assign specified initargs to slots, for example).

How do you provide specialized presets?

Announcing cl-i18n

This is an early release of a humble package.
I could not find a translation framework for CL that served my needs, so I wrote one.
The focus is on clean and easy usage; the code is by no means witchcraft and it’s likely that people already implemented this on their own, but to my knowledge it’s the first one that is available to the public and comes in an ASDF package.

There’s a separate page on cl-i18n that lists its features and deficiencies.
You can also find an usage example there.

The design of programming languages

Only two weeks ago Larry Wall wrote a quite comprehensive paper featuring a list of common major decision points in programming language design.

Today I came across Kent Pitman’s paper Condition Handling in the Lisp Language Family from the year 2001 where he voices his personal experiences in the design of a programming language standard. The most interesting part is this:

“In my experience, much of language design is like this. We think we know how it will all come out, but we don’t always. Usage patterns are often surprising, as one learns if one is around long enough to design a language or two and then watch how expectations play out in reality over a course of years. So it’s a gamble. But the only way not to gamble is not to move ahead.

I once saw an interview on television with a font designer from Bitstream Inc. about how he conceptualized the process of font design. It is not about designing the shape of the letters, he explained, much to my initial surprise. Then he went on to explain that it was really about the shape of words. The font shapes play into that, but they are not, in themselves, the end goal. Programming language design is like that, too. It’s not about the semantics of individual operators, but about how those operators fit together to form sentences in programs.

Unlike the situation with fonts, where whole books can be viewed instantly in a new font to see how the design works, we don’t know in advance what sentences will be made in a programming language. We have to wait and see what people choose to write. Common Lisp took a step forward, and while we can quibble endlessly over whether any given design decision was right, the one design decision I’m most certain was right was to offer the community a rich set of capabilities that would empower them not only to write programs, but also to have a stake in future designs. Never again will I fear sending out e-mail to a design group asking for advice about what the semantics of HANDLER-BIND should be and finding that no one has an opinion! To me, that kind of progress, the evolution of a whole community’s understanding, is the best kind of progress of all.”

Kent Pitman, lead contributor of the ANSI Common Lisp Standard is a very competent advisor on Lisp matters and still greatly involved in the community. Quite often I’m amazed how much insight and effort was put by him and a bunch of other people into making Lisp a language very capable for Rapid Prototyping, Small Team Development (yeah, I made up that latter buzzword) and all the things that make software development a fun experience instead of a frustrating one.

Among those that instantly come to my mind are

  • the symbol data type
  • the condition system
  • the Common Lisp Object System (CLOS) and its Meta Object Protocol (MOP)
  • the reading and printing facilities
  • the type system
  • the garbage collector
  • the ability to use and mix the paradigms of imperative, functional, declarative and object-oriented programming

It is unfortunate that the standardization process has stopped in 1995. But it doesn’t really matter since it gave the Lisp community a solid base to build quasi-standards upon. This deters newbies, of course, but all mostly self-reliant programmers and those who are willing to ask smart questions on comp.lang.lisp happily make it. And this is the type of programmer who profits most from Common Lisp, anyway.

String parsing with the LOOP facility

As part of a read macro I needed to parse strings. Lisp strings don’t have escapes except for double quotes (as they are string delimiters) and the backslash (which is the escape character).

Here’s what I came up with, a really fine example of Algol style code with three nested conditionals:

(defun read-lisp-string (stream)
  "Parse a Lisp string. Expects stream to point to the
  first character after the leading double quote."
  (coerce
    (loop for char = (read-char stream)
          with nbackslashes = 0
          with eos = nil
 
          if (char= char #\\)
            do (setq nbackslashes (+ nbackslashes 1))
            and if (and (evenp nbackslashes)
                              (not (equal nbackslashes 0)))
                collect char
                end
          else
            if (char/= char #\")
                do (setq nbackslashes 0)
                and collect char
            else
                if (oddp nbackslashes)
                    collect char
                else
                    do (setq eos t)
 
          until eos)
    'simple-string))

The most important thing I learned: although in all places you can read that there’s no accepted standard for the LOOP facility, the respective section of the spec is quite helpful in determining whether a certain clause is allowed at some place.

Web applications for the elite

Weblocks is a very impressive web framework for Common Lisp, and my experiences of hacking away with it a few days have produced quite encouraging results.

Imagine a world where you don’t have to keep track of or prevent the user from

  • hitting reload
  • opening multiple pages in his browser
  • using his back and forward buttons

Sounds good? You’d like to be there? Weblocks offers all this — and more, like automatic usage of AJAX requests if supported on the client side.

The only catch:
You need a firm grip on functional programming and a basic understanding of Lisp to use it, but learning Lisp pays off in any case, and functional programming does incredibly more so.
It helps to have experimented with Hunchentoot before.
So, from LAMP to Weblocks is probably a no-go.

Today I found another framework which has not crossed my way before that looks promising: It’s called and is apparently built on Scheme, so it makes use of continuations as well.

Escaping LaTeX code in Lisp

I need to escape strings that get inserted into a LaTeX document for an upcoming project, and found this on the net:

"\\\\""\\~""\\#""\\$""\\%""\\^""\\&""\\{""\\}""\\_"

where string-escaper obviously is a function returning a function that escapes those characters in the string. They implemented string-escaper in Scheme (probably portable) and thus got a quite large bunch of LOC; I suppose it’d be less in Lisp. especially with the help of loop constructs.

I’ll keep you updated on it, since I can’t work on it right now.

« Previous Page