Software Laboratory, Aoyama Gakuin University, Fuchinobe 5-10-1, Sagamihara, 229-8558 Japan
Corresponding author's email address: duerst@it.aoyama.ac.jpWe present a new framework and library, SVuGy1, for creating and manipulating SVG documents, written in the programming language Ruby. In the context of this framework, we explore the design space between declarative and procedural graphics.
Ruby is a purely object oriented scripting language created in Japan. It has gained a lot of popularity recently, in part due to Ruby on Rails, a Web application framework based on convention over configuration.
The motivations for SVuGy are twofold: Research into programming languages, computer graphics, and Web formats, and the easy and quick generation of graphics for lecture materials.
Declarative formats are preferable because they are easier to understand and manipulate, but generating data from programs offers more power and flexibility. Formats on and for the World Wide Web are continuously evolving from procedural scripts towards descriptive data formats.
Declarative formats are by nature domain-specific, and domain-specific languages (DSL) are usually external, i.e. independent of a programming language. However, Ruby makes it very easy to create internal DSLs, where a declarative syntax is part of a program so that access to the full programming language is always possible.
SVuGy takes full advantage of Ruby syntax. Semicolons can be omitted if the end of a statement coincides with the end of a line. Parentheses around method arguments can often be omitted. Methods take a code block as an argument, useful for grouping and for changing context.
A group with some styling, a rectangle, and a circle can be written as follows:
g {
fill yellow
stroke green
stroke_width 3
rect 50, 50, 150, 100
circle 250, 150, 75
}
Names above on the left are factory methods, creating objects and adding them to the group being created. The syntax above is nothing more than SVG rewritten with different punctuation. This is mostly an issue of taste, but we are taking great care to make SVuGy syntax as short, obvious, and unobtrusive as possible.
Using more features of the programming language, we quickly surpass the
level of a syntax alternative. Flexible parameter passing allows variation of
parameter combinations. Using a symbol for the id attribute, a
point object instead of two coordinates, and a string for the
title, the rectangle above can be written as
rect :myID, "a rectangle", point1, 150, 100
Using variables, objects can be stored and reused later. As an example, to position the center of the circle at the bottom right corner of the rectangle, we can write
r1 = rect ... circle r1.br, 75
The real benefit of an internal DSL appears when defining higher-level features. Starting with very simple objects such as boxes with text and arrows, more complex objects can first be explored by programming and then moved to a declarative syntax. This not only applies to graphic objects, but also to more abstract concepts such as layout schemes (alignment, repetition,...).
Here, the following features of Ruby turn out to be particularly useful:
This results in a fast development cycle on several levels: Recurring combinations of graphic objects and layouts are identified, programmed, and made available in a declarative syntax. Recurring programming patterns are identified and abstracted using metaprogramming.
Ruby/SVG is a small library for producing simple SVG. RVG is SVG-inspired but produces raster graphics. rcairo is a Ruby binding for cairo, which can output SVG. All use syntax that is considerably more verbose and less flexible than ours, and their main purpose is to serve as an API, rather than to write graphics by hand. APIs in other programming languages are likewise more verbose and less declarative because they cannot take advantage of Ruby's unique features. Programming languages specialized for 2D graphics, such as PenDraw, are severely limited in many ways.
We have tried to show how SVuGy, based on the scripting language Ruby, can integrate declarative and procedural approaches to graphics in a flexible way. This reduces the gap between procedural experimentation and declarative syntax, and supports a fast transition.
We feel that the synergy between SVG and Ruby and between declarative and procedural graphics exposed by SVuGy is only a start. Topics we plan to explore range from data integration to conversion to client-side scripts (e.g. for layout constraints), and from built-in validation to support for 3D-like graphics.
1 SVuGy is pronounced similar to sveegee, in a sweeping, dynamic way.