svgcode 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4d486f6eb402ed92018dc7ecf6ce1bfcbb714df2
4
- data.tar.gz: 2795cf35e94a4a7a3e4d925fa8c89660a2cfd015
3
+ metadata.gz: 85836f130f6ff7d82e701ed3794699d34a93e6c6
4
+ data.tar.gz: a3ade6019d2663505e5ca24d20b62f63c80efb02
5
5
  SHA512:
6
- metadata.gz: 20beaceac4a88028c7bdffa5af0b1d5bebe85e18cd1a1a17cf4714080c28ba36d2d454cbca484f76371a4bb1a01e61c9e08a3831e02a45f9fdc08c5e51fdcdc2
7
- data.tar.gz: 1af5a856a2cabfb9dac1c4e3f142aad744a8717ef1341a431b712024848ac71012f7d5a8f62dd47c1cc6961d35b610e9904c12aff33f1ff6ae58b19ffe82c580
6
+ metadata.gz: 51b98e6d618d94e0e0211872f1aff91a6b281e41b44abbbc8b42b3f9bda9ec3c13908ec1f0140950ee815df1340e15fb65fed7ffee3e6d0816c410feba69e661
7
+ data.tar.gz: 5447772034b322ba08006c6d0108c587a8c0d0e9dccdc5a58f4df96367c16472adc9cc103da202db94d22602a057e47b01a8738f949b8e0607b2f6775175d812
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- svgcode (0.4.0)
4
+ svgcode (0.6.0)
5
5
  nokogiri (~> 1.8)
6
6
  thor (~> 0.20)
7
7
 
@@ -9,11 +9,43 @@ GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
11
  byebug (9.1.0)
12
+ coderay (1.1.2)
12
13
  diff-lcs (1.3)
14
+ ffi (1.9.23)
15
+ formatador (0.2.5)
16
+ guard (2.14.2)
17
+ formatador (>= 0.2.4)
18
+ listen (>= 2.7, < 4.0)
19
+ lumberjack (>= 1.0.12, < 2.0)
20
+ nenv (~> 0.1)
21
+ notiffany (~> 0.0)
22
+ pry (>= 0.9.12)
23
+ shellany (~> 0.0)
24
+ thor (>= 0.18.1)
25
+ guard-compat (1.2.1)
26
+ guard-shell (0.7.1)
27
+ guard (>= 2.0.0)
28
+ guard-compat (~> 1.0)
29
+ listen (3.1.5)
30
+ rb-fsevent (~> 0.9, >= 0.9.4)
31
+ rb-inotify (~> 0.9, >= 0.9.7)
32
+ ruby_dep (~> 1.2)
33
+ lumberjack (1.0.13)
34
+ method_source (0.9.0)
13
35
  mini_portile2 (2.3.0)
36
+ nenv (0.3.0)
14
37
  nokogiri (1.8.2)
15
38
  mini_portile2 (~> 2.3.0)
39
+ notiffany (0.1.1)
40
+ nenv (~> 0.1)
41
+ shellany (~> 0.0)
42
+ pry (0.11.3)
43
+ coderay (~> 1.1.0)
44
+ method_source (~> 0.9.0)
16
45
  rake (10.5.0)
46
+ rb-fsevent (0.10.3)
47
+ rb-inotify (0.9.10)
48
+ ffi (>= 0.5.0, < 2)
17
49
  rspec (3.7.0)
18
50
  rspec-core (~> 3.7.0)
19
51
  rspec-expectations (~> 3.7.0)
@@ -27,6 +59,8 @@ GEM
27
59
  diff-lcs (>= 1.2.0, < 2.0)
28
60
  rspec-support (~> 3.7.0)
29
61
  rspec-support (3.7.0)
62
+ ruby_dep (1.5.0)
63
+ shellany (0.0.1)
30
64
  thor (0.20.0)
31
65
  yard (0.9.12)
32
66
 
@@ -36,6 +70,8 @@ PLATFORMS
36
70
  DEPENDENCIES
37
71
  bundler (~> 1.16)
38
72
  byebug
73
+ guard
74
+ guard-shell
39
75
  rake (~> 10.0)
40
76
  rspec (~> 3.0)
41
77
  svgcode!
