Common Lisp Weekly News

February 8, 2013

Generating SVG from Lisp is easy!

Filed under: Articles — Tags: , , , , , — lispnews @ 11:47 am

There are libraries dedicated to the task of generating SVG (Simple Vector Graphics) from Lisp. Namely the cl-svg. But they might offer a limited subset of the SVG standard.

Since SVG is an application of XML and XML is closely related to both SGML and HTML/XHTML one could suggest that it might be possible to use standard full-featured HTML-generators. Indeed, it is, and here is how.

CL-WHO of Edi Weitz actually transforms a tree of S-exp into a sequence of commands that ouput the corresponding XML/SGML into the given stream. And this is exactly what is needed to produce SVG from Lisp!

Let’s define a stream where the SVG data will be serialized:

(defparameter *svg* *standard-output*)

Now let’s define a macro that will tune CL-WHO to do the job we want it to do:

(defmacro with-svg (&body body)
  `(progn
     (format *svg* "<?xml version=\"1.0\" standalone=\"yes\"?>~%~%")
     (who:with-html-output
	 (*svg* nil :prologue
		"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">"
		:indent T)
       ,@body)))

Here we print an XML declaration because CL-WHO does not and we ask it to use prologue that is required by SVG. Indentation is optional and is useful for debugging purposes.

The with-svg macro is designed to envelope chunks of SVG code. Let’s translate this example for this macro:

(with-open-file (*svg* "out.svg" :direction :output
		       :if-exists :supersede
		       :if-does-not-exist :create)
  (with-svg 
    (:svg :width "4in" :height "3in" :version "1.1"
	  :xmlns "http://www.w3.org/2000/svg" :|xmlns:xlink| "http://www.w3.org/1999/xlink"
	  (:desc "This graphic links to an external image")

	  (:image :x "200" :y "200" :width "100px" :height "100px"
		  :|xlink:href| "myimage.png"
		  (:title "My image")))))

And don’t forget that empty tags are defined by the who:*html-empty-tags* list.

One last note is that this very approach is suitable for generating arbitrary XML with a truly universal tool that is CL-WHO.

About these ads

2 Comments »

  1. Generating SVG from eveything that has basic string functionalities is easy. The more interesting part would be the converse: Reading and analyzing SVGs.

    Comment by dasuxullebt — February 10, 2013 @ 7:40 pm

  2. This task indeed is more complex and cumbersome. However, there are some Lisp bindings to the librsvg SVG rendering library that can be used solve this task.

    On the other hand, having a convenient way to generate SVG might be interesting from a practical point of view as well.

    Comment by lispnews — February 11, 2013 @ 1:32 pm


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Silver is the New Black Theme. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: