All formats

Victor

LanguageRuby
LicenseMIT
Repositorygithub.com/DannyBen/victor
Documentationvictor.dannyb.co
Depends onnothing
Read / writeno / yes

Victor turns Ruby method calls into SVG elements: rect x: 0, y: 0, width: 100 becomes <rect x="0" y="0" width="100"/>. Any element name works, attribute names with underscores become dashes (stroke_width → stroke-width), and blocks nest elements. The result is plain SVG text you can save, embed in HTML or convert with another tool.

It’s small and has no dependencies. It doesn’t parse or render SVG; to rasterize the output use ruby-vips.

Installation#

Shell
gem install victor

Or in a Gemfile: gem "victor".

Basic usage: build and save an SVG#

Ruby
require "victor"

svg = Victor::SVG.new width: 200, height: 100, viewBox: "0 0 200 100"

svg.build do
  rect x: 0, y: 0, width: 200, height: 100, fill: "#eee"
  circle cx: 150, cy: 50, r: 40, fill: :orange, stroke: :black, stroke_width: 2
  text "Hello", x: 50, y: 55, text_anchor: "middle", font_family: "sans-serif"
end

svg.save "out"   # writes out.svg

How to nest groups and transforms#

Pass a block to any element to put children inside it:

Ruby
svg.build do
  g transform: "translate(10 10)", fill: "#4a90e2" do
    rect width: 80, height: 80, rx: 8
    circle cx: 120, cy: 40, r: 30
  end
  path d: %w[M 10 95 L 190 95], stroke: :gray
end

Arrays are joined with spaces, which is handy for path data and point lists.

How to add CSS styles#

Ruby
svg = Victor::SVG.new width: 200, height: 100
svg.css[".label"] = { font_family: "sans-serif", font_size: "14px", fill: :white }

svg.build do
  rect width: 200, height: 100, fill: "#333"
  text "Styled", x: 20, y: 55, class: "label"
end

The rules go into a <style> element at the top of the SVG.

How to get the SVG as a string#

Ruby
xml = svg.render                      # full document with <svg> root
inner = svg.to_s                      # only the elements, without the root
fragment = svg.render(template: :minimal)  # without xmlns, for inline SVG in HTML

How to combine SVG images#

Append one Victor SVG into another with <<:

Ruby
icon = Victor::SVG.new
icon.circle cx: 8, cy: 8, r: 6, fill: :red

page = Victor::SVG.new width: 300, height: 120
page.g(transform: "translate(20 20)") { page << icon }
page.save "combined.svg"

Tips#