1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
SVGJS_VERSION = '0.31'
# all available modules in the correct loading order
MODULES = %w[ svg regex default color array number viewbox bbox rbox element container fx event defs group arrange mask clip gradient use doc shape rect ellipse line poly path plotable image text textpath nested sugar set memory loader ]
# how many bytes in a "kilobyte"
KILO = 1024
# define default task
task :default => :dist
# module-aware file task
class BuildTask < Rake::FileTask
def modules
prerequisites.map { |f| File.basename(f, '.js') }
end
def remove_prerequisites to_remove
@prerequisites -= to_remove
return self
end
def needed?() super or modules_mismatch? end
def modules_mismatch?
previous_modules != modules
end
def previous_modules
first_line =~ / - ([\w,\s]+) - / && $1.split(/\W+/)
end
def first_line
File.open(name, 'r') { |f| f.gets }
end
end
BuildTask.define_task 'dist/svg.js' => MODULES.map {|m| "src/#{ m }.js" } do |task|
mkdir_p 'dist', :verbose => false
svgjs = ''
task.prerequisites.each do |src|
# bring in source files one by one, but without copyright info
copyright = true
File.open(src).each_line do |line|
copyright = false if copyright and line !~ %r{^(/|\s*$)}
svgjs << " #{ line }" unless copyright
end
svgjs << "\n\n"
end
File.open(task.name, 'w') do |file|
file.puts "/* svg.js %s - %s - svgjs.com/license */" % [version_string, task.modules.join(' ')]
file.puts ';(function() {'
file.puts "\n"
file.puts svgjs
file.puts '}).call(this);'
end
end
file 'dist/svg.min.js' => 'dist/svg.js' do |task|
require 'rubygems'
begin require 'uglifier'
rescue LoadError; fail "Uglifier not available: #{$!}"
else
File.open(task.name, 'w') do |min|
min << Uglifier.new.compile(File.read(task.prerequisites.first))
end
end
end
file 'dist/svg.min.gz' => 'dist/svg.min.js' do |task|
verbose false do
tmp_file = task.name.sub('.gz', '')
cp task.prerequisites.first, tmp_file
sh 'gzip', '--best', tmp_file
end
end
desc "Concatenate source files to build svg.js"
task :concat, [:modules] do |task, args|
modules = args[:modules].to_s.split(':')
toattrsdd, to_exclude = modules.partition {|m| m.sub!(/^(-)?(.+)/, 'src/\2.js'); !$1 }
Rake::Task['dist/svg.js'].
remove_prerequisites(to_exclude).enhance(toattrsdd).
invoke
end
desc "Generate svg.js distribution files and report size statistics"
task :dist => ['dist/svg.js', 'dist/svg.min.js', 'dist/svg.min.gz'] do |task|
orig_size, min_size, gz_size = task.prerequisites.map {|f| File.size(f) }
puts "Original version: %.3fk" % (orig_size.to_f / KILO)
puts "Minified: %.3fk" % (min_size.to_f / KILO)
puts "Minified and gzipped: %.3fk, compression factor %.3f" % [gz_size.to_f / KILO, orig_size.to_f / gz_size]
rm_f 'dist/svg.min.gz', :verbose => false
end
desc "List available modules"
task :modules do
Dir['src/**/*.js'].each do |file|
name = file.gsub(/^src\//,'').gsub(/.js$/,'')
puts name + (MODULES.include?(name) ? '*' : '')
end
puts "\n*included in default build"
end
task(:clean) { rm_rf 'dist' }
desc "Run tests with PhantomJS"
task :test do
sh 'script/test'
Rake::Task[:check_whitespace].invoke
end
desc "Strip trailing whitespace and ensure each file ends with a newline"
task :whitespace do
verbose false do
files = Dir['{src,test,examples}/**/*.{js,html}']
ruby(*%w'-p -i -e $_.sub!(/\s*\Z/,"\n")'.concat(files))
end
end
desc "Checks for trailing whitespace in source files and tests"
task :check_whitespace do
flunked = false
flunk = lambda {|file, num| flunked = true; puts "#{file}:#{num}" }
Dir['{src,test,examples}/**/*.{js,html}'].each do |file|
File.open(file, 'r') {|f| f.each_with_index {|ln, num| flunk.call(file, num + 1) if ln.chomp =~ /\s+$/ } }
end
fail if flunked
end
desc "Generate docco documentation from source files"
task :docco do
verbose false do
sh 'docco', *Dir['src/*.js']
end
end
# svg.js version number + git sha if available
def version_string
desc = `git describe --tags HEAD 2>&1`.chomp
if $?.success?
desc
else
suffix, dir = '', File.basename(Dir.pwd)
# detect git sha from directory name of GitHub zip/tarball
suffix = "-g#{$1}" if dir =~ /^wout-svg.js-([a-f0-9]{7,40})$/
SVGJS_VERSION + suffix
end
end
|