• Stars
    star
    334
  • Rank 121,647 (Top 3 %)
  • Language
    Ruby
  • License
    MIT License
  • Created almost 8 years ago
  • Updated 9 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Ruby SVG Image Builder

Victor

Victor - Ruby SVG Image Builder

Gem Version Build Status Maintainability


Victor is a direct Ruby-to-SVG builder. All method calls are converted directly to SVG elements.

Demo


Table of Contents


Install

$ gem install victor

Or with bundler:

gem 'victor'

Examples

require 'victor'

svg = Victor::SVG.new width: 140, height: 100, style: { background: '#ddd' }

svg.build do 
  rect x: 10, y: 10, width: 120, height: 80, rx: 10, fill: '#666'
  
  circle cx: 50, cy: 50, r: 30, fill: 'yellow'
  circle cx: 58, cy: 32, r: 4, fill: 'black'
  polygon points: %w[45,50 80,30 80,70], fill: '#666'

  3.times do |i|
    x = 80 + i*18
    circle cx: x, cy: 50, r: 4, fill: 'yellow'
  end
end

svg.save 'pacman'

Output:

pacman

See the examples folder for several ruby scripts and their SVG output.

Usage

Initialize your SVG image:

require 'victor'
svg = Victor::SVG.new

Any option you provide to SVG.new will be added as an attribute to the main <svg> element. By default, height and width are set to 100%.

svg = Victor::SVG.new width: '100%', height: '100%'
# same as just Victor::SVG.new

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

As an alternative, you can set the root SVG attributes using the setup method:

require 'victor'
svg = Victor::SVG.new
svg.setup width: 200, height: 150

Victor uses a single method (element) to generate all SVG elements:

svg.element :rect, x: 2, y: 2, width: 200, height: 200
# => <rect x="2" y="2" width="200" height="200"/>

But you can omit it. Calls to any other method, will be delegated to the element method, so normal usage looks more like this:

svg.rect x: 2, y: 2, width: 200, height: 200
# => <rect x="2" y="2" width="200" height="200"/>

In other words, these are the same:

svg.element :anything, option: 'value'
svg.anything option: 'value'

You can use the build method, to generate the SVG with a block

svg.build do 
  rect x: 0, y: 0, width: 100, height: 100, fill: '#ccc'
  rect x: 20, y: 20, width: 60, height: 60, fill: '#f99'
end

If the value of an attribute is a hash, it will be converted to a style-compatible string:

svg.rect x: 0, y: 0, width: 100, height: 100, style: { stroke: '#ccc', fill: 'red' }
# => <rect x=0 y=0 width=100 height=100 style="stroke:#ccc; fill:red"/>

If the value of an attribute is an array, it will be converted to a space delimited string:

svg.path d: ['M', 150, 0, 'L', 75, 200, 'L', 225, 200, 'Z']
# => <path d="M 150 0 L 75 200 L 225 200 Z"/>

For SVG elements that have an inner content - such as text - simply pass it as the first argument:

svg.text "Victor", x: 40, y: 50
# => <text x="40" y="50">Victor</text>

You can also nest elements with blocks:

svg.build do
  g font_size: 30, font_family: 'arial', fill: 'white' do
    text "Scalable Victor Graphics", x: 40, y: 50
  end
end
# => <g font-size="30" font-family="arial" fill="white">
#      <text x="40" y="50">Scalable Victor Graphics</text>
#    </g>

Underscores in attribute names are converted to dashes:

svg.text "Victor", x: 40, y: 50, font_family: 'arial', font_weight: 'bold', font_size: 40
# => <text x="40" y="50" font-family="arial" font-weight="bold" font-size="40">
#      Victor
#    </text>

Features

Composite SVG

Victor also supports the ability to combine several smaller SVG objects into one using the << operator or the #append method.

This operator expects to receive any object that responds to #to_s (can be another SVG object).

require 'victor'
include Victor

# Create a reusable SVG object
frame = SVG.new
frame.rect x: 0, y: 0, width: 100, height: 100, fill: '#336'
frame.rect x: 10, y: 10, width: 80, height: 80, fill: '#fff'

# ... and another
troll = SVG.new
troll.circle cx: 50, cy: 60, r: 24, fill: 'yellow'
troll.polygon points: %w[24,50 50,14 76,54], fill: 'red'

# Combine objects into a single image
svg = SVG.new viewBox: '0 0 100 100'
svg << frame
svg << troll

# ... and save it
svg.save 'framed-troll'

Output:

troll

These two calls are identical:

svg << other
svg.append other

To make this common use case a little easier to use, you can use a block when instantiating a new SVG object:

troll = SVG.new do
  circle cx: 50, cy: 60, r: 24, fill: 'yellow'
end

Which is the same as:

troll = SVG.new
troll.build do
  circle cx: 50, cy: 60, r: 24, fill: 'yellow'
end

Another approach to a more modular SVG composition, would be to subclass Victor::SVG.

See the composite svg example or the subclassing example for more details.

Saving the Output

Generate the full SVG to a string with render:

result = svg.render

Or, save it to a file with save:

svg.save 'filename'
# the '.svg' extension is optional

SVG Templates

The :default SVG template is designed to be a full XML document (i.e., a standalone SVG image). If you wish to use the output as an SVG element inside HTML, you can change the SVG template:

svg = Victor::SVG.new template: :html 
# accepts :html, :minimal, :default or a filename

You can also point it to any other template file:

svg = Victor::SVG.new template: 'path/to/template.svg'

See the templates folder for an understanding of how templates are structured.

Templates can also be provided when rendering or saving the output:

svg.save 'filename', template: :minimal
svg.render template: :minimal

CSS

CSS gets a special treatment in Victor::SVG, with these objectives in mind:

  • Hide implementation details (such as the need for a CDATA marker)
  • Provide a DSL-like syntax for CSS rules

The Victor::SVG objects has a css property, which can contain either a Hash or a String:

svg = Victor::SVG.new

svg.css = css_hash_or_string
# or without the equal sign:
svg.css css_hash_or_string

svg.build do
  # ...
end

This flexibility allows you to apply CSS in multiple ways. Below are some examples.

Assigning CSS rules using the hash syntax

svg = Victor::SVG.new

svg.build do 
  css['.main'] = {
    stroke: "green", 
    stroke_width: 2,
    fill: "yellow"
  }

  circle cx: 35, cy: 35, r: 20, class: 'main'
end

Assigning a full hash to the CSS property

svg.css = {
  '.bar': {
    fill: '#666',
    stroke: '#fff',
    stroke_width: 1
  },
  '.negative': {
    fill: '#f66'
  },
  '.positive': {
    fill: '#6f6'
  }
}

Underscore characters will be converted to dashes (stroke_width becomes stroke-width).

Importing CSS from an external file

svg.css = File.read 'styles.css'

CSS @import directives

If you need to add CSS statements , like @import, use the following syntax:

css['@import'] = [
  "url('https://fonts.googleapis.com/css?family=Audiowide')",
  "url('https://fonts.googleapis.com/css?family=Pacifico')"
]

This is achieved thanks to the fact that when Victor encounters an array in the CSS hash, it will prefix each of the array elements with the hash key, so the above will result in two @import url(...) rows.

See the css example, css string example, or the custom fonts example.

Tagless Elements

Using underscore (_) as the element name will simply add the value to the generated SVG, without any surrounding element. This is designed to allow generating something like this:

<text>
  You are
  <tspan font-weight="bold">not</tspan>
  a banana
</text>

using this Ruby code:

svg.build do 
  text do
    _ 'You are'
    tspan 'not', font_weight: "bold"
    _ 'a banana'
  end
end

See the tagless elements example.

XML Encoding

Plain text values are encoded automatically:

svg.build do
  text "Ben & Jerry's"
end
# <text>Ben &amp; Jerry's</text>

If you need to use the raw, unencoded string, add ! to the element's name:

svg.build do
  text! "Ben & Jerry's"
end
# <text>Ben & Jerry's</text>

See the xml encoding example.

XML Newlines

By default, the generated SVGs will have a newline glue between the elements. You can change this (for example, to an empty string) if the default newlines are not appropriate for your use case.

svg = Victor::SVG.new glue: ''

The glue can also be provided when rendering or saving the output:

svg.save 'filename', glue: ''
svg.render glue: ''

DSL Syntax

Victor also supports a DSL-like syntax. To use it, simply require 'victor/script'.

Once required, you have access to:

  • svg - returns an instance of Victor::SVG
  • All the methods that are available on the SVG object, are included at the root level.

For example:

require 'victor/script'

setup width: 100, height: 100

build do
  circle cx: 50, cy: 50, r: 30, fill: "yellow"
end

puts render
save 'output.svg'

See the dsl example.

Using with Rails

See the example_rails folder.

Related Projects

Victor CLI

A command line utility that allows converting Ruby to SVG as well as SVG to Victor Ruby scripts.

Victor Opal

A Victor playground that works in the browser.

Minichart

A Ruby gem that uses Victor to generate SVG charts

Minichart

Icodi

A Ruby gem that uses Victor to generate consistent random icon images, similar to GitHub's identicon.

Icodi

Contributing / Support

If you experience any issue, have a question or a suggestion, or if you wish to contribute, feel free to open an issue.


More Repositories

1

bashly

Bash command line framework and CLI generator
Ruby
1,902
star
2

FlicFlac

Tiny portable audio converter for Windows (WAV FLAC MP3 OGG APE M4A AAC)
AutoHotkey
212
star
3

madness

Instant Markdown Server
Ruby
85
star
4

completely

Generate bash completion scripts using a simple configuration file
Ruby
81
star
5

alf

Bash Alias Generator and Manager
Shell
70
star
6

Gridy

Snap Windows to Grid
AutoHotkey
61
star
7

php-quandl

Easy access to the Quandl Data API using PHP
PHP
54
star
8

snapcrawl

Crawl a website and take screenshots
Ruby
52
star
9

kojo

Command line utility for generating config files from templates and definition files
Ruby
51
star
10

lightly

Ruby file cache for performing heavy tasks, lightly.
Ruby
38
star
11

icodi

Deterministic Random SVG Icon Generator
Ruby
30
star
12

rush-cli

Personal Package Manager - run your GitHub hosted scripts, locally.
Shell
29
star
13

runfile

Command line for your projects
Ruby
28
star
14

secret_hub

Manage GitHub secrets with support for bulk operations and organization secrets
Ruby
25
star
15

minichart

Create SVG mini charts with Ruby
Ruby
24
star
16

approvals.bash

Bash Interactive Approval Testing
Shell
19
star
17

webcache

Hassle-free caching for HTTP download with ruby
Ruby
16
star
18

pretty_trace

Love Your Ruby's Backtrace
Ruby
16
star
19

quandl

Go library for accessing Quandl API
Go
15
star
20

opcode

Local Command Shortcuts
Shell
14
star
21

pundit_extra

Extensions and helpers for Pundit
Ruby
14
star
22

fuzzycd

Change directories with fuzzy search
Shell
14
star
23

docker-madness

Docker Image for the Madness Markdown Server
Ruby
14
star
24

docker-borg-client

Borg Backup Client Docker on Alpine
Dockerfile
7
star
25

menu_commander

Create menus for any command line tool using simple YAML configuration
Ruby
6
star
26

concode

Generate consistent-codenames from any string (Heroku style, aka Haiku).
Ruby
6
star
27

rush-repo

My package repository for the Rush package manager
Shell
6
star
28

gondl

Command line console for Quandl
Go
6
star
29

eclipse

Encrypt / Decrypt any text with a simple hotkey
AutoHotkey
6
star
30

git-changelog

Create a changelog from your git repository
Shell
6
star
31

extended_yaml

Ruby YAML with support for including and merging additional YAML files
Ruby
5
star
32

jobly

Compact job server with API, CLI, Web UI and a Sidekiq heart
Ruby
5
star
33

victor-cli

Command line for Victor, the Ruby SVG library
Ruby
5
star
34

apicake

Build Dynamic API Wrappers
Ruby
5
star
35

filecache

Go File Cache
Go
5
star
36

recode

Command line refactoring utility
Ruby
5
star
37

fredric

Federal Reserve Economic Data (FRED) API Library and Command Line
Ruby
5
star
38

github-redirector

Source code for get.dannyb.co
Ruby
4
star
39

alf-conf

My alf config
Shell
4
star
40

docker-alpine-ruby

Minimal Ruby docker image with native extensions support
Dockerfile
4
star
41

shell-action-example

Run GitHub-hosted shell scripts inside GitHub Actions
Shell
4
star
42

sting

Minimal, lightweight, multi-YAML settings library
Ruby
4
star
43

WallpaperRandomizer

System Tray Wallpaper Changer
AutoHotkey
4
star
44

rigit

Scaffolding that doesn't bite
Ruby
4
star
45

bobkit

Site Generation Toolkit with Slim, SCSS, CoffeeScript and Markdown
Ruby
4
star
46

slacktail

Command line utility for following your Slack chat from the terminal
Ruby
4
star
47

erbx

ERB Extended with Pretty Tags
Ruby
4
star
48

madman

