Skip to content

Commit de66a0c

Browse files
authored
Handle multiple sheet_instances entries in KicadSch (#8)
* Allow multiple sheet_instances in KicadSch * Support direct sheet_instances paths * Restore sheet instances parsing under sheets
1 parent 7acbbac commit de66a0c

File tree

2 files changed

+108
-21
lines changed

2 files changed

+108
-21
lines changed

lib/sexpr/classes/KicadSch.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ const SINGLE_CHILD_TOKENS = new Set([
2626
"paper",
2727
"title_block",
2828
"lib_symbols",
29-
"sheet_instances",
3029
"embedded_fonts",
3130
])
3231

@@ -39,6 +38,7 @@ const MULTI_CHILD_TOKENS = new Set([
3938
"label",
4039
"junction",
4140
"wire",
41+
"sheet_instances",
4242
])
4343

4444
const SUPPORTED_CHILD_TOKENS = new Set([
@@ -54,7 +54,7 @@ export interface KicadSchConstructorParams {
5454
paper?: Paper
5555
titleBlock?: TitleBlock
5656
libSymbols?: LibSymbols
57-
sheetInstances?: SheetInstances
57+
sheetInstances?: SheetInstances | SheetInstances[]
5858
embeddedFonts?: EmbeddedFonts
5959
properties?: Property[]
6060
images?: Image[]
@@ -77,7 +77,7 @@ export class KicadSch extends SxClass {
7777
private _sxPaper?: Paper
7878
private _sxTitleBlock?: TitleBlock
7979
private _sxLibSymbols?: LibSymbols
80-
private _sxSheetInstances?: SheetInstances
80+
private _sheetInstances: SheetInstances[] = []
8181
private _sxEmbeddedFonts?: EmbeddedFonts
8282
private _properties: Property[] = []
8383
private _images: Image[] = []
@@ -216,7 +216,9 @@ export class KicadSch extends SxClass {
216216
paper: propertyMap.paper as Paper | undefined,
217217
titleBlock: propertyMap.title_block as TitleBlock | undefined,
218218
libSymbols: propertyMap.lib_symbols as LibSymbols | undefined,
219-
sheetInstances: propertyMap.sheet_instances as SheetInstances | undefined,
219+
sheetInstances: arrayPropertyMap.sheet_instances as
220+
| SheetInstances[]
221+
| undefined,
220222
embeddedFonts: propertyMap.embedded_fonts as EmbeddedFonts | undefined,
221223
properties: (arrayPropertyMap.property as Property[]) ?? [],
222224
images: (arrayPropertyMap.image as Image[]) ?? [],
@@ -292,12 +294,16 @@ export class KicadSch extends SxClass {
292294
this._sxLibSymbols = value
293295
}
294296

295-
get sheetInstances(): SheetInstances | undefined {
296-
return this._sxSheetInstances
297+
get sheetInstances(): SheetInstances[] {
298+
return [...this._sheetInstances]
297299
}
298300

299-
set sheetInstances(value: SheetInstances | undefined) {
300-
this._sxSheetInstances = value
301+
set sheetInstances(value: SheetInstances | SheetInstances[] | undefined) {
302+
if (value === undefined) {
303+
this._sheetInstances = []
304+
return
305+
}
306+
this._sheetInstances = Array.isArray(value) ? [...value] : [value]
301307
}
302308

303309
get embeddedFonts(): EmbeddedFonts | undefined {
@@ -381,7 +387,7 @@ export class KicadSch extends SxClass {
381387
if (this._sxPaper) children.push(this._sxPaper)
382388
if (this._sxTitleBlock) children.push(this._sxTitleBlock)
383389
if (this._sxLibSymbols) children.push(this._sxLibSymbols)
384-
if (this._sxSheetInstances) children.push(this._sxSheetInstances)
390+
children.push(...this._sheetInstances)
385391
if (this._sxEmbeddedFonts) children.push(this._sxEmbeddedFonts)
386392
children.push(...this._properties)
387393
children.push(...this._images)

lib/sexpr/classes/SheetInstances.ts

Lines changed: 93 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,44 +2,125 @@ import { SxClass } from "../base-classes/SxClass"
22
import type { PrimitiveSExpr } from "../parseToPrimitiveSExpr"
33
import { quoteSExprString } from "../utils/quoteSExprString"
44
import { toStringValue } from "../utils/toStringValue"
5+
import { SheetInstancesRootPath } from "./SheetInstancesRoot"
6+
7+
const SUPPORTED_CHILD_TOKENS = new Set(["project", "path"])
8+
9+
const parseSheetInstancesChildren = (
10+
primitiveSexprs: PrimitiveSExpr[],
11+
): {
12+
projects: SheetInstancesProject[]
13+
paths: SheetInstancesRootPath[]
14+
} => {
15+
const { propertyMap, arrayPropertyMap } =
16+
SxClass.parsePrimitivesToClassProperties(primitiveSexprs, "sheet_instances")
17+
18+
const unsupportedSingularTokens = Object.keys(propertyMap).filter(
19+
(token) => !SUPPORTED_CHILD_TOKENS.has(token),
20+
)
21+
if (unsupportedSingularTokens.length > 0) {
22+
throw new Error(
23+
`sheet_instances encountered unsupported child token${unsupportedSingularTokens.length > 1 ? "s" : ""} ${unsupportedSingularTokens
24+
.map((token) => `"${token}"`)
25+
.join(", ")}`,
26+
)
27+
}
28+
29+
const unsupportedArrayTokens = Object.keys(arrayPropertyMap).filter(
30+
(token) => !SUPPORTED_CHILD_TOKENS.has(token),
31+
)
32+
if (unsupportedArrayTokens.length > 0) {
33+
throw new Error(
34+
`sheet_instances encountered unsupported repeated child token${unsupportedArrayTokens.length > 1 ? "s" : ""} ${unsupportedArrayTokens
35+
.map((token) => `"${token}"`)
36+
.join(", ")}`,
37+
)
38+
}
39+
40+
const projects = (arrayPropertyMap.project as SheetInstancesProject[]) ?? []
41+
if (!projects.length && propertyMap.project) {
42+
projects.push(propertyMap.project as SheetInstancesProject)
43+
}
44+
45+
const paths = (arrayPropertyMap.path as SheetInstancesRootPath[]) ?? []
46+
if (!paths.length && propertyMap.path) {
47+
paths.push(propertyMap.path as SheetInstancesRootPath)
48+
}
49+
50+
return { projects, paths }
51+
}
552

653
export class SheetInstances extends SxClass {
754
static override token = "sheet_instances"
855
static override parentToken = "kicad_sch"
956
token = "sheet_instances"
1057

11-
projects: SheetInstancesProject[] = []
58+
private _projects: SheetInstancesProject[] = []
59+
private _paths: SheetInstancesRootPath[] = []
1260

1361
static override fromSexprPrimitives(
1462
primitiveSexprs: PrimitiveSExpr[],
1563
): SheetInstances {
1664
const instances = new SheetInstances()
17-
const { arrayPropertyMap } = SxClass.parsePrimitivesToClassProperties(
18-
primitiveSexprs,
19-
"sheet_instances",
20-
)
65+
const { projects, paths } = parseSheetInstancesChildren(primitiveSexprs)
66+
instances.projects = projects
67+
instances.paths = paths
68+
return instances
69+
}
2170

22-
instances.projects =
23-
(arrayPropertyMap.project as SheetInstancesProject[]) ?? []
71+
get projects(): SheetInstancesProject[] {
72+
return [...this._projects]
73+
}
2474

25-
return instances
75+
set projects(value: SheetInstancesProject[]) {
76+
this._projects = [...value]
77+
}
78+
79+
get paths(): SheetInstancesRootPath[] {
80+
return [...this._paths]
81+
}
82+
83+
set paths(value: SheetInstancesRootPath[]) {
84+
this._paths = [...value]
2685
}
2786

2887
override getChildren(): SxClass[] {
29-
return [...this.projects]
88+
return [...this._projects, ...this._paths]
3089
}
3190

3291
override getString(): string {
33-
const lines = ["(sheet_instances"]
34-
for (const project of this.projects) {
35-
lines.push(project.getStringIndented())
92+
const children = this.getChildren()
93+
if (children.length === 0) {
94+
return `(${this.token})`
95+
}
96+
97+
const lines = [`(${this.token}`]
98+
for (const child of children) {
99+
lines.push(child.getStringIndented())
36100
}
37101
lines.push(")")
38102
return lines.join("\n")
39103
}
40104
}
41105
SxClass.register(SheetInstances)
42106

107+
export class SheetInstancesForSheet extends SheetInstances {
108+
static override token = "instances"
109+
static override parentToken = "sheet"
110+
override token = "instances"
111+
112+
static override fromSexprPrimitives(
113+
primitiveSexprs: PrimitiveSExpr[],
114+
): SheetInstancesForSheet {
115+
const instances = new SheetInstancesForSheet()
116+
const { projects, paths } = parseSheetInstancesChildren(primitiveSexprs)
117+
instances.projects = projects
118+
instances.paths = paths
119+
return instances
120+
}
121+
}
122+
SxClass.register(SheetInstancesForSheet)
123+
43124
export class SheetInstancesProject extends SxClass {
44125
static override token = "project"
45126
static override parentToken = "sheet_instances"

0 commit comments

Comments
 (0)