svgplot 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f323e9da91bcaf8ebcd7cd305a32004217aac217
4
- data.tar.gz: 3f9798e086362b17e653b3d4c334b82a0691b562
3
+ metadata.gz: e18768c73ada9428946371059e71d7d74b3748bd
4
+ data.tar.gz: d035ac8e2786d63be01c412004e72c280ea51d14
5
5
  SHA512:
6
- metadata.gz: 778f70e09d43817954b4073dacd64bc94655347f1ee01c91529c8a45ec23a0050c166da9f53554f1ad3d1218a547424307d15a9dab3207fe4863cacedd50cb2c
7
- data.tar.gz: b6cbe8c7f435de1594308ce2b3fa5e8b0596e49450311ede165c50ab386123b5c7f28b268e4c24684d97b233f4925c83409eb67537e0b46a07284ae7341977d2
6
+ metadata.gz: 871812ba7324ffcd641f1ff6acfe90c876c63ee12b5c33f19b499ad3cd5334897acbdc4459258ad3f9f63dc6db51a04c4901fe4eaa565c4eb12283d5799b84f9
7
+ data.tar.gz: a993173c4902c88ac7a0b821a72c68198b7857b5bf34b209875bd43b5263a643d694337483f806d22a235081f6c4ee6b38a5bef3f43a2cf650b4d7b0de8416cf
@@ -1,6 +1,8 @@
1
1
  language: ruby
2
2
  cache: bundler
3
3
  rvm:
4
+ - 2.1.2
5
+ - 2.1.1
4
6
  - 2.1.0
5
7
  - 2.0.0
6
8
  - 1.9.3
data/Rakefile CHANGED
@@ -6,8 +6,8 @@ desc 'Run tests'
6
6
  RSpec::Core::RakeTask.new(:spec)
7
7
 
8
8
  desc 'Run Rubocop on the gem'
9
- Rubocop::RakeTask.new(:rubocop) do |task|
10
- task.patterns = ['lib/**/*.rb', 'spec/**/*.rb', 'dev/**/*.rb']
9
+ RuboCop::RakeTask.new(:rubocop) do |task|
10
+ task.patterns = ['lib/**/*.rb', 'spec/**/*.rb', 'dev/**/*.rb', 'bin/*']
11
11
  task.fail_on_error = true
12
12
  end
13
13
 
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'svgplot'
4
+
5
+ exit SVGPlot::Application.run!(*ARGV)
@@ -35,7 +35,7 @@ Nokogiri::HTML(open(version_url + 'eltindex.html')).css('li').each do |li|
35
35
  end
36
36
  puts
37
37
 
38
- xmlns = %w(svg cc dc rdf inkscape xlink].map! { |e| ('xmlns:' + e).to_sym )
38
+ xmlns = %w(svg cc dc rdf inkscape xlink).map! { |e| ('xmlns:' + e).to_sym }
39
39
  structure[:svg][:attributes].push(:xmlns, *xmlns)
40
40
 
41
41
  skipped_cops = %w(SpaceAroundOperators SpaceInsideHashLiteralBraces HashSyntax)
@@ -2,19 +2,16 @@
2
2
  # SVG generation module
3
3
  module SVGPlot
4
4
  class << self
5
- ##
6
- # Add .new() helper for creating a new Plot object
5
+ ##
6
+ # Add .new() helper for creating a new Plot object
7
7
 
8
- def new(*args)
9
- self::Plot.new(*args)
8
+ def new(*args, &block)
9
+ self::Plot.new(*args, &block)
10
10
  end
11
11
  end
12
-
13
- ##
14
- # Plot object (represents an SVG image)
15
- class Plot
16
- end
17
12
  end
18
13
 
19
14
  require 'svgplot/spec'
15
+ require 'svgplot/application'
20
16
  require 'svgplot/meta'
17
+ require 'svgplot/plot'
@@ -0,0 +1,32 @@
1
+ module SVGPlot
2
+ ##
3
+ # Application object for running .svgplot files
4
+ class Application
5
+ def initialize(*args)
6
+ @files = args.empty? ? Dir.glob(File.expand_path('*.svgplot')) : args
7
+ fail('No input files') if @files.empty?
8
+ end
9
+
10
+ def run!
11
+ @files.each do |file|
12
+ output = file.sub(/\.svgplot/, '') + '.svg'
13
+ File.open(output, 'w') do |fh|
14
+ build file, fh
15
+ end
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def build(file, fh)
22
+ SVGPlot::Plot.new({ width: '100%', height: '100%' }, fh) do
23
+ begin
24
+ instance_eval File.read(file), file
25
+ rescue StandardError => e
26
+ backtrace = e.backtrace.grep(Regexp.new(File.expand_path(file)))
27
+ raise e.class, e.message, backtrace
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -41,16 +41,6 @@ SVGPlot::SVG_EXPANSION = {
41
41
  end
42
42
  }
