circuitdata 0.6.0 → 0.6.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.
@@ -29,7 +29,7 @@
29
29
  "description": "The name of the manufacturer"
30
30
  },
31
31
  "ipc-sm-840-class": {
32
- "type": "list",
32
+ "type": "string",
33
33
  "enum": ["T", "H"],
34
34
  "uom": null,
35
35
  "description": "Soldermask to meet IPC SM 840 Class."
@@ -180,12 +180,30 @@
180
180
  "thickness_min_micron": {
181
181
  "type": "number",
182
182
  "uom": ["um"],
183
- "description": "The minimum thickness in micrometer."
183
+ "description": "The minimum thickness."
184
184
  },
185
185
  "thickness_max_micron": {
186
186
  "type": "number",
187
187
  "uom": ["um"],
188
- "description": "The maximum thickness in micrometer."
188
+ "description": "The maximum thickness."
189
+ },
190
+ "presence_top_boolean": {
191
+ "type": "boolean",
192
+ "uom": null,
193
+ "description": "Indicates presence/capability on top"
194
+ },
195
+ "presence_bottom_boolean": {
196
+ "type": "boolean",
197
+ "uom": null,
198
+ "description": "Indicates presence/capability at bottom"
199
+ },
200
+ "numeric_single_or_range": {
201
+ "type": "string",
202
+ "pattern": "^[-+]?([0-9]*\\.[0-9]+|[0-9]+)$|^([0-9]*|[0-9].[0-9]*)\\.\\.\\.([0-9]|[0-9].[0-9]*)$"
203
+ },
204
+ "boolean_true_false_or_both": {
205
+ "type": "string",
206
+ "pattern": "^[t,T][r,R][u,U][e,E]$|^[f,F][a,A][l,L][s,S][e,E]$|^[t,T][r,R][u,U][e,E],.[f,F][a,A][l,L][s,S][e,E]$|^[f,F][a,A][l,L][s,S][e,E],.[t,T][r,R][u,U][e,E]$"
189
207
  },
190
208
  "range": {
191
209
  "type": "string",
@@ -201,64 +219,92 @@
201
219
  "elements": {
202
220
  "conductive_layer": {
203
221
  "count": {
204
- "type": "integer",
222
+ "type": "number",
205
223
  "uom": null,
206
- "description": "The number of conductive layers."
224
+ "description": "The number of conductive layers.",
225
+ "minimum": 1,
226
+ "maximum": 100,
227
+ "multipleOf": 1.0
207
228
  },
208
229
  "minimum_internal_track_width": {
209
230
  "type": "number",
210
- "uom": ["um"],
231
+ "uom": ["mm"],
211
232
  "description": "The minimum nominal width of conductors on internal/unplated layers (minimum track)."
212
233
  },
213
234
  "minimum_external_track_width": {
214
235
  "type": "number",
215
- "uom": ["um"],
236
+ "uom": ["mm"],
216
237
  "description": "The minimum nominal width of conductors on external/plated layers (minimum track). If only only one minimum track is present, is should be here."
217
238
  },
218
239
  "minimum_internal_spacing_width": {
219
240
  "type": "number",
220
- "uom": ["um"],
241
+ "uom": ["mm"],
221
242
  "description": "The minimum gap between two conductors on the internal layers."
222
243
  },
223
244
  "minimum_external_spacing_width": {
224
245
  "type": "number",
246
+ "uom": ["mm"],
225
247
  "description": "The minimum gap between two conductors on the external layers. If only one minimum gap is present, is should be here."
226
248
  },
227
249
  "external_base_copper_thickness": {
228
250
  "type": "number",
229
251
  "enum": [5.1, 8.5, 12, 17.1, 25.7, 34.3, 68.6, 102.9, 137.2, 171.5, 205.7, 240, 342.9, 480.1],
230
252
  "uom": ["um"],
231
- "description": "Finished base copper thickness following IPC Class on the up to two external layers in micrometer."
253
+ "description": "Finished base copper thickness following IPC Class on the up to two external layers."
232
254
  },
233
255
  "internal_base_copper_thickness": {
234
256
  "type": "number",
235
257
  "enum": [5.1, 8.5, 12, 17.1, 25.7, 34.3, 68.6, 102.9, 137.2, 171.5, 205.7, 240, 342.9, 480.1],
236
258
  "uom": ["um"],
237
- "description": "Finished base copper thickness following IPC Class on the internal layers in micrometer."
259
+ "description": "Finished base copper thickness following IPC Class on the internal layers."
238
260
  },
239
261
  "copper_foil_roughness": {
240
262
  "type": "string",
241
263
  "enum": ["S", "L", "V"],
242
- "uom": ["um"],
264
+ "enum_description": {
265
+ "S": "Standard profile",
266
+ "L": "Low profile",
267
+ "V": "Very low profile"
268
+ },
269
+ "uom": null,
243
270
  "description": "The roughness of the copper foil."
244
271
  },
245
272
  "copper_coverage_average": {
246
273
  "type": "number",
247
274
  "uom": ["%"],
248
- "description": "The average copper coverage of the board. UoM is percentage"
275
+ "description": "The average copper coverage of the board"
249
276
  }
250
277
  },
251
278
  "final_finish": {
252
279
  "finish": {
253
280
  "type": "string",
254
281
  "enum": ["none", "c_bare_copper", "isn", "iag", "enig", "enepig", "osp", "ht_osp", "g", "GS", "t_fused", "tlu_unfused", "dig", "gwb-1_ultrasonic", "gwb-2-thermosonic", "s_hasl", "b1_lfhasl"],
282
+ "enum_description": {
283
+ "none": "No final finish should be used",
284
+ "c_bare_copper": "AABUS",
285
+ "isn": "IPC-4554 Immersion Tin",
286
+ "iag": "IPC-4553 Immersion Silver",
287
+ "enig": "IPC-4552 Immersion Gold",
288
+ "enepig": "IPC-4556 ENEPIG",
289
+ "osp": "J-STD-003 Organic Solderability Preservative",
290
+ "ht_osp": "J-STD-003 High Temperature OSP",
291
+ "g": "ASTM-B-488 Gold for edge printed board connectors and areas not to be soldered",
292
+ "GS": "J-STD-003 Gold Electroplate on areas to be soldered",
293
+ "t_fused": "J-STD-003 Electrodeposited Tin-Lead (fused)",
294
+ "tlu_unfused": "J-STD-003 Electrodeposited Tin-Lead Unfused",
295
+ "dig": "J-STD-003 Direct Immersion Gold (Solderable Surface)",
296
+ "gwb-1_ultrasonic": "ASTM-B-488 Gold Electroplate for areas to be wire bonded (ultrasonic)",
297
+ "gwb-2-thermosonic": "ASTM-B-488 Gold Electroplate for areas to be wire bonded (thermosonic)",
298
+ "s_hasl": "J-STD-003_J-STD-006 Solder Coating over Bare Copper (HASL)",
299
+ "b1_lfhasl": "J-STD-003_J-STD-006 Lead-Free Solder Coating over Bare Copper (Lead-Free HASL, Lead free HASL)"
300
+ },
255
301
  "uom": null,
256
302
  "description": "The material/method/surface to be used in the finish."
257
303
  },
258
304
  "area": {
259
305
  "type": "number",
260
306
  "uom": ["dm2"],
261
- "description": "The area that the finish will cover, in square decimeter."
307
+ "description": "The area that the finish will cover"
262
308
  }
263
309
  },
264
310
  "soldermask": {
@@ -273,31 +319,11 @@
273
319
  "uom": null,
274
320
  "description": "The finish of the soldermask."
275
321
  },
276
- "min_thickness": {
277
- "type": "number",
278
- "uom": ["um"],
279
- "description": "The minimum thickness of the soldermask."
280
- },
281
- "max_thickness": {
282
- "type": "number",
283
- "uom": ["um"],
284
- "description": "The maximum thickness of the soldermask."
285
- },
286
322
  "material": {
287
323
  "type": "string",
288
324
  "uom": null,
289
325
  "description": "The name of a material that appears in the materials section"
290
326
  },
291
- "top": {
292
- "type": "boolean",
293
- "uom": null,
294
- "description": "Indicates soldermask presence/capability at top"
295
- },
296
- "bottom": {
297
- "type": "boolean",
298
- "uom": null,
299
- "description": "Indicates soldermask presence/capability at bottom"
300
- },
301
327
  "allow_touchups": {
302
328
  "type": "boolean",
303
329
  "uom": null,
@@ -309,16 +335,6 @@
309
335
  "type": "string",
310
336
  "uom": null,
311
337
  "description": "This describes the color based on the name of the color; white, yellow. If a specific color needs to be defined, this can be done custom -> colors section."
312
- },
313
- "top": {
314
- "type": "boolean",
315
- "uom": null,
316
- "description": "Indicates legend presence/capability at top"
317
- },
318
- "bottom": {
319
- "type": "boolean",
320
- "uom": null,
321
- "description": "Indicates legend presence/capability at bottom"
322
338
  }
323
339
  },
324
340
  "stiffener": {
@@ -350,16 +366,6 @@
350
366
  "uom": null,
351
367
  "description": "The total thickness of the coverlay"
352
368
  },
353
- "top": {
354
- "type": "boolean",
355
- "uom": null,
356
- "description": "Indicates coverlay presence/capability at top"
357
- },
358
- "bottom": {
359
- "type": "boolean",
360
- "uom": null,
361
- "description": "Indicates coverlay presence/capability at bottom"
362
- },
363
369
  "material": {
364
370
  "type": "string",
365
371
  "uom": null,
@@ -371,16 +377,6 @@
371
377
  "type": "integer",
372
378
  "uom": null,
373
379
  "description": ""
374
- },
375
- "top": {
376
- "type": "boolean",
377
- "uom": null,
378
- "description": "Indicates peelable mask presence/capability at top"
379
- },
380
- "bottom": {
381
- "type": "boolean",
382
- "uom": null,
383
- "description": "Indicates peelable mask presence/capability at bottom"
384
380
  }
385
381
  },
386
382
  "kapton_tape": {
@@ -388,40 +384,6 @@
388
384
  "type": "boolean",
389
385
  "uom": null,
390
386
  "description": "If alternative to DuPont™ Kapton® HN general-purpose film can be used"
391
- },
392
- "top": {
393
- "type": "boolean",
394
- "uom": null,
395
- "description": "Indicates kapton tape presence/capability at top"
396
- },
397
- "bottom": {
398
- "type": "boolean",
399
- "uom": null,
400
- "description": "Indicates kapton tape presence/capability at top"
401
- }
402
- },
403
- "conductive_carbon_print": {
404
- "top": {
405
- "type": "boolean",
406
- "uom": null,
407
- "description": "Indicates Conductive Carbon Print presence/capability at top"
408
- },
409
- "bottom": {
410
- "type": "boolean",
411
- "uom": null,
412
- "description": "Indicates Conductive Carbon Print presence/capability at bottom"
413
- }
414
- },
415
- "silver_print": {
416
- "top": {
417
- "type": "boolean",
418
- "uom": null,
419
- "description": "Indicates silver print presence/capability at top"
420
- },
421
- "bottom": {
422
- "type": "boolean",
423
- "uom": null,
424
- "description": "Indicates silver print presence/capability at bottom"
425
387
  }
426
388
  },