@@ -0,0 +1,16 @@
1
+ require 'svgcode/cli'
2
+ require 'tempfile'
3
+
4
+ guard :shell do
5
+ watch(//) do |mod|
6
+ ngc_file = Tempfile.new
7
+ cli = Svgcode::CLI.new
8
+
9
+ cli.invoke('parse', ['~/Desktop/azabache.svg'],
10
+ out_path: ngc_file.path,
11
+ comments: true
12
+ )
13
+
14
+ cli.invoke('post', [ngc_file.path])
15
+ end
16
+ end
data/TODO.md CHANGED
@@ -15,7 +15,5 @@
15
15
  - optionally print GCode desciptions
16
16
  - write docs
17
17
  - optimise cut order
18
- - better end to end tests
19
- - maybe include LinuxCNC
20
18
  - cut to depth in multiple passes
21
19
  - v-engrave filled areas
@@ -1,43 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'bundler/setup'
4
- require 'svgcode'
5
- require 'thor'
4
+ require 'svgcode/cli'
6
5
 
7
-
8
- class SVGCLI < Thor
9
- desc 'parse SVG_PATH [--out OUT_PATH] [--comments]',
10
- 'parses an SVG file to a G-code file'
11
- option :out_path
12
- option :comments, type: :boolean
13
- long_desc <<-LONGDESC
14
- `svgcode parse ~/Desktop/img.svg` will save the G-code file as
15
- '~/Desktop/img.ngc'.
16
-
17
- Optionally set the --out-path flag to save the G-code file elsewhere
18
- \x5 e.g. `svgcode parse ~/Documents/img.svg --out-path ~/Desktop/gcode.nc`
19
-
20
- Optionally pass the --comments flag to print SVG IDs as comments
21
- \x5 e.g. `svgcode parse --comments ~/Desktop/img.svg`
22
- LONGDESC
23
- def parse(in_path)
24
- in_path = File.expand_path(in_path)
25
- raise "#{in_path} is not readable" unless File.readable?(in_path)
26
- svg_str = File.read(in_path)
27
-
28
- out_path =
29
- if options[:out_path].nil?
30
- in_path.gsub(/\.svg\Z/i, '.ngc')
31
- else
32
- File.expand_path(options[:out_path])
33
- end
34
-
35
- opts = { comments: options[:comments] }
36
- File.open(out_path, 'w') { |f| f << Svgcode.parse(svg_str, opts) }
37
-
38
- puts "G-code written to #{out_path}"
39
- end
40
- end
41
-
42
-
43
- SVGCLI.start(ARGV)
6
+ Svgcode::CLI.start(ARGV)
@@ -1,3 +1,4 @@
1
+ require 'svgcode/utility'
1
2
  require 'svgcode/version'
2
3
  require 'svgcode/gcode/converter'
3
4
  require 'svgcode/svg/transform'
@@ -15,20 +16,24 @@ module Svgcode
15
16
  opts[:max_y] = view_box.split(/\s+/).last.to_f
16
17
  converter = Converter.new(opts)
17
18
 
18
- doc.xpath('//path').each do |path|
19
+ doc.xpath('//path|//circle').each do |el|
19
20
  if opts[:comments]
20
- ids = path.xpath('ancestor::g[@id]').collect do |t|
21
+ ids = el.xpath('ancestor::g[@id]').collect do |t|
21
22
  t.attributes['id'].value
22
23
  end
23
24
 
24
25
  converter.comment!(ids.join(' '))
25
26
  end
26
27
 
27
- converter.transforms = path.xpath('ancestor::g[@transform]').collect do |t|
28
+ converter.transforms = el.xpath('ancestor::g[@transform]').collect do |t|
28
29
  Transform.new(t.attributes['transform'].value)
29
30
  end
30
31
 
31
- converter << path.attributes['d'].value
32
+ if el.name == 'path'
33
+ converter << el.attributes['d'].value
34
+ else
35
+ converter << el
36
+ end
32
37
  end
33
38
 
34
39
  converter.finish
@@ -0,0 +1,76 @@
1
+ require 'svgcode'
2
+ require 'thor'
3
+ require 'net/http'
4
+
5
+ module Svgcode
6
+ class CLI < Thor
7
+ DEFAULT_POST_URL = 'http://linux-cnc.bmo:8080'
8
+ DEFAULT_POST_NAME = 'file'
9
+
10
+ desc 'parse SVG_PATH [--out OUT_PATH] [--comments]',
11
+ 'parses an SVG file to a G-code file'
12
+ option :out_path
13
+ option :comments, type: :boolean
14
+ long_desc <<-LONGDESC
15
+ `svgcode parse ~/Desktop/img.svg` will save the G-code file as
16
+ '~/Desktop/img.ngc'.
17
+
18
+ Optionally set the --out-path flag to save the G-code file elsewhere
19
+ \x5 e.g. `svgcode parse ~/Documents/img.svg --out-path ~/Desktop/gcode.nc`
20
+
21
+ Optionally pass the --comments flag to print SVG IDs as comments
22
+ \x5 e.g. `svgcode parse --comments ~/Desktop/img.svg`
23
+ LONGDESC
24
+ def parse(in_path)
25
+ in_path = File.expand_path(in_path)
26
+ raise "#{in_path} is not readable" unless File.readable?(in_path)
27
+ svg_str = File.read(in_path)
28
+
29
+ out_path =
30
+ if options[:out_path].nil?
31
+ in_path.gsub(/\.svg\Z/i, '.ngc')
32
+ else
33
+ File.expand_path(options[:out_path])
34
+ end
35
+
36
+ opts = { comments: options[:comments] }
37
+ File.open(out_path, 'w') { |f| f << Svgcode.parse(svg_str, opts) }
38
+
39
+ puts "G-code written to #{out_path}"
40
+ end
41
+
42
+ desc 'post NGC_PATH [--url URL] [--post-name POST_NAME]',
43
+ 'posts an GCode file to a server'
44
+ option :url, default: DEFAULT_POST_URL
45
+ option :post_name, default: DEFAULT_POST_NAME
46
+ long_desc <<-LONGDESC
47
+ `svgcode post ~/Desktop/img.ngc` will post the GCode file to
48
+ #{DEFAULT_POST_URL}.
49
+
50
+ Optionally set the --url flag to post the GCode file elsewhere
51
+ \x5 e.g. `svgcode post ~/Documents/img.ngc --url http://192.168.20.7:9999`
52
+
53
+ Optionally pass the --post-name flag to name the file field something other
54
+ than the default '#{DEFAULT_POST_NAME}'
55
+ \x5 e.g. `svgcode post --post-name svgfile`
56
+ LONGDESC
57
+ def post(ngc_path)
58
+ ngc_path = File.expand_path(ngc_path)
59
+ raise "#{ngc_path} is not readable" unless File.readable?(ngc_path)
60
+
61
+ uri = URI(options[:url])
62
+ request = Net::HTTP::Post.new(uri)
63
+ form_data = [[options[:post_name], File.open(ngc_path)]]
64
+ message = nil
65
+
66
+ request.set_form form_data, 'multipart/form-data'
67
+ response = Net::HTTP.start(uri.hostname, uri.port) do |http|
68
+ http.request(request)
69
+ end
70
+
71
+ puts response
72
+
73
+ puts "G-code posted to #{options[:url]}"
74
+ end
75
+ end
76
+ end
@@ -123,6 +123,15 @@ module Svgcode
123
123
  ])
