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,168 @@
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
+
6
+ export class SheetInstances extends SxClass {
7
+ static override token = "instances"
8
+ static override parentToken = "sheet"
9
+ token = "instances"
10
+
11
+ projects: SheetInstancesProject[] = []
12
+
13
+ static override fromSexprPrimitives(
14
+ primitiveSexprs: PrimitiveSExpr[],
15
+ ): SheetInstances {
16
+ const instances = new SheetInstances()
17
+ const { arrayPropertyMap } = SxClass.parsePrimitivesToClassProperties(
18
+ primitiveSexprs,
19
+ "sheet_instances",
20
+ )
21
+
22
+ instances.projects =
23
+ (arrayPropertyMap.project as SheetInstancesProject[]) ?? []
24
+
25
+ return instances
26
+ }
27
+
28
+ override getChildren(): SxClass[] {
29
+ return [...this.projects]
30
+ }
31
+
32
+ override getString(): string {
33
+ const lines = ["(instances"]
34
+ for (const project of this.projects) {
35
+ lines.push(project.getStringIndented())
36
+ }
37
+ lines.push(")")
38
+ return lines.join("\n")
39
+ }
40
+ }
41
+ SxClass.register(SheetInstances)
42
+
43
+ export class SheetInstancesProject extends SxClass {
44
+ static override token = "project"
45
+ static override parentToken = "sheet_instances"
46
+ token = "project"
47
+
48
+ name: string
49
+ paths: SheetInstancePath[] = []
50
+
51
+ constructor(name: string) {
52
+ super()
53
+ this.name = name
54
+ }
55
+
56
+ static override fromSexprPrimitives(
57
+ primitiveSexprs: PrimitiveSExpr[],
58
+ ): SheetInstancesProject {
59
+ const [namePrimitive, ...rest] = primitiveSexprs
60
+ const name = toStringValue(namePrimitive)
61
+ if (name === undefined) {
62
+ throw new Error("sheet project instances require a project name")
63
+ }
64
+
65
+ const project = new SheetInstancesProject(name)
66
+
67
+ const { arrayPropertyMap } = SxClass.parsePrimitivesToClassProperties(
68
+ rest,
69
+ "sheet_project",
70
+ )
71
+
72
+ project.paths = (arrayPropertyMap.path as SheetInstancePath[]) ?? []
73
+
74
+ return project
75
+ }
76
+
77
+ override getChildren(): SxClass[] {
78
+ return [...this.paths]
79
+ }
80
+
81
+ override getString(): string {
82
+ const lines = [`(project ${quoteSExprString(this.name)}`]
83
+ for (const path of this.paths) {
84
+ lines.push(path.getStringIndented())
85
+ }
86
+ lines.push(")")
87
+ return lines.join("\n")
88
+ }
89
+ }
90
+ SxClass.register(SheetInstancesProject)
91
+
92
+ export class SheetInstancePath extends SxClass {
93
+ static override token = "path"
94
+ static override parentToken = "sheet_project"
95
+ token = "path"
96
+
97
+ value: string
98
+ pages: SheetInstancePage[] = []
99
+
100
+ constructor(value: string) {
101
+ super()
102
+ this.value = value
103
+ }
104
+
105
+ static override fromSexprPrimitives(
106
+ primitiveSexprs: PrimitiveSExpr[],
107
+ ): SheetInstancePath {
108
+ const [pathPrimitive, ...rest] = primitiveSexprs
109
+ const value = toStringValue(pathPrimitive)
110
+ if (value === undefined) {
111
+ throw new Error("sheet instance path value must be a string")
112
+ }
113
+
114
+ const path = new SheetInstancePath(value)
115
+
116
+ const { arrayPropertyMap } = SxClass.parsePrimitivesToClassProperties(
117
+ rest,
118
+ "sheet_path",
119
+ )
120
+
121
+ path.pages = (arrayPropertyMap.page as SheetInstancePage[]) ?? []
122
+
123
+ return path
124
+ }
125
+
126
+ override getChildren(): SxClass[] {
127
+ return [...this.pages]
128
+ }
129
+
130
+ override getString(): string {
131
+ const lines = [`(path ${quoteSExprString(this.value)}`]
132
+ for (const page of this.pages) {
133
+ lines.push(page.getStringIndented())
134
+ }
135
+ lines.push(")")
136
+ return lines.join("\n")
137
+ }
138
+ }
139
+ SxClass.register(SheetInstancePath)
140
+
141
+ export class SheetInstancePage extends SxClass {
142
+ static override token = "page"
143
+ static override parentToken = "sheet_path"
144
+ token = "page"
145
+
146
+ value: string
147
+
148
+ constructor(value: string) {
149
+ super()
150
+ this.value = value
151
+ }
152
+
153
+ static override fromSexprPrimitives(
154
+ primitiveSexprs: PrimitiveSExpr[],
155
+ ): SheetInstancePage {
156
+ const [valuePrimitive] = primitiveSexprs
157
+ const value = toStringValue(valuePrimitive)
158
+ if (value === undefined) {
159
+ throw new Error("sheet instance page value must be a string")
160
+ }
161
+ return new SheetInstancePage(value)
162
+ }
163
+
164
+ override getString(): string {
165
+ return `(page ${quoteSExprString(this.value)})`
166
+ }
167
+ }
168
+ SxClass.register(SheetInstancePage)
@@ -0,0 +1,165 @@
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 SUPPORTED_ARRAY_TOKENS = new Set(["page"])
8
+
9
+ export class SheetInstancesRoot extends SxClass {
10
+ static override token = "sheet_instances"
11
+ override token = "sheet_instances"
12
+
13
+ private _paths: SheetInstancesRootPath[] = []
14
+
15
+ static override fromSexprPrimitives(
16
+ primitiveSexprs: PrimitiveSExpr[],
17
+ ): SheetInstancesRoot {
18
+ const sheetInstances = new SheetInstancesRoot()
19
+
20
+ const { propertyMap, arrayPropertyMap } =
21
+ SxClass.parsePrimitivesToClassProperties(primitiveSexprs, this.token)
22
+
23
+ const unsupportedSingularTokens = Object.keys(propertyMap).filter(
24
+ (token) => token !== "path",
25
+ )
26
+ if (unsupportedSingularTokens.length > 0) {
27
+ throw new Error(
28
+ `Unsupported singular child tokens inside sheet_instances expression: ${unsupportedSingularTokens.join(", ")}`,
29
+ )
30
+ }
31
+
32
+ const unsupportedArrayTokens = Object.keys(arrayPropertyMap).filter(
33
+ (token) => token !== "path",
34
+ )
35
+ if (unsupportedArrayTokens.length > 0) {
36
+ throw new Error(
37
+ `Unsupported repeated child tokens inside sheet_instances expression: ${unsupportedArrayTokens.join(", ")}`,
38
+ )
39
+ }
40
+
41
+ const paths = (arrayPropertyMap.path as SheetInstancesRootPath[]) ?? []
42
+ if (!paths.length && propertyMap.path) {
43
+ paths.push(propertyMap.path as SheetInstancesRootPath)
44
+ }
45
+ sheetInstances._paths = paths
46
+
47
+ return sheetInstances
48
+ }
49
+
50
+ get paths(): SheetInstancesRootPath[] {
51
+ return [...this._paths]
52
+ }
53
+
54
+ set paths(value: SheetInstancesRootPath[]) {
55
+ this._paths = [...value]
56
+ }
57
+
58
+ override getChildren(): SxClass[] {
59
+ return [...this._paths]
60
+ }
61
+ }
62
+ SxClass.register(SheetInstancesRoot)
63
+
64
+ export class SheetInstancesRootPath extends SxClass {
65
+ static override token = "path"
66
+ static override parentToken = "sheet_instances"
67
+ override token = "path"
68
+
69
+ private _value = ""
70
+ private _pages: SheetInstancesRootPage[] = []
71
+
72
+ static override fromSexprPrimitives(
73
+ primitiveSexprs: PrimitiveSExpr[],
74
+ ): SheetInstancesRootPath {
75
+ const [valuePrimitive, ...rest] = primitiveSexprs
76
+ const value = toStringValue(valuePrimitive)
77
+ if (value === undefined) {
78
+ throw new Error("sheet_instances path requires a string identifier")
79
+ }
80
+
81
+ const path = new SheetInstancesRootPath()
82
+ path._value = value
83
+
84
+ const { propertyMap, arrayPropertyMap } =
85
+ SxClass.parsePrimitivesToClassProperties(rest, "sheet_instances_path")
86
+
87
+ const unsupportedSingularTokens = Object.keys(propertyMap).filter(
88
+ (token) => !SUPPORTED_ARRAY_TOKENS.has(token),
89
+ )
90
+ if (unsupportedSingularTokens.length > 0) {
91
+ throw new Error(
92
+ `Unsupported singular child tokens inside sheet_instances path expression: ${unsupportedSingularTokens.join(", ")}`,
93
+ )
94
+ }
95
+
96
+ const unsupportedArrayTokens = Object.keys(arrayPropertyMap).filter(
97
+ (token) => !SUPPORTED_ARRAY_TOKENS.has(token),
98
+ )
99
+ if (unsupportedArrayTokens.length > 0) {
100
+ throw new Error(
101
+ `Unsupported repeated child tokens inside sheet_instances path expression: ${unsupportedArrayTokens.join(", ")}`,
102
+ )
103
+ }
104
+
105
+ const pages = (arrayPropertyMap.page as SheetInstancesRootPage[]) ?? []
106
+ if (!pages.length && propertyMap.page) {
107
+ pages.push(propertyMap.page as SheetInstancesRootPage)
108
+ }
109
+ path._pages = pages
110
+
111
+ return path
112
+ }
113
+
114
+ get value(): string {
115
+ return this._value
116
+ }
117
+
118
+ set value(newValue: string) {
119
+ this._value = newValue
120
+ }
121
+
122
+ get pages(): SheetInstancesRootPage[] {
123
+ return [...this._pages]
124
+ }
125
+
126
+ set pages(value: SheetInstancesRootPage[]) {
127
+ this._pages = [...value]
128
+ }
129
+
130
+ override getChildren(): SxClass[] {
131
+ return [...this._pages]
132
+ }
133
+
134
+ override getString(): string {
135
+ const lines = [`(path ${quoteSExprString(this._value)}`]
136
+ for (const page of this._pages) {
137
+ lines.push(page.getStringIndented())
138
+ }
139
+ lines.push(")")
140
+ return lines.join("\n")
141
+ }
142
+ }
143
+ SxClass.register(SheetInstancesRootPath)
144
+
145
+ export class SheetInstancesRootPage extends SxPrimitiveString {
146
+ static override token = "page"
147
+ static override parentToken = "sheet_instances_path"
148
+ override token = "page"
149
+
150
+ static override fromSexprPrimitives(
151
+ primitiveSexprs: PrimitiveSExpr[],
152
+ ): SheetInstancesRootPage {
153
+ const [valuePrimitive] = primitiveSexprs
154
+ const value = toStringValue(valuePrimitive)
155
+ if (value === undefined) {
156
+ throw new Error("sheet_instances page expects a string value")
157
+ }
158
+ return new SheetInstancesRootPage(value)
159
+ }
160
+
161
+ override getString(): string {
162
+ return `(page ${quoteSExprString(this.value)})`
163
+ }
164
+ }
165
+ SxClass.register(SheetInstancesRootPage)
@@ -0,0 +1,122 @@
1
+ import { SxClass } from "../base-classes/SxClass"
2
+ import type { PrimitiveSExpr } from "../parseToPrimitiveSExpr"
3
+ import { indentLines } from "../utils/indentLines"
4
+ import { quoteSExprString } from "../utils/quoteSExprString"
5
+ import { toStringValue } from "../utils/toStringValue"
6
+ import { At } from "./At"
7
+ import { TextEffects } from "./TextEffects"
8
+ import { Uuid } from "./Uuid"
9
+
10
+ export type SheetPinElectricalType =
11
+ | "input"
12
+ | "output"
13
+ | "bidirectional"
14
+ | "tri_state"
15
+ | "passive"
16
+
17
+ const electricalTypes = new Set<SheetPinElectricalType>([
18
+ "input",
19
+ "output",
20
+ "bidirectional",
21
+ "tri_state",
22
+ "passive",
23
+ ])
24
+
25
+ export class SheetPin extends SxClass {
26
+ static override token = "pin"
27
+ static override parentToken = "sheet"
28
+ token = "pin"
29
+
30
+ name = ""
31
+ electricalType: SheetPinElectricalType = "input"
32
+ private _sxAt?: At
33
+ private _sxEffects?: TextEffects
34
+ private _sxUuid?: Uuid
35
+
36
+ static override fromSexprPrimitives(
37
+ primitiveSexprs: PrimitiveSExpr[],
38
+ ): SheetPin {
39
+ if (primitiveSexprs.length < 2) {
40
+ throw new Error("sheet pin requires a name and electrical type")
41
+ }
42
+
43
+ const [rawName, rawType, ...rest] = primitiveSexprs
44
+
45
+ const name = toStringValue(rawName)
46
+ if (name === undefined) {
47
+ throw new Error("sheet pin name must be a string")
48
+ }
49
+
50
+ const electricalType = toStringValue(rawType)
51
+ if (!electricalType || !electricalTypes.has(electricalType as SheetPinElectricalType)) {
52
+ throw new Error(
53
+ `sheet pin electrical type must be one of: ${Array.from(electricalTypes).join(", ")}`,
54
+ )
55
+ }
56
+
57
+ const pin = new SheetPin()
58
+ pin.name = name
59
+ pin.electricalType = electricalType as SheetPinElectricalType
60
+
61
+ const { propertyMap } = SxClass.parsePrimitivesToClassProperties(
62
+ rest,
63
+ this.token,
64
+ )
65
+
66
+ pin._sxAt = propertyMap.at as At | undefined
67
+ pin._sxEffects = propertyMap.effects as TextEffects | undefined
68
+ pin._sxUuid = propertyMap.uuid as Uuid | undefined
69
+
70
+ return pin
71
+ }
72
+
73
+ get position(): At | undefined {
74
+ return this._sxAt
75
+ }
76
+
77
+ set position(value: At | undefined) {
78
+ this._sxAt = value
79
+ }
80
+
81
+ get effects(): TextEffects | undefined {
82
+ return this._sxEffects
83
+ }
84
+
85
+ set effects(value: TextEffects | undefined) {
86
+ this._sxEffects = value
87
+ }
88
+
89
+ get uuid(): Uuid | undefined {
90
+ return this._sxUuid
91
+ }
92
+
93
+ set uuid(value: Uuid | string | undefined) {
94
+ if (value === undefined) {
95
+ this._sxUuid = undefined
96
+ return
97
+ }
98
+ this._sxUuid = value instanceof Uuid ? value : new Uuid(value)
99
+ }
100
+
101
+ override getChildren(): SxClass[] {
102
+ const children: SxClass[] = []
103
+ if (this._sxAt) children.push(this._sxAt)
104
+ if (this._sxEffects) children.push(this._sxEffects)
105
+ if (this._sxUuid) children.push(this._sxUuid)
106
+ return children
107
+ }
108
+
109
+ override getString(): string {
110
+ const header = `(pin ${quoteSExprString(this.name)} ${this.electricalType}`
111
+ const bodyLines = this.getChildren().flatMap((child) =>
112
+ indentLines(child.getString()),
113
+ )
114
+
115
+ if (bodyLines.length === 0) {
116
+ return `${header})`
117
+ }
118
+
119
+ return [header, ...bodyLines, ")"].join("\n")
120
+ }
121
+ }
122
+ SxClass.register(SheetPin)
@@ -0,0 +1,115 @@
1
+ import { SxClass } from "../base-classes/SxClass"
2
+ import type { PrimitiveSExpr } from "../parseToPrimitiveSExpr"
3
+ import { indentLines } from "../utils/indentLines"
4
+ import { quoteSExprString } from "../utils/quoteSExprString"
5
+ import { toStringValue } from "../utils/toStringValue"
6
+ import { At } from "./At"
7
+ import { TextEffects } from "./TextEffects"
8
+ import { SymbolPropertyId as PropertyId } from "./Symbol"
9
+
10
+ export class SheetProperty extends SxClass {
11
+ static override token = "property"
12
+ static override parentToken = "sheet"
13
+ token = "property"
14
+
15
+ key: string
16
+ value: string
17
+ private _sxId?: PropertyId
18
+ private _sxAt?: At
19
+ private _sxEffects?: TextEffects
20
+
21
+ constructor(params: {
22
+ key: string
23
+ value: string
24
+ id?: number | PropertyId
25
+ at?: At
26
+ effects?: TextEffects
27
+ }) {
28
+ super()
29
+ this.key = params.key
30
+ this.value = params.value
31
+ this.id = params.id
32
+ this.at = params.at
33
+ this.effects = params.effects
34
+ }
35
+
36
+ static override fromSexprPrimitives(
37
+ primitiveSexprs: PrimitiveSExpr[],
38
+ ): SheetProperty {
39
+ const [rawKey, rawValue, ...rest] = primitiveSexprs
40
+
41
+ const key = toStringValue(rawKey)
42
+ const value = toStringValue(rawValue)
43
+
44
+ if (key === undefined || value === undefined) {
45
+ throw new Error("sheet property requires string key and value")
46
+ }
47
+
48
+ const { propertyMap } = SxClass.parsePrimitivesToClassProperties(
49
+ rest,
50
+ this.token,
51
+ )
52
+
53
+ return new SheetProperty({
54
+ key,
55
+ value,
56
+ id: propertyMap.id as PropertyId | undefined,
57
+ at: propertyMap.at as At | undefined,
58
+ effects: propertyMap.effects as TextEffects | undefined,
59
+ })
60
+ }
61
+
62
+ get id(): number | undefined {
63
+ return this._sxId?.value
64
+ }
65
+
66
+ set id(value: number | PropertyId | undefined) {
67
+ if (value === undefined) {
68
+ this._sxId = undefined
69
+ return
70
+ }
71
+ this._sxId = value instanceof PropertyId ? value : new PropertyId(value)
72
+ }
73
+
74
+ get idClass(): PropertyId | undefined {
75
+ return this._sxId
76
+ }
77
+
78
+ get at(): At | undefined {
79
+ return this._sxAt
80
+ }
81
+
82
+ set at(value: At | undefined) {
83
+ this._sxAt = value
84
+ }
85
+
86
+ get effects(): TextEffects | undefined {
87
+ return this._sxEffects
88
+ }
89
+
90
+ set effects(value: TextEffects | undefined) {
91
+ this._sxEffects = value
92
+ }
93
+
94
+ override getChildren(): SxClass[] {
95
+ const children: SxClass[] = []
96
+ if (this._sxId) children.push(this._sxId)
97
+ if (this._sxAt) children.push(this._sxAt)
98
+ if (this._sxEffects) children.push(this._sxEffects)
99
+ return children
100
+ }
101
+
102
+ override getString(): string {
103
+ const header = `(property ${quoteSExprString(this.key)} ${quoteSExprString(this.value)}`
104
+ const bodyLines = this.getChildren().flatMap((child) =>
105
+ indentLines(child.getString()),
106
+ )
107
+
108
+ if (bodyLines.length === 0) {
109
+ return `${header})`
110
+ }
111
+
112
+ return [header, ...bodyLines, ")"].join("\n")
113
+ }
114
+ }
115
+ SxClass.register(SheetProperty)
@@ -0,0 +1,44 @@
1
+ import { SxClass } from "../base-classes/SxClass"
2
+ import type { PrimitiveSExpr } from "../parseToPrimitiveSExpr"
3
+ import { indentLines } from "../utils/indentLines"
4
+ import { quoteSExprString } from "../utils/quoteSExprString"
5
+ import { toStringValue } from "../utils/toStringValue"
6
+ import { At } from "./At"
7
+ import { TextEffects } from "./TextEffects"
8
+ import { SymbolPropertyId as PropertyId } from "./Symbol"
9
+ import { toNumberValue } from "../utils/toNumberValue"
10
+
11
+ export class SheetSize extends SxClass {
12
+ static override token = "size"
13
+ static override parentToken = "sheet"
14
+ token = "size"
15
+
16
+ width: number
17
+ height: number
18
+
19
+ constructor(width: number, height: number) {
20
+ super()
21
+ this.width = width
22
+ this.height = height
23
+ }
24
+
25
+ static override fromSexprPrimitives(
26
+ primitiveSexprs: PrimitiveSExpr[],
27
+ ): SheetSize {
28
+ const width = toNumberValue(primitiveSexprs[0])
29
+ const height = toNumberValue(primitiveSexprs[1])
30
+ if (width === undefined || height === undefined) {
31
+ throw new Error("sheet size requires numeric width and height")
32
+ }
33
+ return new SheetSize(width, height)
34
+ }
35
+
36
+ toObject(): { width: number; height: number } {
37
+ return { width: this.width, height: this.height }
38
+ }
39
+
40
+ override getString(): string {
41
+ return `(size ${this.width} ${this.height})`
42
+ }
43
+ }
44
+ SxClass.register(SheetSize)
@@ -0,0 +1,58 @@
1
+ import { SxClass } from "../base-classes/SxClass"
2
+ import { Width } from "./Width"
3
+ import { StrokeType, type StrokeTypeString } from "./StrokeType"
4
+ import { Color, type RGBAColor } from "./Color"
5
+ import type { PrimitiveSExpr } from "../parseToPrimitiveSExpr"
6
+
7
+ export type StrokeProperty = Width | StrokeType | Color
8
+
9
+ export class Stroke extends SxClass {
10
+ static override token = "stroke"
11
+ token = "stroke"
12
+
13
+ _sxWidth?: Width
14
+ _sxType?: StrokeType
15
+ _sxColor?: Color
16
+
17
+ static override fromSexprPrimitives(
18
+ primitiveSexprs: PrimitiveSExpr[],
19
+ ): Stroke {
20
+ const stroke = new Stroke()
21
+
22
+ const { propertyMap } = SxClass.parsePrimitivesToClassProperties(
23
+ primitiveSexprs,
24
+ this.token,
25
+ )
26
+ stroke._sxWidth = propertyMap.width as Width
27
+ stroke._sxType = propertyMap.type as StrokeType
28
+ stroke._sxColor = propertyMap.color as Color
29
+
30
+ return stroke
31
+ }
32
+
33
+ get width(): number | undefined {
34
+ return this._sxWidth?.value
35
+ }
36
+
37
+ get type(): StrokeTypeString | undefined {
38
+ return this._sxType?.type
39
+ }
40
+
41
+ get color(): RGBAColor | undefined {
42
+ return this._sxColor?.color
43
+ }
44
+
45
+ set width(width: number) {
46
+ this._sxWidth = new Width(width)
47
+ }
48
+
49
+ set type(type: StrokeTypeString) {
50
+ this._sxType = new StrokeType(type)
51
+ }
52
+
53
+ set color(color: RGBAColor) {
54
+ // TODO accept color as string
55
+ this._sxColor = new Color([color.r, color.g, color.b, color.a])
56
+ }
57
+ }
58
+ SxClass.register(Stroke)
@@ -0,0 +1,34 @@
1
+ import { SxClass } from "../base-classes/SxClass"
2
+ import type { PrimitiveSExpr } from "../parseToPrimitiveSExpr"
3
+
4
+ export type StrokeTypeString =
5
+ | "dash"
6
+ | "dash_dot"
7
+ | "dash_dot_dot"
8
+ | "dot"
9
+ | "default"
10
+ | "solid"
11
+
12
+ export class StrokeType extends SxClass {
13
+ static override token = "type"
14
+ static override parentToken = "stroke"
15
+ token = "type"
16
+
17
+ type: StrokeTypeString
18
+
19
+ constructor(type: StrokeTypeString) {
20
+ super()
21
+ this.type = type
22
+ }
23
+
24
+ static override fromSexprPrimitives(
25
+ primitiveSexprs: PrimitiveSExpr[],
26
+ ): StrokeType {
27
+ return new StrokeType(primitiveSexprs[0] as StrokeTypeString)
28
+ }
29
+
30
+ override getString() {
31
+ return `(type ${this.type})`
32
+ }
33
+ }
34
+ SxClass.register(StrokeType)