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.
@@ -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)}" ccwRotation={${smtPad.ccw_rotation}} shape="rotated_rect" />`
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.replace(/"/g, '\\"');
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-CQJKDULD.js";
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.33",
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,6 @@
1
1
  import {
2
2
  convertCircuitJsonToTscircuit
3
- } from "../chunk-CQJKDULD.js";
3
+ } from "../chunk-PIWUZ3WB.js";
4
4
  export {
5
5
  convertCircuitJsonToTscircuit
6
6
  };
@@ -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)}" ccwRotation={${smtPad.ccw_rotation}} shape="rotated_rect" />`,
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.replace(/"/g, '\\"')
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
@@ -6,7 +6,7 @@
6
6
  "./cli": "./dist/cli/main.js"
7
7
  },
8
8
  "type": "module",
9
- "version": "0.0.34",
9
+ "version": "0.0.36",
10
10
  "scripts": {
11
11
  "build": "tsup-node lib/index.ts cli/main.ts --format esm --dts",
12
12
  "test": "bun test",
@@ -1 +1 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="800" height="600" data-software-used-string="@tscircuit/core@0.0.1090"><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"/><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"/></svg>
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>
@@ -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(70.0512524814,0,0,-70.0512524814,599.6497437376,319.7949900745)" data-software-used-string="@tscircuit/core@0.0.1322"><style>
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 669.700996219 319.7949900745 A 70.0512524814 70.0512524814 0 0 0 529.5984912562001 319.7949900745" fill="none" stroke="black" stroke-width="3.5025626240700003" data-schematic-arc-id="schematic_arc_0" data-schematic-component-id="schematic_component_0"/><line x1="739.7522487004001" y1="319.7949900745" x2="879.8547536632" y2="319.7949900745" stroke="black" stroke-width="3.5025626240700003" data-schematic-line-id="schematic_line_0" data-schematic-component-id="schematic_component_0"/><rect x="319.44473381200004" y="74.6156063896" width="140.1025049628" height="70.0512524814" fill="purple" stroke="purple" stroke-width="3.5025626240700003" stroke-dasharray="10.507687872210001" transform="rotate(30 389.49598629340005 109.64123263030001)" data-schematic-rect-id="schematic_rect_0" data-schematic-component-id="schematic_component_0"/><path d="M 809.8035011818 109.64123263030001 L 879.8547536632 39.5899801489" stroke="blue" stroke-width="1.401025049628" fill="none" stroke-linecap="round" stroke-linejoin="round" data-schematic-component-id="schematic_component_0"/><circle cx="809.8035011818" cy="529.9487475187" r="35.0256262407" fill="green" stroke="green" stroke-width="3.5025626240700003" stroke-dasharray="10.507687872210001" data-schematic-circle-id="schematic_circle_0" data-schematic-component-id="schematic_component_0"/></g><text x="599.6497437376" y="319.7949900745" fill="red" text-anchor="middle" dominant-baseline="middle" font-family="sans-serif" font-size="14.010250496280001px" transform="rotate(0, 599.6497437376, 319.7949900745)">U1</text><rect class="schematic-box" x="529.5984912562001" y="249.74373759309998" width="140.1025049627999" height="140.10250496280003" stroke-width="1.401025049628px" stroke="rgb(132, 0, 0)" fill="transparent"/></svg>
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" ccwRotation={45} shape="rotated_rect" />
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
- ${tscircuit}
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: 0, y: 0 },
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: 2,
23
+ x1: 3,
24
24
  schematic_line_id: "schematic_line_id_1",
25
25
  schematic_component_id: "schematic_component_id_1",
26
- y1: 0,
27
- x2: 4,
28
- y2: 0,
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: 0,
37
- y: 3,
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: -3, y: 3 },
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: 3, y: 3 },
61
- { x: 4, y: 4 },
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: -3 },
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: 3, y: -3 },
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: 0, y: 0 }}
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={2} y1={0} x2={4} y2={0} strokeWidth={0.05} color="black" isDashed={false}/>
109
- <schematicbox center={{ x: 0, y: 3 }} width={2} height={2} isDashed={true}/>
110
- <schematicrect schX={-3} schY={3} width={2} height={1} rotation={30} strokeWidth={0.05} color="purple" isFilled={true} fillColor="yellow" isDashed={true} />
111
- <schematicpath points={[{"x":3,"y":3},{"x":4,"y":4}]} strokeColor="blue" fillColor="blue" isFilled={false}/>
112
- <schematictext text="U1" x={0} y={-3} anchorAlignment="center" fontSize={0.2} color="red" rotation={45} />
113
- <schematiccircle center={{ x: 3, y: -3 }} radius={0.5} strokeWidth={0.05} color="green" isFilled={true} isDashed={true} />
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
  />