124
124
  end
125
125
 
126
+ # X and Y are the endpoint, and I is the X offset of the centrepoint
127
+ def self.arc(x, y, i)
128
+ Command.new(:g, 2, [
129
+ Command.new(:x, x),
130
+ Command.new(:y, y),
131
+ Command.new(:i, i)
132
+ ])
133
+ end
134
+
126
135
  def self.clear(clearance)
127
136
  Command.new(:g, 0, [
128
137
  Command.new(:z, clearance)
@@ -1,4 +1,5 @@
1
1
  require 'svgcode/gcode/program'
2
+ require 'svgcode/svg/circle'
2
3
  require 'svgcode/svg/path'
3
4
 
4
5
  module Svgcode
@@ -21,39 +22,15 @@ module Svgcode
21
22
  @program.feedrate!
22
23
  end
23
24
 
24
- def <<(svg_d)
25
- svg_start = nil
26
- path = SVG::Path.new(svg_d)
27
- start = nil
28
-
29
- path.commands.each do |cmd|
30
- cmd.apply_transforms!(@transforms)
31
- cmd.absolute? ? cmd.flip_points_y!(@max_y) : cmd.negate_points_y!
32
-
33
- if metric?
34
- cmd.divide_points_by!(PX_PER_MM)
35
- else
36
- cmd.divide_points_by!(PX_PER_INCH)
37
- end
38
-
39
- if (cmd.name == :close || cmd.absolute?) && @program.relative?
40
- @program.absolute!
41
- elsif cmd.relative? && @program.absolute?
42
- @program.relative!
43
- end
44
-
45
- case cmd.name
46
- when :move
47
- start = cmd.relative? ? cmd.absolute(@program.pos) : cmd
48
- @program.go!(cmd.points.first.x, cmd.points.first.y)
49
- when :line
50
- @program.cut!(cmd.points.first.x, cmd.points.first.y)
51
- when :cubic
52
- cubic!(cmd)
53
- when :close
54
- @program.cut!(start.points.first.x, start.points.first.y)
55
- start = nil
56
- end
25
+ def <<(str_or_command)
26
+ @start = nil
27
+
28
+ if str_or_command.is_a?(String)
29
+ path = SVG::Path.new(str_or_command)
30
+ path.commands.each { |cmd| add_command(cmd)}
31
+ else
32
+ cmd = SVG::Circle.new(str_or_command)
33
+ add_command(cmd)
57
34
  end
58
35
  end
59
36
 
@@ -80,6 +57,39 @@ module Svgcode
80
57
 
81
58
  private
82
59
 
60
+ def add_command(cmd)
61
+ cmd.apply_transforms!(@transforms)
62
+ cmd.absolute? ? cmd.flip_points_y!(@max_y) : cmd.negate_points_y!
63
+
64
+ if metric?
65
+ cmd.divide_points_by!(PX_PER_MM)
66
+ else
67
+ cmd.divide_points_by!(PX_PER_INCH)
68
+ end
69
+
70
+ if cmd.name == :close || cmd.absolute?
71
+ @program.absolute!
72
+ elsif cmd.relative?
73
+ @program.relative!
74
+ end
75
+
76
+ case cmd.name
77
+ when :move
78
+ @start = cmd.relative? ? cmd.absolute(@program.pos) : cmd
79
+ @program.go!(cmd.points.first.x, cmd.points.first.y)
80
+ when :line
81
+ @program.cut!(cmd.points.first.x, cmd.points.first.y)
82
+ when :cubic
83
+ cubic!(cmd)
84
+ when :circle
85
+ @program.go!(cmd.start_x, cmd.centre_y)
86
+ @program.arc!(cmd.start_x, cmd.centre_y, cmd.radius)
87
+ when :close
88
+ @program.cut!(@start.points.first.x, @start.points.first.y)
89
+ @start = nil
90
+ end
91
+ end
92
+
83
93
  def cubic!(cmd)
84
94
  # A relative SVG cubic bezier has all control points relative to start.
85
95
  # G-code I&J are relative to start, and P&Q relative to end.
@@ -61,7 +61,7 @@ module Svgcode
61
61
 
62
62
  def <<(command)
63
63
  if !command.is_a?(String) &&
64
- (@x.nil? || @y.nil?) &&
64
+ (@x.nil? || @y.nil?) &&
65
65
  command.letter == 'G' &&
66
66
  command.number < 6 &&
67
67
  command != Command.relative &&
@@ -156,6 +156,10 @@ module Svgcode
156
156
  end
157
157
  end
158
158
 
159
+ def arc!(x, y, i)
160
+ self << Command.arc(x, y, i)
161
+ end
162
+
159
163
  def pos
160
164
  Svgcode::SVG::Point.new(@x, @y)
161
165
  end
@@ -0,0 +1,91 @@
1
+ require 'svgcode/svg/point'
2
+
3
+ module Svgcode
4
+ module SVG
5
+ class BaseCommand
6
+ attr_reader :name, :absolute, :points
7
+
8
+ NAMES = {
9
+ 'm' => :move,
10
+ 'l' => :line,
11
+ 'c' => :cubic,
12
+ 'z' => :close
13
+ }
14
+
15
+ def initialize(opts)
16
+ @name = opts[:name]
17
+ @absolute = !!opts[:absolute]
18
+ @points = opts[:points] || []
19
+ end
20
+
21
+ def absolute?
22
+ @absolute
23
+ end
24
+
25
+ def relative?
26
+ !@absolute
27
+ end
28
+
29
+ def absolute(pos)
30
+ points = @points.collect { |p| p + pos }
31
+ Command.new(name: @name, absolute: true, points: points)
32
+ end
33
+
34
+ def absolute!(pos)
35
+ if relative?
36
+ @points.collect! { |p| p + pos }
37
+ @absolute = true
38
+ end
39
+ end
40
+
41
+ def negate_points_y
42
+ points = @points.collect { |point| point.negate_y }
43
+ Command.new(name: @name, absolute: @absolute, points: points)
44
+ end
45
+
46
+ def negate_points_y!
47
+ @points.each { |point| point.negate_y! }
48
+ nil
49
+ end
50
+
51
+ def divide_points_by!(amount)
52
+ @points.each { |point| point.divide_by!(amount) }
53
+ nil
54
+ end
55
+
56
+ def flip_points_y!(max_y)
57
+ @points.each { |point| point.flip_y!(max_y) }
58
+ nil
59
+ end
60
+
61
+ def apply_transforms!(transforms)
62
+ unless transforms.empty?
63
+ transforms.reverse.each do |transform|
64
+ @points.collect! { |point| transform.apply(point) }
65
+ end
66
+ end
67
+ end
68
+
69
+ def name_str
70
+ Command.name_str(@name, absolute?)
71
+ end
72
+
73
+ def ==(other)
74
+ other.is_a?(self.class) &&
75
+ other.name == @name &&
76
+ other.absolute? == @absolute &&
77
+ other.points == @points
78
+ end
79
+
80
+ def to_s
81
+ name_str + @points.collect { |p| p.to_s }.join(' ')
82
+ end
83
+
84
+ def self.name_str(sym, absolute)
85
+ str = NAMES.key(sym).dup
86
+ str.upcase! if absolute
87
+ str
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,54 @@
1
+ require 'svgcode/utility'
2
+ require 'svgcode/svg/base_command'
3
+ require 'svgcode/svg/point'
4
+ require 'nokogiri'
5
+
6
+ module Svgcode
7
+ module SVG
8
+ class Circle < BaseCommand
9
+ attr_reader :centre_x, :centre_y, :radius
10
+
11
+ def initialize(element_or_x, y = nil, r = nil)
12
+ @name = :circle
13
+ @absolute = true
14
+
15
+ if element_or_x.is_a?(Nokogiri::XML::Element)
16
+ @centre_x = Utility.x_to_f(element_or_x.attributes['cx'].value)
17
+ @centre_y = Utility.x_to_f(element_or_x.attributes['cy'].value)
18
+ @radius = Utility.x_to_f(element_or_x.attributes['r'].value)
19
+ else
20
+ @centre_x = Utility.x_to_f(element_or_x)
21
+ @centre_y = Utility.x_to_f(y)
22
+ @radius = Utility.x_to_f(r)
23
+ end
24
+
25
+ @points = [ Point.new(@centre_x, @centre_y) ]
26
+ end
27
+
28
+ def start_x
29
+ @centre_x - @radius
30
+ end
31
+
32
+ def apply_transforms!(transforms)
33
+ super(transforms)
34
+
35
+ transforms.reverse.each do |transform|
36
+ r_start = transform.apply(Point.new(start_x, 0))
37
+ r_end = transform.apply(Point.new(@centre_x, 0))
38
+ @centre_x = r_end.x
39
+ @radius = @centre_x - r_start.x
40
+ end
41
+
42
+ @centre_x = @points.first.x
43
+ @centre_y = @points.first.y
44
+ end
45
+
46
+ def divide_points_by!(amount)
47
+ super(amount)
48
+ @centre_x = @points.first.x
49
+ @centre_y = @points.first.y
50
+ @radius /= amount
51
+ end
52
+ end
53
+ end
54
+ end
@@ -1,4 +1,4 @@
1
- require 'svgcode/svg/command'
1
+ require 'svgcode/svg/path_command'
2
2
 
3
3
  module Svgcode
4
4
  module SVG
@@ -6,7 +6,7 @@ module Svgcode
6
6
  attr_reader :commands
7
7
 
8
8
  def initialize(str)
9
- @commands = str.split(/(?=[a-z])/i).collect { |s| Command.new(s) }
9
+ @commands = str.split(/(?=[a-z])/i).collect { |s| PathCommand.new(s) }
10
10
  end
11
11
  end
12
12
  end
@@ -1,8 +1,9 @@
1
1
  require 'svgcode/svg/point'
2
+ require 'svgcode/svg/base_command'
2
3
 
3
4
  module Svgcode
4
5
  module SVG
5
- class Command
6
+ class PathCommand < BaseCommand
6
7
  attr_reader :name, :absolute, :points
7
8
 
8
9
  NAMES = {
@@ -46,7 +47,7 @@ module Svgcode
46
47
 
47
48
  def absolute(pos)
48
49
  points = @points.collect { |p| p + pos }
49
- Command.new(name: @name, absolute: true, points: points)
50
+ PathCommand.new(name: @name, absolute: true, points: points)
50
51
  end
51
52
 
52
53
  def absolute!(pos)
@@ -58,7 +59,7 @@ module Svgcode
58
59
 
59
60
  def negate_points_y
60
61
  points = @points.collect { |point| point.negate_y }
61
- Command.new(name: @name, absolute: @absolute, points: points)
62
+ PathCommand.new(name: @name, absolute: @absolute, points: points)
62
63
  end
63
64
 
64
65
  def negate_points_y!
@@ -74,7 +75,7 @@ module Svgcode
74
75
  def flip_points_y!(max_y)
75
76
  @points.each { |point| point.flip_y!(max_y) }
76
77
  nil
77
- end
78
+ end
78
79
 
79
80
  def apply_transforms!(transforms)
80
81
  unless transforms.empty?
@@ -85,13 +86,13 @@ module Svgcode
85
86
  end
86
87
 
87
88
  def name_str
88
- Command.name_str(@name, absolute?)
89
+ PathCommand.name_str(@name, absolute?)
89
90
  end
90
91
 
91
92
  def ==(other)
92
- other.is_a?(self.class) &&
93
- other.name == @name &&
94
- other.absolute? == @absolute &&
93
+ other.is_a?(self.class) &&
94
+ other.name == @name &&
95
+ other.absolute? == @absolute &&
95
96
  other.points == @points
96
97
  end
97
98
 
@@ -1,3 +1,5 @@
1
+ require 'svgcode/utility'
2
+
1
3
  module Svgcode
2
4
  module SVG
3
5
  class Point
@@ -9,11 +11,11 @@ module Svgcode
9
11
  def initialize(str_or_x, y = nil)
10
12
  if y.nil?
11
13
  parts = str_or_x.split(VALUE_SEP)
12
- @x = Point.str_to_f(parts.first)
13
- @y = Point.str_to_f(parts.last)
14
+ @x = Utility.x_to_f(parts.first)
15
+ @y = Utility.x_to_f(parts.last)
14
16
  else
15
- @x = str_or_x.to_f
16
- @y = y.to_f
17
+ @x = Utility.x_to_f(str_or_x)
18
+ @y = Utility.x_to_f(y)
17
19
  end
18
20
  end
19
21
 
@@ -62,6 +64,12 @@ module Svgcode
62
64
  @y /= amount
63
65
  end
64
66
 
67
+ def flip_y(max_y)
68
+ p = Point.new(@x, @y)
69
+ p.flip_y!(max_y)
70
+ p
71
+ end
72
+
65
73
  def flip_y!(max_y)
66
74
  @y = max_y - @y
67
75
  end
@@ -77,10 +85,6 @@ module Svgcode
77
85
  def self.parse(str)
78
86
  str.split(OBJECT_SEP).collect { |p| Point.new(p.strip) }
79
87
  end
80
-
81
- def self.str_to_f(str)
82
- str.include?('e') ? "%f" % str : str.to_f
83
- end
84
88
  end
85
89
  end
86
90
  end
@@ -1,3 +1,4 @@
1
+ require 'svgcode/utility'
1
2
  require 'svgcode/svg/point'
2
3
  require 'matrix'
3
4
 
@@ -14,26 +15,26 @@ module Svgcode
14
15
  nums.each_with_index do |n, i|
15
16
  case i
16
17
  when 0
17
- @a = n.to_f
18
+ @a = Svgcode::Utility.x_to_f(n)
18
19
  when 1
19
- @b = n.to_f
20
+ @b = Svgcode::Utility.x_to_f(n)
20
21
  when 2
21
- @c = n.to_f
22
+ @c = Svgcode::Utility.x_to_f(n)
22
23
  when 3
23
- @d = n.to_f
24
+ @d = Svgcode::Utility.x_to_f(n)
24
25
  when 4
25
- @e = n.to_f
26
+ @e = Svgcode::Utility.x_to_f(n)
26
27
  when 5
27
- @f = n.to_f
28
+ @f = Svgcode::Utility.x_to_f(n)
28
29
  end
29
30
  end
30
31
  else
31
- @a = str_or_a.to_f
32
- @b = b.to_f
33
- @c = c.to_f
34
- @d = d.to_f
35
- @e = e.to_f
36
- @f = f.to_f
32
+ @a = Svgcode::Utility.x_to_f(str_or_a)
33
+ @b = Svgcode::Utility.x_to_f(b)
34
+ @c = Svgcode::Utility.x_to_f(c)
35
+ @d = Svgcode::Utility.x_to_f(d)
36
+ @e = Svgcode::Utility.x_to_f(e)
37
+ @f = Svgcode::Utility.x_to_f(f)
37
38
  end
38
39
  end
39
40
 
@@ -0,0 +1,28 @@
1
+ module Svgcode
2
+ module Utility
3
+ SCI_SEP = /e/i
4
+
5
+ def self.x_to_f(x)
6
+ f =
7
+ if x.is_a?(Numeric)
8
+ x.to_f
9
+ elsif x.is_a?(String)
10
+ if x.match(SCI_SEP)
11
+ parts = x.split(SCI_SEP)
12
+
13
+ unless parts.length == 2
14
+ raise ArgumentError.new('x is an unknown number format')
15
+ end
16
+
17
+ parts.first.to_f * 10.0 ** parts.last.to_f
18
+ else
19
+ x.to_f
20
+ end
21
+ else
22
+ raise ArgumentError.new('x must be a Numeric or a String')
23
+ end
24
+
25
+ f
26
+ end
27
+ end
28
+ end
@@ -1,3 +1,3 @@
1
1
  module Svgcode
2
- VERSION = '0.4.0'
2
+ VERSION = '0.6.0'
3
3
  end
@@ -23,8 +23,11 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency 'bundler', '~> 1.16'
24
24
  spec.add_development_dependency 'rake', '~> 10.0'
25
25
  spec.add_development_dependency 'rspec', '~> 3.0'
26
+
26
27
  spec.add_development_dependency 'byebug'
27
28
  spec.add_development_dependency 'yard'
29
+ spec.add_development_dependency 'guard'
30
+ spec.add_development_dependency 'guard-shell'
28
31
 
29
32
  spec.add_dependency 'nokogiri', '~> 1.8'
30
33
  spec.add_dependency 'thor', '~> 0.20'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: svgcode
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-18 00:00:00.000000000 Z
11
+ date: 2018-04-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -80,6 +80,34 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: guard
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: guard-shell
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
83
111
  - !ruby/object:Gem::Dependency
84
112
  name: nokogiri
85
113
  requirement: !ruby/object:Gem::Requirement
@@ -119,6 +147,7 @@ files:
119
147
  - ".gitignore"
120
148
  - Gemfile
121
149
  - Gemfile.lock
150
+ - Guardfile
122
151
  - LICENSE.txt
123
152
  - README.md
124
153
  - README/linux-cnc-reverb.png
@@ -129,14 +158,18 @@ files:
129
158
  - bin/setup
130
159
  - bin/svgcode
131
160
  - lib/svgcode.rb
161
+ - lib/svgcode/cli.rb
132
162
  - lib/svgcode/gcode/command.rb
133
163
  - lib/svgcode/gcode/converter.rb
134
164
  - lib/svgcode/gcode/invalid_command_error.rb
135
165
  - lib/svgcode/gcode/program.rb
136
- - lib/svgcode/svg/command.rb
166
+ - lib/svgcode/svg/base_command.rb
167
+ - lib/svgcode/svg/circle.rb
137
168
  - lib/svgcode/svg/path.rb
169
+ - lib/svgcode/svg/path_command.rb
138
170
  - lib/svgcode/svg/point.rb
139
171
  - lib/svgcode/svg/transform.rb
172
+ - lib/svgcode/utility.rb
140
173
  - lib/svgcode/version.rb
141
174
  - svgcode.gemspec
142
175
  homepage: https://github.com/benjineering/svgcode