kicadts 0.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.
Files changed (188) hide show
  1. package/.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc +111 -0
  2. package/.vscode/settings.json +16 -0
  3. package/AGENTS.md +30 -0
  4. package/README.md +206 -0
  5. package/biome.json +93 -0
  6. package/bun.lock +48 -0
  7. package/bunfig.toml +5 -0
  8. package/lib/index.ts +1 -0
  9. package/lib/sexpr/base-classes/SxClass.ts +164 -0
  10. package/lib/sexpr/base-classes/SxPrimitiveBoolean.ts +35 -0
  11. package/lib/sexpr/base-classes/SxPrimitiveNumber.ts +26 -0
  12. package/lib/sexpr/base-classes/SxPrimitiveString.ts +26 -0
  13. package/lib/sexpr/classes/At.ts +38 -0
  14. package/lib/sexpr/classes/Bus.ts +83 -0
  15. package/lib/sexpr/classes/BusEntry.ts +142 -0
  16. package/lib/sexpr/classes/Color.ts +29 -0
  17. package/lib/sexpr/classes/Dnp.ts +8 -0
  18. package/lib/sexpr/classes/EmbeddedFonts.ts +70 -0
  19. package/lib/sexpr/classes/ExcludeFromSim.ts +8 -0
  20. package/lib/sexpr/classes/FieldsAutoplaced.ts +8 -0
  21. package/lib/sexpr/classes/Footprint.ts +719 -0
  22. package/lib/sexpr/classes/FootprintAttr.ts +102 -0
  23. package/lib/sexpr/classes/FootprintAutoplaceCost180.ts +9 -0
  24. package/lib/sexpr/classes/FootprintAutoplaceCost90.ts +9 -0
  25. package/lib/sexpr/classes/FootprintClearance.ts +9 -0
  26. package/lib/sexpr/classes/FootprintDescr.ts +44 -0
  27. package/lib/sexpr/classes/FootprintLocked.ts +32 -0
  28. package/lib/sexpr/classes/FootprintModel.ts +145 -0
  29. package/lib/sexpr/classes/FootprintNetTiePadGroups.ts +50 -0
  30. package/lib/sexpr/classes/FootprintPad.ts +705 -0
  31. package/lib/sexpr/classes/FootprintPath.ts +44 -0
  32. package/lib/sexpr/classes/FootprintPlaced.ts +32 -0
  33. package/lib/sexpr/classes/FootprintPrivateLayers.ts +56 -0
  34. package/lib/sexpr/classes/FootprintSheetfile.ts +44 -0
  35. package/lib/sexpr/classes/FootprintSheetname.ts +44 -0
  36. package/lib/sexpr/classes/FootprintSolderMaskMargin.ts +9 -0
  37. package/lib/sexpr/classes/FootprintSolderPasteMargin.ts +9 -0
  38. package/lib/sexpr/classes/FootprintSolderPasteRatio.ts +9 -0
  39. package/lib/sexpr/classes/FootprintTags.ts +44 -0
  40. package/lib/sexpr/classes/FootprintTedit.ts +21 -0
  41. package/lib/sexpr/classes/FootprintThermalGap.ts +9 -0
  42. package/lib/sexpr/classes/FootprintThermalWidth.ts +9 -0
  43. package/lib/sexpr/classes/FootprintZoneConnect.ts +9 -0
  44. package/lib/sexpr/classes/FpArc.ts +289 -0
  45. package/lib/sexpr/classes/FpCircle.ts +293 -0
  46. package/lib/sexpr/classes/FpLine.ts +288 -0
  47. package/lib/sexpr/classes/FpPoly.ts +266 -0
  48. package/lib/sexpr/classes/FpPolyFill.ts +48 -0
  49. package/lib/sexpr/classes/FpPolyLocked.ts +40 -0
  50. package/lib/sexpr/classes/FpRect.ts +293 -0
  51. package/lib/sexpr/classes/FpText.ts +341 -0
  52. package/lib/sexpr/classes/FpTextBox.ts +412 -0
  53. package/lib/sexpr/classes/GrLine.ts +245 -0
  54. package/lib/sexpr/classes/GrLineAngle.ts +32 -0
  55. package/lib/sexpr/classes/GrLineEnd.ts +61 -0
  56. package/lib/sexpr/classes/GrLineLocked.ts +40 -0
  57. package/lib/sexpr/classes/GrLineStart.ts +61 -0
  58. package/lib/sexpr/classes/GrText.ts +202 -0
  59. package/lib/sexpr/classes/Image.ts +256 -0
  60. package/lib/sexpr/classes/InBom.ts +8 -0
  61. package/lib/sexpr/classes/Junction.ts +134 -0
  62. package/lib/sexpr/classes/KicadPcb.ts +313 -0
  63. package/lib/sexpr/classes/KicadSch.ts +303 -0
  64. package/lib/sexpr/classes/KicadSchGenerator.ts +32 -0
  65. package/lib/sexpr/classes/KicadSchGeneratorVersion.ts +30 -0
  66. package/lib/sexpr/classes/KicadSchVersion.ts +22 -0
  67. package/lib/sexpr/classes/Label.ts +136 -0
  68. package/lib/sexpr/classes/Layer.ts +51 -0
  69. package/lib/sexpr/classes/Layers.ts +47 -0
  70. package/lib/sexpr/classes/LibSymbols.ts +61 -0
  71. package/lib/sexpr/classes/NoConnect.ts +73 -0
  72. package/lib/sexpr/classes/OnBoard.ts +8 -0
  73. package/lib/sexpr/classes/PadChamfer.ts +50 -0
  74. package/lib/sexpr/classes/PadChamferRatio.ts +9 -0
  75. package/lib/sexpr/classes/PadClearance.ts +9 -0
  76. package/lib/sexpr/classes/PadDieLength.ts +9 -0
  77. package/lib/sexpr/classes/PadDrill.ts +145 -0
  78. package/lib/sexpr/classes/PadDrillOffset.ts +54 -0
  79. package/lib/sexpr/classes/PadLayers.ts +59 -0
  80. package/lib/sexpr/classes/PadNet.ts +56 -0
  81. package/lib/sexpr/classes/PadOptions.ts +182 -0
  82. package/lib/sexpr/classes/PadPinFunction.ts +9 -0
  83. package/lib/sexpr/classes/PadPinType.ts +9 -0
  84. package/lib/sexpr/classes/PadPrimitiveGrArc.ts +254 -0
  85. package/lib/sexpr/classes/PadPrimitiveGrCircle.ts +279 -0
  86. package/lib/sexpr/classes/PadPrimitiveGrLine.ts +126 -0
  87. package/lib/sexpr/classes/PadPrimitives.ts +289 -0
  88. package/lib/sexpr/classes/PadRectDelta.ts +57 -0
  89. package/lib/sexpr/classes/PadRoundrectRratio.ts +9 -0
  90. package/lib/sexpr/classes/PadSize.ts +54 -0
  91. package/lib/sexpr/classes/PadSolderMaskMargin.ts +9 -0
  92. package/lib/sexpr/classes/PadSolderPasteMargin.ts +9 -0
  93. package/lib/sexpr/classes/PadSolderPasteMarginRatio.ts +9 -0
  94. package/lib/sexpr/classes/PadTeardrops.ts +208 -0
  95. package/lib/sexpr/classes/PadThermalBridgeAngle.ts +9 -0
  96. package/lib/sexpr/classes/PadThermalGap.ts +9 -0
  97. package/lib/sexpr/classes/PadThermalWidth.ts +9 -0
  98. package/lib/sexpr/classes/PadZoneConnect.ts +9 -0
  99. package/lib/sexpr/classes/Paper.ts +119 -0
  100. package/lib/sexpr/classes/PcbGeneral.ts +75 -0
  101. package/lib/sexpr/classes/PcbGeneralLegacyTeardrops.ts +44 -0
  102. package/lib/sexpr/classes/PcbGeneralThickness.ts +9 -0
  103. package/lib/sexpr/classes/PcbGenerator.ts +16 -0
  104. package/lib/sexpr/classes/PcbGeneratorVersion.ts +16 -0
  105. package/lib/sexpr/classes/PcbLayerDefinition.ts +102 -0
  106. package/lib/sexpr/classes/PcbLayers.ts +34 -0
  107. package/lib/sexpr/classes/PcbNet.ts +56 -0
  108. package/lib/sexpr/classes/PcbVersion.ts +9 -0
  109. package/lib/sexpr/classes/Property.ts +246 -0
  110. package/lib/sexpr/classes/PropertyHide.ts +9 -0
  111. package/lib/sexpr/classes/PropertyUnlocked.ts +9 -0
  112. package/lib/sexpr/classes/Pts.ts +65 -0
  113. package/lib/sexpr/classes/RenderCache.ts +221 -0
  114. package/lib/sexpr/classes/SchematicText.ts +141 -0
  115. package/lib/sexpr/classes/Segment.ts +222 -0
  116. package/lib/sexpr/classes/SegmentEnd.ts +59 -0
  117. package/lib/sexpr/classes/SegmentLocked.ts +33 -0
  118. package/lib/sexpr/classes/SegmentNet.ts +62 -0
  119. package/lib/sexpr/classes/SegmentStart.ts +59 -0
  120. package/lib/sexpr/classes/Setup/PcbPlotParams.ts +729 -0
  121. package/lib/sexpr/classes/Setup/PcbPlotParamsBase.ts +9 -0
  122. package/lib/sexpr/classes/Setup/PcbPlotParamsNumericProperties.ts +105 -0
  123. package/lib/sexpr/classes/Setup/PcbPlotParamsStringPropertiesA.ts +104 -0
  124. package/lib/sexpr/classes/Setup/PcbPlotParamsStringPropertiesB.ts +105 -0
  125. package/lib/sexpr/classes/Setup/Setup.ts +573 -0
  126. package/lib/sexpr/classes/Setup/SetupPropertyTypes.ts +119 -0
  127. package/lib/sexpr/classes/Setup/Stackup.ts +140 -0
  128. package/lib/sexpr/classes/Setup/StackupLayer.ts +233 -0
  129. package/lib/sexpr/classes/Setup/StackupLayerProperties.ts +78 -0
  130. package/lib/sexpr/classes/Setup/StackupProperties.ts +41 -0
  131. package/lib/sexpr/classes/Setup/base.ts +167 -0
  132. package/lib/sexpr/classes/Setup/index.ts +14 -0
  133. package/lib/sexpr/classes/Setup/setupMultiValueProperties.ts +54 -0
  134. package/lib/sexpr/classes/Setup/setupNumericProperties.ts +151 -0
  135. package/lib/sexpr/classes/Setup/setupPropertyHandlers.ts +90 -0
  136. package/lib/sexpr/classes/Setup/setupStringProperties.ts +75 -0
  137. package/lib/sexpr/classes/Sheet.ts +205 -0
  138. package/lib/sexpr/classes/SheetFill.ts +44 -0
  139. package/lib/sexpr/classes/SheetInstances.ts +168 -0
  140. package/lib/sexpr/classes/SheetInstancesRoot.ts +165 -0
  141. package/lib/sexpr/classes/SheetPin.ts +122 -0
  142. package/lib/sexpr/classes/SheetProperty.ts +115 -0
  143. package/lib/sexpr/classes/SheetSize.ts +44 -0
  144. package/lib/sexpr/classes/Stroke.ts +58 -0
  145. package/lib/sexpr/classes/StrokeType.ts +34 -0
  146. package/lib/sexpr/classes/Symbol.ts +1541 -0
  147. package/lib/sexpr/classes/TextEffects.ts +444 -0
  148. package/lib/sexpr/classes/TitleBlock.ts +352 -0
  149. package/lib/sexpr/classes/Unit.ts +28 -0
  150. package/lib/sexpr/classes/Uuid.ts +8 -0
  151. package/lib/sexpr/classes/Via.ts +328 -0
  152. package/lib/sexpr/classes/ViaNet.ts +59 -0
  153. package/lib/sexpr/classes/Width.ts +8 -0
  154. package/lib/sexpr/classes/Wire.ts +91 -0
  155. package/lib/sexpr/classes/Xy.ts +35 -0
  156. package/lib/sexpr/classes/Zone.ts +41 -0
  157. package/lib/sexpr/index.ts +130 -0
  158. package/lib/sexpr/parseKicadSexpr.ts +5 -0
  159. package/lib/sexpr/parseToPrimitiveSExpr.ts +240 -0
  160. package/lib/sexpr/utils/indentLines.ts +3 -0
  161. package/lib/sexpr/utils/parseYesNo.ts +12 -0
  162. package/lib/sexpr/utils/quoteSExprString.ts +8 -0
  163. package/lib/sexpr/utils/strokeFromArgs.ts +19 -0
  164. package/lib/sexpr/utils/toNumberValue.ts +13 -0
  165. package/lib/sexpr/utils/toStringValue.ts +10 -0
  166. package/package.json +26 -0
  167. package/scripts/download-references.ts +66 -0
  168. package/tests/fixtures/expectEqualPrimitiveSExpr.ts +200 -0
  169. package/tests/sexpr/KicadPcbDemos.test.ts +48 -0
  170. package/tests/sexpr/KicadSchDemos.test.ts +49 -0
  171. package/tests/sexpr/classes/Footprint.test.ts +277 -0
  172. package/tests/sexpr/classes/FootprintPad.test.ts +71 -0
  173. package/tests/sexpr/classes/FpArc.test.ts +45 -0
  174. package/tests/sexpr/classes/FpCircle.test.ts +39 -0
  175. package/tests/sexpr/classes/FpPoly.test.ts +43 -0
  176. package/tests/sexpr/classes/FpRect.test.ts +40 -0
  177. package/tests/sexpr/classes/FpTextBox.test.ts +84 -0
  178. package/tests/sexpr/classes/Image.test.ts +50 -0
  179. package/tests/sexpr/classes/KicadSch.test.ts +97 -0
  180. package/tests/sexpr/classes/Paper.test.ts +30 -0
  181. package/tests/sexpr/classes/Property.test.ts +48 -0
  182. package/tests/sexpr/classes/Setup.test.ts +189 -0
  183. package/tests/sexpr/classes/Sheet.test.ts +107 -0
  184. package/tests/sexpr/classes/Stroke.test.ts +15 -0
  185. package/tests/sexpr/classes/Symbol.test.ts +96 -0
  186. package/tests/sexpr/classes/TextEffects.test.ts +56 -0
  187. package/tests/sexpr/classes/TitleBlock.test.ts +40 -0
  188. package/tsconfig.json +35 -0
