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,303 @@
1
+ import { SxClass } from "../base-classes/SxClass"
2
+ import type { PrimitiveSExpr } from "../parseToPrimitiveSExpr"
3
+ import { Image } from "./Image"
4
+ import { KicadSchGenerator } from "./KicadSchGenerator"
5
+ import { KicadSchGeneratorVersion } from "./KicadSchGeneratorVersion"
6
+ import { KicadSchVersion } from "./KicadSchVersion"
7
+ import { LibSymbols } from "./LibSymbols"
8
+ import { Paper } from "./Paper"
9
+ import { Property } from "./Property"
10
+ import { Label } from "./Label"
11
+ import { SchematicSymbol } from "./Symbol"
12
+ import { SchematicText } from "./SchematicText"
13
+ import { Sheet } from "./Sheet"
14
+ import { EmbeddedFonts } from "./EmbeddedFonts"
15
+ import { SheetInstances } from "./SheetInstances"
16
+ import { TitleBlock } from "./TitleBlock"
17
+ import { Uuid } from "./Uuid"
18
+ import { Wire } from "./Wire"
19
+ import { Junction } from "./Junction"
20
+
21
+ const SINGLE_CHILD_TOKENS = new Set([
22
+ "version",
23
+ "generator",
24
+ "generator_version",
25
+ "uuid",
26
+ "paper",
27
+ "title_block",
28
+ "lib_symbols",
29
+ "sheet_instances",
30
+ "embedded_fonts",
31
+ ])
32
+
33
+ const MULTI_CHILD_TOKENS = new Set([
34
+ "property",
35
+ "image",
36
+ "sheet",
37
+ "symbol",
38
+ "text",
39
+ "label",
40
+ "junction",
41
+ "wire",
42
+ ])
43
+
44
+ const SUPPORTED_CHILD_TOKENS = new Set([
45
+ ...SINGLE_CHILD_TOKENS,
46
+ ...MULTI_CHILD_TOKENS,
47
+ ])
48
+
49
+ export class KicadSch extends SxClass {
50
+ static override token = "kicad_sch"
51
+ token = "kicad_sch"
52
+
53
+ private _sxVersion?: KicadSchVersion
54
+ private _sxGenerator?: KicadSchGenerator
55
+ private _sxGeneratorVersion?: KicadSchGeneratorVersion
56
+ private _sxUuid?: Uuid
57
+ private _sxPaper?: Paper
58
+ private _sxTitleBlock?: TitleBlock
59
+ private _sxLibSymbols?: LibSymbols
60
+ private _sxSheetInstances?: SheetInstances
61
+ private _sxEmbeddedFonts?: EmbeddedFonts
62
+ private _properties: Property[] = []
63
+ private _images: Image[] = []
64
+ private _sheets: Sheet[] = []
65
+ private _symbols: SchematicSymbol[] = []
66
+ private _texts: SchematicText[] = []
67
+ private _labels: Label[] = []
68
+ private _wires: Wire[] = []
69
+ private _junctions: Junction[] = []
70
+
71
+ static override fromSexprPrimitives(
72
+ primitiveSexprs: PrimitiveSExpr[],
73
+ ): KicadSch {
74
+ const kicadSch = new KicadSch()
75
+
76
+ for (const primitive of primitiveSexprs) {
77
+ if (!Array.isArray(primitive)) {
78
+ throw new Error(
79
+ `kicad_sch encountered unexpected primitive child: ${JSON.stringify(primitive)}`,
80
+ )
81
+ }
82
+ if (primitive.length === 0 || typeof primitive[0] !== "string") {
83
+ throw new Error(
84
+ `kicad_sch encountered invalid child expression: ${JSON.stringify(primitive)}`,
85
+ )
86
+ }
87
+ }
88
+
89
+ const { propertyMap, arrayPropertyMap } =
90
+ SxClass.parsePrimitivesToClassProperties(primitiveSexprs, this.token)
91
+
92
+ for (const token of Object.keys(propertyMap)) {
93
+ if (!SUPPORTED_CHILD_TOKENS.has(token)) {
94
+ throw new Error(
95
+ `kicad_sch encountered unsupported child token "${token}"`,
96
+ )
97
+ }
98
+ }
99
+
100
+ for (const [token, entries] of Object.entries(arrayPropertyMap)) {
101
+ if (!SUPPORTED_CHILD_TOKENS.has(token)) {
102
+ throw new Error(
103
+ `kicad_sch encountered unsupported child token "${token}"`,
104
+ )
105
+ }
106
+ if (!MULTI_CHILD_TOKENS.has(token) && entries.length > 1) {
107
+ throw new Error(
108
+ `kicad_sch does not support repeated child token "${token}"`,
109
+ )
110
+ }
111
+ }
112
+
113
+ kicadSch._sxVersion = propertyMap.version as KicadSchVersion | undefined
114
+ kicadSch._sxGenerator = propertyMap.generator as
115
+ | KicadSchGenerator
116
+ | undefined
117
+ kicadSch._sxGeneratorVersion = propertyMap.generator_version as
118
+ | KicadSchGeneratorVersion
119
+ | undefined
120
+ kicadSch._sxUuid = propertyMap.uuid as Uuid | undefined
121
+ kicadSch._sxPaper = propertyMap.paper as Paper | undefined
122
+ kicadSch._sxTitleBlock = propertyMap.title_block as TitleBlock | undefined
123
+ kicadSch._sxLibSymbols = propertyMap.lib_symbols as LibSymbols | undefined
124
+ kicadSch._sxSheetInstances = propertyMap.sheet_instances as SheetInstances | undefined
125
+ kicadSch._sxEmbeddedFonts = propertyMap.embedded_fonts as EmbeddedFonts | undefined
126
+ kicadSch._properties = (arrayPropertyMap.property as Property[]) ?? []
127
+ kicadSch._images = (arrayPropertyMap.image as Image[]) ?? []
128
+ kicadSch._sheets = (arrayPropertyMap.sheet as Sheet[]) ?? []
129
+ kicadSch._symbols = (arrayPropertyMap.symbol as SchematicSymbol[]) ?? []
130
+ kicadSch._texts = (arrayPropertyMap.text as SchematicText[]) ?? []
131
+ kicadSch._labels = (arrayPropertyMap.label as Label[]) ?? []
132
+ kicadSch._junctions = (arrayPropertyMap.junction as Junction[]) ?? []
133
+ kicadSch._wires = (arrayPropertyMap.wire as Wire[]) ?? []
134
+
135
+ return kicadSch
136
+ }
137
+
138
+ get version(): number | undefined {
139
+ return this._sxVersion?.value
140
+ }
141
+
142
+ set version(value: number | undefined) {
143
+ this._sxVersion =
144
+ value === undefined ? undefined : new KicadSchVersion(value)
145
+ }
146
+
147
+ get generator(): string | undefined {
148
+ return this._sxGenerator?.value
149
+ }
150
+
151
+ set generator(value: string | undefined) {
152
+ this._sxGenerator =
153
+ value === undefined ? undefined : new KicadSchGenerator(value)
154
+ }
155
+
156
+ get generatorVersion(): string | undefined {
157
+ return this._sxGeneratorVersion?.value
158
+ }
159
+
160
+ set generatorVersion(value: string | undefined) {
161
+ this._sxGeneratorVersion =
162
+ value === undefined ? undefined : new KicadSchGeneratorVersion(value)
163
+ }
164
+
165
+ get uuid(): Uuid | undefined {
166
+ return this._sxUuid
167
+ }
168
+
169
+ set uuid(value: Uuid | string | undefined) {
170
+ if (value === undefined) {
171
+ this._sxUuid = undefined
172
+ return
173
+ }
174
+ this._sxUuid = value instanceof Uuid ? value : new Uuid(value)
175
+ }
176
+
177
+ get paper(): Paper | undefined {
178
+ return this._sxPaper
179
+ }
180
+
181
+ set paper(value: Paper | undefined) {
182
+ this._sxPaper = value
183
+ }
184
+
185
+ get titleBlock(): TitleBlock | undefined {
186
+ return this._sxTitleBlock
187
+ }
188
+
189
+ set titleBlock(value: TitleBlock | undefined) {
190
+ this._sxTitleBlock = value
191
+ }
192
+
193
+ get libSymbols(): LibSymbols | undefined {
194
+ return this._sxLibSymbols
195
+ }
196
+
197
+ set libSymbols(value: LibSymbols | undefined) {
198
+ this._sxLibSymbols = value
199
+ }
200
+
201
+ get sheetInstances(): SheetInstances | undefined {
202
+ return this._sxSheetInstances
203
+ }
204
+
205
+ set sheetInstances(value: SheetInstances | undefined) {
206
+ this._sxSheetInstances = value
207
+ }
208
+
209
+ get embeddedFonts(): EmbeddedFonts | undefined {
210
+ return this._sxEmbeddedFonts
211
+ }
212
+
213
+ set embeddedFonts(value: EmbeddedFonts | undefined) {
214
+ this._sxEmbeddedFonts = value
215
+ }
216
+
217
+ get properties(): Property[] {
218
+ return [...this._properties]
219
+ }
220
+
221
+ set properties(value: Property[]) {
222
+ this._properties = [...value]
223
+ }
224
+
225
+ get images(): Image[] {
226
+ return [...this._images]
227
+ }
228
+
229
+ set images(value: Image[]) {
230
+ this._images = [...value]
231
+ }
232
+
233
+ get sheets(): Sheet[] {
234
+ return [...this._sheets]
235
+ }
236
+
237
+ set sheets(value: Sheet[]) {
238
+ this._sheets = [...value]
239
+ }
240
+
241
+ get symbols(): SchematicSymbol[] {
242
+ return [...this._symbols]
243
+ }
244
+
245
+ set symbols(value: SchematicSymbol[]) {
246
+ this._symbols = [...value]
247
+ }
248
+
249
+ get texts(): SchematicText[] {
250
+ return [...this._texts]
251
+ }
252
+
253
+ set texts(value: SchematicText[]) {
254
+ this._texts = [...value]
255
+ }
256
+
257
+ get labels(): Label[] {
258
+ return [...this._labels]
259
+ }
260
+
261
+ set labels(value: Label[]) {
262
+ this._labels = [...value]
263
+ }
264
+
265
+ get junctions(): Junction[] {
266
+ return [...this._junctions]
267
+ }
268
+
269
+ set junctions(value: Junction[]) {
270
+ this._junctions = [...value]
271
+ }
272
+
273
+ get wires(): Wire[] {
274
+ return [...this._wires]
275
+ }
276
+
277
+ set wires(value: Wire[]) {
278
+ this._wires = [...value]
279
+ }
280
+
281
+ override getChildren(): SxClass[] {
282
+ const children: SxClass[] = []
283
+ if (this._sxVersion) children.push(this._sxVersion)
284
+ if (this._sxGenerator) children.push(this._sxGenerator)
285
+ if (this._sxGeneratorVersion) children.push(this._sxGeneratorVersion)
286
+ if (this._sxUuid) children.push(this._sxUuid)
287
+ if (this._sxPaper) children.push(this._sxPaper)
288
+ if (this._sxTitleBlock) children.push(this._sxTitleBlock)
289
+ if (this._sxLibSymbols) children.push(this._sxLibSymbols)
290
+ if (this._sxSheetInstances) children.push(this._sxSheetInstances)
291
+ if (this._sxEmbeddedFonts) children.push(this._sxEmbeddedFonts)
292
+ children.push(...this._properties)
293
+ children.push(...this._images)
294
+ children.push(...this._sheets)
295
+ children.push(...this._symbols)
296
+ children.push(...this._texts)
297
+ children.push(...this._labels)
298
+ children.push(...this._junctions)
299
+ children.push(...this._wires)
300
+ return children
301
+ }
302
+ }
303
+ SxClass.register(KicadSch)
@@ -0,0 +1,32 @@
1
+ import { SxClass } from "../base-classes/SxClass"
2
+ import { SxPrimitiveString } from "../base-classes/SxPrimitiveString"
3
+ import type { PrimitiveSExpr } from "../parseToPrimitiveSExpr"
4
+ import { quoteSExprString } from "../utils/quoteSExprString"
5
+ import { toStringValue } from "../utils/toStringValue"
6
+
7
+ const isSymbolToken = (value: string) => /^[A-Za-z0-9._-]+$/.test(value)
8
+
9
+ export class KicadSchGenerator extends SxPrimitiveString {
10
+ static override token = "generator"
11
+ static override parentToken = "kicad_sch"
12
+ override token = "generator"
13
+
14
+ static override fromSexprPrimitives(
15
+ primitiveSexprs: PrimitiveSExpr[],
16
+ ): KicadSchGenerator {
17
+ const [rawValue] = primitiveSexprs
18
+ const parsedValue = toStringValue(rawValue)
19
+ if (parsedValue === undefined) {
20
+ throw new Error("generator expects a string argument")
21
+ }
22
+ return new KicadSchGenerator(parsedValue)
23
+ }
24
+
25
+ override getString(): string {
26
+ const serialized = isSymbolToken(this.value)
27
+ ? this.value
28
+ : quoteSExprString(this.value)
29
+ return `(generator ${serialized})`
30
+ }
31
+ }
32
+ SxClass.register(KicadSchGenerator)
@@ -0,0 +1,30 @@
1
+ import { SxClass } from "../base-classes/SxClass"
2
+ import { SxPrimitiveString } from "../base-classes/SxPrimitiveString"
3
+ import type { PrimitiveSExpr } from "../parseToPrimitiveSExpr"
4
+ import { quoteSExprString } from "../utils/quoteSExprString"
5
+ import { toStringValue } from "../utils/toStringValue"
6
+
7
+ export class KicadSchGeneratorVersion extends SxPrimitiveString {
8
+ static override token = "generator_version"
9
+ static override parentToken = "kicad_sch"
10
+ override token = "generator_version"
11
+
12
+ static override fromSexprPrimitives(
13
+ primitiveSexprs: PrimitiveSExpr[],
14
+ ): KicadSchGeneratorVersion {
15
+ const [rawValue] = primitiveSexprs
16
+ const parsedValue = toStringValue(rawValue)
17
+ if (parsedValue === undefined) {
18
+ throw new Error("generator_version expects a string argument")
19
+ }
20
+ return new KicadSchGeneratorVersion(parsedValue)
21
+ }
22
+
23
+ override getString(): string {
24
+ const serialized = /^[^\s()\"]+$/.test(this.value)
25
+ ? this.value
26
+ : quoteSExprString(this.value)
27
+ return `(generator_version ${serialized})`
28
+ }
29
+ }
30
+ SxClass.register(KicadSchGeneratorVersion)
@@ -0,0 +1,22 @@
1
+ import { SxClass } from "../base-classes/SxClass"
2
+ import { SxPrimitiveNumber } from "../base-classes/SxPrimitiveNumber"
3
+ import type { PrimitiveSExpr } from "../parseToPrimitiveSExpr"
4
+ import { toNumberValue } from "../utils/toNumberValue"
5
+
6
+ export class KicadSchVersion extends SxPrimitiveNumber {
7
+ static override token = "version"
8
+ static override parentToken = "kicad_sch"
9
+ override token = "version"
10
+
11
+ static override fromSexprPrimitives(
12
+ primitiveSexprs: PrimitiveSExpr[],
13
+ ): KicadSchVersion {
14
+ const [rawValue] = primitiveSexprs
15
+ const parsedValue = toNumberValue(rawValue)
16
+ if (parsedValue === undefined) {
17
+ throw new Error("version expects a numeric argument")
18
+ }
19
+ return new KicadSchVersion(parsedValue)
20
+ }
21
+ }
22
+ SxClass.register(KicadSchVersion)
@@ -0,0 +1,136 @@
1
+ import { SxClass } from "../base-classes/SxClass"
2
+ import type { PrimitiveSExpr } from "../parseToPrimitiveSExpr"
3
+ import { quoteSExprString } from "../utils/quoteSExprString"
4
+ import { toStringValue } from "../utils/toStringValue"
5
+ import { At } from "./At"
6
+ import { TextEffects } from "./TextEffects"
7
+ import { Uuid } from "./Uuid"
8
+ import { FieldsAutoplaced } from "./FieldsAutoplaced"
9
+
10
+ const SUPPORTED_TOKENS = new Set(["at", "effects", "uuid", "fields_autoplaced"])
11
+
12
+ export class Label extends SxClass {
13
+ static override token = "label"
14
+ static override parentToken = "kicad_sch"
15
+ override token = "label"
16
+
17
+ private _value = ""
18
+ private _sxAt?: At
19
+ private _sxEffects?: TextEffects
20
+ private _sxUuid?: Uuid
21
+ private _sxFieldsAutoplaced?: FieldsAutoplaced
22
+
23
+ static override fromSexprPrimitives(
24
+ primitiveSexprs: PrimitiveSExpr[],
25
+ ): Label {
26
+ const [textPrimitive, ...rest] = primitiveSexprs
27
+ const value = toStringValue(textPrimitive)
28
+ if (value === undefined) {
29
+ throw new Error("label expects a string value")
30
+ }
31
+
32
+ const label = new Label()
33
+ label._value = value
34
+
35
+ const { propertyMap, arrayPropertyMap } =
36
+ SxClass.parsePrimitivesToClassProperties(rest, this.token)
37
+
38
+ const unsupportedTokens = Object.keys(propertyMap).filter(
39
+ (token) => !SUPPORTED_TOKENS.has(token),
40
+ )
41
+ if (unsupportedTokens.length > 0) {
42
+ throw new Error(
43
+ `Unsupported child tokens inside label expression: ${unsupportedTokens.join(", ")}`,
44
+ )
45
+ }
46
+
47
+ for (const [token, entries] of Object.entries(arrayPropertyMap)) {
48
+ if (!SUPPORTED_TOKENS.has(token)) {
49
+ throw new Error(
50
+ `Unsupported child tokens inside label expression: ${token}`,
51
+ )
52
+ }
53
+ if (entries.length > 1) {
54
+ throw new Error(`label does not support repeated child tokens: ${token}`)
55
+ }
56
+ }
57
+
58
+ label._sxAt =
59
+ (arrayPropertyMap.at?.[0] as At | undefined) ??
60
+ (propertyMap.at as At | undefined)
61
+ label._sxEffects =
62
+ (arrayPropertyMap.effects?.[0] as TextEffects | undefined) ??
63
+ (propertyMap.effects as TextEffects | undefined)
64
+ label._sxUuid =
65
+ (arrayPropertyMap.uuid?.[0] as Uuid | undefined) ??
66
+ (propertyMap.uuid as Uuid | undefined)
67
+ label._sxFieldsAutoplaced =
68
+ (arrayPropertyMap.fields_autoplaced?.[0] as FieldsAutoplaced | undefined) ??
69
+ (propertyMap.fields_autoplaced as FieldsAutoplaced | undefined)
70
+
71
+ return label
72
+ }
73
+
74
+ get value(): string {
75
+ return this._value
76
+ }
77
+
78
+ set value(newValue: string) {
79
+ this._value = newValue
80
+ }
81
+
82
+ get at(): At | undefined {
83
+ return this._sxAt
84
+ }
85
+
86
+ set at(value: At | undefined) {
87
+ this._sxAt = value
88
+ }
89
+
90
+ get effects(): TextEffects | undefined {
91
+ return this._sxEffects
92
+ }
93
+
94
+ set effects(value: TextEffects | undefined) {
95
+ this._sxEffects = value
96
+ }
97
+
98
+ get uuid(): Uuid | undefined {
99
+ return this._sxUuid
100
+ }
101
+
102
+ set uuid(value: Uuid | string | undefined) {
103
+ if (value === undefined) {
104
+ this._sxUuid = undefined
105
+ return
106
+ }
107
+ this._sxUuid = value instanceof Uuid ? value : new Uuid(value)
108
+ }
109
+
110
+ get fieldsAutoplaced(): boolean {
111
+ return this._sxFieldsAutoplaced?.value ?? false
112
+ }
113
+
114
+ set fieldsAutoplaced(value: boolean) {
115
+ this._sxFieldsAutoplaced = new FieldsAutoplaced(value)
116
+ }
117
+
118
+ override getChildren(): SxClass[] {
119
+ const children: SxClass[] = []
120
+ if (this._sxAt) children.push(this._sxAt)
121
+ if (this._sxEffects) children.push(this._sxEffects)
122
+ if (this._sxUuid) children.push(this._sxUuid)
123
+ if (this._sxFieldsAutoplaced) children.push(this._sxFieldsAutoplaced)
124
+ return children
125
+ }
126
+
127
+ override getString(): string {
128
+ const lines = [`(label ${quoteSExprString(this._value)}`]
129
+ for (const child of this.getChildren()) {
130
+ lines.push(child.getStringIndented())
131
+ }
132
+ lines.push(")")
133
+ return lines.join("\n")
134
+ }
135
+ }
136
+ SxClass.register(Label)
@@ -0,0 +1,51 @@
1
+ import { SxClass } from "../base-classes/SxClass"
2
+ import { printSExpr, type PrimitiveSExpr } from "../parseToPrimitiveSExpr"
3
+ import { quoteSExprString } from "../utils/quoteSExprString"
4
+
5
+ export class Layer extends SxClass {
6
+ static override token = "layer"
7
+ token = "layer"
8
+
9
+ private _names: string[] = []
10
+
11
+ constructor(names: Array<string | number> = []) {
12
+ super()
13
+ this.names = names.map((name) => String(name))
14
+ }
15
+
16
+ static override fromSexprPrimitives(
17
+ primitiveSexprs: PrimitiveSExpr[],
18
+ ): Layer {
19
+ const names = primitiveSexprs.map((primitive) =>
20
+ typeof primitive === "string" || typeof primitive === "number"
21
+ ? String(primitive)
22
+ : printSExpr(primitive),
23
+ )
24
+ return new Layer(names)
25
+ }
26
+
27
+ get names(): string[] {
28
+ return [...this._names]
29
+ }
30
+
31
+ set names(values: Array<string | number>) {
32
+ this._names = values.map((value) => String(value))
33
+ }
34
+
35
+ addName(name: string | number) {
36
+ this._names.push(String(name))
37
+ }
38
+
39
+ override getString(): string {
40
+ const rendered = this._names
41
+ .map((name) => {
42
+ if (/^[^\s()"]+$/u.test(name) && !["nil", "#t", "#f"].includes(name)) {
43
+ return name
44
+ }
45
+ return quoteSExprString(name)
46
+ })
47
+ .join(" ")
48
+ return `(layer ${rendered})`
49
+ }
50
+ }
51
+ SxClass.register(Layer)
@@ -0,0 +1,47 @@
1
+ import { SxClass } from "../base-classes/SxClass"
2
+ import { printSExpr, type PrimitiveSExpr } from "../parseToPrimitiveSExpr"
3
+ import { quoteSExprString } from "../utils/quoteSExprString"
4
+
5
+ export class Layers extends SxClass {
6
+ static override token = "layers"
7
+ token = "layers"
8
+
9
+ private _names: string[] = []
10
+
11
+ constructor(names: Array<string | number> = []) {
12
+ super()
13
+ this.names = names
14
+ }
15
+
16
+ static override fromSexprPrimitives(
17
+ primitiveSexprs: PrimitiveSExpr[],
18
+ ): Layers {
19
+ const names = primitiveSexprs.map((primitive) =>
20
+ typeof primitive === "string" || typeof primitive === "number"
21
+ ? String(primitive)
22
+ : printSExpr(primitive),
23
+ )
24
+ return new Layers(names)
25
+ }
26
+
27
+ get names(): string[] {
28
+ return [...this._names]
29
+ }
30
+
31
+ set names(values: Array<string | number>) {
32
+ this._names = values.map((value) => String(value))
33
+ }
34
+
35
+ override getString(): string {
36
+ const rendered = this._names
37
+ .map((name) => {
38
+ if (/^[^\s()"]+$/u.test(name) && !["nil", "#t", "#f"].includes(name)) {
39
+ return name
40
+ }
41
+ return quoteSExprString(name)
42
+ })
43
+ .join(" ")
44
+ return `(layers ${rendered})`
45
+ }
46
+ }
47
+ SxClass.register(Layers)
@@ -0,0 +1,61 @@
1
+ import { SxClass } from "../base-classes/SxClass"
2
+ import type { PrimitiveSExpr } from "../parseToPrimitiveSExpr"
3
+ import { SchematicSymbol } from "./Symbol"
4
+
5
+ const SUPPORTED_ARRAY_TOKENS = new Set(["symbol"])
6
+
7
+ export class LibSymbols extends SxClass {
8
+ static override token = "lib_symbols"
9
+ static override parentToken = "kicad_sch"
10
+ override token = "lib_symbols"
11
+
12
+ private _symbols: SchematicSymbol[] = []
13
+
14
+ static override fromSexprPrimitives(
15
+ primitiveSexprs: PrimitiveSExpr[],
16
+ ): LibSymbols {
17
+ const libSymbols = new LibSymbols()
18
+
19
+ const { propertyMap, arrayPropertyMap } =
20
+ SxClass.parsePrimitivesToClassProperties(primitiveSexprs, this.token)
21
+
22
+ const unsupportedSingularTokens = Object.keys(propertyMap).filter(
23
+ (token) => !SUPPORTED_ARRAY_TOKENS.has(token),
24
+ )
25
+ if (unsupportedSingularTokens.length > 0) {
26
+ throw new Error(
27
+ `Unsupported child tokens inside lib_symbols expression: ${unsupportedSingularTokens.join(", ")}`,
28
+ )
29
+ }
30
+
31
+ const unsupportedArrayTokens = Object.keys(arrayPropertyMap).filter(
32
+ (token) => !SUPPORTED_ARRAY_TOKENS.has(token),
33
+ )
34
+ if (unsupportedArrayTokens.length > 0) {
35
+ throw new Error(
36
+ `Unsupported repeated child tokens inside lib_symbols expression: ${unsupportedArrayTokens.join(", ")}`,
37
+ )
38
+ }
39
+
40
+ const symbols = (arrayPropertyMap.symbol as SchematicSymbol[]) ?? []
41
+ if (!symbols.length && propertyMap.symbol) {
42
+ symbols.push(propertyMap.symbol as SchematicSymbol)
43
+ }
44
+ libSymbols._symbols = symbols
45
+
46
+ return libSymbols
47
+ }
48
+
49
+ get symbols(): SchematicSymbol[] {
50
+ return [...this._symbols]
51
+ }
52
+
53
+ set symbols(value: SchematicSymbol[]) {
54
+ this._symbols = [...value]
55
+ }
56
+
57
+ override getChildren(): SxClass[] {
58
+ return [...this._symbols]
59
+ }
60
+ }
61
+ SxClass.register(LibSymbols)