gerber 0 → 1
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.
- data/Gemfile +1 -1
- data/README.markdown +42 -0
- data/Rakefile +7 -0
- data/gerber.gemspec +4 -2
- data/lib/gerber.rb +43 -2
- data/lib/gerber/aperture.rb +34 -0
- data/lib/gerber/layer.rb +35 -0
- data/lib/gerber/layer/parser.rb +207 -0
- data/lib/gerber/parser.rb +275 -0
- data/test/gerber.rb +38 -0
- data/test/gerber/example2.gerber +89 -0
- data/test/gerber/hexapod.gerber +1590 -0
- data/test/gerber/layer.rb +6 -0
- data/test/gerber/layer/parser.rb +481 -0
- data/test/gerber/m02_not_at_end.gerber +24 -0
- data/test/gerber/parser.rb +202 -0
- data/test/gerber/sample_4pcb.gerber +23 -0
- data/test/gerber/two_boxes.gerber +19 -0
- data/test/gerber/wikipedia.gerber +23 -0
- metadata +45 -5
@@ -0,0 +1,24 @@
|
|
1
|
+
G04 Taken from the example at http://www.4pcb.com/sample-gerber-file.html*
|
2
|
+
%ICAS*%
|
3
|
+
%MOIN*%
|
4
|
+
%IPPOS*%
|
5
|
+
%ASAXBY*%
|
6
|
+
G74*%FSLAN2X34Y34*%
|
7
|
+
%ADD10C,0.0550*%
|
8
|
+
%ADD11R,0.0550X0.0550*%
|
9
|
+
%ADD12R,0.0500X0.0500*%
|
10
|
+
%ADD13R,0.0960X0.0960*%
|
11
|
+
%ADD14O,0.0590X0.0886*%
|
12
|
+
G54D37*
|
13
|
+
G01X0006910Y0004900D02*
|
14
|
+
X0004900Y0002890D01*
|
15
|
+
X0012800Y0006640D02*
|
16
|
+
X0012480D01*
|
17
|
+
M02*
|
18
|
+
X0012390Y0006550D01*
|
19
|
+
X0011350D01*
|
20
|
+
X0010550Y0005750D01*
|
21
|
+
X0010050D01*
|
22
|
+
X0009750Y0005450D01*
|
23
|
+
Y0005150D01*
|
24
|
+
X0009300Y0004700D01*
|
@@ -0,0 +1,202 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'gerber/parser'
|
3
|
+
|
4
|
+
describe Gerber::Parser do
|
5
|
+
let(:parser) { Gerber::Parser.new }
|
6
|
+
|
7
|
+
describe "when parsing coordinates" do
|
8
|
+
before do
|
9
|
+
parser.coordinate_format = 3,3
|
10
|
+
parser.parse_parameter('MOMM')
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "with leading zero omission" do
|
14
|
+
before do
|
15
|
+
parser.zero_omission = :leading
|
16
|
+
end
|
17
|
+
|
18
|
+
it "must parse positive numbers" do
|
19
|
+
parser.parse_coordinate('12345').must_equal 12.345.mm
|
20
|
+
parser.parse_coordinate('+12345').must_equal 12.345.mm
|
21
|
+
end
|
22
|
+
|
23
|
+
it "must parse negative numbers" do
|
24
|
+
parser.parse_coordinate('-12345').must_equal -12.345.mm
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "with trailing zero omission" do
|
29
|
+
before do
|
30
|
+
parser.zero_omission = :trailing
|
31
|
+
end
|
32
|
+
|
33
|
+
it "must parse positive numbers" do
|
34
|
+
parser.parse_coordinate('12345').must_equal 123.45.mm
|
35
|
+
parser.parse_coordinate('+12345').must_equal 123.45.mm
|
36
|
+
end
|
37
|
+
|
38
|
+
it "must parse negative numbers" do
|
39
|
+
parser.parse_coordinate('-12345').must_equal -123.45.mm
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "when parsing parameters" do
|
45
|
+
let(:parser) { Gerber::Parser.new }
|
46
|
+
|
47
|
+
describe "when parsing a Mode parameter" do
|
48
|
+
before do
|
49
|
+
parser.parse_parameter('MOIN')
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "when parsing an aperture definition" do
|
53
|
+
describe "for a standard circle" do
|
54
|
+
it "without a hole" do
|
55
|
+
parser.parse_parameter('ADD10C,0.0070*')
|
56
|
+
parser.apertures[10].must_equal(Gerber::Aperture.new(:circle=>0.007.inch))
|
57
|
+
end
|
58
|
+
|
59
|
+
it "with a round hole" do
|
60
|
+
parser.parse_parameter('ADD10C,0.0070X0.025*')
|
61
|
+
parser.apertures[10].must_equal(Gerber::Aperture.new(:circle=>0.007.inch, :hole=>0.025.inch))
|
62
|
+
end
|
63
|
+
|
64
|
+
it "with a square hole" do
|
65
|
+
parser.parse_parameter('ADD10C,0.0070X0.025X0.050*')
|
66
|
+
parser.apertures[10].must_equal(Gerber::Aperture.new(:circle=>0.007.inch, :hole=>{:x=>0.025.inch,:y=>0.050.inch}))
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "for a standard rectangle" do
|
71
|
+
it "without a hole" do
|
72
|
+
parser.parse_parameter('ADD10R,0.020X0.040*')
|
73
|
+
parser.apertures[10].must_equal(Gerber::Aperture.new(:rectangle=>[0.020.inch, 0.040.inch]))
|
74
|
+
end
|
75
|
+
|
76
|
+
it "with a round hole" do
|
77
|
+
parser.parse_parameter('ADD10R,0.020X0.040X0.025*')
|
78
|
+
parser.apertures[10].must_equal(Gerber::Aperture.new(:rectangle=>[0.020.inch, 0.040.inch], :hole=>0.025.inch))
|
79
|
+
end
|
80
|
+
|
81
|
+
it "with a square hole" do
|
82
|
+
parser.parse_parameter('ADD10R,0.020X0.040X0.025X0.050*')
|
83
|
+
parser.apertures[10].must_equal(Gerber::Aperture.new(:rectangle=>[0.020.inch, 0.040.inch], :hole=>{:x=>0.025.inch,:y=>0.050.inch}))
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "for a standard obround" do
|
88
|
+
let(:obround) { [0.020.inch, 0.040.inch] }
|
89
|
+
|
90
|
+
it "without a hole" do
|
91
|
+
parser.parse_parameter('ADD10O,0.020X0.040*')
|
92
|
+
parser.apertures[10].must_equal(Gerber::Aperture.new(:obround=>obround))
|
93
|
+
end
|
94
|
+
|
95
|
+
it "with a round hole" do
|
96
|
+
parser.parse_parameter('ADD10O,0.020X0.040X0.025*')
|
97
|
+
parser.apertures[10].must_equal(Gerber::Aperture.new(:obround=>[0.020.inch, 0.040.inch], :hole=>0.025.inch))
|
98
|
+
end
|
99
|
+
|
100
|
+
it "with a square hole" do
|
101
|
+
parser.parse_parameter('ADD10O,0.020X0.040X0.025X0.050*')
|
102
|
+
parser.apertures[10].must_equal(Gerber::Aperture.new(:obround=>[0.020.inch, 0.040.inch], :hole=>{:x=>0.025.inch,:y=>0.050.inch}))
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
describe "for a standard regular polygon" do
|
107
|
+
describe "with rotation" do
|
108
|
+
it "without a hole" do
|
109
|
+
parser.parse_parameter('ADD10P,0.030X4X90*')
|
110
|
+
parser.apertures[10].shape.must_be_kind_of(Geometry::RegularPolygon)
|
111
|
+
parser.apertures[10].must_equal(Gerber::Aperture.new(:polygon=>0.030.inch, :sides=>4, :rotation=>90.0.degrees))
|
112
|
+
end
|
113
|
+
|
114
|
+
it "with a round hole" do
|
115
|
+
parser.parse_parameter('ADD10P,0.030X4X90X0.040*')
|
116
|
+
parser.apertures[10].must_equal(Gerber::Aperture.new(:polygon=>0.030.inch, :sides=>4, :rotation=>90.0.degrees, :hole=>0.040.inch))
|
117
|
+
end
|
118
|
+
|
119
|
+
it "with a square hole" do
|
120
|
+
parser.parse_parameter('ADD10P,0.030X4X90X0.040X0.025*')
|
121
|
+
parser.apertures[10].must_equal(Gerber::Aperture.new(:polygon=>0.030.inch, :sides=>4, :rotation=>90.0.degrees, :hole=>{:x=>0.040.inch,:y=>0.025.inch}))
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe "without rotation" do
|
126
|
+
it "without a hole" do
|
127
|
+
parser.parse_parameter('ADD10P,0.030X4*')
|
128
|
+
parser.apertures[10].must_equal(Gerber::Aperture.new(:polygon=>0.030.inch, :sides=>4))
|
129
|
+
end
|
130
|
+
|
131
|
+
it "with a round hole" do
|
132
|
+
parser.parse_parameter('ADD10P,0.030X4X0X0.040*')
|
133
|
+
parser.apertures[10].must_equal(Gerber::Aperture.new(:polygon=>0.030.inch, :sides=>4, :rotation=>0.0, :hole=>0.040.inch))
|
134
|
+
end
|
135
|
+
|
136
|
+
it "with a square hole" do
|
137
|
+
parser.parse_parameter('ADD10P,0.030X4X0X0.040X0.025*')
|
138
|
+
parser.apertures[10].must_equal(Gerber::Aperture.new(:polygon=>0.030.inch, :sides=>4, :rotation=>0.0, :hole=>{:x=>0.040.inch,:y=>0.025.inch}))
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
describe "for a macro" do
|
144
|
+
it "without parameters" do
|
145
|
+
parser.parse_parameter('ADD10CIRC')
|
146
|
+
parser.apertures[10].must_equal(Gerber::Aperture.new(:type=>'CIRC'))
|
147
|
+
end
|
148
|
+
|
149
|
+
it "with 1 parameter" do
|
150
|
+
parser.parse_parameter('ADD10CIRC,0.010')
|
151
|
+
parser.apertures[10].must_equal(Gerber::Aperture.new(:type=>'CIRC', :parameters=>[0.010.inch]))
|
152
|
+
end
|
153
|
+
|
154
|
+
it "with multiple parameters" do
|
155
|
+
parser.parse_parameter('ADD10CIRC,0.010X0.020')
|
156
|
+
parser.apertures[10].must_equal(Gerber::Aperture.new(:type=>'CIRC', :parameters=>[0.010.inch,0.020.inch]))
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
describe "when parsing a format specification" do
|
163
|
+
let(:parser) { Gerber::Parser.new }
|
164
|
+
|
165
|
+
it "leading absolute" do
|
166
|
+
parser.parse_parameter('FSLAX25Y25')
|
167
|
+
parser.zero_omission.must_equal :leading
|
168
|
+
parser.absolute.must_equal true
|
169
|
+
parser.integer_places.must_equal 2
|
170
|
+
parser.decimal_places.must_equal 5
|
171
|
+
parser.total_places.must_equal 7
|
172
|
+
end
|
173
|
+
|
174
|
+
it "leading incremental" do
|
175
|
+
parser.parse_parameter('FSLIX25Y25')
|
176
|
+
parser.zero_omission.must_equal :leading
|
177
|
+
parser.absolute.must_equal false
|
178
|
+
parser.integer_places.must_equal 2
|
179
|
+
parser.decimal_places.must_equal 5
|
180
|
+
parser.total_places.must_equal 7
|
181
|
+
end
|
182
|
+
|
183
|
+
it "trailing absolute" do
|
184
|
+
parser.parse_parameter('FSTAX25Y25')
|
185
|
+
parser.absolute.must_equal true
|
186
|
+
parser.zero_omission.must_equal :trailing
|
187
|
+
parser.integer_places.must_equal 2
|
188
|
+
parser.decimal_places.must_equal 5
|
189
|
+
parser.total_places.must_equal 7
|
190
|
+
end
|
191
|
+
|
192
|
+
it "trailing incremental" do
|
193
|
+
parser.parse_parameter('FSTIX25Y25')
|
194
|
+
parser.absolute.must_equal false
|
195
|
+
parser.zero_omission.must_equal :trailing
|
196
|
+
parser.integer_places.must_equal 2
|
197
|
+
parser.decimal_places.must_equal 5
|
198
|
+
parser.total_places.must_equal 7
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
G04 Taken from the example at http://www.4pcb.com/sample-gerber-file.html*
|
2
|
+
%MOIN*%
|
3
|
+
%IPPOS*%
|
4
|
+
%ASAXBY*%
|
5
|
+
G74*
|
6
|
+
%FSLAN2X34Y34*%
|
7
|
+
%ADD10C,0.0550*%
|
8
|
+
%ADD11R,0.0550X0.0550*%
|
9
|
+
%ADD12R,0.0500X0.0500*%
|
10
|
+
%ADD13R,0.0960X0.0960*%
|
11
|
+
%ADD14O,0.0590X0.0886*%
|
12
|
+
G54D37*
|
13
|
+
G01X0006910Y0004900D02*
|
14
|
+
X0004900Y0002890D01*
|
15
|
+
X0012800Y0006640D02*
|
16
|
+
X0012480D01*
|
17
|
+
X0012390Y0006550D01*
|
18
|
+
X0011350D01*
|
19
|
+
X0010550Y0005750D01*
|
20
|
+
X0010050D01*
|
21
|
+
X0009750Y0005450D01*
|
22
|
+
Y0005150D01*
|
23
|
+
X0009300Y0004700D01*
|
@@ -0,0 +1,23 @@
|
|
1
|
+
G04 Film Name: paste_top*
|
2
|
+
G04 Origin Date: Thu Sep 20 15:54:22 2007*
|
3
|
+
G04 Layer: PIN/PASTEMASK_TOP*
|
4
|
+
G04 http://en.wikipedia.org/wiki/Gerber_format*
|
5
|
+
%FSLAX55Y55*MOIN*%
|
6
|
+
%IR0*IPPOS*OFA0.00000B0.00000*MIA0B0*SFA1.00000B1.00000*%
|
7
|
+
%ADD28R,.11X.043*%
|
8
|
+
%ADD39O,.07X.022*%
|
9
|
+
%AMMACRO19*
|
10
|
+
21,1,.0512,.0512,0.0,0.0,45.*%
|
11
|
+
%ADD19MACRO19*%
|
12
|
+
%LPD*%
|
13
|
+
G75*
|
14
|
+
G54D10*
|
15
|
+
X176250Y117500D03*
|
16
|
+
Y130000D03*
|
17
|
+
Y163750D03*
|
18
|
+
G54D39*
|
19
|
+
X496250Y142500D03*
|
20
|
+
Y137500D03*
|
21
|
+
Y132500D03*
|
22
|
+
Y127500D03*
|
23
|
+
M02*
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gerber
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '
|
4
|
+
version: '1'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,8 +9,24 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-03-
|
13
|
-
dependencies:
|
12
|
+
date: 2013-03-11 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: geometry
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '6'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '6'
|
14
30
|
description: Tools for working with Gerber and Extended Gerber files
|
15
31
|
email:
|
16
32
|
- bfoz@bfoz.net
|
@@ -24,6 +40,20 @@ files:
|
|
24
40
|
- Rakefile
|
25
41
|
- gerber.gemspec
|
26
42
|
- lib/gerber.rb
|
43
|
+
- lib/gerber/aperture.rb
|
44
|
+
- lib/gerber/layer.rb
|
45
|
+
- lib/gerber/layer/parser.rb
|
46
|
+
- lib/gerber/parser.rb
|
47
|
+
- test/gerber.rb
|
48
|
+
- test/gerber/example2.gerber
|
49
|
+
- test/gerber/hexapod.gerber
|
50
|
+
- test/gerber/layer.rb
|
51
|
+
- test/gerber/layer/parser.rb
|
52
|
+
- test/gerber/m02_not_at_end.gerber
|
53
|
+
- test/gerber/parser.rb
|
54
|
+
- test/gerber/sample_4pcb.gerber
|
55
|
+
- test/gerber/two_boxes.gerber
|
56
|
+
- test/gerber/wikipedia.gerber
|
27
57
|
homepage: http://github.com/bfoz/gerber
|
28
58
|
licenses: []
|
29
59
|
post_install_message:
|
@@ -48,6 +78,16 @@ rubygems_version: 1.8.24
|
|
48
78
|
signing_key:
|
49
79
|
specification_version: 3
|
50
80
|
summary: Everything you need to read and write Gerber RS-274-D and Extended Gerber
|
51
|
-
RS-
|
52
|
-
test_files:
|
81
|
+
RS-274X files
|
82
|
+
test_files:
|
83
|
+
- test/gerber.rb
|
84
|
+
- test/gerber/example2.gerber
|
85
|
+
- test/gerber/hexapod.gerber
|
86
|
+
- test/gerber/layer.rb
|
87
|
+
- test/gerber/layer/parser.rb
|
88
|
+
- test/gerber/m02_not_at_end.gerber
|
89
|
+
- test/gerber/parser.rb
|
90
|
+
- test/gerber/sample_4pcb.gerber
|
91
|
+
- test/gerber/two_boxes.gerber
|
92
|
+
- test/gerber/wikipedia.gerber
|
53
93
|
has_rdoc:
|