427
389
  "inner_packaging": {
@@ -630,34 +592,6 @@
630
592
  "description": "The weight of the array measured in grams."
631
593
  }
632
594
  },
633
- "inner_packaging": {
634
- "type_of_bag": {
635
- "type": "string",
636
- "enum": ["a", "b", "c", "d"],
637
- "uom": null,
638
- "description": "The material of the bag to be used"
639
- },
640
- "hic": {
641
- "type": "boolean",
642
- "uom": null,
643
- "description": "True to include a Humidity Indicator Card (HIC), False to not"
644
- },
645
- "esd": {
646
- "type": "boolean",
647
- "uom": null,
648
- "description": "True to indicate that packaging for ESD-sensitive required."
649
- },
650
- "desiccant": {
651
- "type": "boolean",
652
- "uom": null,
653
- "description": "True to indicate that a desiccant material is required."
654
- },
655
- "vacuum": {
656
- "type": "boolean",
657
- "uom": null,
658
- "description": "True to indicate that vacuum is needed for shrinkage - no heat rap or shrink rap allowed."
659
- }
660
- },
661
595
  "mechanical": {
662
596
  "edge_bevelling": {
663
597
  "type": "boolean",
@@ -779,6 +713,9 @@
779
713
  },
780
714
  "standards": {
781
715
  "type": "array",
716
+ "items": {
717
+ "type": "string"
718
+ },
782
719
  "uom": null,
783
720
  "description": "Possible values are the ones listed in the subelement \"standards\" but typical will be \"ul\" and \"rohs\". Separate by comma."
784
721
  },
@@ -925,35 +862,35 @@
925
862
  "type": "string",
926
863
  "enum": ["1", "2", "3", "3A", "3S", "3M"],
927
864
  "uom": null,
928
- "description": "Requirements according to IPC 6012 class."
865
+ "description": "Requirements according to IPC 6012 class"
929
866
  },
