Skip to content

Instantly share code, notes, and snippets.

@bcardiff
Created January 11, 2013 17:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bcardiff/4512417 to your computer and use it in GitHub Desktop.
Save bcardiff/4512417 to your computer and use it in GitHub Desktop.
SVG Generator spike with same RVG API from RMagick. (output svg xml only)
require 'rexml/document'
class SVG
def initialize(width, height)
@doc = REXML::Document.new
@doc << REXML::XMLDecl.new
@svg = @doc.add_element 'svg'
@svg.add_attribute 'xmlns', 'http://www.w3.org/2000/svg'
@svg.add_attribute 'width', width
@svg.add_attribute 'height', height
@canvas = Node.new @svg.add_element 'g'
yield @canvas
end
def to_xml
@doc.to_s
end
class Node
def self.node_attribute(*attrs)
attrs.each do |attr|
self.class_eval %Q{
def #{attr}=(val)
xml_node.add_attribute '#{attr}', val
end
}
end
end
def self.style_attribute(*attrs)
attrs.each do |attr|
self.class_eval %Q{
def #{attr}=(val)
@styles[:#{attr}] = val
write_style
end
}
end
end
attr_reader :xml_node
node_attribute :x, :y, :width, :height, :d
style_attribute :background_fill_opacity, :background_fill
def initialize(xml_node)
@xml_node = xml_node
@styles = {}
@transform = ''
end
def styles(options)
@styles.merge! options
write_style
end
def translate(x, y)
@transform << "translate(#{x} #{y}) "
write_transform
yield self if block_given?
self
end
def scale(s)
@transform << "scale(#{s}) "
write_transform
yield self if block_given?
self
end
def g
res = Node.new xml_node.add_element 'g'
yield res if block_given?
res
end
def path(path)
res = Node.new xml_node.add_element 'path'
res.d = path
res
end
def text(x, y)
res = Node.new xml_node.add_element 'text'
res.x = x
res.y = y
yield res if block_given?
res
end
def tspan(text)
res = Node.new xml_node.add_element 'tspan'
res.xml_node.text = text
res
end
def rect(width, height, x, y)
res = Node.new xml_node.add_element 'rect'
res.x = x
res.y = y
res.width = width
res.height = height
res
end
private
def write_transform
@xml_node.add_attribute 'transform', @transform unless @transform.empty?
end
def write_style
style = (@styles.map { |key, value| "#{to_svg_style_name(key)}:#{value}" }).join(';')
@xml_node.add_attribute 'style', style unless style.empty?
end
def to_svg_style_name(options_name)
options_name.to_s.gsub '_', '-'
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment