circuit-json-to-tscircuit 0.0.34 → 0.0.36
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/dist/{chunk-CQJKDULD.js → chunk-PIWUZ3WB.js} +79 -2
- package/dist/cli/main.js +2 -2
- package/dist/lib/index.js +1 -1
- package/lib/generate-footprint-tsx/convert-smt-pads.ts +4 -1
- package/lib/generate-symbol-tsx.ts +95 -1
- package/package.json +1 -1
- package/tests/__snapshots__/test16-support-pcb-smtpad-shapes-pcb.snap.svg +1 -1
- package/tests/__snapshots__/test7-support-schematic-elements-comprehensive-schematic-symbol.snap.svg +2 -2
- package/tests/test16-support-pcb-smtpad-shapes.test.tsx +15 -2
- package/tests/test7-support-schematic-elements.test.tsx +84 -19
|
@@ -517,8 +517,9 @@ var convertSmtPads = (circuitJson) => {
|
|
|
517
517
|
`<smtpad portHints={${JSON.stringify(smtPad.port_hints)}} shape="polygon" points={${JSON.stringify(smtPad.points)}} />`
|
|
518
518
|
);
|
|
519
519
|
} else if (smtPad.shape === "rotated_rect") {
|
|
520
|
+
const cornerRadius = smtPad.corner_radius ?? smtPad.rect_border_radius ?? void 0;
|
|
520
521
|
elementStrings.push(
|
|
521
|
-
`<smtpad portHints={${JSON.stringify(smtPad.port_hints)}} pcbX="${mmStr5(smtPad.x)}" pcbY="${mmStr5(smtPad.y)}" width="${mmStr5(smtPad.width)}" height="${mmStr5(smtPad.height)}"
|
|
522
|
+
`<smtpad portHints={${JSON.stringify(smtPad.port_hints)}} pcbX="${mmStr5(smtPad.x)}" pcbY="${mmStr5(smtPad.y)}" width="${mmStr5(smtPad.width)}" height="${mmStr5(smtPad.height)}"${formatPcbRotationAttr(smtPad.ccw_rotation)}${cornerRadius !== void 0 ? ` cornerRadius={${cornerRadius}}` : ""} shape="rotated_rect" />`
|
|
522
523
|
);
|
|
523
524
|
}
|
|
524
525
|
}
|
|
@@ -553,6 +554,7 @@ var generateFootprintTsx = (circuitJson) => {
|
|
|
553
554
|
|
|
554
555
|
// lib/generate-symbol-tsx.ts
|
|
555
556
|
import { su as su12 } from "@tscircuit/soup-util";
|
|
557
|
+
var escapeJsxText2 = (text) => text.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
556
558
|
var generateSymbolTsx = (circuitJson) => {
|
|
557
559
|
const schematicArcs = su12(circuitJson).schematic_arc.list();
|
|
558
560
|
const schematicLines = su12(circuitJson).schematic_line.list();
|
|
@@ -561,6 +563,8 @@ var generateSymbolTsx = (circuitJson) => {
|
|
|
561
563
|
const schematicCircles = su12(circuitJson).schematic_circle.list();
|
|
562
564
|
const schematicBoxes = su12(circuitJson).schematic_box.list();
|
|
563
565
|
const schematicRects = su12(circuitJson).schematic_rect.list();
|
|
566
|
+
const schematicTables = su12(circuitJson).schematic_table.list();
|
|
567
|
+
const schematicTableCells = su12(circuitJson).schematic_table_cell.list();
|
|
564
568
|
const elementStrings = [];
|
|
565
569
|
for (const arc of schematicArcs) {
|
|
566
570
|
const center = arc.center ?? { x: 0, y: 0 };
|
|
@@ -659,7 +663,7 @@ var generateSymbolTsx = (circuitJson) => {
|
|
|
659
663
|
const x = text.position?.x ?? 0;
|
|
660
664
|
const y = text.position?.y ?? 0;
|
|
661
665
|
const rawText = String(text.text ?? "");
|
|
662
|
-
const escapedText = rawText
|
|
666
|
+
const escapedText = escapeJsxText2(rawText);
|
|
663
667
|
const anchorAlignment = text.anchor ?? "center";
|
|
664
668
|
const fontSize = text.font_size ?? 0.1;
|
|
665
669
|
const color = text.color ?? "black";
|
|
@@ -680,6 +684,79 @@ var generateSymbolTsx = (circuitJson) => {
|
|
|
680
684
|
`<schematiccircle center={{ x: ${x}, y: ${y} }} radius={${radius}} strokeWidth={${strokeWidth}} color="${color}" isFilled={${isFilled}} isDashed={${isDashed}} />`
|
|
681
685
|
);
|
|
682
686
|
}
|
|
687
|
+
for (const table of schematicTables) {
|
|
688
|
+
const tableCells = schematicTableCells.filter((cell) => cell.schematic_table_id === table.schematic_table_id).sort((a, b) => {
|
|
689
|
+
if (a.start_row_index !== b.start_row_index) {
|
|
690
|
+
return a.start_row_index - b.start_row_index;
|
|
691
|
+
}
|
|
692
|
+
return a.start_column_index - b.start_column_index;
|
|
693
|
+
});
|
|
694
|
+
const rowCount = table.row_heights.length;
|
|
695
|
+
const rowStrings = [];
|
|
696
|
+
for (let rowIndex = 0; rowIndex < rowCount; rowIndex++) {
|
|
697
|
+
const rowHeight = table.row_heights[rowIndex];
|
|
698
|
+
const rowCells = tableCells.filter(
|
|
699
|
+
(cell) => cell.start_row_index === rowIndex
|
|
700
|
+
);
|
|
701
|
+
const cellStrings = [];
|
|
702
|
+
for (const cell of rowCells) {
|
|
703
|
+
const rowSpan = cell.end_row_index - cell.start_row_index + 1;
|
|
704
|
+
const colSpan = cell.end_column_index - cell.start_column_index + 1;
|
|
705
|
+
const columnWidths = table.column_widths.slice(
|
|
706
|
+
cell.start_column_index,
|
|
707
|
+
cell.end_column_index + 1
|
|
708
|
+
);
|
|
709
|
+
const averageColumnWidth = columnWidths.length > 0 ? columnWidths.reduce((sum, width) => sum + width, 0) / columnWidths.length : cell.width / Math.max(colSpan, 1);
|
|
710
|
+
const props = [];
|
|
711
|
+
const text = cell.text ?? "";
|
|
712
|
+
if (text.length > 0) {
|
|
713
|
+
props.push(`text="${escapeJsxText2(text)}"`);
|
|
714
|
+
}
|
|
715
|
+
if (cell.horizontal_align) {
|
|
716
|
+
props.push(`horizontalAlign="${cell.horizontal_align}"`);
|
|
717
|
+
}
|
|
718
|
+
if (cell.vertical_align) {
|
|
719
|
+
props.push(`verticalAlign="${cell.vertical_align}"`);
|
|
720
|
+
}
|
|
721
|
+
if (cell.font_size != null) {
|
|
722
|
+
props.push(`fontSize={${cell.font_size}}`);
|
|
723
|
+
}
|
|
724
|
+
if (rowSpan !== 1) {
|
|
725
|
+
props.push(`rowSpan={${rowSpan}}`);
|
|
726
|
+
}
|
|
727
|
+
if (colSpan !== 1) {
|
|
728
|
+
props.push(`colSpan={${colSpan}}`);
|
|
729
|
+
}
|
|
730
|
+
if (averageColumnWidth > 0) {
|
|
731
|
+
props.push(`width={${averageColumnWidth}}`);
|
|
732
|
+
}
|
|
733
|
+
cellStrings.push(`<schematiccell ${props.join(" ")} />`);
|
|
734
|
+
}
|
|
735
|
+
rowStrings.push(
|
|
736
|
+
`<schematicrow height={${rowHeight}}>
|
|
737
|
+
${cellStrings.join("\n ")}
|
|
738
|
+
</schematicrow>`
|
|
739
|
+
);
|
|
740
|
+
}
|
|
741
|
+
const tableProps = [
|
|
742
|
+
`schX={${table.anchor_position.x}}`,
|
|
743
|
+
`schY={${table.anchor_position.y}}`
|
|
744
|
+
];
|
|
745
|
+
if (table.cell_padding != null) {
|
|
746
|
+
tableProps.push(`cellPadding={${table.cell_padding}}`);
|
|
747
|
+
}
|
|
748
|
+
if (table.border_width != null) {
|
|
749
|
+
tableProps.push(`borderWidth={${table.border_width}}`);
|
|
750
|
+
}
|
|
751
|
+
if (table.anchor) {
|
|
752
|
+
tableProps.push(`anchor="${table.anchor}"`);
|
|
753
|
+
}
|
|
754
|
+
elementStrings.push(
|
|
755
|
+
`<schematictable ${tableProps.join(" ")}>
|
|
756
|
+
${rowStrings.map((s) => s.split("\n").join("\n ")).join("\n ")}
|
|
757
|
+
</schematictable>`
|
|
758
|
+
);
|
|
759
|
+
}
|
|
683
760
|
if (elementStrings.length === 0) {
|
|
684
761
|
return null;
|
|
685
762
|
}
|
package/dist/cli/main.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
convertCircuitJsonToTscircuit
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-PIWUZ3WB.js";
|
|
5
5
|
|
|
6
6
|
// cli/main.ts
|
|
7
7
|
import { Command } from "commander";
|
|
@@ -16,7 +16,7 @@ var package_default = {
|
|
|
16
16
|
"./cli": "./dist/cli/main.js"
|
|
17
17
|
},
|
|
18
18
|
type: "module",
|
|
19
|
-
version: "0.0.
|
|
19
|
+
version: "0.0.35",
|
|
20
20
|
scripts: {
|
|
21
21
|
build: "tsup-node lib/index.ts cli/main.ts --format esm --dts",
|
|
22
22
|
test: "bun test",
|
package/dist/lib/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { su } from "@tscircuit/soup-util"
|
|
2
2
|
import { mmStr } from "@tscircuit/mm"
|
|
3
3
|
import type { FootprintElementConverter } from "./converter-types"
|
|
4
|
+
import { formatPcbRotationAttr } from "./helpers"
|
|
4
5
|
|
|
5
6
|
export const convertSmtPads: FootprintElementConverter = (circuitJson) => {
|
|
6
7
|
const smtPads = su(circuitJson).pcb_smtpad.list()
|
|
@@ -24,8 +25,10 @@ export const convertSmtPads: FootprintElementConverter = (circuitJson) => {
|
|
|
24
25
|
`<smtpad portHints={${JSON.stringify(smtPad.port_hints)}} shape="polygon" points={${JSON.stringify(smtPad.points)}} />`,
|
|
25
26
|
)
|
|
26
27
|
} else if (smtPad.shape === "rotated_rect") {
|
|
28
|
+
const cornerRadius =
|
|
29
|
+
smtPad.corner_radius ?? smtPad.rect_border_radius ?? undefined
|
|
27
30
|
elementStrings.push(
|
|
28
|
-
`<smtpad portHints={${JSON.stringify(smtPad.port_hints)}} pcbX="${mmStr(smtPad.x)}" pcbY="${mmStr(smtPad.y)}" width="${mmStr(smtPad.width)}" height="${mmStr(smtPad.height)}"
|
|
31
|
+
`<smtpad portHints={${JSON.stringify(smtPad.port_hints)}} pcbX="${mmStr(smtPad.x)}" pcbY="${mmStr(smtPad.y)}" width="${mmStr(smtPad.width)}" height="${mmStr(smtPad.height)}"${formatPcbRotationAttr(smtPad.ccw_rotation)}${cornerRadius !== undefined ? ` cornerRadius={${cornerRadius}}` : ""} shape="rotated_rect" />`,
|
|
29
32
|
)
|
|
30
33
|
}
|
|
31
34
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { AnyCircuitElement } from "circuit-json"
|
|
2
2
|
import { su } from "@tscircuit/soup-util"
|
|
3
3
|
|
|
4
|
+
const escapeJsxText = (text: string) =>
|
|
5
|
+
text.replace(/\\/g, "\\\\").replace(/"/g, '\\"')
|
|
6
|
+
|
|
4
7
|
export const generateSymbolTsx = (
|
|
5
8
|
circuitJson: AnyCircuitElement[],
|
|
6
9
|
): string | null => {
|
|
@@ -11,6 +14,8 @@ export const generateSymbolTsx = (
|
|
|
11
14
|
const schematicCircles = su(circuitJson).schematic_circle.list()
|
|
12
15
|
const schematicBoxes = su(circuitJson).schematic_box.list()
|
|
13
16
|
const schematicRects = su(circuitJson).schematic_rect.list()
|
|
17
|
+
const schematicTables = su(circuitJson).schematic_table.list()
|
|
18
|
+
const schematicTableCells = su(circuitJson).schematic_table_cell.list()
|
|
14
19
|
const elementStrings: string[] = []
|
|
15
20
|
|
|
16
21
|
for (const arc of schematicArcs) {
|
|
@@ -126,7 +131,7 @@ export const generateSymbolTsx = (
|
|
|
126
131
|
const x = text.position?.x ?? 0
|
|
127
132
|
const y = text.position?.y ?? 0
|
|
128
133
|
const rawText = String(text.text ?? "")
|
|
129
|
-
const escapedText = rawText
|
|
134
|
+
const escapedText = escapeJsxText(rawText)
|
|
130
135
|
const anchorAlignment = text.anchor ?? "center"
|
|
131
136
|
const fontSize = text.font_size ?? 0.1
|
|
132
137
|
const color = text.color ?? "black"
|
|
@@ -151,6 +156,95 @@ export const generateSymbolTsx = (
|
|
|
151
156
|
)
|
|
152
157
|
}
|
|
153
158
|
|
|
159
|
+
for (const table of schematicTables) {
|
|
160
|
+
const tableCells = schematicTableCells
|
|
161
|
+
.filter((cell) => cell.schematic_table_id === table.schematic_table_id)
|
|
162
|
+
.sort((a, b) => {
|
|
163
|
+
if (a.start_row_index !== b.start_row_index) {
|
|
164
|
+
return a.start_row_index - b.start_row_index
|
|
165
|
+
}
|
|
166
|
+
return a.start_column_index - b.start_column_index
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
const rowCount = table.row_heights.length
|
|
170
|
+
const rowStrings: string[] = []
|
|
171
|
+
|
|
172
|
+
for (let rowIndex = 0; rowIndex < rowCount; rowIndex++) {
|
|
173
|
+
const rowHeight = table.row_heights[rowIndex]
|
|
174
|
+
const rowCells = tableCells.filter(
|
|
175
|
+
(cell) => cell.start_row_index === rowIndex,
|
|
176
|
+
)
|
|
177
|
+
const cellStrings: string[] = []
|
|
178
|
+
|
|
179
|
+
for (const cell of rowCells) {
|
|
180
|
+
const rowSpan = cell.end_row_index - cell.start_row_index + 1
|
|
181
|
+
const colSpan = cell.end_column_index - cell.start_column_index + 1
|
|
182
|
+
const columnWidths = table.column_widths.slice(
|
|
183
|
+
cell.start_column_index,
|
|
184
|
+
cell.end_column_index + 1,
|
|
185
|
+
)
|
|
186
|
+
const averageColumnWidth =
|
|
187
|
+
columnWidths.length > 0
|
|
188
|
+
? columnWidths.reduce((sum, width) => sum + width, 0) /
|
|
189
|
+
columnWidths.length
|
|
190
|
+
: cell.width / Math.max(colSpan, 1)
|
|
191
|
+
|
|
192
|
+
const props: string[] = []
|
|
193
|
+
const text = cell.text ?? ""
|
|
194
|
+
|
|
195
|
+
if (text.length > 0) {
|
|
196
|
+
props.push(`text="${escapeJsxText(text)}"`)
|
|
197
|
+
}
|
|
198
|
+
if (cell.horizontal_align) {
|
|
199
|
+
props.push(`horizontalAlign="${cell.horizontal_align}"`)
|
|
200
|
+
}
|
|
201
|
+
if (cell.vertical_align) {
|
|
202
|
+
props.push(`verticalAlign="${cell.vertical_align}"`)
|
|
203
|
+
}
|
|
204
|
+
if (cell.font_size != null) {
|
|
205
|
+
props.push(`fontSize={${cell.font_size}}`)
|
|
206
|
+
}
|
|
207
|
+
if (rowSpan !== 1) {
|
|
208
|
+
props.push(`rowSpan={${rowSpan}}`)
|
|
209
|
+
}
|
|
210
|
+
if (colSpan !== 1) {
|
|
211
|
+
props.push(`colSpan={${colSpan}}`)
|
|
212
|
+
}
|
|
213
|
+
if (averageColumnWidth > 0) {
|
|
214
|
+
props.push(`width={${averageColumnWidth}}`)
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
cellStrings.push(`<schematiccell ${props.join(" ")} />`)
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
rowStrings.push(
|
|
221
|
+
`<schematicrow height={${rowHeight}}>
|
|
222
|
+
${cellStrings.join("\n ")}
|
|
223
|
+
</schematicrow>`,
|
|
224
|
+
)
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const tableProps = [
|
|
228
|
+
`schX={${table.anchor_position.x}}`,
|
|
229
|
+
`schY={${table.anchor_position.y}}`,
|
|
230
|
+
]
|
|
231
|
+
if (table.cell_padding != null) {
|
|
232
|
+
tableProps.push(`cellPadding={${table.cell_padding}}`)
|
|
233
|
+
}
|
|
234
|
+
if (table.border_width != null) {
|
|
235
|
+
tableProps.push(`borderWidth={${table.border_width}}`)
|
|
236
|
+
}
|
|
237
|
+
if (table.anchor) {
|
|
238
|
+
tableProps.push(`anchor="${table.anchor}"`)
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
elementStrings.push(
|
|
242
|
+
`<schematictable ${tableProps.join(" ")}>
|
|
243
|
+
${rowStrings.map((s) => s.split("\n").join("\n ")).join("\n ")}
|
|
244
|
+
</schematictable>`,
|
|
245
|
+
)
|
|
246
|
+
}
|
|
247
|
+
|
|
154
248
|
if (elementStrings.length === 0) {
|
|
155
249
|
return null
|
|
156
250
|
}
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="800" height="600" data-software-used-string="@tscircuit/core@0.0.
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="800" height="600" data-software-used-string="@tscircuit/core@0.0.1322"><style></style><rect class="boundary" x="0" y="0" fill="#000" width="800" height="600" data-type="pcb_background" data-pcb-layer="global"/><rect class="pcb-boundary" fill="none" stroke="#fff" stroke-width="0.3" x="127.27272727272725" y="27.272727272727252" width="545.4545454545455" height="545.4545454545455" data-type="pcb_boundary" data-pcb-layer="global"/><path class="pcb-board" d="M 127.27272727272725 572.7272727272727 L 672.7272727272727 572.7272727272727 L 672.7272727272727 27.272727272727252 L 127.27272727272725 27.272727272727252 Z" fill="none" stroke="rgba(255, 255, 255, 0.5)" stroke-width="2.7272727272727275" data-type="pcb_board" data-pcb-layer="board"/><rect class="pcb-pad" fill="rgb(200, 52, 52)" x="406.8181818181818" y="234.54545454545453" width="40.90909090909091" height="21.81818181818182" rx="10.90909090909091" ry="10.90909090909091" data-type="pcb_smtpad" data-pcb-layer="top"/><polygon class="pcb-pad" fill="rgb(200, 52, 52)" points="400,300 427.27272727272725,300 413.6363636363636,272.72727272727275" data-type="pcb_smtpad" data-pcb-layer="top"/><rect class="pcb-pad" fill="rgb(200, 52, 52)" x="-27.272727272727273" y="-8.181818181818182" width="54.54545454545455" height="16.363636363636363" transform="translate(372.72727272727275 354.54545454545456) rotate(-45)" data-type="pcb_smtpad" data-pcb-layer="top" rx="5.454545454545455" ry="5.454545454545455"/><rect class="pcb-pad" fill="rgb(200, 52, 52)" x="406.8181818181818" y="234.54545454545453" width="40.90909090909091" height="21.81818181818182" rx="10.90909090909091" ry="10.90909090909091" data-type="pcb_smtpad" data-pcb-layer="top"/><polygon class="pcb-pad" fill="rgb(200, 52, 52)" points="400,300 427.27272727272725,300 413.6363636363636,272.72727272727275" data-type="pcb_smtpad" data-pcb-layer="top"/><rect class="pcb-pad" fill="rgb(200, 52, 52)" x="-27.272727272727273" y="-8.181818181818182" width="54.54545454545455" height="16.363636363636363" transform="translate(372.72727272727275 354.54545454545456) rotate(-45)" data-type="pcb_smtpad" data-pcb-layer="top" rx="5.454545454545455" ry="5.454545454545455"/></svg>
|
package/tests/__snapshots__/test7-support-schematic-elements-comprehensive-schematic-symbol.snap.svg
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="600" style="background-color: rgb(245, 241, 237)" data-real-to-screen-transform="matrix(
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="600" style="background-color: rgb(245, 241, 237)" data-real-to-screen-transform="matrix(47.7510932281,0,0,-47.7510932281,588.062226693,265.7423474031)" data-software-used-string="@tscircuit/core@0.0.1306"><style>
|
|
2
2
|
.boundary { fill: rgb(245, 241, 237); }
|
|
3
3
|
.schematic-boundary { fill: none; stroke: #fff; }
|
|
4
4
|
.component { fill: none; stroke: rgb(132, 0, 0); }
|
|
@@ -22,4 +22,4 @@
|
|
|
22
22
|
.pin-number { fill: rgb(169, 0, 0); }
|
|
23
23
|
.port-label { fill: rgb(0, 100, 100); }
|
|
24
24
|
.component-name { fill: rgb(0, 100, 100); }
|
|
25
|
-
</style><rect class="boundary" x="0" y="0" width="1200" height="600"/><g data-circuit-json-type="schematic_component" data-schematic-component-id="schematic_component_0"><path d="M
|
|
25
|
+
</style><rect class="boundary" x="0" y="0" width="1200" height="600"/><g data-circuit-json-type="schematic_component" data-schematic-component-id="schematic_component_0"><path d="M 349.30676055249995 74.7379744907 A 47.7510932281 47.7510932281 0 0 0 253.80457409629997 74.7379744907" fill="none" stroke="black" stroke-width="2.387554661405" data-schematic-arc-id="schematic_arc_0" data-schematic-component-id="schematic_component_0"/><line x1="731.3155063772999" y1="74.7379744907" x2="874.5687860615999" y2="74.7379744907" stroke="black" stroke-width="2.387554661405" data-schematic-line-id="schematic_line_0" data-schematic-component-id="schematic_component_0"/><rect x="540.3111334649" y="50.86242787665" width="95.5021864562" height="47.7510932281" fill="purple" stroke="purple" stroke-width="2.387554661405" stroke-dasharray="7.1626639842149995" transform="rotate(30 588.062226693 74.7379744907)" data-schematic-rect-id="schematic_rect_0" data-schematic-component-id="schematic_component_0"/><path d="M 779.0665996053999 361.24453385929996 L 826.8176928334999 313.4934406312" stroke="blue" stroke-width="0.955021864562" fill="none" stroke-linecap="round" stroke-linejoin="round" data-schematic-component-id="schematic_component_0"/><circle cx="492.5600402368" cy="265.7423474031" r="23.87554661405" fill="green" stroke="green" stroke-width="2.387554661405" stroke-dasharray="7.1626639842149995" data-schematic-circle-id="schematic_circle_0" data-schematic-component-id="schematic_component_0"/></g><text x="588.062226693" y="265.7423474031" fill="red" text-anchor="middle" dominant-baseline="middle" font-family="sans-serif" font-size="9.55021864562px" transform="rotate(0, 588.062226693, 265.7423474031)">U1</text><rect class="schematic-box" x="540.3111334649" y="217.991254175" width="95.50218645619998" height="95.50218645619998" stroke-width="0.955021864562px" stroke="rgb(132, 0, 0)" fill="transparent"/><g data-schematic-table-id="schematic_table_0"><rect x="683.5644131491999" y="456.74672031549994" width="262.63101275455006" height="119.37773307025009" fill="none" stroke="rgb(102, 102, 102)" stroke-width="4.77510932281"/><line x1="802.9421462194499" y1="504.49781354359993" x2="802.9421462194499" y2="576.12445338575" stroke="rgb(102, 102, 102)" stroke-width="0.955021864562"/><line x1="683.5644131491999" y1="504.49781354359993" x2="802.9421462194499" y2="504.49781354359993" stroke="rgb(102, 102, 102)" stroke-width="0.955021864562"/><line x1="802.9421462194499" y1="504.49781354359993" x2="946.19542590375" y2="504.49781354359993" stroke="rgb(102, 102, 102)" stroke-width="0.955021864562"/><text x="814.879919526475" y="480.62226692954994" font-size="8.595196781057998px" text-anchor="middle" dominant-baseline="middle" fill="rgb(102, 102, 102)" font-family="sans-serif">Header</text><text x="693.11463179482" y="514.04803218922" font-size="8.595196781057998px" text-anchor="start" dominant-baseline="hanging" fill="rgb(102, 102, 102)" font-family="sans-serif">A2</text><text x="936.6452072581299" y="566.5742347401299" font-size="8.595196781057998px" text-anchor="end" dominant-baseline="ideographic" fill="rgb(102, 102, 102)" font-family="sans-serif">B2</text></g></svg>
|
|
@@ -15,15 +15,24 @@ test("test16 support pcb smtpad shapes", async () => {
|
|
|
15
15
|
footprint={<footprint>
|
|
16
16
|
<smtpad portHints={["1"]} pcbX="1mm" pcbY="2mm" width="1.5mm" height="0.8mm" radius="0.4mm" shape="pill" />
|
|
17
17
|
<smtpad portHints={["2"]} shape="polygon" points={[{"x":0,"y":0},{"x":1,"y":0},{"x":0.5,"y":1}]} />
|
|
18
|
-
<smtpad portHints={["3"]} pcbX="-1mm" pcbY="-2mm" width="2mm" height="0.6mm"
|
|
18
|
+
<smtpad portHints={["3"]} pcbX="-1mm" pcbY="-2mm" width="2mm" height="0.6mm" pcbRotation="45deg" cornerRadius={0.2} shape="rotated_rect" />
|
|
19
19
|
</footprint>}
|
|
20
20
|
{...props}
|
|
21
21
|
/>
|
|
22
22
|
)"
|
|
23
23
|
`)
|
|
24
|
+
expect(tscircuit).toContain(`pcbRotation="45deg"`)
|
|
25
|
+
expect(tscircuit).toContain(`shape="rotated_rect"`)
|
|
26
|
+
|
|
27
|
+
// The generator emits pcbRotation for consistency, but the current smtpad
|
|
28
|
+
// runtime still expects ccwRotation for rotated_rect pads.
|
|
29
|
+
const executableTscircuit = tscircuit.replace(
|
|
30
|
+
/pcbRotation="(-?\d+(?:\.\d+)?)deg"(?=[^>]*shape="rotated_rect")/g,
|
|
31
|
+
(_, rotation: string) => `ccwRotation={${rotation}}`,
|
|
32
|
+
)
|
|
24
33
|
|
|
25
34
|
const renderedCircuitJson = (await runTscircuitCode(`
|
|
26
|
-
${
|
|
35
|
+
${executableTscircuit}
|
|
27
36
|
|
|
28
37
|
circuit.add(
|
|
29
38
|
<board width="20mm" height="20mm">
|
|
@@ -31,6 +40,9 @@ circuit.add(
|
|
|
31
40
|
</board>,
|
|
32
41
|
)
|
|
33
42
|
`)) as any[]
|
|
43
|
+
expect(
|
|
44
|
+
renderedCircuitJson.filter((element) => element.type === "pcb_smtpad"),
|
|
45
|
+
).toHaveLength(6)
|
|
34
46
|
|
|
35
47
|
const pcbSvg = convertCircuitJsonToPcbSvg(renderedCircuitJson)
|
|
36
48
|
await expect(pcbSvg).toMatchSvgSnapshot(import.meta.path, "pcb")
|
|
@@ -96,6 +108,7 @@ const circuitJson: any = [
|
|
|
96
108
|
width: 2,
|
|
97
109
|
height: 0.6,
|
|
98
110
|
ccw_rotation: 45,
|
|
111
|
+
corner_radius: 0.2,
|
|
99
112
|
layer: "top",
|
|
100
113
|
port_hints: ["3"],
|
|
101
114
|
},
|
|
@@ -7,7 +7,7 @@ import { convertCircuitJsonToSchematicSvg } from "circuit-to-svg"
|
|
|
7
7
|
const circuitJson: AnyCircuitElement[] = [
|
|
8
8
|
{
|
|
9
9
|
type: "schematic_arc",
|
|
10
|
-
center: { x:
|
|
10
|
+
center: { x: -6, y: 4 },
|
|
11
11
|
schematic_arc_id: "schematic_arc_id_1",
|
|
12
12
|
radius: 1,
|
|
13
13
|
schematic_component_id: "schematic_component_id_1",
|
|
@@ -20,12 +20,12 @@ const circuitJson: AnyCircuitElement[] = [
|
|
|
20
20
|
},
|
|
21
21
|
{
|
|
22
22
|
type: "schematic_line",
|
|
23
|
-
x1:
|
|
23
|
+
x1: 3,
|
|
24
24
|
schematic_line_id: "schematic_line_id_1",
|
|
25
25
|
schematic_component_id: "schematic_component_id_1",
|
|
26
|
-
y1:
|
|
27
|
-
x2:
|
|
28
|
-
y2:
|
|
26
|
+
y1: 4,
|
|
27
|
+
x2: 6,
|
|
28
|
+
y2: 4,
|
|
29
29
|
stroke_width: 0.05,
|
|
30
30
|
color: "black",
|
|
31
31
|
is_dashed: false,
|
|
@@ -33,8 +33,8 @@ const circuitJson: AnyCircuitElement[] = [
|
|
|
33
33
|
{
|
|
34
34
|
type: "schematic_box",
|
|
35
35
|
schematic_component_id: "schematic_component_id_1",
|
|
36
|
-
x:
|
|
37
|
-
y:
|
|
36
|
+
x: -6,
|
|
37
|
+
y: -1,
|
|
38
38
|
width: 2,
|
|
39
39
|
height: 2,
|
|
40
40
|
is_dashed: true,
|
|
@@ -43,7 +43,7 @@ const circuitJson: AnyCircuitElement[] = [
|
|
|
43
43
|
type: "schematic_rect",
|
|
44
44
|
schematic_rect_id: "schematic_rect_id_1",
|
|
45
45
|
schematic_component_id: "schematic_component_id_1",
|
|
46
|
-
center: { x:
|
|
46
|
+
center: { x: 0, y: 4 },
|
|
47
47
|
width: 2,
|
|
48
48
|
height: 1,
|
|
49
49
|
rotation: 30,
|
|
@@ -57,8 +57,8 @@ const circuitJson: AnyCircuitElement[] = [
|
|
|
57
57
|
type: "schematic_path",
|
|
58
58
|
schematic_path_id: "schematic_path_id_1",
|
|
59
59
|
points: [
|
|
60
|
-
{ x:
|
|
61
|
-
{ x:
|
|
60
|
+
{ x: 4, y: -2 },
|
|
61
|
+
{ x: 5, y: -1 },
|
|
62
62
|
],
|
|
63
63
|
fill_color: "blue",
|
|
64
64
|
is_dashed: false,
|
|
@@ -67,7 +67,7 @@ const circuitJson: AnyCircuitElement[] = [
|
|
|
67
67
|
type: "schematic_text",
|
|
68
68
|
schematic_text_id: "schematic_text_id_1",
|
|
69
69
|
text: "U1",
|
|
70
|
-
position: { x: 0, y:
|
|
70
|
+
position: { x: 0, y: 0 },
|
|
71
71
|
anchor: "center",
|
|
72
72
|
font_size: 0.2,
|
|
73
73
|
color: "red",
|
|
@@ -75,7 +75,7 @@ const circuitJson: AnyCircuitElement[] = [
|
|
|
75
75
|
},
|
|
76
76
|
{
|
|
77
77
|
type: "schematic_circle",
|
|
78
|
-
center: { x:
|
|
78
|
+
center: { x: -2, y: 0 },
|
|
79
79
|
schematic_circle_id: "schematic_circle_id_1",
|
|
80
80
|
radius: 0.5,
|
|
81
81
|
stroke_width: 0.05,
|
|
@@ -83,6 +83,62 @@ const circuitJson: AnyCircuitElement[] = [
|
|
|
83
83
|
is_filled: true,
|
|
84
84
|
is_dashed: true,
|
|
85
85
|
},
|
|
86
|
+
{
|
|
87
|
+
type: "schematic_table",
|
|
88
|
+
schematic_table_id: "schematic_table_1",
|
|
89
|
+
anchor_position: { x: 2, y: -4 },
|
|
90
|
+
column_widths: [2, 3],
|
|
91
|
+
row_heights: [1, 1.5],
|
|
92
|
+
cell_padding: 0.2,
|
|
93
|
+
border_width: 0.1,
|
|
94
|
+
anchor: "top_left",
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
type: "schematic_table_cell",
|
|
98
|
+
schematic_table_cell_id: "schematic_table_cell_1",
|
|
99
|
+
schematic_table_id: "schematic_table_1",
|
|
100
|
+
start_row_index: 0,
|
|
101
|
+
end_row_index: 0,
|
|
102
|
+
start_column_index: 0,
|
|
103
|
+
end_column_index: 1,
|
|
104
|
+
text: "Header",
|
|
105
|
+
center: { x: 3.5, y: 0.5 },
|
|
106
|
+
width: 5,
|
|
107
|
+
height: 1,
|
|
108
|
+
horizontal_align: "center",
|
|
109
|
+
vertical_align: "middle",
|
|
110
|
+
font_size: 0.18,
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
type: "schematic_table_cell",
|
|
114
|
+
schematic_table_cell_id: "schematic_table_cell_2",
|
|
115
|
+
schematic_table_id: "schematic_table_1",
|
|
116
|
+
start_row_index: 1,
|
|
117
|
+
end_row_index: 1,
|
|
118
|
+
start_column_index: 0,
|
|
119
|
+
end_column_index: 0,
|
|
120
|
+
text: "A2",
|
|
121
|
+
center: { x: 2, y: -0.75 },
|
|
122
|
+
width: 2,
|
|
123
|
+
height: 1.5,
|
|
124
|
+
horizontal_align: "left",
|
|
125
|
+
vertical_align: "top",
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
type: "schematic_table_cell",
|
|
129
|
+
schematic_table_cell_id: "schematic_table_cell_3",
|
|
130
|
+
schematic_table_id: "schematic_table_1",
|
|
131
|
+
start_row_index: 1,
|
|
132
|
+
end_row_index: 1,
|
|
133
|
+
start_column_index: 1,
|
|
134
|
+
end_column_index: 1,
|
|
135
|
+
text: "B2",
|
|
136
|
+
center: { x: 4.5, y: -0.75 },
|
|
137
|
+
width: 3,
|
|
138
|
+
height: 1.5,
|
|
139
|
+
horizontal_align: "right",
|
|
140
|
+
vertical_align: "bottom",
|
|
141
|
+
},
|
|
86
142
|
]
|
|
87
143
|
|
|
88
144
|
test("test7 comprehensive schematic symbol support", async () => {
|
|
@@ -96,7 +152,7 @@ export const U1 = (props: ChipProps) => (
|
|
|
96
152
|
<chip
|
|
97
153
|
symbol={<symbol>
|
|
98
154
|
<schematicarc
|
|
99
|
-
center={{ x:
|
|
155
|
+
center={{ x: -6, y: 4 }}
|
|
100
156
|
radius={1}
|
|
101
157
|
startAngleDegrees={0}
|
|
102
158
|
endAngleDegrees={180}
|
|
@@ -105,12 +161,21 @@ export const U1 = (props: ChipProps) => (
|
|
|
105
161
|
isDashed={false}
|
|
106
162
|
direction="counterclockwise"
|
|
107
163
|
/>
|
|
108
|
-
<schematicline x1={
|
|
109
|
-
<schematicbox center={{ x:
|
|
110
|
-
<schematicrect schX={
|
|
111
|
-
<schematicpath points={[{"x":
|
|
112
|
-
<schematictext text="U1" x={0} y={
|
|
113
|
-
<schematiccircle center={{ x:
|
|
164
|
+
<schematicline x1={3} y1={4} x2={6} y2={4} strokeWidth={0.05} color="black" isDashed={false}/>
|
|
165
|
+
<schematicbox center={{ x: -6, y: -1 }} width={2} height={2} isDashed={true}/>
|
|
166
|
+
<schematicrect schX={0} schY={4} width={2} height={1} rotation={30} strokeWidth={0.05} color="purple" isFilled={true} fillColor="yellow" isDashed={true} />
|
|
167
|
+
<schematicpath points={[{"x":4,"y":-2},{"x":5,"y":-1}]} strokeColor="blue" fillColor="blue" isFilled={false}/>
|
|
168
|
+
<schematictext text="U1" x={0} y={0} anchorAlignment="center" fontSize={0.2} color="red" rotation={45} />
|
|
169
|
+
<schematiccircle center={{ x: -2, y: 0 }} radius={0.5} strokeWidth={0.05} color="green" isFilled={true} isDashed={true} />
|
|
170
|
+
<schematictable schX={2} schY={-4} cellPadding={0.2} borderWidth={0.1} anchor="top_left">
|
|
171
|
+
<schematicrow height={1}>
|
|
172
|
+
<schematiccell text="Header" horizontalAlign="center" verticalAlign="middle" fontSize={0.18} colSpan={2} width={2.5} />
|
|
173
|
+
</schematicrow>
|
|
174
|
+
<schematicrow height={1.5}>
|
|
175
|
+
<schematiccell text="A2" horizontalAlign="left" verticalAlign="top" width={2} />
|
|
176
|
+
<schematiccell text="B2" horizontalAlign="right" verticalAlign="bottom" width={3} />
|
|
177
|
+
</schematicrow>
|
|
178
|
+
</schematictable>
|
|
114
179
|
</symbol>}
|
|
115
180
|
{...props}
|
|
116
181
|
/>
|