The Markdown Swiss Army Knife
Ruby
3
star
49

loadrunner

GitHub Webhook Server and Event Simulator
Ruby
3
star
50

audio_addict

AudioAddict Command Line for Voting and Playlist Management
Ruby
3
star
51

experiments

GitHub Experiments
3
star
52

docker-snapcrawl

Crawl a website and take screenshots (Docker version)
Dockerfile
3
star
53

my-github

Comprehensive index of my open source projects on GitHub
HTML
3
star
54

bashly-book

Source for bashly.dannyb.co
Shell
3
star
55

docker-sshd

Alpine SSH Client and Server
Shell
3
star
56

colsole

Utility functions for colorful console applications with Ruby
Ruby
3
star
57

rspec_approvals

Interactive Approval Testing for RSpec
Ruby
3
star
58

requires

Require all files in a directory
Ruby
3
star
59

redirectly

Redirect server with dynamic URL and hostname support
Ruby
3
star
60

mister_bin

Build modular command line tools
Ruby
3
star
61

docker-mdbook

Docker with mdbook
Dockerfile
2
star
62

voicemaker

Create Text to Speech files with the Voicemaker API from Ruby or the command line
Ruby
2
star
63

bootstrap

My personal Ubuntu bootstrap metascript
Shell
2
star
64

echo-webserver

A web server that echoes the request back
Ruby
2
star
65

httpme

Static files web server with basic authentication
Ruby
2
star
66

clipper

Pure Command Line Arguments Parser
Crystal
2
star
67

docker-ruby-python

Docker Alpine with Ruby and Python 2+3
Dockerfile
2
star
68

getcomments

Extract Comments from Ruby Code
Ruby
2
star
69

eod

EOD Historical Data API Library and Command Line
Ruby
2
star
70

TinySpeech

Portable system tray utility for Windows that adds a global hotkey for speaking any selected text using the default (SAPI) Windows Text-to-Speech.
AutoIt
2
star
71

docker-alpine-mongo

Docker Alpine MongoDB Image
Dockerfile
2
star
72

docker-alpine-php

Docker PHP CLI Image based on Alpine
Dockerfile
2
star
73

colorly

Command Line Color Palette Generator
Ruby
2
star
74

sector-seven-builder

Static site generator for sector-seven.com
SCSS
2
star
75

docker-rush-sandbox

Docker sandbox for experimenting with Rush CLI
Dockerfile
2
star
76

stress-server

Docker image for simulating server resource stress
Ruby
1
star
77

super_docopt

docopt-based command line utility builder
Ruby
1
star
78

intrinio

Library and command line interface for Intrinio data API
Ruby
1
star
79

hash_cabinet

File-based, key-object store with hash-like access.
Ruby
1
star
80

docker-alpine-ruby-mongo

Docker image with ruby and mongo tools based on Alpine
Dockerfile
1
star
81

clicumber

Cucumber step definitions for testing command line applications
Ruby
1
star
82

action-test

Testing the authoring process of GitHub actions
Shell
1
star
83

docker-redirector

HTTP Redirector Docker Image
Ruby
1
star
84

docker-zsh

ZSH on Alpine for testing ZSH related scripts
Shell
1
star
85

pobject

Automatically persist objects to disk as YAML files
Ruby
1
star
86

docker-ruby-php

Alpine image with Ruby and PHP CLI
Dockerfile
1
star
87

respec

RSpec Convenience Wrapper
Shell
1
star
88

docker-gotty

Docker image with Browser Based Linux Terminal
Dockerfile
1
star
89

sasstool

Sass (SassC) command line renderer with globbing import support.
Ruby
1
star
90

dcind

Docker Compose in Docker
Dockerfile
1
star
91

bashly-support

Support code snippets for bashly
Shell
1
star
92

docker-whoami

Whoami Debug Webserver Docker Image
Dockerfile
1
star
93

actions-debug

Debug GitHub Actions workflow configuration
Ruby
1
star
94

docker-nikto

Nikto vulnerability scanner docker image
Shell
1
star
95

docker-fallback

Default Ingress Backend
Ruby
1
star
96

yamlcon

YAML Configuration File Loader
Ruby
1
star
97

example-rig

Sample rigit rig
1
star
98

favicon.sh

Favicon generator
Shell
1
star
99

node-jsoncache

A Node.js module for caching JSON objects and raw data
JavaScript
1
star
100

docker-alpine-crystal

Docker Alpine Crystal Image
Dockerfile
1
star