SVuGy: SVG と Ruby で遊ぼう

SVuGy: Fun with SVG and Ruby

Ruby Kaigi 2008, Tsukuba, 2008/6/22

Martin J. DÜRST

Aoyama Gakuin University

http://www.sw.it.aoyama.ac.jp/SVuGy/RubyKaigi2008Presentation.html

AGU

© 2008 Martin J. Dürst, Aoyama Gakuin University

Overview

[see Collophon for how to view best]

What is SVuGy?

Ruby DSL for SVG

SVG + Ruby = SVuGy

Pronounced SVeeGee ( スゥィージー)

Versions

What is SVG

SVG Example

<rect x='100' y='200'
    width='50' height='30'/>

SVuGy Goals

Practical: Create simple diagrams for lectures

Research: Study procedural → declarative transition (see SVGopen2007 paper)

Side-effect:
Ruby metaprogramming and DSL experience

Source for student projects

Why Programming?

Graphics editors available, e.g. Inkscape, Adobe Illustrator,...

But:

Why SVuGy?

A rectangle in SVG:

<rect x='100' y='200' width='50' height='30'/>

Wouldn't you sometimes want to write this like:

rect 100, 200, 50, 30

With SVuGy, you can!

SVuGy Basic Shapes

rect 100, 200, 30, 50
circle 300, 300, 50
ellipse 400, 500, 20, 60
polygon 100, 100, 20, 100, 20, 20, 100, 20
text 'Hello SVuGy!', 50, 40

And so on...

More SVuGy

Grouping:

g {
  # group content
}

Anchors:

a 'IRI' {
  # link content
}

Implementation Basics

Metaprogramming:
Too Much Is Not Enough?

Looking for every way to make coding shorter and easier!

SVuGy Styling

Syntax variants:

  1. Style hash: rect(0, 0, 200, 200).
    style(:fill => :red)
  2. Style block: rect(0, 0, 200, 200) {
    style { fill :red } }
  3. Property method: rect(0, 0, 200, 200).
    fill(:red)
  4. Property constructor: rect(0, 0, 200,
    200) { fill :red }

Everything is Missing

(miss?)using method_missing

Example before: style(:fill => :red)
(or style(fill: :red) for 1.9)

Example after: fill red

Missing Variables

Before:

r = rect 100, 200, 30, 50
line r.tl, r.br

After:

rect :r 100, 200, 30, 50
line r.tl, r.br

Symbol is SVG id; scope is SVG document!

Argument Parsing

rect 100, 200, 30, 50
rect 30, 50
rect :id 100, 200, 30, 50
rect point, 30, 50
...

Semi-manually coded, function based on class

High-end automatic solution half complete

method_chained?

Return value and block use depending on chaining

my_style = style(fill: :red,
    stroke: :green) { }
my_group = g.style(...) { }

Ideal solution:

if method_chained?
  ...

Current hack !?

(one variant)

if block_given?
  if @chained then
    @chained = false
    instance_eval(&block)
    @chained = true
  else
    warn "Block on style, ignored"
  end
end

Beyond SVG: More Objects

Composite objects introduced on a by-need base

An Example: Rotated Text

(one class, one method, three lines of actual code)

New in 0.4

Further Work

Please try out SVuGy and send feedback!

Demo

[if time permits]

Further Reading

SVuGy Home Page (http://www.sw.it.aoyama.ac.jp/SVuGy)

SVuGy - Exploring the Space between Procedural and Declarative Graphics, Martin J. Dürst, Makoto Fujimori, Takeshi Maemura, Tohru Koga, Kazunari Ito, Proc. SVG Open 2007, Tokyo, Japan, Sept. 2007. [presentation]

Collophon

or how these slides were produced,
and how they are best viewed