930
867
  "ipc_6013_class": {
931
868
  "type": "string",
932
869
  "enum": ["1", "2", "3"],
933
870
  "uom": null,
934
- "description": "Requirements according to IPC 6013 for flexible or rigid-flex boards."
871
+ "description": "Requirements according to IPC 6013 for flexible or rigid-flex boards"
935
872
  },
936
- "ipc_6018":{
873
+ "ipc_6018": {
937
874
  "type": "boolean",
938
875
  "uom": null,
939
- "description": "IPC-6018 Microwave End Product Board Inspection and Test."
876
+ "description": "IPC-6018 Microwave End Product Board Inspection and Test"
940
877
  }
941
878
  },
942
879
  "testing": {
943
880
  "netlist": {
944
881
  "type": "boolean",
945
882
  "uom": null,
946
- "description": "100% Netlist testing according to IPC-D-356, ODB++ or IPC2581."
883
+ "description": "100% Netlist testing according to IPC-D-356, ODB++ or IPC2581"
947
884
  },
948
885
  "allow_generate_netlist": {
949
886
  "type": "boolean",
950
887
  "uom": null,
951
- "description": "Allow Netlist to be generated from Gerber or other file format if needed."
888
+ "description": "Allow Netlist to be generated from Gerber or other file format if needed"
952
889
  },
953
890
  "hipot": {
954
891
  "type": "boolean",
955
892
  "uom": null,
956
- "description": " HiPot Test (Dielectric Withstanding Voltage Test)."
893
+ "description": "HiPot Test (Dielectric Withstanding Voltage Test)"
957
894
  },
958
895
  "4_wire": {
959
896
  "type": "boolean",
@@ -1136,4 +1073,4 @@
1136
1073
  }
1137
1074
  }
1138
1075
  }
1139
- }
1076
+ }
@@ -0,0 +1,176 @@
1
+ class Circuitdata::Tools
2
+ def initialize()
3
+ require 'json'
4
+ @schema_path = File.join(File.dirname(__FILE__), 'schema_files/v1/ottp_circuitdata_schema.json')
5
+ @definitions_path = File.join(File.dirname(__FILE__), 'schema_files/v1/ottp_circuitdata_schema_definitions.json')
6
+ @ra = {}
7
+ end
8
+
9
+ def update_ra(type, key, value)
10
+ parsed_elements = Circuitdata.read_json(@definitions_path)[2]
11
+ unless @ra[:structured].has_key? key
12
+ @ra[:structured][key] = {
13
+ :type => value[:type],
14
+ :elements => {},
15
+ :name => nil,
16
+ :description => nil,
17
+ :aliases => nil
18
+ }
19
+ @ra[:structured][key][:name] = value[:name] if value.has_key? :name
20
+ @ra[:structured][key][:description] = value[:decription] if value.has_key? :decription
21
+ if value.has_key? :aliases
22
+ @ra[:structured][key][:aliases] = value[:aliases] unless value[:aliases] == ""
23
+ end
24
+ end
25
+ if value.has_key? :properties
26
+ value[:properties].each do |skey, svalue|
27
+ unless @ra[:structured][key][:elements].has_key? skey
28
+ @ra[:structured][key][:elements][skey] = {
29
+ :in_product_generic => false,
30
+ :in_product_stackup => false,
31
+ :in_profile_default => false,
32
+ :in_profile_enforced => false,
33
+ :in_profile_restricted => false,
34
+ :in_capabilities => false,
35
+ :type => nil,
36
+ :arrayitems => nil,
37
+ :enum => nil,
38
+ :description => nil,
39
+ :uom => nil,
40
+ :minimum => nil,
41
+ :maximum => nil,
42
+ :in_profile_restricted_regex => nil,
43
+ :in_capabilities_regex => nil
44
+ }
45
+ if svalue.has_key? :$ref
46
+ elements = svalue[:$ref].split('/')
47
+ if elements.length < 5
48
+ element = parsed_elements[elements[1].to_sym][elements[2].to_sym][elements[3].to_sym]
49
+ else
50
+ element = parsed_elements[elements[1].to_sym][elements[2].to_sym][elements[3].to_sym][elements[4].to_sym]
51
+ end
52
+ else
53
+ element = nil
54
+ [:rigid_conductive_layer, :flexible_conductive_layer].include? key.to_sym ? newkey = :conductive_layer : newkey = key.to_sym
55
+ if parsed_elements[:definitions][:elements].has_key? newkey
56
+ element = parsed_elements[:definitions][:elements][newkey][skey.to_sym] if parsed_elements[:definitions][:elements][newkey].has_key? skey.to_sym
57
+ end
58
+ end
59
+ unless element.nil?
60
+ if element.has_key? :type
61
+ @ra[:structured][key][:elements][skey][:type] = element[:type]
62
+ if element[:type] == "array"
63
+ if element.has_key? :items and element[:items].has_key? :type
64
+ @ra[:structured][key][:elements][skey][:arrayitems] == element[:items][:type]
65
+ end
66
+ end
67
+ end
68
+ @ra[:structured][key][:elements][skey][:enum] = element[:enum] if element.has_key? :enum
69
+ @ra[:structured][key][:elements][skey][:description] = element[:description] if element.has_key? :description
70
+ @ra[:structured][key][:elements][skey][:uom] = element[:uom] if element.has_key? :uom
71
+ @ra[:structured][key][:elements][skey][:minimum] = element[:minimum] if element.has_key? :minimum
72
+ @ra[:structured][key][:elements][skey][:maximum] = element[:maximum] if element.has_key? :maximum
73
+ end
74
+ else
75
+ if [:in_profile_restricted, :in_capabilities].include? type
76
+ case @ra[:structured][key][:elements][skey][:type]
77
+ when *["number", "integer", "boolean", "string"]
78
+ @ra[:structured][key][:elements][skey][:type] = "number" if @ra[:structured][key][:elements][skey][:type] == "integer"
79
+ unless ( svalue.has_key? :type and svalue[:type] == "array" ) and ( svalue.has_key? :items and svalue[:items].has_key? :type and svalue[:items][:type] == @ra[:structured][key][:elements][skey][:type])
80
+ (@ra[:errors][type][key] ||= {})[skey] = "Type is #{@ra[:structured][key][:elements][skey][:type]}, wrong check"
81
+ end
82
+ when "array"
83
+ unless svalue.has_key? :type and svalue[:type] == "array"
84
+ (@ra[:errors][type][key] ||= {})[skey] = "Type is #{@ra[:structured][key][:elements][skey][:type]}, wrong check"
85
+ end
86
+ else
87
+ puts "unknown type #{@ra[:structured][key][:elements][skey][:type]} in #{key}, #{skey}"
88
+ end
89
+ end
90
+ end
91
+ @ra[:structured][key][:elements][skey][type] = true
92
+ end
93
+ end
94
+ end
95
+
96
+ def create_structure
97
+ @ra[:structured] = {}
98
+ @ra[:errors] = {:in_profile_restricted => {}, :in_capabilities => {}}
99
+ parsed_schema = Circuitdata.read_json(@schema_path)[2]
100
+ parsed_schema[:properties][:open_trade_transfer_package][:properties][:products][:patternProperties]["^(?!generic$).*".to_sym][:properties][:printed_circuits_fabrication_data][:properties].each do |key, value|
101
+ self.update_ra(:in_product_generic, key, value)
102
+ end
103
+ ["defaults", "restricted", "enforced"].each do |sym|
104
+ parsed_schema[:properties][:open_trade_transfer_package][:properties][:profiles][:properties][sym.to_sym][:properties][:printed_circuits_fabrication_data][:properties].each do |key, value|
105
+ case sym
106
+ when "defaults"
107
+ t = :in_profile_default
108
+ when "restricted"
109
+ t = :in_profile_restricted
110
+ when "enforced"
111
+ t = :in_profile_enforced
112
+ end
113
+ self.update_ra(t, key, value)
114
+ end
115
+ end
116
+ parsed_schema[:properties][:open_trade_transfer_package][:properties][:capabilities][:properties][:printed_circuits_fabrication_data][:properties].each do |key, value|
117
+ self.update_ra(:in_capabilities, key, value)
118
+ end
119
+ @ra[:structured].sort.to_h
120
+ @ra[:structured].delete(:version)
121
+ return @ra
122
+ end
123
+
124
+ def create_documentation(ra)
125
+ ra[:documentation] = "## Elements and tags\n"
126
+ ra[:structured].each do |element_key, element_value|
127
+ ra[:documentation] += "[#{element_key}](##{element_key.to_s.downcase.tr(" ", "-")})\n"
128
+ element_value[:elements].each do |e_key, e_value|
129
+ ra[:documentation] += "* #{e_key}\n"
130
+ end
131
+ ra[:documentation] += "\n"
132
+ end
133
+ ra[:structured].each do |element_key, element_value|
134
+ ra[:documentation] += "### #{element_key}\n"
135
+ ra[:documentation] += "Name: #{element_value[:name]}\n" unless element_value[:name].nil?
136
+ ra[:documentation] += "Aliases: #{element_value[:aliases]}\n" unless element_value[:aliases].nil?
137
+ ra[:documentation] += "#{element_value[:description]}\n" unless element_value[:description].nil?
138
+ ra[:documentation] += "\n"
139
+ element_value[:elements].each do |e_key, e_value|
140
+ ra[:documentation] += "#### #{e_key}\n"
141
+ ra[:documentation] += "Aliases: #{e_value[:aliases]}\n" unless e_value[:aliases].nil?
142
+ ra[:documentation] += "#{e_value[:description]}\n" unless e_value[:description].nil?
143
+ ra[:documentation] += "Unit of Measure: #{e_value[:uom][0]}\n" unless e_value[:uom].nil?
144
+ unless e_value[:type].nil?
145
+ if e_value[:type] == "array"
146
+ if e_value[:arrayitems].nil?
147
+ ra[:documentation] += "Type: #{e_value[:type].capitalize} of unknown type\n"
148
+ else
149
+ ra[:documentation] += "Type: #{e_value[:type].capitalize} of #{e_value[:arrayitems].capitalize}\n"
150
+ end
151
+ else
152
+ ra[:documentation] += "Type: #{e_value[:type].capitalize}\n"
153
+ end
154
+ end
155
+ if e_value.has_key? :enum and not e_value[:enum].nil?
156
+ ra[:documentation] += "Use one of these values:\n"
157
+ e_value[:enum].each do |ev|
158
+ ra[:documentation] += "* #{ev}\n"
159
+ end
160
+ end
161
+ ra[:documentation] += "Use in:\n"
162
+ e_value[:in_product_generic] ? ra[:documentation] += "* *Generic product section: Allowed*\n" : ra[:documentation] += "* *Generic product section: Disallowed*\n"
163
+ e_value[:in_product_stackup] ? ra[:documentation] += "* *Stackup product section: Allowed*\n" : ra[:documentation] += "* *Gtackup product section: Disallowed*\n"
164
+ e_value[:in_profile_default] ? ra[:documentation] += "* *Profile defaults section: Allowed*\n" : ra[:documentation] += "* *Profile defaults section: Disallowed*\n"
165
+ e_value[:in_profile_enforced] ? ra[:documentation] += "* *Profile enforced section: Allowed*\n" : ra[:documentation] += "* *Profile enforced section: Disallowed*\n"
166
+ e_value[:in_profile_restricted] ? ra[:documentation] += "* *Profile restricted section: Allowed*\n" : ra[:documentation] += "* *Profile restricted section: Disallowed*\n"
167
+ ra[:documentation] += "* - Value in restricted section must match regex #{e_value[:in_profile_restricted_regex]}\n" unless e_value[:in_profile_restricted_regex].nil?
168
+ e_value[:in_capabilities] ? ra[:documentation] += "* *Capabilites section: Allowed*\n" : ra[:documentation] += "* *Capabilities section: Disallowed*\n"
169
+ ra[:documentation] += "* - Value in capabilites section must match regex #{e_value[:in_capabilities_regex]}\n" unless e_value[:in_capabilities_regex].nil?
170
+ ra[:documentation] += "\n"
171
+ end
172
+ end
173
+ puts ra[:documentation]
174
+ end
175
+
176
+ end