kicadts 0.0.1 → 0.0.2
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/.github/workflows/bun-formatcheck.yml +26 -0
- package/.github/workflows/bun-pver-release.yml +70 -0
- package/.github/workflows/bun-test.yml +32 -0
- package/.github/workflows/bun-typecheck.yml +26 -0
- package/.vscode/settings.json +1 -1
- package/AGENTS.md +1 -0
- package/LICENSE +21 -0
- package/README.md +101 -91
- package/TODO.md +46 -0
- package/bunfig.toml +2 -2
- package/lib/sexpr/classes/At.ts +15 -0
- package/lib/sexpr/classes/Bus.ts +23 -3
- package/lib/sexpr/classes/BusEntry.ts +30 -3
- package/lib/sexpr/classes/EmbeddedFonts.ts +1 -3
- package/lib/sexpr/classes/Footprint.ts +157 -27
- package/lib/sexpr/classes/FootprintAttr.ts +3 -1
- package/lib/sexpr/classes/FootprintModel.ts +1 -4
- package/lib/sexpr/classes/FootprintNetTiePadGroups.ts +3 -1
- package/lib/sexpr/classes/FootprintPad.ts +206 -54
- package/lib/sexpr/classes/FpArc.ts +23 -0
- package/lib/sexpr/classes/FpCircle.ts +24 -3
- package/lib/sexpr/classes/FpLine.ts +31 -3
- package/lib/sexpr/classes/FpPoly.ts +24 -4
- package/lib/sexpr/classes/FpRect.ts +24 -3
- package/lib/sexpr/classes/FpText.ts +43 -9
- package/lib/sexpr/classes/FpTextBox.ts +43 -5
- package/lib/sexpr/classes/GrLine.ts +20 -1
- package/lib/sexpr/classes/GrText.ts +38 -12
- package/lib/sexpr/classes/Image.ts +38 -11
- package/lib/sexpr/classes/Junction.ts +36 -4
- package/lib/sexpr/classes/KicadPcb.ts +49 -1
- package/lib/sexpr/classes/KicadSch.ts +119 -25
- package/lib/sexpr/classes/Label.ts +45 -5
- package/lib/sexpr/classes/NoConnect.ts +20 -3
- package/lib/sexpr/classes/PadLayers.ts +13 -1
- package/lib/sexpr/classes/PadOptions.ts +4 -5
- package/lib/sexpr/classes/PadPrimitiveGrArc.ts +22 -4
- package/lib/sexpr/classes/PadPrimitiveGrCircle.ts +23 -4
- package/lib/sexpr/classes/PadPrimitives.ts +3 -1
- package/lib/sexpr/classes/PadSize.ts +15 -0
- package/lib/sexpr/classes/PadTeardrops.ts +3 -1
- package/lib/sexpr/classes/PcbGeneral.ts +14 -7
- package/lib/sexpr/classes/PcbLayerDefinition.ts +5 -1
- package/lib/sexpr/classes/Property.ts +64 -9
- package/lib/sexpr/classes/Pts.ts +7 -5
- package/lib/sexpr/classes/SchematicText.ts +39 -9
- package/lib/sexpr/classes/Segment.ts +21 -0
- package/lib/sexpr/classes/SegmentNet.ts +3 -1
- package/lib/sexpr/classes/Setup/PcbPlotParams.ts +10 -50
- package/lib/sexpr/classes/Setup/Setup.ts +12 -11
- package/lib/sexpr/classes/Setup/Stackup.ts +14 -19
- package/lib/sexpr/classes/Setup/StackupLayerProperties.ts +3 -1
- package/lib/sexpr/classes/Setup/StackupProperties.ts +0 -1
- package/lib/sexpr/classes/Setup/base.ts +1 -3
- package/lib/sexpr/classes/Setup/setupMultiValueProperties.ts +0 -1
- package/lib/sexpr/classes/Sheet.ts +85 -3
- package/lib/sexpr/classes/SheetPin.ts +4 -1
- package/lib/sexpr/classes/Symbol.ts +176 -51
- package/lib/sexpr/classes/TextEffects.ts +25 -8
- package/lib/sexpr/classes/TitleBlock.ts +21 -4
- package/lib/sexpr/classes/Via.ts +38 -3
- package/lib/sexpr/classes/ViaNet.ts +2 -1
- package/lib/sexpr/classes/Wire.ts +23 -3
- package/lib/sexpr/classes/Xy.ts +1 -3
- package/lib/sexpr/classes/Zone.ts +1 -3
- package/lib/sexpr/parseToPrimitiveSExpr.ts +6 -1
- package/lib/sexpr/utils/strokeFromArgs.ts +5 -6
- package/lib/sexpr/utils/toStringValue.ts +2 -1
- package/package.json +2 -1
- package/scripts/download-references.ts +24 -22
- package/tests/fixtures/expectEqualPrimitiveSExpr.ts +6 -7
- package/tests/fixtures/png-matcher.ts +109 -0
- package/tests/fixtures/preload.ts +1 -0
- package/tests/sexpr/classes/FootprintPad.test.ts +8 -1
- package/tests/sexpr/classes/Image.test.ts +9 -1
- package/tests/sexpr/classes/KicadSch.test.ts +1 -3
- package/tests/sexpr/classes/Setup.test.ts +0 -1
- package/bun.lock +0 -48
|
@@ -2,7 +2,7 @@ import { SxClass } from "../base-classes/SxClass"
|
|
|
2
2
|
import { printSExpr, type PrimitiveSExpr } from "../parseToPrimitiveSExpr"
|
|
3
3
|
import { quoteSExprString } from "../utils/quoteSExprString"
|
|
4
4
|
import { toStringValue } from "../utils/toStringValue"
|
|
5
|
-
import { At } from "./At"
|
|
5
|
+
import { At, type AtInput } from "./At"
|
|
6
6
|
import { Layer } from "./Layer"
|
|
7
7
|
import { TextEffects } from "./TextEffects"
|
|
8
8
|
import { Uuid } from "./Uuid"
|
|
@@ -22,6 +22,17 @@ const SUPPORTED_SINGLE_TOKENS = new Set([
|
|
|
22
22
|
|
|
23
23
|
const SUPPORTED_MULTI_TOKENS = new Set<string>()
|
|
24
24
|
|
|
25
|
+
export interface FpTextConstructorParams {
|
|
26
|
+
type?: FpTextType
|
|
27
|
+
text?: string
|
|
28
|
+
position?: AtInput | Xy
|
|
29
|
+
unlocked?: boolean
|
|
30
|
+
hidden?: boolean
|
|
31
|
+
layer?: Layer | string | string[]
|
|
32
|
+
effects?: TextEffects
|
|
33
|
+
uuid?: Uuid | string
|
|
34
|
+
}
|
|
35
|
+
|
|
25
36
|
export class FpText extends SxClass {
|
|
26
37
|
static override token = "fp_text"
|
|
27
38
|
token = "fp_text"
|
|
@@ -35,6 +46,18 @@ export class FpText extends SxClass {
|
|
|
35
46
|
private _sxEffects?: TextEffects
|
|
36
47
|
private _sxUuid?: Uuid
|
|
37
48
|
|
|
49
|
+
constructor(params: FpTextConstructorParams = {}) {
|
|
50
|
+
super()
|
|
51
|
+
if (params.type !== undefined) this.type = params.type
|
|
52
|
+
if (params.text !== undefined) this.text = params.text
|
|
53
|
+
if (params.position !== undefined) this.position = params.position
|
|
54
|
+
if (params.unlocked !== undefined) this.unlocked = params.unlocked
|
|
55
|
+
if (params.hidden !== undefined) this.hidden = params.hidden
|
|
56
|
+
if (params.layer !== undefined) this.layer = params.layer
|
|
57
|
+
if (params.effects !== undefined) this.effects = params.effects
|
|
58
|
+
if (params.uuid !== undefined) this.uuid = params.uuid
|
|
59
|
+
}
|
|
60
|
+
|
|
38
61
|
static override fromSexprPrimitives(
|
|
39
62
|
primitiveSexprs: PrimitiveSExpr[],
|
|
40
63
|
): FpText {
|
|
@@ -62,7 +85,9 @@ export class FpText extends SxClass {
|
|
|
62
85
|
if (typeof primitive === "string") {
|
|
63
86
|
if (primitive === "unlocked") {
|
|
64
87
|
if (sawBareUnlocked) {
|
|
65
|
-
throw new Error(
|
|
88
|
+
throw new Error(
|
|
89
|
+
"fp_text encountered duplicate bare unlocked tokens",
|
|
90
|
+
)
|
|
66
91
|
}
|
|
67
92
|
sawBareUnlocked = true
|
|
68
93
|
continue
|
|
@@ -74,9 +99,7 @@ export class FpText extends SxClass {
|
|
|
74
99
|
sawBareHide = true
|
|
75
100
|
continue
|
|
76
101
|
}
|
|
77
|
-
throw new Error(
|
|
78
|
-
`fp_text encountered unsupported flag "${primitive}"`,
|
|
79
|
-
)
|
|
102
|
+
throw new Error(`fp_text encountered unsupported flag "${primitive}"`)
|
|
80
103
|
}
|
|
81
104
|
|
|
82
105
|
if (!Array.isArray(primitive) || primitive.length === 0) {
|
|
@@ -170,8 +193,17 @@ export class FpText extends SxClass {
|
|
|
170
193
|
return this._sxPosition
|
|
171
194
|
}
|
|
172
195
|
|
|
173
|
-
set position(value:
|
|
174
|
-
|
|
196
|
+
set position(value: AtInput | Xy | undefined) {
|
|
197
|
+
if (value === undefined) {
|
|
198
|
+
this._sxPosition = undefined
|
|
199
|
+
return
|
|
200
|
+
}
|
|
201
|
+
if (value instanceof Xy) {
|
|
202
|
+
this._sxPosition = value
|
|
203
|
+
return
|
|
204
|
+
}
|
|
205
|
+
// Handle AtInput (At, array, or object)
|
|
206
|
+
this._sxPosition = At.from(value as AtInput)
|
|
175
207
|
}
|
|
176
208
|
|
|
177
209
|
get unlocked(): boolean {
|
|
@@ -287,7 +319,8 @@ class FpTextUnlocked extends SxClass {
|
|
|
287
319
|
): FpTextUnlocked {
|
|
288
320
|
const [raw] = primitiveSexprs
|
|
289
321
|
const rawString = toStringValue(raw)
|
|
290
|
-
const value =
|
|
322
|
+
const value =
|
|
323
|
+
rawString === undefined ? true : !/^(no|false)$/iu.test(rawString)
|
|
291
324
|
return new FpTextUnlocked({ value, bare: false })
|
|
292
325
|
}
|
|
293
326
|
|
|
@@ -323,7 +356,8 @@ class FpTextHide extends SxClass {
|
|
|
323
356
|
): FpTextHide {
|
|
324
357
|
const [raw] = primitiveSexprs
|
|
325
358
|
const rawString = toStringValue(raw)
|
|
326
|
-
const value =
|
|
359
|
+
const value =
|
|
360
|
+
rawString === undefined ? true : !/^(no|false)$/iu.test(rawString)
|
|
327
361
|
return new FpTextHide({ value, bare: false })
|
|
328
362
|
}
|
|
329
363
|
|
|
@@ -31,6 +31,20 @@ const SUPPORTED_SINGLE_TOKENS = new Set([
|
|
|
31
31
|
|
|
32
32
|
const SUPPORTED_MULTI_TOKENS = new Set<string>()
|
|
33
33
|
|
|
34
|
+
export interface FpTextBoxConstructorParams {
|
|
35
|
+
locked?: boolean
|
|
36
|
+
text?: string
|
|
37
|
+
start?: FpTextBoxStart | { x: number; y: number }
|
|
38
|
+
end?: FpTextBoxEnd | { x: number; y: number }
|
|
39
|
+
pts?: Pts
|
|
40
|
+
angle?: FpTextBoxAngle | number
|
|
41
|
+
layer?: Layer | string | string[]
|
|
42
|
+
uuid?: Uuid | string
|
|
43
|
+
effects?: TextEffects
|
|
44
|
+
stroke?: Stroke
|
|
45
|
+
renderCache?: RenderCache
|
|
46
|
+
}
|
|
47
|
+
|
|
34
48
|
export class FpTextBox extends SxClass {
|
|
35
49
|
static override token = "fp_text_box"
|
|
36
50
|
token = "fp_text_box"
|
|
@@ -47,6 +61,21 @@ export class FpTextBox extends SxClass {
|
|
|
47
61
|
private _sxStroke?: Stroke
|
|
48
62
|
private _sxRenderCache?: RenderCache
|
|
49
63
|
|
|
64
|
+
constructor(params: FpTextBoxConstructorParams = {}) {
|
|
65
|
+
super()
|
|
66
|
+
if (params.locked !== undefined) this.locked = params.locked
|
|
67
|
+
if (params.text !== undefined) this.text = params.text
|
|
68
|
+
if (params.start !== undefined) this.start = params.start
|
|
69
|
+
if (params.end !== undefined) this.end = params.end
|
|
70
|
+
if (params.pts !== undefined) this.pts = params.pts
|
|
71
|
+
if (params.angle !== undefined) this.angle = params.angle
|
|
72
|
+
if (params.layer !== undefined) this.layer = params.layer
|
|
73
|
+
if (params.uuid !== undefined) this.uuid = params.uuid
|
|
74
|
+
if (params.effects !== undefined) this.effects = params.effects
|
|
75
|
+
if (params.stroke !== undefined) this.stroke = params.stroke
|
|
76
|
+
if (params.renderCache !== undefined) this.renderCache = params.renderCache
|
|
77
|
+
}
|
|
78
|
+
|
|
50
79
|
static override fromSexprPrimitives(
|
|
51
80
|
primitiveSexprs: PrimitiveSExpr[],
|
|
52
81
|
): FpTextBox {
|
|
@@ -134,7 +163,9 @@ export class FpTextBox extends SxClass {
|
|
|
134
163
|
fpTextBox._sxUuid = propertyMap.uuid as Uuid | undefined
|
|
135
164
|
fpTextBox._sxEffects = propertyMap.effects as TextEffects | undefined
|
|
136
165
|
fpTextBox._sxStroke = propertyMap.stroke as Stroke | undefined
|
|
137
|
-
fpTextBox._sxRenderCache = propertyMap.render_cache as
|
|
166
|
+
fpTextBox._sxRenderCache = propertyMap.render_cache as
|
|
167
|
+
| RenderCache
|
|
168
|
+
| undefined
|
|
138
169
|
|
|
139
170
|
return fpTextBox
|
|
140
171
|
}
|
|
@@ -164,7 +195,10 @@ export class FpTextBox extends SxClass {
|
|
|
164
195
|
this._sxStart = undefined
|
|
165
196
|
return
|
|
166
197
|
}
|
|
167
|
-
this._sxStart =
|
|
198
|
+
this._sxStart =
|
|
199
|
+
value instanceof FpTextBoxStart
|
|
200
|
+
? value
|
|
201
|
+
: new FpTextBoxStart([value.x, value.y])
|
|
168
202
|
}
|
|
169
203
|
|
|
170
204
|
get end(): FpTextBoxEnd | undefined {
|
|
@@ -176,7 +210,10 @@ export class FpTextBox extends SxClass {
|
|
|
176
210
|
this._sxEnd = undefined
|
|
177
211
|
return
|
|
178
212
|
}
|
|
179
|
-
this._sxEnd =
|
|
213
|
+
this._sxEnd =
|
|
214
|
+
value instanceof FpTextBoxEnd
|
|
215
|
+
? value
|
|
216
|
+
: new FpTextBoxEnd([value.x, value.y])
|
|
180
217
|
}
|
|
181
218
|
|
|
182
219
|
get pts(): Pts | undefined {
|
|
@@ -196,7 +233,8 @@ export class FpTextBox extends SxClass {
|
|
|
196
233
|
this._sxAngle = undefined
|
|
197
234
|
return
|
|
198
235
|
}
|
|
199
|
-
this._sxAngle =
|
|
236
|
+
this._sxAngle =
|
|
237
|
+
value instanceof FpTextBoxAngle ? value : new FpTextBoxAngle([value])
|
|
200
238
|
}
|
|
201
239
|
|
|
202
240
|
get layer(): Layer | undefined {
|
|
@@ -378,7 +416,7 @@ export class FpTextBoxAngle extends SxClass {
|
|
|
378
416
|
const numeric =
|
|
379
417
|
typeof raw === "number"
|
|
380
418
|
? raw
|
|
381
|
-
: toNumberValue(raw as PrimitiveSExpr) ?? 0
|
|
419
|
+
: (toNumberValue(raw as PrimitiveSExpr) ?? 0)
|
|
382
420
|
return new FpTextBoxAngle([numeric])
|
|
383
421
|
}
|
|
384
422
|
|
|
@@ -25,6 +25,17 @@ const SUPPORTED_SINGLE_TOKENS = new Set([
|
|
|
25
25
|
"locked",
|
|
26
26
|
])
|
|
27
27
|
|
|
28
|
+
export interface GrLineConstructorParams {
|
|
29
|
+
start?: GrLineStart | GrLinePoint
|
|
30
|
+
end?: GrLineEnd | GrLinePoint
|
|
31
|
+
angle?: number
|
|
32
|
+
layer?: Layer | string | Array<string | number>
|
|
33
|
+
width?: Width | number
|
|
34
|
+
stroke?: Stroke
|
|
35
|
+
uuid?: Uuid | string
|
|
36
|
+
locked?: boolean
|
|
37
|
+
}
|
|
38
|
+
|
|
28
39
|
export class GrLine extends SxClass {
|
|
29
40
|
static override token = "gr_line"
|
|
30
41
|
override token = "gr_line"
|
|
@@ -38,8 +49,16 @@ export class GrLine extends SxClass {
|
|
|
38
49
|
private _sxUuid?: Uuid
|
|
39
50
|
private _sxLocked?: GrLineLocked
|
|
40
51
|
|
|
41
|
-
constructor() {
|
|
52
|
+
constructor(params: GrLineConstructorParams = {}) {
|
|
42
53
|
super()
|
|
54
|
+
if (params.start !== undefined) this.start = params.start
|
|
55
|
+
if (params.end !== undefined) this.end = params.end
|
|
56
|
+
if (params.angle !== undefined) this.angle = params.angle
|
|
57
|
+
if (params.layer !== undefined) this.layer = params.layer
|
|
58
|
+
if (params.width !== undefined) this.width = params.width
|
|
59
|
+
if (params.stroke !== undefined) this.stroke = params.stroke
|
|
60
|
+
if (params.uuid !== undefined) this.uuid = params.uuid
|
|
61
|
+
if (params.locked !== undefined) this.locked = params.locked
|
|
43
62
|
}
|
|
44
63
|
|
|
45
64
|
static override fromSexprPrimitives(
|
|
@@ -2,7 +2,7 @@ import { SxClass } from "../base-classes/SxClass"
|
|
|
2
2
|
import type { PrimitiveSExpr } from "../parseToPrimitiveSExpr"
|
|
3
3
|
import { quoteSExprString } from "../utils/quoteSExprString"
|
|
4
4
|
import { toStringValue } from "../utils/toStringValue"
|
|
5
|
-
import { At } from "./At"
|
|
5
|
+
import { At, type AtInput } from "./At"
|
|
6
6
|
import { Xy } from "./Xy"
|
|
7
7
|
import { Layer } from "./Layer"
|
|
8
8
|
import { TextEffects } from "./TextEffects"
|
|
@@ -22,6 +22,14 @@ const SUPPORTED_SINGLE_TOKENS = new Set([
|
|
|
22
22
|
"effects",
|
|
23
23
|
])
|
|
24
24
|
|
|
25
|
+
export interface GrTextConstructorParams {
|
|
26
|
+
text?: string
|
|
27
|
+
position?: AtInput | Xy | GrTextPosition
|
|
28
|
+
layer?: Layer | string | Array<string | number>
|
|
29
|
+
uuid?: Uuid | string
|
|
30
|
+
effects?: TextEffects
|
|
31
|
+
}
|
|
32
|
+
|
|
25
33
|
export class GrText extends SxClass {
|
|
26
34
|
static override token = "gr_text"
|
|
27
35
|
override token = "gr_text"
|
|
@@ -32,9 +40,17 @@ export class GrText extends SxClass {
|
|
|
32
40
|
private _sxUuid?: Uuid
|
|
33
41
|
private _sxEffects?: TextEffects
|
|
34
42
|
|
|
35
|
-
constructor(
|
|
43
|
+
constructor(params: GrTextConstructorParams | string = {}) {
|
|
36
44
|
super()
|
|
37
|
-
|
|
45
|
+
if (typeof params === "string") {
|
|
46
|
+
this.text = params
|
|
47
|
+
} else {
|
|
48
|
+
if (params.text !== undefined) this.text = params.text
|
|
49
|
+
if (params.position !== undefined) this.position = params.position
|
|
50
|
+
if (params.layer !== undefined) this.layer = params.layer
|
|
51
|
+
if (params.uuid !== undefined) this.uuid = params.uuid
|
|
52
|
+
if (params.effects !== undefined) this.effects = params.effects
|
|
53
|
+
}
|
|
38
54
|
}
|
|
39
55
|
|
|
40
56
|
static override fromSexprPrimitives(
|
|
@@ -125,23 +141,33 @@ export class GrText extends SxClass {
|
|
|
125
141
|
return this._sxPosition
|
|
126
142
|
}
|
|
127
143
|
|
|
128
|
-
set position(
|
|
129
|
-
value: At | Xy | GrTextPosition | undefined,
|
|
130
|
-
) {
|
|
144
|
+
set position(value: AtInput | Xy | GrTextPosition | undefined,) {
|
|
131
145
|
if (value === undefined) {
|
|
132
146
|
this._sxPosition = undefined
|
|
133
147
|
return
|
|
134
148
|
}
|
|
135
|
-
if (value instanceof
|
|
149
|
+
if (value instanceof Xy) {
|
|
136
150
|
this._sxPosition = value
|
|
137
151
|
return
|
|
138
152
|
}
|
|
139
|
-
|
|
140
|
-
if (
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
153
|
+
// Check if it's GrTextPosition (plain object with x, y)
|
|
154
|
+
if (
|
|
155
|
+
typeof value === "object" &&
|
|
156
|
+
"x" in value &&
|
|
157
|
+
"y" in value &&
|
|
158
|
+
!Array.isArray(value) &&
|
|
159
|
+
!(value instanceof At)
|
|
160
|
+
) {
|
|
161
|
+
const { x, y, angle } = value as GrTextPosition
|
|
162
|
+
if (angle !== undefined) {
|
|
163
|
+
this._sxPosition = new At([x, y, angle])
|
|
164
|
+
} else {
|
|
165
|
+
this._sxPosition = new Xy(x, y)
|
|
166
|
+
}
|
|
167
|
+
return
|
|
144
168
|
}
|
|
169
|
+
// Handle AtInput (At, array, or object with angle)
|
|
170
|
+
this._sxPosition = At.from(value as AtInput)
|
|
145
171
|
}
|
|
146
172
|
|
|
147
173
|
get layer(): Layer | undefined {
|
|
@@ -5,7 +5,7 @@ import { toNumberValue } from "../utils/toNumberValue"
|
|
|
5
5
|
import { toStringValue } from "../utils/toStringValue"
|
|
6
6
|
import { Layer } from "./Layer"
|
|
7
7
|
import { Uuid } from "./Uuid"
|
|
8
|
-
import { At } from "./At"
|
|
8
|
+
import { At, type AtInput } from "./At"
|
|
9
9
|
import { Xy } from "./Xy"
|
|
10
10
|
|
|
11
11
|
const SUPPORTED_SINGLE_TOKENS = new Set([
|
|
@@ -19,6 +19,14 @@ const SUPPORTED_SINGLE_TOKENS = new Set([
|
|
|
19
19
|
|
|
20
20
|
const SUPPORTED_MULTI_TOKENS = new Set<string>()
|
|
21
21
|
|
|
22
|
+
export interface ImageConstructorParams {
|
|
23
|
+
position?: AtInput | Xy
|
|
24
|
+
scale?: ImageScale | number
|
|
25
|
+
layer?: Layer | string | string[]
|
|
26
|
+
uuid?: Uuid | string
|
|
27
|
+
data?: ImageData | string | string[]
|
|
28
|
+
}
|
|
29
|
+
|
|
22
30
|
export class Image extends SxClass {
|
|
23
31
|
static override token = "image"
|
|
24
32
|
token = "image"
|
|
@@ -29,6 +37,16 @@ export class Image extends SxClass {
|
|
|
29
37
|
private _sxUuid?: Uuid
|
|
30
38
|
private _sxData?: ImageData
|
|
31
39
|
|
|
40
|
+
constructor(params: ImageConstructorParams = {}) {
|
|
41
|
+
super()
|
|
42
|
+
|
|
43
|
+
if (params.position !== undefined) this.position = params.position
|
|
44
|
+
if (params.scale !== undefined) this.scale = params.scale
|
|
45
|
+
if (params.layer !== undefined) this.layer = params.layer
|
|
46
|
+
if (params.uuid !== undefined) this.uuid = params.uuid
|
|
47
|
+
if (params.data !== undefined) this.data = params.data
|
|
48
|
+
}
|
|
49
|
+
|
|
32
50
|
static override fromSexprPrimitives(
|
|
33
51
|
primitiveSexprs: PrimitiveSExpr[],
|
|
34
52
|
): Image {
|
|
@@ -51,17 +69,13 @@ export class Image extends SxClass {
|
|
|
51
69
|
|
|
52
70
|
for (const token of Object.keys(propertyMap)) {
|
|
53
71
|
if (!SUPPORTED_SINGLE_TOKENS.has(token)) {
|
|
54
|
-
throw new Error(
|
|
55
|
-
`image encountered unsupported child token "${token}"`,
|
|
56
|
-
)
|
|
72
|
+
throw new Error(`image encountered unsupported child token "${token}"`)
|
|
57
73
|
}
|
|
58
74
|
}
|
|
59
75
|
|
|
60
76
|
for (const [token, entries] of Object.entries(arrayPropertyMap)) {
|
|
61
77
|
if (!SUPPORTED_SINGLE_TOKENS.has(token)) {
|
|
62
|
-
throw new Error(
|
|
63
|
-
`image encountered unsupported child token "${token}"`,
|
|
64
|
-
)
|
|
78
|
+
throw new Error(`image encountered unsupported child token "${token}"`)
|
|
65
79
|
}
|
|
66
80
|
if (!SUPPORTED_MULTI_TOKENS.has(token) && entries.length > 1) {
|
|
67
81
|
throw new Error(
|
|
@@ -89,8 +103,17 @@ export class Image extends SxClass {
|
|
|
89
103
|
return this._sxPosition
|
|
90
104
|
}
|
|
91
105
|
|
|
92
|
-
set position(value:
|
|
93
|
-
|
|
106
|
+
set position(value: AtInput | Xy | undefined) {
|
|
107
|
+
if (value === undefined) {
|
|
108
|
+
this._sxPosition = undefined
|
|
109
|
+
return
|
|
110
|
+
}
|
|
111
|
+
if (value instanceof Xy) {
|
|
112
|
+
this._sxPosition = value
|
|
113
|
+
return
|
|
114
|
+
}
|
|
115
|
+
// Handle AtInput (At, array, or object)
|
|
116
|
+
this._sxPosition = At.from(value as AtInput)
|
|
94
117
|
}
|
|
95
118
|
|
|
96
119
|
get scale(): ImageScale | undefined {
|
|
@@ -209,7 +232,9 @@ export class ImageData extends SxClass {
|
|
|
209
232
|
static override fromSexprPrimitives(
|
|
210
233
|
primitiveSexprs: PrimitiveSExpr[],
|
|
211
234
|
): ImageData {
|
|
212
|
-
const chunks = primitiveSexprs.map((primitive) =>
|
|
235
|
+
const chunks = primitiveSexprs.map((primitive) =>
|
|
236
|
+
primitiveToChunk(primitive),
|
|
237
|
+
)
|
|
213
238
|
return new ImageData(chunks)
|
|
214
239
|
}
|
|
215
240
|
|
|
@@ -241,7 +266,9 @@ export class ImageData extends SxClass {
|
|
|
241
266
|
if (this._chunks.length === 0) {
|
|
242
267
|
return "(data)"
|
|
243
268
|
}
|
|
244
|
-
const rendered = this._chunks
|
|
269
|
+
const rendered = this._chunks
|
|
270
|
+
.map((chunk) => quoteSExprString(chunk))
|
|
271
|
+
.join(" ")
|
|
245
272
|
return `(data ${rendered})`
|
|
246
273
|
}
|
|
247
274
|
}
|
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
import { SxClass } from "../base-classes/SxClass"
|
|
2
2
|
import type { PrimitiveSExpr } from "../parseToPrimitiveSExpr"
|
|
3
|
-
import { At } from "./At"
|
|
3
|
+
import { At, type AtInput } from "./At"
|
|
4
4
|
import { Color } from "./Color"
|
|
5
5
|
import { Uuid } from "./Uuid"
|
|
6
6
|
import { SxPrimitiveNumber } from "../base-classes/SxPrimitiveNumber"
|
|
7
7
|
|
|
8
8
|
const SUPPORTED_TOKENS = new Set(["at", "diameter", "color", "uuid"])
|
|
9
9
|
|
|
10
|
+
export interface JunctionConstructorParams {
|
|
11
|
+
at?: AtInput
|
|
12
|
+
diameter?: number | JunctionDiameter
|
|
13
|
+
color?: Color
|
|
14
|
+
uuid?: string | Uuid
|
|
15
|
+
}
|
|
16
|
+
|
|
10
17
|
export class Junction extends SxClass {
|
|
11
18
|
static override token = "junction"
|
|
12
19
|
static override parentToken = "kicad_sch"
|
|
@@ -17,6 +24,30 @@ export class Junction extends SxClass {
|
|
|
17
24
|
private _sxColor?: Color
|
|
18
25
|
private _sxUuid?: Uuid
|
|
19
26
|
|
|
27
|
+
constructor(params: JunctionConstructorParams = {}) {
|
|
28
|
+
super()
|
|
29
|
+
|
|
30
|
+
if (params.at !== undefined) {
|
|
31
|
+
this.at = params.at
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (params.diameter !== undefined) {
|
|
35
|
+
if (params.diameter instanceof JunctionDiameter) {
|
|
36
|
+
this._sxDiameter = params.diameter
|
|
37
|
+
} else {
|
|
38
|
+
this.diameter = params.diameter
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (params.color !== undefined) {
|
|
43
|
+
this.color = params.color
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (params.uuid !== undefined) {
|
|
47
|
+
this.uuid = params.uuid
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
20
51
|
static override fromSexprPrimitives(
|
|
21
52
|
primitiveSexprs: PrimitiveSExpr[],
|
|
22
53
|
): Junction {
|
|
@@ -83,8 +114,8 @@ export class Junction extends SxClass {
|
|
|
83
114
|
return this._sxAt
|
|
84
115
|
}
|
|
85
116
|
|
|
86
|
-
set at(value:
|
|
87
|
-
this._sxAt = value
|
|
117
|
+
set at(value: AtInput | undefined) {
|
|
118
|
+
this._sxAt = value !== undefined ? At.from(value) : undefined
|
|
88
119
|
}
|
|
89
120
|
|
|
90
121
|
get diameter(): number | undefined {
|
|
@@ -92,7 +123,8 @@ export class Junction extends SxClass {
|
|
|
92
123
|
}
|
|
93
124
|
|
|
94
125
|
set diameter(value: number | undefined) {
|
|
95
|
-
this._sxDiameter =
|
|
126
|
+
this._sxDiameter =
|
|
127
|
+
value === undefined ? undefined : new JunctionDiameter(value)
|
|
96
128
|
}
|
|
97
129
|
|
|
98
130
|
get color(): Color | undefined {
|
|
@@ -18,6 +18,27 @@ import { TitleBlock } from "./TitleBlock"
|
|
|
18
18
|
import { Via } from "./Via"
|
|
19
19
|
import { Zone } from "./Zone"
|
|
20
20
|
|
|
21
|
+
export interface KicadPcbConstructorParams {
|
|
22
|
+
version?: number
|
|
23
|
+
generator?: string
|
|
24
|
+
generatorVersion?: string
|
|
25
|
+
general?: PcbGeneral
|
|
26
|
+
paper?: Paper
|
|
27
|
+
titleBlock?: TitleBlock
|
|
28
|
+
layers?: PcbLayers
|
|
29
|
+
setup?: Setup
|
|
30
|
+
properties?: Property[]
|
|
31
|
+
nets?: PcbNet[]
|
|
32
|
+
footprints?: Footprint[]
|
|
33
|
+
images?: Image[]
|
|
34
|
+
segments?: Segment[]
|
|
35
|
+
graphicLines?: GrLine[]
|
|
36
|
+
graphicTexts?: GrText[]
|
|
37
|
+
vias?: Via[]
|
|
38
|
+
zones?: Zone[]
|
|
39
|
+
otherChildren?: SxClass[]
|
|
40
|
+
}
|
|
41
|
+
|
|
21
42
|
export class KicadPcb extends SxClass {
|
|
22
43
|
static override token = "kicad_pcb"
|
|
23
44
|
token = "kicad_pcb"
|
|
@@ -41,6 +62,32 @@ export class KicadPcb extends SxClass {
|
|
|
41
62
|
private _zones: Zone[] = []
|
|
42
63
|
private _otherChildren: SxClass[] = []
|
|
43
64
|
|
|
65
|
+
constructor(params: KicadPcbConstructorParams = {}) {
|
|
66
|
+
super()
|
|
67
|
+
if (params.version !== undefined) this.version = params.version
|
|
68
|
+
if (params.generator !== undefined) this.generator = params.generator
|
|
69
|
+
if (params.generatorVersion !== undefined)
|
|
70
|
+
this.generatorVersion = params.generatorVersion
|
|
71
|
+
if (params.general !== undefined) this.general = params.general
|
|
72
|
+
if (params.paper !== undefined) this.paper = params.paper
|
|
73
|
+
if (params.titleBlock !== undefined) this.titleBlock = params.titleBlock
|
|
74
|
+
if (params.layers !== undefined) this.layers = params.layers
|
|
75
|
+
if (params.setup !== undefined) this.setup = params.setup
|
|
76
|
+
if (params.properties !== undefined) this.properties = params.properties
|
|
77
|
+
if (params.nets !== undefined) this.nets = params.nets
|
|
78
|
+
if (params.footprints !== undefined) this.footprints = params.footprints
|
|
79
|
+
if (params.images !== undefined) this.images = params.images
|
|
80
|
+
if (params.segments !== undefined) this.segments = params.segments
|
|
81
|
+
if (params.graphicLines !== undefined)
|
|
82
|
+
this.graphicLines = params.graphicLines
|
|
83
|
+
if (params.graphicTexts !== undefined)
|
|
84
|
+
this.graphicTexts = params.graphicTexts
|
|
85
|
+
if (params.vias !== undefined) this.vias = params.vias
|
|
86
|
+
if (params.zones !== undefined) this.zones = params.zones
|
|
87
|
+
if (params.otherChildren !== undefined)
|
|
88
|
+
this.otherChildren = params.otherChildren
|
|
89
|
+
}
|
|
90
|
+
|
|
44
91
|
static override fromSexprPrimitives(
|
|
45
92
|
primitiveSexprs: PrimitiveSExpr[],
|
|
46
93
|
): KicadPcb {
|
|
@@ -155,7 +202,8 @@ export class KicadPcb extends SxClass {
|
|
|
155
202
|
}
|
|
156
203
|
|
|
157
204
|
set generator(value: string | undefined) {
|
|
158
|
-
this._sxGenerator =
|
|
205
|
+
this._sxGenerator =
|
|
206
|
+
value === undefined ? undefined : new PcbGenerator(value)
|
|
159
207
|
}
|
|
160
208
|
|
|
161
209
|
get generatorVersion(): string | undefined {
|