kicad 0.8.1 → 0.9.3
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 +4 -4
- data/README.md +9 -1
- data/lib/kicad/ast.rb +301 -47
- data/lib/kicad/grammar.rb +75 -67
- data/lib/kicad/grammar.tt +1 -1
- data/lib/kicad/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2a91d99c4c831dbc121717ef0609e05c8fe07c20d1b2044bfddda163c75c6620
|
4
|
+
data.tar.gz: 9110254e21b4e2913160100ec75f2887ea327107a0fefb257a23e77a9dfba362
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 44681ff57b45bebeea66e8a0dc92932e8219354dd2545e2dd4a9b4feb614aa7d2d528aff3946875c4373ff701e95015961e7865d0cc12a527404b84d29ae4b74
|
7
|
+
data.tar.gz: f2af698d30cd4b24a700a03a937f7a7a6c9913250c63aa99b3d75828191bb7d589d6fa06acd4a342f66c7d8a585d48ed8487aa0d1059e69a70262b2ce0da54cc
|
data/README.md
CHANGED
@@ -17,10 +17,18 @@ Parse, load, modify and rewrite Kicad (s-epression) files into a convenient tree
|
|
17
17
|
|
18
18
|
## Development
|
19
19
|
|
20
|
-
After checking out the repo, run `bundle` to install dependencies.
|
20
|
+
After checking out the repo, run `bundle` to install dependencies.
|
21
21
|
|
22
22
|
To install this gem onto your local machine from local source code, run `rake install`.
|
23
23
|
|
24
|
+
## Resources
|
25
|
+
|
26
|
+
KiCad uses a version of the Cadence SPECCTRA Design Language, defined in https://cdn.hackaday.io/files/1666717130852064/specctra.pdf
|
27
|
+
|
28
|
+
KiCad's documentation of this is at https://dev-docs.kicad.org/en/file-formats/sexpr-intro/
|
29
|
+
|
30
|
+
A related Rust library that was not consulted while building this is https://github.com/adom-inc/kicad_lib/tree/main/kicad_sexpr
|
31
|
+
|
24
32
|
## Contributing
|
25
33
|
|
26
34
|
Bug reports and pull requests are welcome on GitHub at https://github.com/cjheath/kicad-rb
|
data/lib/kicad/ast.rb
CHANGED
@@ -11,136 +11,390 @@ module KiCad
|
|
11
11
|
def emit depth = 0
|
12
12
|
"\t"*depth +
|
13
13
|
'(' +
|
14
|
-
@values.map{|v|
|
14
|
+
@values.map{|v| String === v ? v.inspect : v.to_s }*' ' +
|
15
15
|
(@children.size == 0 ? '' : "\n" + @children.map{|c| c.emit(depth+1) }*''+"\t"*depth) +
|
16
16
|
")\n"
|
17
17
|
end
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
v.inspect
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
19
|
+
# Define setter and getter methods for each value type this class allows
|
20
|
+
def self.value_types vts
|
21
|
+
i = 1 # @values[0] is always the class symbol
|
22
|
+
vts.each do |k, v|
|
23
|
+
# puts "#{self.name} attribute #{k.to_s} => #{v.inspect}"
|
24
|
+
# puts "attr_accessor #{self.name}.#{k} (values #{v.inspect}) is stored in @values[#{i}]"
|
25
|
+
begin
|
26
|
+
o = i # Avoid capturing i after the loop ends
|
27
|
+
define_method(:"#{k}") do
|
28
|
+
# puts "accessing #{self.class.name}.#{k} as @values[#{o}]"
|
29
|
+
@values[o]
|
30
|
+
end
|
31
|
+
define_method(:"#{k}=") do |v|
|
32
|
+
# puts "setting #{self.class.name}.#{k} as @values[#{o}]"
|
33
|
+
# REVISIT: Check valid data type matching v
|
34
|
+
@values[o] = v
|
35
|
+
end
|
36
|
+
end
|
37
|
+
i = i+1
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def children_of_type *cts # cts is an array of AST class symbols or strings
|
42
|
+
class_names = cts.flatten.map{|k| 'KiCad::AST::'+self.class.to_class_name(k)}
|
43
|
+
@children.filter{|h| class_names.include?(h.class.name) }
|
44
|
+
end
|
45
|
+
|
46
|
+
# Define methods for each child type this class allows
|
47
|
+
def self.child_types *cts
|
48
|
+
# puts "#{self.name} allows child types #{cts.inspect}"
|
49
|
+
cts.each do |c|
|
50
|
+
if Array === c
|
51
|
+
define_method(:"all_#{c[0].to_s}") do
|
52
|
+
# puts "Looking for all [#{class_names*', '}] in #{@children.map{|q| q.class.name}.inspect}"
|
53
|
+
children_of_type(c)
|
54
|
+
end
|
55
|
+
# REVISIT: Allow deleting and adding instances to the array
|
56
|
+
# new_child = KiCad.parse('(some new node)').value
|
57
|
+
# @children.append(new_child)
|
58
|
+
else
|
59
|
+
class_name = 'KiCad::AST::'+to_class_name(c)
|
60
|
+
define_method(:"#{c}") do
|
61
|
+
# puts "Looking for first #{class_name} in #{@children.map{|q| q.class.name}.inspect}"
|
62
|
+
a = children_of_type(c)
|
63
|
+
puts "Choosing first #{self.class.name}.#{c} of #{a.size}" if a.size > 1
|
64
|
+
a.first
|
65
|
+
end
|
66
|
+
# Allow deleting this instance
|
67
|
+
define_method(:"unset_#{c.to_s}") do
|
68
|
+
child = send(:"#{c}")
|
69
|
+
@children = @children - [child] if child
|
70
|
+
child ? true : nil
|
71
|
+
end
|
72
|
+
end
|
29
73
|
end
|
30
74
|
end
|
75
|
+
|
76
|
+
def self.to_class_name sym
|
77
|
+
sym.to_s.gsub(/\A[a-z]|_[a-z]/) {|from| from[-1].upcase }
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.to_symbol class_name
|
81
|
+
class_name.to_s.gsub(/[A-Z]/) {|from| '_'+from[-1].downcase }.sub(/\A_/,'')
|
82
|
+
end
|
31
83
|
end
|
32
84
|
|
33
85
|
class KicadSymbolLib < Node
|
34
|
-
|
35
|
-
super
|
36
|
-
end
|
86
|
+
child_types :version, :generator, :generator_version, [:symbol]
|
37
87
|
end
|
38
88
|
|
39
|
-
|
89
|
+
class Generator < Node
|
90
|
+
end
|
40
91
|
|
41
|
-
class
|
92
|
+
class GeneratorVersion < Node
|
42
93
|
end
|
43
94
|
|
44
|
-
|
95
|
+
class Version < Node
|
96
|
+
end
|
97
|
+
|
98
|
+
# Uncomment or add whatever class you need to customise:
|
99
|
+
|
100
|
+
# Position Identifier
|
45
101
|
class At < Node
|
102
|
+
value_types :x => Float, :y => Float, :angle => Float
|
46
103
|
end
|
47
104
|
|
48
|
-
|
105
|
+
# Coordinate Point List
|
106
|
+
class Pts < Node
|
107
|
+
value_types({})
|
108
|
+
child_types [:xy]
|
49
109
|
end
|
50
110
|
|
51
|
-
class
|
111
|
+
class Xy < Node
|
112
|
+
value_types :x => Float, :y => Float
|
52
113
|
end
|
53
114
|
|
54
|
-
|
115
|
+
# Stroke Definition
|
116
|
+
class Stroke < Node
|
117
|
+
child_types :width, :type, :color
|
55
118
|
end
|
56
119
|
|
57
|
-
class
|
120
|
+
class Width < Node
|
121
|
+
value_types :width => Float
|
58
122
|
end
|
59
123
|
|
60
|
-
class
|
124
|
+
class Type < Node
|
125
|
+
value_types :type => [:dash, :dash_dot, :dash_dot_dot, :dot, :default, :solid]
|
61
126
|
end
|
62
127
|
|
63
|
-
class
|
128
|
+
class Color < Node
|
129
|
+
value_types :r => Integer, :g => Integer, :b => Integer, :a => Integer
|
64
130
|
end
|
65
131
|
|
66
|
-
|
132
|
+
# Text Effects
|
133
|
+
class Effects < Node
|
134
|
+
child_types :font, :justify, :hide
|
67
135
|
end
|
68
136
|
|
69
137
|
class Font < Node
|
138
|
+
child_types :face, :size, :thickness, :bold, :italic, :line_spacing
|
70
139
|
end
|
71
140
|
|
72
|
-
class
|
141
|
+
class Face < Node
|
142
|
+
value_types :face_name => String
|
73
143
|
end
|
74
144
|
|
75
|
-
class
|
145
|
+
class Size < Node
|
146
|
+
value_types :height => Float, :width => Float
|
76
147
|
end
|
77
148
|
|
78
|
-
class
|
149
|
+
class Thickness < Node
|
150
|
+
value_types :thickness => Float
|
79
151
|
end
|
80
152
|
|
81
|
-
class
|
153
|
+
class Bold < Node
|
154
|
+
value_types :bold => [:no, :yes]
|
82
155
|
end
|
83
156
|
|
84
|
-
class
|
157
|
+
class Italic < Node
|
158
|
+
value_types :bold => [:no, :yes]
|
85
159
|
end
|
86
160
|
|
87
|
-
class
|
161
|
+
class LineSpacing < Node
|
162
|
+
value_types :line_spacing => Float
|
88
163
|
end
|
89
164
|
|
90
|
-
class
|
165
|
+
class Justify < Node
|
166
|
+
value_types :justify => [[:right, :left, :top, :bottom, :mirror]] # Can have multiple
|
91
167
|
end
|
92
168
|
|
93
|
-
class
|
169
|
+
class Hide < Node
|
170
|
+
value_types :hide => [:no, :yes]
|
94
171
|
end
|
95
172
|
|
96
|
-
|
173
|
+
# Page Settings
|
174
|
+
class Paper < Node
|
175
|
+
# REVISIT: Either paper_size or width/height
|
176
|
+
value_types :paper_size => [:A0, :A1, :A2, :A3, :A4, :A5, :A, :B, :C, :D, :E],
|
177
|
+
:width => Float, :height => Float,
|
178
|
+
:portrait => [:portrait]
|
97
179
|
end
|
98
180
|
|
99
|
-
|
181
|
+
# Title Block
|
182
|
+
class TitleBlock < Node
|
183
|
+
child_types :title, :date, :rev, :company, # All take one string as value
|
184
|
+
[:comment] # N (1..9) and String # REVISIT: Implement Comment
|
100
185
|
end
|
101
186
|
|
102
|
-
|
187
|
+
# Properties
|
188
|
+
class Property < Node
|
189
|
+
value_types :key => String, :value => String
|
190
|
+
child_types :at, :effects
|
191
|
+
|
192
|
+
# Set or clear (hide) on the property_node
|
193
|
+
def hide=(h = true)
|
194
|
+
v = (h ? :yes : :no)
|
195
|
+
if !effects
|
196
|
+
# puts "No effects yet"
|
197
|
+
prop = KiCad.parse(%Q{(effects(hide #{v}))})&.value
|
198
|
+
@children.append(prop) if prop
|
199
|
+
elsif (existing = effects.hide)
|
200
|
+
# puts "Effects and hide already"
|
201
|
+
existing.hide = v
|
202
|
+
else
|
203
|
+
# Create new (hide) node:
|
204
|
+
# puts "Effects but no hide"
|
205
|
+
prop = KiCad.parse(%Q{(hide #{v})})&.value
|
206
|
+
@children.append(prop) if prop
|
207
|
+
end
|
208
|
+
end
|
103
209
|
end
|
104
210
|
|
105
|
-
|
211
|
+
# Universally Unique Identifier
|
212
|
+
class Uuid < Node
|
213
|
+
value_types :uuid => String
|
106
214
|
end
|
107
215
|
|
108
|
-
|
216
|
+
# Images
|
217
|
+
class Image < Node
|
218
|
+
child_types :at, :scale, :layer, :uuid, :data
|
109
219
|
end
|
110
220
|
|
111
|
-
class
|
221
|
+
class Data < Node
|
222
|
+
value_types :data => String # REVISIT: Base64 data - not encoded as a string I think?
|
112
223
|
end
|
113
224
|
|
114
|
-
class
|
225
|
+
class Circle < Node
|
226
|
+
child_types :center, :radius, :stroke, :fill
|
227
|
+
end
|
228
|
+
|
229
|
+
class Center < Xy
|
230
|
+
# value_types :x => Float, :y => Float
|
115
231
|
end
|
116
232
|
|
117
233
|
class Radius < Node
|
234
|
+
value_types :radius => Float
|
235
|
+
end
|
236
|
+
|
237
|
+
class Fill < Node
|
238
|
+
value_types :fill => [:no, :yes]
|
239
|
+
end
|
240
|
+
|
241
|
+
class Arc < Node
|
242
|
+
child_types :start, :mid, :end, :stroke, :fill
|
243
|
+
end
|
244
|
+
|
245
|
+
class Start < Xy
|
246
|
+
# value_types :x => Float, :y => Float
|
247
|
+
end
|
248
|
+
|
249
|
+
class Mid < Xy
|
250
|
+
# value_types :x => Float, :y => Float
|
251
|
+
end
|
252
|
+
|
253
|
+
class End < Xy
|
254
|
+
# value_types :x => Float, :y => Float
|
118
255
|
end
|
119
256
|
|
120
257
|
class Rectangle < Node
|
258
|
+
child_types :start, :end, :stroke, :fill
|
121
259
|
end
|
122
260
|
|
123
|
-
class
|
261
|
+
class Polyline < Node
|
262
|
+
child_types :pts, :stroke, :fill
|
124
263
|
end
|
125
264
|
|
126
|
-
class
|
265
|
+
class Text < Node
|
266
|
+
value_types :text => String
|
267
|
+
child_types :at, :effects
|
127
268
|
end
|
128
269
|
|
129
|
-
class
|
270
|
+
class Offset < Xy
|
271
|
+
# value_types :x => Float, :y => Float
|
130
272
|
end
|
131
273
|
|
132
|
-
|
274
|
+
# Symbol Pins
|
275
|
+
class Pin < Node
|
276
|
+
value_types :electrical_type => [
|
277
|
+
:input, # Pin is an input.
|
278
|
+
:output, # Pin is an output.
|
279
|
+
:bidirectional, # Pin can be both input and output.
|
280
|
+
:tri_state, # Pin is a tri-state output.
|
281
|
+
:passive, # Pin is electrically passive.
|
282
|
+
:free, # Not internally connected.
|
283
|
+
:unspecified, # Pin does not have a specified electrical type.
|
284
|
+
:power_in, # Pin is a power input.
|
285
|
+
:power_out, # Pin is a power output.
|
286
|
+
:open_collector, # Pin is an open collector output.
|
287
|
+
:open_emitter, # Pin is an open emitter output.
|
288
|
+
:no_connect, # Pin has no electrical connection.
|
289
|
+
], :graphic_style => [
|
290
|
+
:line,
|
291
|
+
:inverted,
|
292
|
+
:clock,
|
293
|
+
:inverted_clock,
|
294
|
+
:input_low,
|
295
|
+
:clock_low,
|
296
|
+
:output_low,
|
297
|
+
:edge_clock_high,
|
298
|
+
:non_logic
|
299
|
+
]
|
300
|
+
child_types :length, :name, :number
|
133
301
|
end
|
134
302
|
|
135
|
-
class
|
303
|
+
class Length < Node
|
304
|
+
value_types :length => Float
|
136
305
|
end
|
137
306
|
|
138
|
-
class
|
307
|
+
class Name < Node
|
308
|
+
value_types :name => String
|
309
|
+
child_types :effects
|
139
310
|
end
|
140
311
|
|
141
|
-
class
|
312
|
+
class Number < Node
|
313
|
+
value_types :number => String
|
314
|
+
child_types :effects
|
315
|
+
end
|
316
|
+
|
317
|
+
class Polygon < Node
|
318
|
+
child_types :pts, :stroke, :fill
|
319
|
+
end
|
320
|
+
|
321
|
+
# Symbols
|
322
|
+
class Symbol < Node
|
323
|
+
value_types :id => String
|
324
|
+
child_types :extends, :exclude_from_sym, :pin_numbers, :pin_names, :in_bom, :on_board,
|
325
|
+
[:property],
|
326
|
+
[:shape, :circle, :rectangle, :text, :polyline, :arc], # REVISIT: Lots more types of graphic items here...
|
327
|
+
[:pin],
|
328
|
+
[:symbol], # Child symbols (units) embedded in a parent
|
329
|
+
:unit_name,
|
330
|
+
:embedded_fonts
|
331
|
+
|
332
|
+
# Get or set Property values by key, or as a Hash
|
333
|
+
def property_node k
|
334
|
+
self.all_property.detect{|p| p.key == k}
|
335
|
+
end
|
336
|
+
|
337
|
+
def property k = nil
|
338
|
+
if k
|
339
|
+
property_node(k)&.value
|
340
|
+
else # Return all properties as a Hash
|
341
|
+
Hash[*self.all_property.map{|p| [p.key, p.value] }.flatten]
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
def [](k)
|
346
|
+
property[k]
|
347
|
+
end
|
348
|
+
|
349
|
+
def []=(k, v)
|
350
|
+
puts "Setting property #{k} to #{v.inspect}"
|
351
|
+
if (p = property_node)
|
352
|
+
p.send(:"#{self.class.to_symbol k}=", v)
|
353
|
+
else # Create new Property using the parser:
|
354
|
+
prop = KiCad.parse(%Q{
|
355
|
+
(property "#{k}" #{String === v ? v.inspect : v.to_s}
|
356
|
+
(at 0 0 0)
|
357
|
+
(effects(font(size 1.27 1.27)))
|
358
|
+
(hide yes)
|
359
|
+
)
|
360
|
+
})&.value
|
361
|
+
@children.append(prop) if prop
|
362
|
+
end
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
366
|
+
class Extends < Node
|
367
|
+
value_types :library_id => String
|
368
|
+
end
|
369
|
+
|
370
|
+
class PinNumbers < Node
|
371
|
+
value_types :hide => [:no, :yes]
|
372
|
+
end
|
373
|
+
|
374
|
+
class PinNames < Node
|
375
|
+
child_types :offset
|
376
|
+
value_types :hide => [:no, :yes]
|
377
|
+
end
|
378
|
+
|
379
|
+
class InBom < Node
|
380
|
+
value_types :in_bom => [:no, :yes]
|
381
|
+
end
|
382
|
+
|
383
|
+
class OnBoard < Node
|
384
|
+
value_types :on_board => [:no, :yes]
|
385
|
+
end
|
386
|
+
|
387
|
+
class UnitName < Node
|
388
|
+
value_types :name => String
|
389
|
+
end
|
390
|
+
|
391
|
+
class EmbeddedFonts < Node
|
392
|
+
value_types :embedded_fonts => [:no, :yes]
|
393
|
+
end
|
394
|
+
|
395
|
+
class ExcludeFromSim < Node
|
396
|
+
value_types :exclude_from_sim => [:no, :yes]
|
142
397
|
end
|
143
|
-
=end
|
144
398
|
|
145
399
|
end
|
146
400
|
end
|
data/lib/kicad/grammar.rb
CHANGED
@@ -33,19 +33,23 @@ module KiCad
|
|
33
33
|
|
34
34
|
module Node2
|
35
35
|
def s1
|
36
|
-
elements[
|
36
|
+
elements[0]
|
37
37
|
end
|
38
38
|
|
39
|
-
def
|
39
|
+
def s2
|
40
40
|
elements[2]
|
41
41
|
end
|
42
42
|
|
43
|
-
def
|
43
|
+
def values
|
44
44
|
elements[3]
|
45
45
|
end
|
46
46
|
|
47
|
-
def
|
48
|
-
elements[
|
47
|
+
def nodes
|
48
|
+
elements[4]
|
49
|
+
end
|
50
|
+
|
51
|
+
def s3
|
52
|
+
elements[6]
|
49
53
|
end
|
50
54
|
end
|
51
55
|
|
@@ -74,84 +78,88 @@ module KiCad
|
|
74
78
|
end
|
75
79
|
|
76
80
|
i0, s0 = index, []
|
77
|
-
|
78
|
-
r1 = true
|
79
|
-
@index += match_len
|
80
|
-
else
|
81
|
-
terminal_parse_failure('\'(\'')
|
82
|
-
r1 = nil
|
83
|
-
end
|
81
|
+
r1 = _nt_s
|
84
82
|
s0 << r1
|
85
83
|
if r1
|
86
|
-
|
84
|
+
if (match_len = has_terminal?('(', false, index))
|
85
|
+
r2 = true
|
86
|
+
@index += match_len
|
87
|
+
else
|
88
|
+
terminal_parse_failure('\'(\'')
|
89
|
+
r2 = nil
|
90
|
+
end
|
87
91
|
s0 << r2
|
88
92
|
if r2
|
89
|
-
|
90
|
-
loop do
|
91
|
-
i4, s4 = index, []
|
92
|
-
r5 = _nt_value
|
93
|
-
s4 << r5
|
94
|
-
if r5
|
95
|
-
r6 = _nt_s
|
96
|
-
s4 << r6
|
97
|
-
end
|
98
|
-
if s4.last
|
99
|
-
r4 = instantiate_node(SyntaxNode,input, i4...index, s4)
|
100
|
-
r4.extend(Node0)
|
101
|
-
else
|
102
|
-
@index = i4
|
103
|
-
r4 = nil
|
104
|
-
end
|
105
|
-
if r4
|
106
|
-
s3 << r4
|
107
|
-
else
|
108
|
-
break
|
109
|
-
end
|
110
|
-
end
|
111
|
-
if s3.empty?
|
112
|
-
@index = i3
|
113
|
-
r3 = nil
|
114
|
-
else
|
115
|
-
r3 = instantiate_node(SyntaxNode,input, i3...index, s3)
|
116
|
-
end
|
93
|
+
r3 = _nt_s
|
117
94
|
s0 << r3
|
118
95
|
if r3
|
119
|
-
|
96
|
+
s4, i4 = [], index
|
120
97
|
loop do
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
if
|
125
|
-
|
126
|
-
|
98
|
+
i5, s5 = index, []
|
99
|
+
r6 = _nt_value
|
100
|
+
s5 << r6
|
101
|
+
if r6
|
102
|
+
r7 = _nt_s
|
103
|
+
s5 << r7
|
127
104
|
end
|
128
|
-
if
|
129
|
-
|
130
|
-
|
105
|
+
if s5.last
|
106
|
+
r5 = instantiate_node(SyntaxNode,input, i5...index, s5)
|
107
|
+
r5.extend(Node0)
|
131
108
|
else
|
132
|
-
@index =
|
133
|
-
|
109
|
+
@index = i5
|
110
|
+
r5 = nil
|
134
111
|
end
|
135
|
-
if
|
136
|
-
|
112
|
+
if r5
|
113
|
+
s4 << r5
|
137
114
|
else
|
138
115
|
break
|
139
116
|
end
|
140
117
|
end
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
118
|
+
if s4.empty?
|
119
|
+
@index = i4
|
120
|
+
r4 = nil
|
121
|
+
else
|
122
|
+
r4 = instantiate_node(SyntaxNode,input, i4...index, s4)
|
123
|
+
end
|
124
|
+
s0 << r4
|
125
|
+
if r4
|
126
|
+
s8, i8 = [], index
|
127
|
+
loop do
|
128
|
+
i9, s9 = index, []
|
129
|
+
r10 = _nt_node
|
130
|
+
s9 << r10
|
131
|
+
if r10
|
132
|
+
r11 = _nt_s
|
133
|
+
s9 << r11
|
134
|
+
end
|
135
|
+
if s9.last
|
136
|
+
r9 = instantiate_node(SyntaxNode,input, i9...index, s9)
|
137
|
+
r9.extend(Node1)
|
138
|
+
else
|
139
|
+
@index = i9
|
140
|
+
r9 = nil
|
141
|
+
end
|
142
|
+
if r9
|
143
|
+
s8 << r9
|
144
|
+
else
|
145
|
+
break
|
146
|
+
end
|
150
147
|
end
|
151
|
-
|
152
|
-
|
153
|
-
|
148
|
+
r8 = instantiate_node(SyntaxNode,input, i8...index, s8)
|
149
|
+
s0 << r8
|
150
|
+
if r8
|
151
|
+
if (match_len = has_terminal?(')', false, index))
|
152
|
+
r12 = true
|
153
|
+
@index += match_len
|
154
|
+
else
|
155
|
+
terminal_parse_failure('\')\'')
|
156
|
+
r12 = nil
|
157
|
+
end
|
154
158
|
s0 << r12
|
159
|
+
if r12
|
160
|
+
r13 = _nt_s
|
161
|
+
s0 << r13
|
162
|
+
end
|
155
163
|
end
|
156
164
|
end
|
157
165
|
end
|
data/lib/kicad/grammar.tt
CHANGED
data/lib/kicad/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kicad
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Clifford Heath
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date:
|
10
|
+
date: 2025-05-09 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: bundler
|
@@ -114,7 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
114
114
|
- !ruby/object:Gem::Version
|
115
115
|
version: '0'
|
116
116
|
requirements: []
|
117
|
-
rubygems_version: 3.6.
|
117
|
+
rubygems_version: 3.6.2
|
118
118
|
specification_version: 4
|
119
119
|
summary: Load and rewrite Kicad s-expression files into a tree structure for scripting
|
120
120
|
test_files: []
|