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.
- package/.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc +111 -0
- package/.vscode/settings.json +16 -0
- package/AGENTS.md +30 -0
- package/README.md +206 -0
- package/biome.json +93 -0
- package/bun.lock +48 -0
- package/bunfig.toml +5 -0
- package/lib/index.ts +1 -0
- package/lib/sexpr/base-classes/SxClass.ts +164 -0
- package/lib/sexpr/base-classes/SxPrimitiveBoolean.ts +35 -0
- package/lib/sexpr/base-classes/SxPrimitiveNumber.ts +26 -0
- package/lib/sexpr/base-classes/SxPrimitiveString.ts +26 -0
- package/lib/sexpr/classes/At.ts +38 -0
- package/lib/sexpr/classes/Bus.ts +83 -0
- package/lib/sexpr/classes/BusEntry.ts +142 -0
- package/lib/sexpr/classes/Color.ts +29 -0
- package/lib/sexpr/classes/Dnp.ts +8 -0
- package/lib/sexpr/classes/EmbeddedFonts.ts +70 -0
- package/lib/sexpr/classes/ExcludeFromSim.ts +8 -0
- package/lib/sexpr/classes/FieldsAutoplaced.ts +8 -0
- package/lib/sexpr/classes/Footprint.ts +719 -0
- package/lib/sexpr/classes/FootprintAttr.ts +102 -0
- package/lib/sexpr/classes/FootprintAutoplaceCost180.ts +9 -0
- package/lib/sexpr/classes/FootprintAutoplaceCost90.ts +9 -0
- package/lib/sexpr/classes/FootprintClearance.ts +9 -0
- package/lib/sexpr/classes/FootprintDescr.ts +44 -0
- package/lib/sexpr/classes/FootprintLocked.ts +32 -0
- package/lib/sexpr/classes/FootprintModel.ts +145 -0
- package/lib/sexpr/classes/FootprintNetTiePadGroups.ts +50 -0
- package/lib/sexpr/classes/FootprintPad.ts +705 -0
- package/lib/sexpr/classes/FootprintPath.ts +44 -0
- package/lib/sexpr/classes/FootprintPlaced.ts +32 -0
- package/lib/sexpr/classes/FootprintPrivateLayers.ts +56 -0
- package/lib/sexpr/classes/FootprintSheetfile.ts +44 -0
- package/lib/sexpr/classes/FootprintSheetname.ts +44 -0
- package/lib/sexpr/classes/FootprintSolderMaskMargin.ts +9 -0
- package/lib/sexpr/classes/FootprintSolderPasteMargin.ts +9 -0
- package/lib/sexpr/classes/FootprintSolderPasteRatio.ts +9 -0
- package/lib/sexpr/classes/FootprintTags.ts +44 -0
- package/lib/sexpr/classes/FootprintTedit.ts +21 -0
- package/lib/sexpr/classes/FootprintThermalGap.ts +9 -0
- package/lib/sexpr/classes/FootprintThermalWidth.ts +9 -0
- package/lib/sexpr/classes/FootprintZoneConnect.ts +9 -0
- package/lib/sexpr/classes/FpArc.ts +289 -0
- package/lib/sexpr/classes/FpCircle.ts +293 -0
- package/lib/sexpr/classes/FpLine.ts +288 -0
- package/lib/sexpr/classes/FpPoly.ts +266 -0
- package/lib/sexpr/classes/FpPolyFill.ts +48 -0
- package/lib/sexpr/classes/FpPolyLocked.ts +40 -0
- package/lib/sexpr/classes/FpRect.ts +293 -0
- package/lib/sexpr/classes/FpText.ts +341 -0
- package/lib/sexpr/classes/FpTextBox.ts +412 -0
- package/lib/sexpr/classes/GrLine.ts +245 -0
- package/lib/sexpr/classes/GrLineAngle.ts +32 -0
- package/lib/sexpr/classes/GrLineEnd.ts +61 -0
- package/lib/sexpr/classes/GrLineLocked.ts +40 -0
- package/lib/sexpr/classes/GrLineStart.ts +61 -0
- package/lib/sexpr/classes/GrText.ts +202 -0
- package/lib/sexpr/classes/Image.ts +256 -0
- package/lib/sexpr/classes/InBom.ts +8 -0
- package/lib/sexpr/classes/Junction.ts +134 -0
- package/lib/sexpr/classes/KicadPcb.ts +313 -0
- package/lib/sexpr/classes/KicadSch.ts +303 -0
- package/lib/sexpr/classes/KicadSchGenerator.ts +32 -0
- package/lib/sexpr/classes/KicadSchGeneratorVersion.ts +30 -0
- package/lib/sexpr/classes/KicadSchVersion.ts +22 -0
- package/lib/sexpr/classes/Label.ts +136 -0
- package/lib/sexpr/classes/Layer.ts +51 -0
- package/lib/sexpr/classes/Layers.ts +47 -0
- package/lib/sexpr/classes/LibSymbols.ts +61 -0
- package/lib/sexpr/classes/NoConnect.ts +73 -0
- package/lib/sexpr/classes/OnBoard.ts +8 -0
- package/lib/sexpr/classes/PadChamfer.ts +50 -0
- package/lib/sexpr/classes/PadChamferRatio.ts +9 -0
- package/lib/sexpr/classes/PadClearance.ts +9 -0
- package/lib/sexpr/classes/PadDieLength.ts +9 -0
- package/lib/sexpr/classes/PadDrill.ts +145 -0
- package/lib/sexpr/classes/PadDrillOffset.ts +54 -0
- package/lib/sexpr/classes/PadLayers.ts +59 -0
- package/lib/sexpr/classes/PadNet.ts +56 -0
- package/lib/sexpr/classes/PadOptions.ts +182 -0
- package/lib/sexpr/classes/PadPinFunction.ts +9 -0
- package/lib/sexpr/classes/PadPinType.ts +9 -0
- package/lib/sexpr/classes/PadPrimitiveGrArc.ts +254 -0
- package/lib/sexpr/classes/PadPrimitiveGrCircle.ts +279 -0
- package/lib/sexpr/classes/PadPrimitiveGrLine.ts +126 -0
- package/lib/sexpr/classes/PadPrimitives.ts +289 -0
- package/lib/sexpr/classes/PadRectDelta.ts +57 -0
- package/lib/sexpr/classes/PadRoundrectRratio.ts +9 -0
- package/lib/sexpr/classes/PadSize.ts +54 -0
- package/lib/sexpr/classes/PadSolderMaskMargin.ts +9 -0
- package/lib/sexpr/classes/PadSolderPasteMargin.ts +9 -0
- package/lib/sexpr/classes/PadSolderPasteMarginRatio.ts +9 -0
- package/lib/sexpr/classes/PadTeardrops.ts +208 -0
- package/lib/sexpr/classes/PadThermalBridgeAngle.ts +9 -0
- package/lib/sexpr/classes/PadThermalGap.ts +9 -0
- package/lib/sexpr/classes/PadThermalWidth.ts +9 -0
- package/lib/sexpr/classes/PadZoneConnect.ts +9 -0
- package/lib/sexpr/classes/Paper.ts +119 -0
- package/lib/sexpr/classes/PcbGeneral.ts +75 -0
- package/lib/sexpr/classes/PcbGeneralLegacyTeardrops.ts +44 -0
- package/lib/sexpr/classes/PcbGeneralThickness.ts +9 -0
- package/lib/sexpr/classes/PcbGenerator.ts +16 -0
- package/lib/sexpr/classes/PcbGeneratorVersion.ts +16 -0
- package/lib/sexpr/classes/PcbLayerDefinition.ts +102 -0
- package/lib/sexpr/classes/PcbLayers.ts +34 -0
- package/lib/sexpr/classes/PcbNet.ts +56 -0
- package/lib/sexpr/classes/PcbVersion.ts +9 -0
- package/lib/sexpr/classes/Property.ts +246 -0
- package/lib/sexpr/classes/PropertyHide.ts +9 -0
- package/lib/sexpr/classes/PropertyUnlocked.ts +9 -0
- package/lib/sexpr/classes/Pts.ts +65 -0
- package/lib/sexpr/classes/RenderCache.ts +221 -0
- package/lib/sexpr/classes/SchematicText.ts +141 -0
- package/lib/sexpr/classes/Segment.ts +222 -0
- package/lib/sexpr/classes/SegmentEnd.ts +59 -0
- package/lib/sexpr/classes/SegmentLocked.ts +33 -0
- package/lib/sexpr/classes/SegmentNet.ts +62 -0
- package/lib/sexpr/classes/SegmentStart.ts +59 -0
- package/lib/sexpr/classes/Setup/PcbPlotParams.ts +729 -0
- package/lib/sexpr/classes/Setup/PcbPlotParamsBase.ts +9 -0
- package/lib/sexpr/classes/Setup/PcbPlotParamsNumericProperties.ts +105 -0
- package/lib/sexpr/classes/Setup/PcbPlotParamsStringPropertiesA.ts +104 -0
- package/lib/sexpr/classes/Setup/PcbPlotParamsStringPropertiesB.ts +105 -0
- package/lib/sexpr/classes/Setup/Setup.ts +573 -0
- package/lib/sexpr/classes/Setup/SetupPropertyTypes.ts +119 -0
- package/lib/sexpr/classes/Setup/Stackup.ts +140 -0
- package/lib/sexpr/classes/Setup/StackupLayer.ts +233 -0
- package/lib/sexpr/classes/Setup/StackupLayerProperties.ts +78 -0
- package/lib/sexpr/classes/Setup/StackupProperties.ts +41 -0
- package/lib/sexpr/classes/Setup/base.ts +167 -0
- package/lib/sexpr/classes/Setup/index.ts +14 -0
- package/lib/sexpr/classes/Setup/setupMultiValueProperties.ts +54 -0
- package/lib/sexpr/classes/Setup/setupNumericProperties.ts +151 -0
- package/lib/sexpr/classes/Setup/setupPropertyHandlers.ts +90 -0
- package/lib/sexpr/classes/Setup/setupStringProperties.ts +75 -0
- package/lib/sexpr/classes/Sheet.ts +205 -0
- package/lib/sexpr/classes/SheetFill.ts +44 -0
- package/lib/sexpr/classes/SheetInstances.ts +168 -0
- package/lib/sexpr/classes/SheetInstancesRoot.ts +165 -0
- package/lib/sexpr/classes/SheetPin.ts +122 -0
- package/lib/sexpr/classes/SheetProperty.ts +115 -0
- package/lib/sexpr/classes/SheetSize.ts +44 -0
- package/lib/sexpr/classes/Stroke.ts +58 -0
- package/lib/sexpr/classes/StrokeType.ts +34 -0
- package/lib/sexpr/classes/Symbol.ts +1541 -0
- package/lib/sexpr/classes/TextEffects.ts +444 -0
- package/lib/sexpr/classes/TitleBlock.ts +352 -0
- package/lib/sexpr/classes/Unit.ts +28 -0
- package/lib/sexpr/classes/Uuid.ts +8 -0
- package/lib/sexpr/classes/Via.ts +328 -0
- package/lib/sexpr/classes/ViaNet.ts +59 -0
- package/lib/sexpr/classes/Width.ts +8 -0
- package/lib/sexpr/classes/Wire.ts +91 -0
- package/lib/sexpr/classes/Xy.ts +35 -0
- package/lib/sexpr/classes/Zone.ts +41 -0
- package/lib/sexpr/index.ts +130 -0
- package/lib/sexpr/parseKicadSexpr.ts +5 -0
- package/lib/sexpr/parseToPrimitiveSExpr.ts +240 -0
- package/lib/sexpr/utils/indentLines.ts +3 -0
- package/lib/sexpr/utils/parseYesNo.ts +12 -0
- package/lib/sexpr/utils/quoteSExprString.ts +8 -0
- package/lib/sexpr/utils/strokeFromArgs.ts +19 -0
- package/lib/sexpr/utils/toNumberValue.ts +13 -0
- package/lib/sexpr/utils/toStringValue.ts +10 -0
- package/package.json +26 -0
- package/scripts/download-references.ts +66 -0
- package/tests/fixtures/expectEqualPrimitiveSExpr.ts +200 -0
- package/tests/sexpr/KicadPcbDemos.test.ts +48 -0
- package/tests/sexpr/KicadSchDemos.test.ts +49 -0
- package/tests/sexpr/classes/Footprint.test.ts +277 -0
- package/tests/sexpr/classes/FootprintPad.test.ts +71 -0
- package/tests/sexpr/classes/FpArc.test.ts +45 -0
- package/tests/sexpr/classes/FpCircle.test.ts +39 -0
- package/tests/sexpr/classes/FpPoly.test.ts +43 -0
- package/tests/sexpr/classes/FpRect.test.ts +40 -0
- package/tests/sexpr/classes/FpTextBox.test.ts +84 -0
- package/tests/sexpr/classes/Image.test.ts +50 -0
- package/tests/sexpr/classes/KicadSch.test.ts +97 -0
- package/tests/sexpr/classes/Paper.test.ts +30 -0
- package/tests/sexpr/classes/Property.test.ts +48 -0
- package/tests/sexpr/classes/Setup.test.ts +189 -0
- package/tests/sexpr/classes/Sheet.test.ts +107 -0
- package/tests/sexpr/classes/Stroke.test.ts +15 -0
- package/tests/sexpr/classes/Symbol.test.ts +96 -0
- package/tests/sexpr/classes/TextEffects.test.ts +56 -0
- package/tests/sexpr/classes/TitleBlock.test.ts +40 -0
- 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)
|