3

Looking for a tool to programmatically generate SVG images, I found that Emacs 26 can do it out of the box!

Example adapted from the Elisp reference manual:

(require 'svg)
(let ((svg (svg-create 400 400 :stroke-width 10)))
  (svg-gradient svg "gradient1" 'linear '((0 . "red") (100 . "blue")))
  (svg-circle svg 200 200 100 :gradient "gradient1" :stroke-color "green")
  svg)

Now how do I save that to an SVG file?

I’m using Emacs 26.1 in the Termux terminal emulator on my phone, so no graphics.

  • 1
    svg seems to contain XML structure stored as a list. It seems you'd need to just serialize it back to XML, and you'd get a svg string you could save to a file. I'm looking for a function that can do such serialization, and surprisingly, libxml has only parsing functions. – DoMiNeLa10 Jul 28 '18 at 16:10
2

And if, like me, you're trying to do the same in org-mode, with-temp-buffer in combination with buffer-string does the trick:

#+begin_src emacs-lisp :file test.svg
    (let ((svg (svg-create 400 400 :stroke-width 10)))
      (svg-gradient svg "gradient1" 'linear '((0 . "red") (100 . "blue")))
      (svg-circle svg 200 200 100 :gradient "gradient1" :stroke-color "green")
      (with-temp-buffer
        (svg-print svg)
        (buffer-string)))
#+end_src
1

Thought I shouldn’t be lazy and found a way by digging around and reading docs. Key is the svg-print function which serializes the svg structure:

(require 'svg)
(let ((svg (svg-create 400 400 :stroke-width 10)))
  (svg-gradient svg "gradient1" 'linear '((0 . "red") (100 . "blue")))
  (svg-circle svg 200 200 100 :gradient "gradient1" :stroke-color "green")
  (with-temp-file "circle.svg"
    (set-buffer-multibyte nil)
    (svg-print svg)))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.