43
43
 
44
- SVGPlot::SVG_DEFAULTS = {
45
- text: { fill: 'black' },
46
- line: { stroke: 'black' },
47
- rect: { stroke: 'black' },
48
- circle: { stroke: 'black' },
49
- ellipse: { stroke: 'black' },
50
- polygon: { stroke: 'black' },
51
- polyline: { stroke: 'black' }
52
- }
53
-
54
44
  # TODO: move to documentation?
55
45
  SVGPlot::SVG_TRANSFORM = [
56
46
  :matrix, # expects an array of 6 elements
@@ -67,5 +57,9 @@ SVGPlot::CSS_STYLE = [
67
57
  :stroke,
68
58
  :fill_opacity,
69
59
  :stroke_opacity,
70
- :opacity
60
+ :opacity,
61
+ :'text-align',
62
+ :font,
63
+ :'white-space',
64
+ :display
71
65
  ]
@@ -0,0 +1,636 @@
1
+ # rubocop:disable all
2
+ module SVGPlot
3
+ class SVGTag
4
+ attr_reader :tag, :attributes, :children
5
+
6
+ def initialize(tag, attributes={}, &block)
7
+ @tag = validate_tag(tag)
8
+ @attributes = validate_attributes(attributes)
9
+ @children = []
10
+
11
+ if block
12
+ instance_exec &block
13
+ end
14
+ end
15
+
16
+ ##
17
+ # Provide methods for SVG transformations
18
+ ##
19
+
20
+ def translate(tx, ty = 0)
21
+ add_transform(:translate, "#{tx}, #{ty}")
22
+ self
23
+ end
24
+
25
+ def scale(sx, sy = 1)
26
+ add_transform(:scale, "#{sx}, #{sy}")
27
+ self
28
+ end
29
+
30
+ def rotate(angle, cx = nil, cy = nil)
31
+ add_transform(:rotate, "#{angle}#{(cx.nil? or cy.nil?) ? "" : ", #{cx}, #{cy}"}")
32
+ self
33
+ end
34
+
35
+ def skewX(angle)
36
+ add_transform(:skewX, "#{angle}")
37
+ self
38
+ end
39
+
40
+ def skewY(angle)
41
+ add_transform(:skewY, "#{angle}")
42
+ self
43
+ end
44
+
45
+ def matrix(a, b, c, d, e, f)
46
+ add_transform(:matrix, "#{a}, #{b}, #{c}, #{d}, #{e}, #{f}")
47
+ self
48
+ end
49
+
50
+ def validate_tag(tag)
51
+ raise "#{tag} is not a valid tag" unless SVGPlot::SVG_ELEMENTS.include?(tag.to_sym)
52
+ tag.to_sym
53
+ end
54
+
55
+ def validate_attributes(attributes)
56
+ clean_attributes = {}
57
+ transforms = {}
58
+ styles = {}
59
+
60
+ attributes.each do |attribute, value|
61
+ if SVGPlot::SVG_TRANSFORM.include? attribute
62
+ transforms[attribute] = value
63
+ elsif SVGPlot::CSS_STYLE.include? attribute
64
+ styles[attribute] = value
65
+ else
66
+ clean_attributes[validate_attribute(attribute)] = value
67
+ end
68
+ end
69
+
70
+ #always prefer more verbose definition.
71
+ unless transforms.empty?
72
+ transforms.merge!(clean_attributes[:transform]) if clean_attributes[:transform]
73
+ str = ""
74
+ write_transforms(transforms, str)
75
+ clean_attributes[validate_attribute(:transform)] = str
76
+ end
77
+
78
+ unless styles.empty?
79
+ styles.merge!(clean_attributes[:style]) if clean_attributes[:style]
80
+ clean_attributes[validate_attribute(:style)] = styles
81
+ end
82
+ clean_attributes
83
+ end
84
+
85
+ def validate_attribute(attribute)
86
+ raise "#{@tag} does not support attribute #{attribute}" unless SVGPlot::SVG_STRUCTURE[@tag.to_sym][:attributes].include?(attribute.to_sym)
87
+ attribute.to_sym
88
+ end
89
+
90
+ def write_styles(styles, output)
91
+ styles.each do |attribute, value|
92
+ attribute = attribute.to_s
93
+ attribute.gsub!('_','-')
94
+ output << "#{attribute}:#{value};"
95
+ end
96
+ end
97
+
98
+ def write_transforms(transforms, output)
99
+ transforms.each do |attribute, value|
100
+ value = [value] unless value.is_a?(Array)
101
+ output << "#{attribute.to_s}(#{value.join(',')}) "
102
+ end
103
+ end
104
+
105
+ def write_points(points, output)
106
+ points.each_with_index do |value, index|
107
+ output << value.to_s
108
+ output << ',' if index.even?
109
+ output << ' ' if (index.odd? and (index != points.size-1))
110
+ end
111
+ end
112
+
113
+ #special case for raw blocks.
114
+ def raw(data)
115
+ append_child SVGPlot::SVGRaw.new(@img, data)
116
+ end
117
+
118
+ #special case for path block
119
+ def path(attributes = {}, &block)
120
+ append_child SVGPlot::SVGPath.new(@img, attributes, &block)
121
+ end
122
+
123
+ #special case for use block
124
+ def use(id, attributes = {})
125
+ id = id.attributes[:id] if id.is_a? SVGPlot::SVGTag
126
+ append_child SVGPlot::SVGTagWithParent.new(@img, "use", attributes.merge("xlink:href" => "##{id}"))
127
+ end
128
+
129
+
130
+ #special case for linearGradient
131
+ def linearGradient(id, attributes={}, if_exists = :skip, &block)
132
+ raise "image reference isn't set, cannot use 'defs' (and thus linearGradient) !" if @img.nil?
133
+ @img.add_def(id, SVGPlot::SVGLinearGradient.new(@img, attributes), if_exists, &block)
134
+ end
135
+
136
+
137
+ #special case for radialGradient
138
+ def radialGradient(id, attributes={}, if_exists = :skip, &block)
139
+ raise "image reference isn't set, cannot use 'defs' (and thus radialGradient) !" if @img.nil?
140
+ @img.add_def(id, SVGPlot::SVGRadialGradient.new(@img, attributes), if_exists, &block)
141
+ end
142
+
143
+
144
+
145
+
146
+ def spawn_child(tag, *args, &block)
147
+ #expected args: nil, [hash], [...]
148
+ parameters = {} if args.size == 0
149
+
150
+ unless parameters #are empty
151
+ parameters = args[0] if args[0].is_a? Hash
152
+ end
153
+
154
+ unless parameters #are set
155
+ #try to find args expansion rule
156
+ expansion = SVGPlot::SVG_EXPANSION[tag.to_sym]
157
+ raise "Unnamed parameters for #{tag} are not allowed!" unless expansion
158
+
159
+ if expansion.is_a? Array
160
+ raise "Bad unnamed parameter count for #{tag}, expecting #{expansion.size} got #{if args.last.is_a? Hash then args.size-1 else args.size end}" unless (args.size == expansion.size and not args.last.is_a? Hash) or (args.size - 1 == expansion.size and args.last.is_a? Hash)
161
+ parameters = Hash[expansion.zip(args)]
162
+ if args.last.is_a? Hash
163
+ parameters.merge! args.last
164
+ end
165
+ elsif expansion.is_a? Proc
166
+ hash = args.pop if args.last.is_a? Hash
167
+ parameters = expansion.call(args)
168
+ parameters.merge! hash if hash
169
+ else
170
+ raise "Unexpected expansion mechanism: #{expansion.class}"
171
+ end
172
+ end
173
+
174
+ # add default parameters if they are not overwritten
175
+ merge_defaults().each do |key, value|
176
+ parameters[key] = value unless parameters[key]
177
+ end if @defaults
178
+
179
+ append_child(SVGPlot::SVGTagWithParent.new(@img, tag, parameters, &block))
180
+ end
181
+
182
+
183
+ def append_child(child)
184
+ @children.push(child)
185
+ child.push_defaults(merge_defaults()) if @defaults
186
+ child
187
+ end
188
+
189
+
190
+ def merge_defaults()
191
+ result = {}
192
+ return result if @defaults.empty?
193
+ @defaults.each { |d| result.merge!(d) }
194
+ result
195
+ end
196
+
197
+
198
+ def push_defaults(defaults)
199
+ @defaults = [] unless @defaults
200
+ @defaults.push(defaults)
201
+ end
202
+
203
+
204
+ def pop_defaults()
205
+ @defaults.pop()
206
+ end
207
+
208
+
209
+ def with_style(style={}, &proc)
210
+ push_defaults(style)
211
+ # Call the block
212
+ self.instance_exec(&proc)
213
+ # Pop style again to revert changes
214
+ pop_defaults()
215
+ end
216
+
217
+
218
+ def validate_child_name(name)
219
+ #aliases the name (like, group instead of g)
220
+ name = SVGPlot::SVG_ALIAS[name.to_sym] if SVGPlot::SVG_ALIAS[name.to_sym]
221
+
222
+ #raises only if given name is an actual svg tag. In other case -- assumes user just mistyped.
223
+ if SVGPlot::SVG_STRUCTURE[@tag.to_sym][:elements].include?(name.to_sym)
224
+ name.to_sym
225
+ elsif SVGPlot::SVG_ELEMENTS.include?(name.to_sym)
226
+ raise "#{@tag} should not contain child #{name}"
227
+ end
228
+ end
229
+
230
+
231
+ def method_missing(meth, *args, &block)
232
+ #if method is a setter or a getter, check valid attributes:
233
+ check = /^(?<name>.*)(?<op>=|\?)$/.match(meth)
234
+ if check
235
+ raise "Passing a code block to setter or getter is not permited!" if block
236
+ name = validate_attribute(check[:name].to_sym)
237
+ if check[:op] == '?'
238
+ @attributes[name]
239
+ elsif check[:op] == '='
240
+ raise "Setting an attribute with multiple values is not permited!" if args.size > 1
241
+ @attributes[name] = args[0]
242
+ end
243
+ elsif child = validate_child_name(meth)
244
+ spawn_child(child, *args, &block)
245
+ else
246
+ super
247
+ end
248
+ end
249
+
250
+
251
+ def write(output)
252
+ raise "Can not write to given output!" unless output.respond_to?(:<<)
253
+ output << "<#{@tag.to_s}"
254
+ @attributes.each do
255
+ |attribute, value|
256
+ output << " #{attribute.to_s}=\""
257
+ if attribute == :style
258
+ write_styles(value, output)
259
+ elsif attribute == :points
260
+ write_points(value, output)
261
+ else
262
+ output << "#{value.to_s}"
263
+ end
264
+ output << "\""
265
+ end
266
+
267
+ if @children.empty?
268
+ output << "/>"
269
+ else
270
+ output << ">"
271
+ @children.each { |c| c.write(output) }
272
+ output << "</#{@tag.to_s}>"
273
+ end
274
+ end
275
+
276
+ def to_s
277
+ str = ""
278
+ write(str)
279
+ return str
280
+ end
281
+
282
+
283
+ private
284
+
285
+ def add_transform(type, params)
286
+ attr_name = validate_attribute(:transform)
287
+ @attributes[attr_name] = "" if @attributes[attr_name].nil?
288
+ @attributes[attr_name] = @attributes[attr_name] + "#{type}(#{params})"
289
+ end
290
+
291
+ end
292
+ end
293
+
294
+
295
+ #Extension of SVGTag to provide a reference to the parent img (used for defs)
296
+ module SVGPlot
297
+ class SVGTagWithParent < SVGPlot::SVGTag
298
+ attr_reader :img
299
+
300
+ def initialize(img, tag, params = {}, output=nil, &block)
301
+ @img = img
302
+ super(tag, params, &block)
303
+ end
304
+ end
305
+ end
306
+
307
+
308
+
309
+ #inherit from tag for basic functionality, control raw data using the write method
310
+ module SVGPlot
311
+ class SVGRaw < SVGPlot::SVGTagWithParent
312
+
313
+ def initialize(img, data)
314
+ @img = img
315
+ @data = data
316
+ end
317
+
318
+ def write(output)
319
+ output << @data.to_s
320
+ end
321
+ end
322
+ end
323
+
324
+
325
+
326
+ module SVGPlot
327
+ class Plot < SVGPlot::SVGTagWithParent
328
+ def initialize(params = {}, output=nil, &block)
329
+ @defs = nil
330
+ @defs_ids = {}
331
+
332
+ params[:"version"] = "1.1" unless params[:"version"]
333
+ params[:"xmlns"] = "http://www.w3.org/2000/svg" unless params[:"xmlns"]
334
+ params[:"xmlns:xlink"] = "http://www.w3.org/1999/xlink" unless params[:"xmlns:xlink"]
335
+ super(self, "svg", params, &block)
336
+
337
+ @output = (output or "")
338
+ validate_output(@output) if output
339
+
340
+ if block
341
+ write(@output)
342
+ end
343
+ end
344
+
345
+ def add_def(id, child, if_exists = :skip, &block)
346
+ #init on the fly if needed
347
+ @defs = SVGPlot::SVGTagWithParent.new(@img, "defs") if @defs.nil?
348
+
349
+ #raise an error if id is already present and if_exists is :fail
350
+ raise "Definition '#{id}' already exists" if @defs_ids.has_key? id and if_exists == :fail
351
+
352
+ #return the existing element if id is already present and if_exists is :skip
353
+ return @defs_ids[id] if if_exists == :skip and @defs_ids.has_key? id
354
+
355
+ #search for the existing element
356
+ if @defs_ids[id]
357
+ old_idx = nil
358
+ @defs.children.each_with_index { |c,i| if c.attributes[:id] == id then old_idx = i ; break end }
359
+ end
360
+
361
+ #force the id, append the child to definitions and call the given block to fill the group
362
+ child.attributes[:id] = id
363
+ @defs.append_child child
364
+ @defs_ids[id] = child
365
+ child.instance_exec block
366
+
367
+ #remove the old element if present
368
+ @defs.children.delete_at old_idx if old_idx
369
+
370
+ return child
371
+ end
372
+
373
+ def def_group(id, if_exists = :skip, &block)
374
+ g = SVGPlot::SVGTagWithParent.new(@img, "g", :id => id)
375
+ return add_def(id, g, if_exists, &block)
376
+ end
377
+
378
+ #def text(x, y, text, style=DefaultStyles[:text])
379
+ # @output << %Q{<text x="#{x}" y="#{y}"}
380
+ # style = fix_style(default_style.merge(style))
381
+ # @output << %Q{ font-family="#{style.delete "font-family"}"} if style["font-family"]
382
+ # @output << %Q{ font-size="#{style.delete "font-size"}"} if style["font-size"]
383
+ # write_style style
384
+ # @output << ">"
385
+ # dy = 0 # First line should not be shifted
386
+ # text.each_line do |line|
387
+ # @output << %Q{<tspan x="#{x}" dy="#{dy}em">}
388
+ # dy = 1 # Next lines should be shifted
389
+ # @output << line.rstrip
390
+ # @output << "</tspan>"
391
+ # end
392
+ # @output << "</text>"
393
+ #end
394
+
395
+
396
+ def write(output)
397
+ validate_output(output)
398
+ write_header(output)
399
+
400
+ @children.unshift @defs if @defs
401
+ super(output)
402
+ @children.shift if @defs
403
+ end
404
+
405
+
406
+ # how to define output << image ?
407
+ #def <<(output)
408
+ # write(output)
409
+ #end
410
+
411
+ private
412
+
413
+ def validate_output(output)
414
+ raise "Illegal output object: #{output.inspect}" unless output.respond_to?(:<<)
415
+ end
416
+
417
+ # Writes file header
418
+ def write_header(output)
419
+ output << <<-HEADER
420
+ <?xml version="1.0" standalone="no"?>
421
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
422
+ HEADER
423
+ end
424
+ end
425
+ end
426
+
427
+ #SVG Path element, with ruby methods to describe the path
428
+ class SVGPlot::SVGPath < SVGPlot::SVGTagWithParent
429
+ def initialize(img = nil, attributes={}, &block)
430
+ attributes.merge!(:d => "") unless attributes.has_key? :d
431
+ super(img, "path", attributes)
432
+ end
433
+
434
+ ##
435
+ # moveTo commands
436
+ #
437
+ # Moves pen to specified point x,y without drawing.
438
+ #
439
+ ##
440
+ def moveTo(x, y)
441
+ add_d("m#{x},#{y}")
442
+ end
443
+
444
+
445
+ def moveToA(x, y)
446
+ add_d("M#{x},#{y}")
447
+ end
448
+
449
+
450
+ ##
451
+ # lineTo commands
452
+ #
453
+ # Draws a line from current pen location to specified point x,y.
454
+ #
455
+ ##
456
+ def lineTo(x, y)
457
+ add_d("l#{x},#{y}")
458
+ end
459
+
460
+
461
+ def lineToA(x, y)
462
+ add_d("L#{x},#{y}")
463
+ end
464
+
465
+
466
+ ##
467
+ # horizontal lineTo commands
468
+ #
469
+ # Draws a horizontal line to the point defined by x.
470
+ #
471
+ ##
472
+ def hlineTo(x)
473
+ add_d("h#{x}")
474
+ end
475
+
476
+
477
+ def hlineToA(x)
478
+ add_d("H#{x}")
479
+ end
480
+
481
+
482
+ ##
483
+ # vertical lineTo commands
484
+ #
485
+ # Draws a vertical line to the point defined by y.
486
+ #
487
+ ##
488
+ def vlineTo(y)
489
+ add_d("v#{y}")
490
+ end
491
+
492
+
493
+ def vlineToA(y)
494
+ add_d("V#{y}")
495
+ end
496
+
497
+
498
+ ##
499
+ # curveTo commands
500
+ #
501
+ # Draws a cubic Bezier curve from current pen point to dx,dy. x1,y1 and x2,y2
502
+ # are start and end control points of the curve, controlling how it bends.
503
+ #
504
+ ##
505
+ def curveTo(dx, dy, x1, y1, x2, y2)
506
+ add_d("c#{x1},#{y1} #{x2},#{y2} #{dx},#{dy}")
507
+ end
508
+
509
+
510
+ def curveToA(dx, dy, x1, y1, x2, y2)
511
+ add_d("C#{x1},#{y1} #{x2},#{y2} #{dx},#{dy}")
512
+ end
513
+
514
+
515
+ ##
516
+ # smooth curveTo commands
517
+ #
518
+ # Draws a cubic Bezier curve from current pen point to dx,dy. x2,y2 is the
519
+ # end control point. The start control point is is assumed to be the same
520
+ # as the end control point of the previous curve.
521
+ #
522
+ ##
523
+ def scurveTo(dx, dy, x2, y2)
524
+ add_d("s#{x2},#{y2} #{dx},#{dy}")
525
+ end
526
+
527
+
528
+ def scurveToA(dx, dy, x2, y2)
529
+ add_d("S#{x2},#{y2} #{dx},#{dy}")
530
+ end
531
+
532
+
533
+ ##
534
+ # quadratic Bezier curveTo commands
535
+ #
536
+ # Draws a quadratic Bezier curve from current pen point to dx,dy. x1,y1 is the
537
+ # control point controlling how the curve bends.
538
+ #
539
+ ##
540
+ def qcurveTo(dx, dy, x1, y1)
541
+ add_d("q#{x1},#{y1} #{dx},#{dy}")
542
+ end
543
+
544
+
545
+ def qcurveToA(dx, dy, x1, y1)
546
+ add_d("Q#{x1},#{y1} #{dx},#{dy}")
547
+ end
548
+
549
+
550
+ ##
551
+ # smooth quadratic Bezier curveTo commands
552
+ #
553
+ # Draws a quadratic Bezier curve from current pen point to dx,dy. The control
554
+ # point is assumed to be the same as the last control point used.
555
+ #
556
+ ##
557
+ def sqcurveTo(dx, dy)
558
+ add_d("t#{dx},#{dy}")
559
+ end
560
+
561
+
562
+ def sqcurveToA(dx, dy)
563
+ add_d("T#{dx},#{dy}")
564
+ end
565
+
566
+
567
+ ##
568
+ # elliptical arc commands
569
+ #
570
+ # Draws an elliptical arc from the current point to the point x,y. rx and ry
571
+ # are the elliptical radius in x and y direction.
572
+ # The x-rotation determines how much the arc is to be rotated around the
573
+ # x-axis. It only seems to have an effect when rx and ry have different values.
574
+ # The large-arc-flag doesn't seem to be used (can be either 0 or 1). Neither
575
+ # value (0 or 1) changes the arc.
576
+ # The sweep-flag determines the direction to draw the arc in.
577
+ #
578
+ ##
579
+ def arcTo(dx, dy, rx, ry, axis_rotation, large_arc_flag, sweep_flag)
580
+ add_d("a#{rx},#{ry} #{axis_rotation} #{large_arc_flag},#{sweep_flag} #{dx},#{dy}")
581
+ end
582
+
583
+
584
+ def arcToA(dx, dy, rx, ry, axis_rotation, large_arc_flag, sweep_flag)
585
+ add_d("A#{rx},#{ry} #{axis_rotation} #{large_arc_flag},#{sweep_flag} #{dx},#{dy}")
586
+ end
587
+
588
+
589
+ ##
590
+ # close path command
591
+ #
592
+ # Closes the path by drawing a line from current point to first point.
593
+ #
594
+ ##
595
+ def close
596
+ add_d("Z")
597
+ end
598
+
599
+
600
+ private
601
+ def add_d(op)
602
+ @attributes[:d] = @attributes[:d] + " " + op
603
+ end
604
+ end
605
+
606
+ #SVG base gradient element, with ruby methods to describe the gradient
607
+ class SVGPlot::SVGGradient < SVGPlot::SVGTagWithParent
608
+
609
+ def fill
610
+ "url(##{@attributes[:id]})"
611
+ end
612
+
613
+
614
+ def stop(offset, color, opacity)
615
+ append_child(SVGPlot::SVGTag.new("stop", "offset" => offset, "stop-color" => color, "stop-opacity" => opacity))
616
+ end
617
+
618
+ end
619
+
620
+ #SVG linear gradient element
621
+ class SVGPlot::SVGLinearGradient < SVGPlot::SVGGradient
622
+
623
+ def initialize(img, attributes={}, &block)
624
+ super(img, "linearGradient", attributes, &block)
625
+ end
626
+
627
+ end
628
+
629
+ #SVG radial gradient element
630
+ class SVGPlot::SVGRadialGradient < SVGPlot::SVGGradient
631
+
632
+ def initialize(img, attributes={}, &block)
633
+ super(img, "radialGradient", attributes, &block)
634
+ end
635
+
636
+ end
@@ -2,6 +2,6 @@ require 'spec_helper'
2
2
 
3
3
  describe SVGPlot do
4
4
  it 'works' do
5
- expect(true).to be_true
5
+ expect(true).to be true
6
6
  end
7
7
  end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'svgplot'
3
- s.version = '0.0.1'
3
+ s.version = '0.0.2'
4
4
  s.date = Time.now.strftime("%Y-%m-%d")
5
5
 
6
6
  s.summary = 'SVG Generation Library'
@@ -17,10 +17,12 @@ Gem::Specification.new do |s|
17
17
 
18
18
  s.files = `git ls-files`.split
19
19
  s.test_files = `git ls-files spec/*`.split
20
+ s.executables = ['svgplot']
20
21
 
21
- s.add_development_dependency 'rubocop', '~> 0.19.0'
22
- s.add_development_dependency 'rake', '~> 10.1.1'
23
- s.add_development_dependency 'coveralls', '~> 0.7.0'
24
- s.add_development_dependency 'rspec', '~> 2.14.1'
25
- s.add_development_dependency 'fuubar', '~> 1.3.2'
22
+ s.add_development_dependency 'rubocop', '~> 0.28.0'
23
+ s.add_development_dependency 'rake', '~> 10.4.0'
24
+ s.add_development_dependency 'coveralls', '~> 0.7.1'
25
+ s.add_development_dependency 'rspec', '~> 3.1.0'
26
+ s.add_development_dependency 'fuubar', '~> 2.0.0'
27
+ s.add_development_dependency 'nokogiri', '~> 1.6.5'
26
28
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: svgplot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Les Aker
@@ -11,95 +11,113 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2014-03-23 00:00:00.000000000 Z
14
+ date: 2015-01-04 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rubocop
18
18
  requirement: !ruby/object:Gem::Requirement
19
19
  requirements:
20
- - - ~>
20
+ - - "~>"
21
21
  - !ruby/object:Gem::Version
22
- version: 0.19.0
22
+ version: 0.28.0
23
23
  type: :development
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
- - - ~>
27
+ - - "~>"
28
28
  - !ruby/object:Gem::Version
29
- version: 0.19.0
29
+ version: 0.28.0
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: rake
32
32
  requirement: !ruby/object:Gem::Requirement
33
33
  requirements:
34
- - - ~>
34
+ - - "~>"
35
35
  - !ruby/object:Gem::Version
36
- version: 10.1.1
36
+ version: 10.4.0
37
37
  type: :development
38
38
  prerelease: false
39
39
  version_requirements: !ruby/object:Gem::Requirement
40
40
  requirements:
41
- - - ~>
41
+ - - "~>"
42
42
  - !ruby/object:Gem::Version
43
- version: 10.1.1
43
+ version: 10.4.0
44
44
  - !ruby/object:Gem::Dependency
45
45
  name: coveralls
46
46
  requirement: !ruby/object:Gem::Requirement
47
47
  requirements:
48
- - - ~>
48
+ - - "~>"
49
49
  - !ruby/object:Gem::Version
50
- version: 0.7.0
50
+ version: 0.7.1
51
51
  type: :development
52
52
  prerelease: false
53
53
  version_requirements: !ruby/object:Gem::Requirement
54
54
  requirements:
55
- - - ~>
55
+ - - "~>"
56
56
  - !ruby/object:Gem::Version
57
- version: 0.7.0
57
+ version: 0.7.1
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rspec
60
60
  requirement: !ruby/object:Gem::Requirement
61
61
  requirements:
62
- - - ~>
62
+ - - "~>"
63
63
  - !ruby/object:Gem::Version
64
- version: 2.14.1
64
+ version: 3.1.0
65
65
  type: :development
66
66
  prerelease: false
67
67
  version_requirements: !ruby/object:Gem::Requirement
68
68
  requirements:
69
- - - ~>
69
+ - - "~>"
70
70
  - !ruby/object:Gem::Version
71
- version: 2.14.1
71
+ version: 3.1.0
72
72
  - !ruby/object:Gem::Dependency
73
73
  name: fuubar
74
74
  requirement: !ruby/object:Gem::Requirement
75
75
  requirements:
76
- - - ~>
76
+ - - "~>"
77
77
  - !ruby/object:Gem::Version
78
- version: 1.3.2
78
+ version: 2.0.0
79
79
  type: :development
80
80
  prerelease: false
81
81
  version_requirements: !ruby/object:Gem::Requirement
82
82
  requirements:
83
- - - ~>
83
+ - - "~>"
84
84
  - !ruby/object:Gem::Version
85
- version: 1.3.2
85
+ version: 2.0.0
86
+ - !ruby/object:Gem::Dependency
87
+ name: nokogiri
88
+ requirement: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - "~>"
91
+ - !ruby/object:Gem::Version
92
+ version: 1.6.5
93
+ type: :development
94
+ prerelease: false
95
+ version_requirements: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - "~>"
98
+ - !ruby/object:Gem::Version
99
+ version: 1.6.5
86
100
  description: Ruby interface for creating SVG images
87
101
  email: EMAIL_ADDRESS
88
- executables: []
102
+ executables:
103
+ - svgplot
89
104
  extensions: []
90
105
  extra_rdoc_files: []
91
106
  files:
92
- - .gitignore
93
- - .rspec
94
- - .rubocop.yml
95
- - .travis.yml
107
+ - ".gitignore"
108
+ - ".rspec"
109
+ - ".rubocop.yml"
110
+ - ".travis.yml"
96
111
  - Gemfile
97
112
  - LICENSE
98
113
  - README.md
99
114
  - Rakefile
115
+ - bin/svgplot
100
116
  - dev/update_spec.rb
101
117
  - lib/svgplot.rb
118
+ - lib/svgplot/application.rb
102
119
  - lib/svgplot/meta.rb
120
+ - lib/svgplot/plot.rb
103
121
  - lib/svgplot/spec.rb
104
122
  - spec/spec_helper.rb
105
123
  - spec/svgplot_spec.rb
@@ -114,17 +132,17 @@ require_paths:
114
132
  - lib
115
133
  required_ruby_version: !ruby/object:Gem::Requirement
116
134
  requirements:
117
- - - '>='
135
+ - - ">="
118
136
  - !ruby/object:Gem::Version
119
137
  version: '0'
120
138
  required_rubygems_version: !ruby/object:Gem::Requirement
121
139
  requirements:
122
- - - '>='
140
+ - - ">="
123
141
  - !ruby/object:Gem::Version
124
142
  version: '0'
125
143
  requirements: []
126
144
  rubyforge_project:
127
- rubygems_version: 2.0.14
145
+ rubygems_version: 2.2.2
128
146
  signing_key:
129
147
  specification_version: 4
130
148
  summary: SVG Generation Library