@@ -0,0 +1,189 @@
1
+ import { expect, test } from "bun:test"
2
+
3
+ import { Setup, SxClass } from "lib/sexpr"
4
+
5
+ test("Setup", () => {
6
+ const [setup] = SxClass.parse(`
7
+ (setup
8
+ (stackup
9
+ (layer "F.SilkS"
10
+ (type "Top Silk Screen")
11
+ )
12
+ (layer "dielectric 1"
13
+ (type "core")
14
+ (thickness 1.51)
15
+ (material "FR4")
16
+ (epsilon_r 4.5)
17
+ (loss_tangent 0.02)
18
+ )
19
+ (copper_finish "None")
20
+ (dielectric_constraints no)
21
+ )
22
+ (pad_to_mask_clearance 0)
23
+ (solder_mask_min_width 0.01)
24
+ (pad_to_paste_clearance 0)
25
+ (pad_to_paste_clearance_ratio 0)
26
+ (last_trace_width 0.254)
27
+ (trace_clearance 0.254)
28
+ (zone_clearance 0.2)
29
+ (zone_45_only no)
30
+ (trace_min 0.254)
31
+ (segment_width 0.2)
32
+ (edge_width 0.15)
33
+ (via_size 0.889)
34
+ (via_drill 0.635)
35
+ (via_min_size 0.889)
36
+ (via_min_drill 0.508)
37
+ (uvia_size 0.508)
38
+ (uvia_drill 0.127)
39
+ (uvias_allowed no)
40
+ (uvia_min_size 0.508)
41
+ (uvia_min_drill 0.127)
42
+ (pcb_text_width 0.3)
43
+ (pcb_text_size 1.5 1.5)
44
+ (mod_edge_width 0.15)
45
+ (mod_text_size 1.5 1.5)
46
+ (mod_text_width 0.15)
47
+ (pad_size 0.0005 0.0005)
48
+ (pad_drill 0)
49
+ (allow_soldermask_bridges_in_footprints no)
50
+ (tenting front back)
51
+ (aux_axis_origin 10 15)
52
+ (grid_origin 20 25)
53
+ (visible_elements 7FFFFFFF)
54
+ (pcbplotparams
55
+ (layerselection 0x00000000_00000000_00000000_000000a5)
56
+ (plot_on_all_layers_selection 0x00000000_00000000_00000000_00000000)
57
+ (disableapertmacros no)
58
+ (usegerberextensions yes)
59
+ (usegerberattributes no)
60
+ (usegerberadvancedattributes no)
61
+ (creategerberjobfile no)
62
+ (dashed_line_dash_ratio 12)
63
+ (dashed_line_gap_ratio 3)
64
+ (svgprecision 6)
65
+ (plotframeref no)
66
+ (mode 1)
67
+ (useauxorigin no)
68
+ (hpglpennumber 1)
69
+ (hpglpenspeed 20)
70
+ (hpglpendiameter 15)
71
+ (pdf_front_fp_property_popups yes)
72
+ (pdf_back_fp_property_popups yes)
73
+ (pdf_metadata yes)
74
+ (pdf_single_document no)
75
+ (dxfpolygonmode yes)
76
+ (dxfimperialunits yes)
77
+ (dxfusepcbnewfont yes)
78
+ (psnegative no)
79
+ (psa4output no)
80
+ (plot_black_and_white yes)
81
+ (plotinvisibletext no)
82
+ (sketchpadsonfab no)
83
+ (plotpadnumbers no)
84
+ (hidednponfab no)
85
+ (sketchdnponfab yes)
86
+ (crossoutdnponfab yes)
87
+ (subtractmaskfromsilk no)
88
+ (outputformat 1)
89
+ (mirror no)
90
+ (drillshape 1)
91
+ (scaleselection 1)
92
+ (outputdirectory "")
93
+ )
94
+ )
95
+ `)
96
+
97
+ expect(setup).toBeInstanceOf(Setup)
98
+ expect(setup!.getString()).toMatchInlineSnapshot(`
99
+ "(setup
100
+ (stackup
101
+ (layer \"F.SilkS\"
102
+ (type \"Top Silk Screen\")
103
+ )
104
+ (layer \"dielectric 1\"
105
+ (type \"core\")
106
+ (thickness 1.51)
107
+ (material \"FR4\")
108
+ (epsilon_r 4.5)
109
+ (loss_tangent 0.02)
110
+ )
111
+ (copper_finish \"None\")
112
+ (dielectric_constraints no)
113
+ )
114
+ (pad_to_mask_clearance 0)
115
+ (solder_mask_min_width 0.01)
116
+ (pad_to_paste_clearance 0)
117
+ (pad_to_paste_clearance_ratio 0)
118
+ (last_trace_width 0.254)
119
+ (trace_clearance 0.254)
120
+ (zone_clearance 0.2)
121
+ (zone_45_only no)
122
+ (trace_min 0.254)
123
+ (segment_width 0.2)
124
+ (edge_width 0.15)
125
+ (via_size 0.889)
126
+ (via_drill 0.635)
127
+ (via_min_size 0.889)
128
+ (via_min_drill 0.508)
129
+ (uvia_size 0.508)
130
+ (uvia_drill 0.127)
131
+ (uvias_allowed no)
132
+ (uvia_min_size 0.508)
133
+ (uvia_min_drill 0.127)
134
+ (pcb_text_width 0.3)
135
+ (pcb_text_size 1.5 1.5)
136
+ (mod_edge_width 0.15)
137
+ (mod_text_size 1.5 1.5)
138
+ (mod_text_width 0.15)
139
+ (pad_size 0.0005 0.0005)
140
+ (pad_drill 0)
141
+ (allow_soldermask_bridges_in_footprints no)
142
+ (tenting front back)
143
+ (aux_axis_origin 10 15)
144
+ (grid_origin 20 25)
145
+ (visible_elements 7FFFFFFF)
146
+ (pcbplotparams
147
+ (layerselection 0x00000000_00000000_00000000_000000a5)
148
+ (plot_on_all_layers_selection 0x00000000_00000000_00000000_00000000)
149
+ (disableapertmacros no)
150
+ (usegerberextensions yes)
151
+ (usegerberattributes no)
152
+ (usegerberadvancedattributes no)
153
+ (creategerberjobfile no)
154
+ (dashed_line_dash_ratio 12)
155
+ (dashed_line_gap_ratio 3)
156
+ (svgprecision 6)
157
+ (plotframeref no)
158
+ (mode 1)
159
+ (useauxorigin no)
160
+ (hpglpennumber 1)
161
+ (hpglpenspeed 20)
162
+ (hpglpendiameter 15)
163
+ (pdf_front_fp_property_popups yes)
164
+ (pdf_back_fp_property_popups yes)
165
+ (pdf_metadata yes)
166
+ (pdf_single_document no)
167
+ (dxfpolygonmode yes)
168
+ (dxfimperialunits yes)
169
+ (dxfusepcbnewfont yes)
170
+ (psnegative no)
171
+ (psa4output no)
172
+ (plot_black_and_white yes)
173
+ (plotinvisibletext no)
174
+ (sketchpadsonfab no)
175
+ (plotpadnumbers no)
176
+ (hidednponfab no)
177
+ (sketchdnponfab yes)
178
+ (crossoutdnponfab yes)
179
+ (subtractmaskfromsilk no)
180
+ (outputformat 1)
181
+ (mirror no)
182
+ (drillshape 1)
183
+ (scaleselection 1)
184
+ (outputdirectory \"\")
185
+ )
186
+ )"
187
+ `)
188
+ })
189
+
@@ -0,0 +1,107 @@
1
+ import { At, Sheet, SheetProperty, SheetPin, Stroke, SxClass } from "lib/sexpr"
2
+ import { expect, test } from "bun:test"
3
+
4
+ test("Sheet", () => {
5
+ const [sheet] = SxClass.parse(`
6
+ (sheet
7
+ (at 25.4 30.48 0)
8
+ (size 100 70)
9
+ (exclude_from_sim no)
10
+ (in_bom yes)
11
+ (on_board yes)
12
+ (dnp no)
13
+ (fields_autoplaced yes)
14
+ (stroke (width 0.1) (type solid) (color 0 0 0 1))
15
+ (fill (color 0 0 0 1))
16
+ (uuid aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee)
17
+ (property "Sheet name" "Controller"
18
+ (id 0)
19
+ (at 0 0 0)
20
+ (effects (font (size 1.27 1.27) (thickness 0.1524)))
21
+ )
22
+ (pin "IN" input
23
+ (at 50.8 0 180)
24
+ (uuid 11111111-2222-3333-4444-555555555555)
25
+ (effects (font (size 1 1) (thickness 0.15)))
26
+ )
27
+ (instances
28
+ (project "Project"
29
+ (path "/0001"
30
+ (page "1")
31
+ )
32
+ )
33
+ )
34
+ )
35
+ `)
36
+
37
+ expect(sheet).toBeInstanceOf(Sheet)
38
+ const s = sheet as Sheet
39
+ expect(s.position).toBeInstanceOf(At)
40
+ expect(s.size).toEqual({ width: 100, height: 70 })
41
+ expect(s.excludeFromSim).toBe(false)
42
+ expect(s.inBom).toBe(true)
43
+ expect(s.onBoard).toBe(true)
44
+ expect(s.dnp).toBe(false)
45
+ expect(s.fieldsAutoplaced).toBe(true)
46
+ expect(s.stroke).toBeInstanceOf(Stroke)
47
+ expect(s.fill?.color).toBeDefined()
48
+ expect(s.uuid?.value).toBe("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee")
49
+ expect(s.properties).toHaveLength(1)
50
+ expect(s.properties[0]).toBeInstanceOf(SheetProperty)
51
+ expect(s.pins).toHaveLength(1)
52
+ expect(s.pins[0]).toBeInstanceOf(SheetPin)
53
+ const pin = s.pins[0]!
54
+ expect(pin.name).toBe("IN")
55
+ expect(pin.electricalType).toBe("input")
56
+ expect(pin.position).toBeInstanceOf(At)
57
+ expect(pin.effects).toBeDefined()
58
+ expect(s.instances).toBeDefined()
59
+
60
+ expect(s.getString()).toMatchInlineSnapshot(`
61
+ "(sheet
62
+ (at 25.4 30.48 0)
63
+ (size 100 70)
64
+ (exclude_from_sim no)
65
+ (in_bom yes)
66
+ (on_board yes)
67
+ (dnp no)
68
+ (fields_autoplaced yes)
69
+ (stroke
70
+ (width 0.1)
71
+ (type solid)
72
+ (color 0 0 0 1)
73
+ )
74
+ (fill
75
+ (color 0 0 0 1)
76
+ )
77
+ (uuid aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee)
78
+ (property \"Sheet name\" \"Controller\"
79
+ (id 0)
80
+ (at 0 0 0)
81
+ (effects
82
+ (font
83
+ (size 1.27 1.27)
84
+ (thickness 0.1524)
85
+ )
86
+ )
87
+ )
88
+ (pin \"IN\" input
89
+ (at 50.8 0 180)
90
+ (effects
91
+ (font
92
+ (size 1 1)
93
+ (thickness 0.15)
94
+ )
95
+ )
96
+ (uuid 11111111-2222-3333-4444-555555555555)
97
+ )
98
+ (instances
99
+ (project \"Project\"
100
+ (path \"/0001\"
101
+ (page \"1\")
102
+ )
103
+ )
104
+ )
105
+ )"
106
+ `)
107
+ })
@@ -0,0 +1,15 @@
1
+ import { Stroke, SxClass } from "lib/sexpr"
2
+ import { test, expect } from "bun:test"
3
+
4
+ test("Stroke", () => {
5
+ const [stroke] = SxClass.parse(
6
+ "(stroke (width 1) (type solid) (color 0 0 0 1))",
7
+ )
8
+ expect(stroke!.getString()).toMatchInlineSnapshot(`
9
+ "(stroke
10
+ (width 1)
11
+ (type solid)
12
+ (color 0 0 0 1)
13
+ )"
14
+ `)
15
+ })
@@ -0,0 +1,96 @@
1
+ import {
2
+ At,
3
+ SxClass,
4
+ SchematicSymbol,
5
+ SymbolProperty,
6
+ SymbolPin,
7
+ TextEffects,
8
+ } from "lib/sexpr"
9
+ import { expect, test } from "bun:test"
10
+
11
+ test("Symbol parse", () => {
12
+ const [symbol] = SxClass.parse(`
13
+ (symbol "Device:R"
14
+ (at 10 20 90)
15
+ (unit 2)
16
+ (in_bom yes)
17
+ (on_board no)
18
+ (uuid 12345678-1234-1234-1234-123456789abc)
19
+ (property "Reference" "R?"
20
+ (id 0)
21
+ (at 0 0 0)
22
+ (effects (font (size 1.27 1.27) (thickness 0.1524)))
23
+ )
24
+ (pin input line (at 0 -5.08 90) (length 2.54)
25
+ (name "A" (effects (font (size 1.27 1.27))))
26
+ (number "1" (effects (font (size 1.27 1.27))))
27
+ )
28
+ (instances (project "Project" (path "/0001" (reference "R1") (unit 1))))
29
+ )
30
+ `)
31
+
32
+ console.log(symbol)
33
+
34
+ expect(symbol).toBeInstanceOf(SchematicSymbol)
35
+ const sym = symbol as SchematicSymbol
36
+ expect(sym.libraryId).toBe("Device:R")
37
+ expect(sym.inBom).toBe(true)
38
+ expect(sym.onBoard).toBe(false)
39
+ expect(sym.uuid).toBe("12345678-1234-1234-1234-123456789abc")
40
+ expect(sym.properties).toHaveLength(1)
41
+ const property = sym.properties[0] as SymbolProperty
42
+ expect(property.key).toBe("Reference")
43
+ expect(property.value).toBe("R?")
44
+ expect(property.id).toBe(0)
45
+ expect(sym.pins).toHaveLength(1)
46
+ const pin = sym.pins[0] as SymbolPin
47
+ expect(pin.name).toBe("A")
48
+ expect(pin.numberString).toBe("1")
49
+ expect(sym.instances).toBeDefined()
50
+
51
+ expect(sym.getString()).toMatchInlineSnapshot(`
52
+ "(symbol "Device:R"
53
+ (at 10 20 90)
54
+ (unit 2)
55
+ (in_bom yes)
56
+ (on_board no)
57
+ (uuid 12345678-1234-1234-1234-123456789abc)
58
+ (property "Reference" "R?"
59
+ (id 0)
60
+ (at 0 0 0)
61
+ (effects
62
+ (font
63
+ (size 1.27 1.27)
64
+ (thickness 0.1524)
65
+ )
66
+ )
67
+ )
68
+ (pin input line
69
+ (at 0 -5.08 90)
70
+ (length 2.54)
71
+ (name "A"
72
+ (effects
73
+ (font
74
+ (size 1.27 1.27)
75
+ )
76
+ )
77
+ )
78
+ (number "1"
79
+ (effects
80
+ (font
81
+ (size 1.27 1.27)
82
+ )
83
+ )
84
+ )
85
+ )
86
+ (instances
87
+ (project "Project"
88
+ (path "/0001"
89
+ (reference "R1")
90
+ (unit 1)
91
+ )
92
+ )
93
+ )
94
+ )"
95
+ `)
96
+ })
@@ -0,0 +1,56 @@
1
+ import { SxClass, TextEffects, TextEffectsJustify } from "lib/sexpr"
2
+ import { expect, test } from "bun:test"
3
+
4
+ test("TextEffects", () => {
5
+ const [effects] = SxClass.parse(`
6
+ (effects
7
+ (font
8
+ (face "KiCad Font")
9
+ (size 1.5 1.2)
10
+ (thickness 0.3)
11
+ bold
12
+ italic
13
+ (line_spacing 1.1)
14
+ )
15
+ (justify left top mirror)
16
+ hide
17
+ )
18
+ `)
19
+
20
+ expect(effects).toBeInstanceOf(TextEffects)
21
+
22
+ const textEffects = effects as TextEffects
23
+ expect(textEffects.font.face).toBe("KiCad Font")
24
+ expect(textEffects.font.size).toEqual({ height: 1.5, width: 1.2 })
25
+ expect(textEffects.font.thickness).toBe(0.3)
26
+ expect(textEffects.font.bold).toBe(true)
27
+ expect(textEffects.font.italic).toBe(true)
28
+ expect(textEffects.font.lineSpacing).toBe(1.1)
29
+
30
+ const justify = textEffects.justify as TextEffectsJustify
31
+ expect(justify.horizontal).toBe("left")
32
+ expect(justify.vertical).toBe("top")
33
+ expect(justify.mirror).toBe(true)
34
+
35
+ expect(textEffects.hiddenText).toBe(true)
36
+
37
+ textEffects.hiddenText = false
38
+ textEffects.justify = new TextEffectsJustify({
39
+ horizontal: "right",
40
+ vertical: "bottom",
41
+ })
42
+
43
+ expect(textEffects.getString()).toMatchInlineSnapshot(`
44
+ "(effects
45
+ (font
46
+ (face \"KiCad Font\")
47
+ (size 1.5 1.2)
48
+ (thickness 0.3)
49
+ bold
50
+ italic
51
+ (line_spacing 1.1)
52
+ )
53
+ (justify right bottom)
54
+ )"
55
+ `)
56
+ })
@@ -0,0 +1,40 @@
1
+ import { SxClass, TitleBlock } from "lib/sexpr"
2
+ import { expect, test } from "bun:test"
3
+
4
+ test("TitleBlock", () => {
5
+ const [titleBlock] = SxClass.parse(`
6
+ (title_block
7
+ (title "Project Title")
8
+ (date "2024-05-12")
9
+ (rev "A1")
10
+ (company "ACME Corp")
11
+ (comment 2 "Secondary comment")
12
+ (comment 1 "Primary comment")
13
+ )
14
+ `)
15
+
16
+ expect(titleBlock).toBeInstanceOf(TitleBlock)
17
+
18
+ const block = titleBlock as TitleBlock
19
+ expect(block.title).toBe("Project Title")
20
+ expect(block.date).toBe("2024-05-12")
21
+ expect(block.rev).toBe("A1")
22
+ expect(block.company).toBe("ACME Corp")
23
+ expect(block.getComment(1)).toBe("Primary comment")
24
+ expect(block.getComment(2)).toBe("Secondary comment")
25
+
26
+ block.setComment(3, "Additional note")
27
+ expect(block.getComment(3)).toBe("Additional note")
28
+
29
+ expect(block.getString()).toMatchInlineSnapshot(`
30
+ "(title_block
31
+ (title \"Project Title\")
32
+ (date \"2024-05-12\")
33
+ (rev \"A1\")
34
+ (company \"ACME Corp\")
35
+ (comment 1 \"Primary comment\")
36
+ (comment 2 \"Secondary comment\")
37
+ (comment 3 \"Additional note\")
38
+ )"
39
+ `)
40
+ })
package/tsconfig.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "compilerOptions": {
3
+ // Environment setup & latest features
4
+ "lib": ["ESNext"],
5
+ "target": "ESNext",
6
+ "module": "Preserve",
7
+ "moduleDetection": "force",
8
+ "jsx": "react-jsx",
9
+ "allowJs": true,
10
+
11
+ "baseUrl": ".",
12
+ "paths": {
13
+ "lib/*": ["./lib/*"],
14
+ "tests/*": ["./tests/*"]
15
+ },
16
+
17
+ // Bundler mode
18
+ "moduleResolution": "bundler",
19
+ "allowImportingTsExtensions": true,
20
+ "verbatimModuleSyntax": true,
21
+ "noEmit": true,
22
+
23
+ // Best practices
24
+ "strict": true,
25
+ "skipLibCheck": true,
26
+ "noFallthroughCasesInSwitch": true,
27
+ "noUncheckedIndexedAccess": true,
28
+ "noImplicitOverride": true,
29
+
30
+ // Some stricter flags (disabled by default)
31
+ "noUnusedLocals": false,
32
+ "noUnusedParameters": false,
33
+ "noPropertyAccessFromIndexSignature": false
34
+ }
35
+ }