SVG by Hand and by Code
2019.06.18 - Nat Tuck - ~3 Minutes
This post is an attempt to walk through programattic generation of SVG files, step by step.
Part 1: SVG By Hand
Prereq: Kate Editor
$ sudo apt install kate
Simple SVG document:
<?xml version="1.0" encoding="UTF-8"?>
<svg width="100" height="100">
<circle cx="50" cy="50" r="20" />
</svg>
Exercises
Ex 1
- Paste the above document into Kate.
- Save it as “circle.svg”
- Open it in Inkscape and Firefox to confirm that it’s reasonable.
Ex 2
- Skim the SVG tutorial at W3 Schools SVG Tutorial
- By hand, using the Kate editor, create an SVG document with three concentric circles, colored as a bullseye.
Ex 3
- Create an SVG document that uses a path tag and the “h” and “v” commands to draw a square.
- Put the path in a group tag. Use the group tag to rotate the square into a diamond. Hint: look at the docs for the “transform” attribute.
Part 2: SVG By Code
Prereqs: Kate Editor; Ruby w/ Nokogiri
$ sudo apt install ruby ruby-nokogiri kate
Ruby Review
Here’s a Ruby tutorial: CodeCademy Ruby
Go through the first 4 lessons of the “Learn Ruby” course.
Quick Re-Review
Start the interactive ruby shell:
$ irb
irb>
Try these commands and see what happens:
irb> text = "the quick brown fox"
irb> text
irb> words_array = text.split(/\s+/)
irb> words_array
irb> array2 = words_array.reverse
irb> array2
irb> array2.join(" + ")
irb> "word".upcase
irb> array3 = words_array.map {|w| w.upcase }
irb> array3
Handling XML
XML describes a tree of tags. Take a look at the diagram here .
Nokogiri is a library for writing Ruby programs to manipulate XML documents.
Try this:
irb> require 'nokogiri'
irb> doc = Nokogiri::XML("<svg/>")
irb> root = doc.xpath("//svg")[0]
irb> circ = Nokogiri::XML::Node.new("circle", doc)
irb> circ["cx"] = 50
irb> circ["cy"] = 50; circ["r"] = 20
irb> circ
irb> root.add_child(circ)
irb> doc
irb> puts doc.to_xml
Now consider this program:
#!/usr/bin/env ruby
require 'nokogiri'
def add_node(parent, name, attrs)
node = Nokogiri::XML::Node.new(name, parent.document)
attrs.each do |kk,vv|
node[kk.to_s] = vv.to_s
end
parent.add_child(node)
node
end
doc = Nokogiri::XML('<svg width="100" height="100" />')
root = doc.xpath("//svg")[0]
group = add_node(root, "g", { transform: "translate(10 10)" })
20.times do |ii|
x = 10 + 10 * (ii % 5)
y = 10 + 10 * (ii / 5)
add_node(group, "circle", { cx: x, cy: y, r: 5 })
end
puts doc.to_xml
Paste the above into Kate and save as “grid.rb”. Then, in a terminal in the same directory:
$ ruby grid.rb
$ ruby grid.rb > grid.svg
Then open grid.svg in Inkscape to see what you got.
Ex 1
Modify grid.rb to draw a bullseye with N rings, where N is a variable that can be changed.
More stuff
Here are the official Nokogiri Tutorials .