Skip to content

Instantly share code, notes, and snippets.

@jl2
Last active August 29, 2015 14:02
Show Gist options
  • Save jl2/87438ed9d4ea0712581d to your computer and use it in GitHub Desktop.
Save jl2/87438ed9d4ea0712581d to your computer and use it in GitHub Desktop.
Very rudimentary library for generating simple SVG files from Common Lisp. Handles points, lines, and polygons.
(defstruct svg
(points nil :type list)
(polys nil :type list)
(lines nil :type list))
(defstruct point
(x 0.0 :type (or float integer))
(y 0.0 :type (or float integer)))
(defstruct line
(pt1 0.0 :type point)
(pt2 0.0 :type point))
(defstruct polygon
(points nil :type list))
(defun add-point (img x y)
(setf (svg-points img) (cons (make-point :x x :y y) (svg-points img))))
(defun add-line (img x1 y1 x2 y2)
(setf (svg-lines img) (cons (make-line :pt1 (make-point :x x1 :y y1) :pt2 (make-point :x x2 :y y2)) (svg-lines img))))
(defun add-polygon (img &rest pts)
(setf (svg-polys img) (cons (make-polygon :points (mapcar #'(lambda (pt) (make-point :x (car pt) :y (cadr pt))) pts)) (svg-polys img))))
(defun to_file (img &key (stream t))
(format stream "<?xml version=\"1.0\" standalone=\"no\"?> <!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"> <svg width=\"100%\" height=\"100%\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">")
(dolist (poly (svg-polys img))
(format stream "<polygon points=\"")
(dolist (pt (polygon-points poly))
(let ((ptstr (mapcar #'(lambda (x) (format nil "~a,~a" (point-x x) (point-y x))) pt)))
(format stream "~{~a ~}" ptstr)))
(format stream "\" style=\"fill:#cccccc; stroke:#000000;stroke-width:1\"/>"))
(dolist (line (svg-lines img))
(let* ((p1 (line-pt1 line))
(p2 (line-pt2 line)))
(format stream "<line x1=\"~a\" y1=\"~a\" x2=\"~a\" y2=\"~a\" style=\"stroke:rgb(99,99,99);stroke-width:2\"/>" (point-x p1) (point-y p1) (point-x p2) (point-y p2))))
(dolist (pt (svg-points img))
(format stream "<circle cx=\"~a\" cy=\"~a\" r=\"3\" stroke=\"blue\" stroke-width=\"2\" fill=\"green\"/>" (point-x pt) (point-y pt)))
(format stream "</svg>"))
;; (load "svg.lisp")
(defun test-it ()
(let ((img (make-svg)))
(add-line img 0 0 500 500)
(add-line img 0 500 500 0)
(add-point img 250 250)
(add-point img 125 125)
(add-point img 375 125)
(add-point img 375 375)
(add-point img 125 375)
(add-polygon img '(250 250) '(125 125) '(125 375))
(add-polygon img '(250 250) '(375 375) '(375 125))
(add-polygon img '(125 125) '(375 125) '(310 190) '(190 190))
(with-open-file (stream "/tmp/test3.svg" :direction :output :if-exists :supersede)
(to_file img :stream stream))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment