move project files from client's code; clean; package.
Johnathon Wright
committed Apr 10, 2011
commit 720df9f4aabdb1154e83aca6dcfe87c1a5e85a4c
Showing 14
changed files with
338 additions
and 0 deletions
README.markdown
+12
-0
| @@ | @@ -0,0 +1,12 @@ |
| + | Introducing Sketch |
| + | ==================== |
| + | |
| + | |
| + | Examples |
| + | ------- |
| + | |
| + | _basic syntax_ |
| + | |
| + | class Smile < Sketch::Base |
| + | |
| + | |
Rakefile
+29
-0
| @@ | @@ -0,0 +1,29 @@ |
| + | #!/usr/bin/env rake |
| + | |
| + | require 'rake' |
| + | require 'rake/testtask' |
| + | |
| + | PACKAGE = 'sketch' |
| + | |
| + | PKG_FILE_NAME = "#{PACKAGE}-#{VERSION}" |
| + | |
| + | desc "Run unit tests" |
| + | Rake::TestTask.new("test") { |t| |
| + | t.pattern = 'test/*_test.rb' |
| + | t.verbose = true |
| + | t.warning = true |
| + | } |
| + | |
| + | desc 'Generate HTML readme file' |
| + | task :readme do |
| + | `markdown README.markdown > README.html` |
| + | end |
| + | |
| + | desc 'clean temporary files, rdoc, and gem package' |
| + | task :clean => [:clobber_package, :clobber_rdoc] do |
| + | temp_filenames = File.join('**', '*.*~') |
| + | temp_files = Dir.glob(temp_filenames) |
| + | |
| + | File.delete(*temp_files) |
| + | end |
| + | |
SKETCH_VERSION
+1
-0
| @@ | @@ -0,0 +1 @@ |
| + | 0.1.0 |
examples/smile.rb
+24
-0
| @@ | @@ -0,0 +1,24 @@ |
| + | class Smile < Sketch::Base |
| + | |
| + | # def draw( canvas ) |
| + | # circle.new(:id => 'face', :cx => 200, :cy => 200, :r => 195, :fill => "yellow") |
| + | # ellipse(:id => 'left-eye', :center => [120, 150], :radius => [p18, 33], :fill => 'black') |
| + | # ellipse(:id => 'right-eye', :center => [280, 150], :radius => [18, 33], :fill => 'black') |
| + | # path(:id => 'mount', :stoke_width => '10', :stroke => 'black', :stroke_linecap => 'round') do |instructions| |
| + | # instructions.move_to 120, 280 |
| + | # instructions.q 200, 330 280,280 |
| + | # end |
| + | # end |
| + | |
| + | def draw( canvas ) |
| + | Circle.new(:id => 'face', :cx => 200, :cy => 200, :r => 195, :fill => "yellow").draw(canvas) |
| + | Sketch::Ellipse.new(:id => 'left-eye', :cx => 120, :cy => 150, :rx => 18, :ry => 33, :fill => 'black').draw(canvas) |
| + | Sketch::Ellipse.new(:id => 'right-eye', :cx => 280, :cy => 150, :rx => 18, :ry => 33, :fill => 'black').draw(canvas) |
| + | Sketch::Path.new(:id => 'mouth', :stroke_width => 10, :stroke => 'black', :fill => 'none', :stroke_linecap => 'round', :d => ['M120,280 Q200,330 280,280']).draw(canvas) |
| + | end |
| + | |
| + | end |
| + | |
| + | |
| + | |
| + | |
sketch/base.rb b/lib/sketch/base.rb
+39
-0
| @@ | @@ -0,0 +1,39 @@ |
| + | module Sketch |
| + | class Base < Valuable |
| + | |
| + | has_value :id |
| + | has_value :klass |
| + | |
| + | def to_svg( doc_atts = {} ) |
| + | svg_builder(doc_atts) do |canvas| |
| + | self.draw( canvas ) |
| + | end.to_xml |
| + | end |
| + | |
| + | def to_html( doc_atts = {} ) |
| + | svg_builder(doc_atts) do |canvas| |
| + | self.draw( canvas ) |
| + | end.doc.root |
| + | end |
| + | |
| + | def svg_attributes |
| + | out = {} |
| + | |
| + | #svg is heavy in dashes. Ruby symbols can't handle them. |
| + | attributes.each do |name, value| |
| + | out[name.to_s.gsub('_', '-')] = value |
| + | end |
| + | |
| + | out[:class] = out.delete(:klass) if out.has_key?(:klass) |
| + | |
| + | out |
| + | end |
| + | |
| + | private |
| + | |
| + | def svg_builder(atts) |
| + | Canvas.new( atts ).builder {|canvas| yield canvas} |
| + | end |
| + | end |
| + | end |
| + | |
sketch/canvas.rb b/lib/sketch/canvas.rb
+43
-0
| @@ | @@ -0,0 +1,43 @@ |
| + | module Sketch |
| + | class Canvas < Valuable |
| + | |
| + | has_value :doctype, :default => false |
| + | has_value :inline, :default => false |
| + | has_value :svg_version, :default => '1.1' |
| + | has_value :namespace_bindings, :default => [:svg, :xlink, :events] |
| + | |
| + | has_value :width, :default => 500 |
| + | has_value :height, :default => 300 |
| + | |
| + | def builder |
| + | Nokogiri::XML::Builder.new do |document| |
| + | render_doctype( document ) |
| + | document.svg( svg_attributes ) {|svg| yield svg if block_given?} |
| + | end |
| + | end |
| + | |
| + | def default_doctype |
| + | ['svg', "-//W3C//DTD SVG 1.0//EN", "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"] |
| + | end |
| + | |
| + | def render_doctype( document ) |
| + | self.doctype &&= self.default_doctype |
| + | |
| + | if( self.doctype ) |
| + | document.doc.create_internal_subset(*self.doctype) |
| + | end |
| + | end |
| + | |
| + | def svg_attributes |
| + | { |
| + | 'width' => width, |
| + | 'height' => height, |
| + | 'version' => svg_version, |
| + | 'xmlns' => 'http://www.w3.org/2000/svg', |
| + | 'xmlns:ev' => 'http://www.w3.org/2001/xml-events', |
| + | 'xmlns:xlink' => 'http://www.w3.org/1999/xlink', |
| + | } |
| + | end |
| + | |
| + | end |
| + | end |
sketch/circle.rb b/lib/sketch/circle.rb
+16
-0
| @@ | @@ -0,0 +1,16 @@ |
| + | module Sketch |
| + | class Circle < Base |
| + | |
| + | has_value :cx |
| + | has_value :cy |
| + | has_value :r, :alias => :radius |
| + | has_value :fill |
| + | has_value :stroke |
| + | has_value :stroke_width |
| + | |
| + | def draw(canvas) |
| + | canvas.circle(:cx => self.cx, :cy => self.cy, :r => self.radius, :fill => self.fill, :stroke => self.stroke, 'stroke_width' => self.stroke_width) |
| + | end |
| + | end |
| + | end |
| + | |
sketch/ellipse.rb b/lib/sketch/ellipse.rb
+19
-0
| @@ | @@ -0,0 +1,19 @@ |
| + | module Sketch |
| + | class Ellipse < Base |
| + | |
| + | has_value :cx |
| + | has_value :cy |
| + | has_value :rx |
| + | has_value :ry |
| + | has_value :radius |
| + | has_value :fill |
| + | has_value :stroke |
| + | has_value :stroke_width |
| + | |
| + | def draw(canvas) |
| + | canvas.ellipse( svg_attributes ) |
| + | end |
| + | |
| + | end |
| + | end |
| + | |
sketch/path.rb b/lib/sketch/path.rb
+20
-0
| @@ | @@ -0,0 +1,20 @@ |
| + | module Sketch |
| + | class Path < Base |
| + | |
| + | has_value :fill, :default => 'none' |
| + | has_value :stroke, :default => 'black' |
| + | has_value :stroke_width, :default => 1 |
| + | has_value :stroke_linecap |
| + | has_value :d, :alias => 'commands', :default => [] |
| + | |
| + | def draw(canvas) |
| + | canvas.path(svg_attributes) |
| + | end |
| + | |
| + | def svg_attributes |
| + | super.merge(:d => self.commands.join(' ')) |
| + | end |
| + | |
| + | end |
| + | end |
| + | |
sketch.gemspec
+22
-0
| @@ | @@ -0,0 +1,22 @@ |
| + | version = File.read(File.expand_path("../SKETCH_VERSION",__FILE__)).strip |
| + | require 'rubygems' |
| + | |
| + | require 'rake' |
| + | |
| + | spec = Gem::Specification.new do |s| |
| + | s.name = 'sketch' |
| + | s.version = version |
| + | s.platform = 'Gem::Platform::Ruby' |
| + | s.summary = "build SVG images" |
| + | s.description = "build SVG images" |
| + | s.require_path = 'lib' |
| + | s.files = FileList['lib/**/*.rb', '[A-Z]*', 'examples/**/*', 'test/**/*'].to_a |
| + | s.add_dependency('valuable') |
| + | |
| + | s.license = 'MIT' |
| + | |
| + | s.author = "Johnathon Wright0" |
| + | s.email = "jw@mustmodify.com" |
| + | s.homepage = "http://sketch.mustmodify.com/" |
| + | end |
| + | |
test/base_test.rb
+25
-0
| @@ | @@ -0,0 +1,25 @@ |
| + | #prerequisites |
| + | require 'rubygems' |
| + | require 'test/unit' |
| + | require 'nokogiri' |
| + | require 'valuable' |
| + | |
| + | # require file being tested |
| + | $: << File.expand_path(File.dirname(__FILE__) + '/../lib/sketch') |
| + | require 'base.rb' |
| + | require 'canvas.rb' |
| + | |
| + | class EmptySquare < Sketch::Base |
| + | def draw(canvas) |
| + | canvas.rect('x' => 50, 'y' => 20, 'width' => 10, 'height' => 20) |
| + | end |
| + | end |
| + | |
| + | class BaseTest < Test::Unit::TestCase |
| + | |
| + | def test_that_nodes_are_added_to_the_canvas |
| + | assert_equal 1, Nokogiri::XML(EmptySquare.new.to_svg).css('rect[x="50"][y="20"][width="10"][height="20"]').size |
| + | end |
| + | |
| + | end |
| + | |
test/canvas_test.rb
+24
-0
| @@ | @@ -0,0 +1,24 @@ |
| + | #prerequisites |
| + | require 'rubygems' |
| + | require 'test/unit' |
| + | require 'nokogiri' |
| + | require 'valuable' |
| + | |
| + | # require file being tested |
| + | $: << File.expand_path(File.dirname(__FILE__) + '/../lib/sketch') |
| + | require 'canvas.rb' |
| + | |
| + | class CanvasTest < Test::Unit::TestCase |
| + | |
| + | def test_that_width_is_configurable |
| + | art = Sketch::Canvas.new(:width => 350).builder.to_xml |
| + | assert_equal 1, Nokogiri::XML(art).css('svg[width="350"]').size |
| + | end |
| + | |
| + | def test_that_height_is_configurable |
| + | art = Sketch::Canvas.new(:height => 450).builder.to_xml |
| + | assert_equal 1, Nokogiri::XML(art).css('svg[height="450"]').size |
| + | end |
| + | |
| + | end |
| + | |
test/doctype_test.rb
+34
-0
| @@ | @@ -0,0 +1,34 @@ |
| + | #prerequisites |
| + | require 'rubygems' |
| + | require 'nokogiri' |
| + | require 'valuable' |
| + | |
| + | # require file being tested |
| + | $: << File.expand_path(File.dirname(__FILE__) + '/../lib/sketch') |
| + | require 'canvas.rb' |
| + | require 'base.rb' |
| + | |
| + | class Minimalist < Sketch::Base |
| + | def draw( canvas ) |
| + | end |
| + | end |
| + | |
| + | class DoctypeTest < Test::Unit::TestCase |
| + | |
| + | def test_that_doctype_is_off_by_default |
| + | assert_equal false, Sketch::Canvas.new.doctype |
| + | end |
| + | |
| + | def test_that_it_does_not_include_doctype_by_default |
| + | # https://jwatt.org/svg/authoring/#doctype-declaration |
| + | artwork = Minimalist.new.to_svg |
| + | assert_no_match(/doctype/i, artwork) |
| + | end |
| + | |
| + | def test_that_it_includes_doctype_when_configured |
| + | artwork = Minimalist.new.to_svg(:doctype => true) |
| + | assert_match(/doctype/i, artwork) |
| + | end |
| + | |
| + | end |
| + | |
test/svg_namespace_test.rb
+30
-0
| @@ | @@ -0,0 +1,30 @@ |
| + | #prerequisites |
| + | require 'nokogiri' |
| + | require 'valuable' |
| + | |
| + | # require file being tested |
| + | $: << File.expand_path(File.dirname(__FILE__) + '/../lib/sketch') |
| + | require 'canvas.rb' |
| + | require 'base.rb' |
| + | |
| + | class Minimalist < Sketch::Base |
| + | def draw( canvas ) |
| + | end |
| + | end |
| + | |
| + | class DoctypeTest < Test::Unit::TestCase |
| + | |
| + | def test_that_it_adds_namespace_binds_by_default |
| + | # https://jwatt.org/svg/authoring/#doctype-declaration |
| + | artwork = Minimalist.new.to_svg |
| + | svgns = %r(xmlns="http://www.w3.org/2000/svg") |
| + | xmlns = %r(xmlns:xlink="http://www.w3.org/1999/xlink") |
| + | xlinkns = %r(xmlns:ev="http://www.w3.org/2001/xml-events") |
| + | |
| + | assert_match svgns, artwork |
| + | assert_match xmlns, artwork |
| + | assert_match xlinkns, artwork |
| + | end |
| + | |
| + | end |
| + | |