diff --git a/src/fn/jst.ts b/src/fn/jst.ts
index 39a49981..e5cf5537 100644
--- a/src/fn/jst.ts
+++ b/src/fn/jst.ts
@@ -150,17 +150,20 @@ function generateSilkscreenBody(
numPins?: number,
p?: number,
): PcbSilkscreenPath {
- if (variant === "ph") {
+ if (variant === "ph" && numPins && p) {
+ const pinSpan = (numPins - 1) * p
+ const bodyLeft = -pinSpan / 2 - 1.5
+ const bodyRight = pinSpan / 2 + 1.5
return {
type: "pcb_silkscreen_path",
layer: "top",
pcb_component_id: "",
route: [
- { x: -3, y: 3 },
- { x: 3, y: 3 },
- { x: 3, y: -2 },
- { x: -3, y: -2 },
- { x: -3, y: 3 },
+ { x: bodyLeft, y: 3 },
+ { x: bodyRight, y: 3 },
+ { x: bodyRight, y: -2 },
+ { x: bodyLeft, y: -2 },
+ { x: bodyLeft, y: 3 },
],
stroke_width: 0.1,
pcb_silkscreen_path_id: "",
@@ -222,6 +225,8 @@ export const jst = (
const str = typeof raw_params.string === "string" ? raw_params.string : ""
const match = str.match(/(?:^|_)jst(\d+)(?:_|$)/)
const zhMatch = str.match(/(?:^|_)zh(\d+)(?:_|$)/)
+ // Match trailing pin count after variant, e.g. jst_ph_4, jst_sh_6
+ const trailingMatch = str.match(/(?:^|_)(\d+)(?:_|$)/)
if (match && match[1]) {
const parsed = Number.parseInt(match[1], 10)
if (!Number.isNaN(parsed)) {
@@ -234,6 +239,12 @@ export const jst = (
numPins = parsed
}
}
+ if (typeof numPins !== "number" && trailingMatch && trailingMatch[1]) {
+ const parsed = Number.parseInt(trailingMatch[1], 10)
+ if (!Number.isNaN(parsed)) {
+ numPins = parsed
+ }
+ }
if (typeof numPins !== "number") {
throw new Error(
diff --git a/tests/__snapshots__/jst.test.tsjst2_ph.snap.svg b/tests/__snapshots__/jst.test.tsjst2_ph.snap.svg
index e01f15a3..fdda7f65 100644
--- a/tests/__snapshots__/jst.test.tsjst2_ph.snap.svg
+++ b/tests/__snapshots__/jst.test.tsjst2_ph.snap.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/tests/__snapshots__/jst_ph_4.snap.svg b/tests/__snapshots__/jst_ph_4.snap.svg
new file mode 100644
index 00000000..e341b829
--- /dev/null
+++ b/tests/__snapshots__/jst_ph_4.snap.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/tests/jst_ph_4.test.ts b/tests/jst_ph_4.test.ts
new file mode 100644
index 00000000..e157ac60
--- /dev/null
+++ b/tests/jst_ph_4.test.ts
@@ -0,0 +1,13 @@
+import { expect, test } from "bun:test"
+import { convertCircuitJsonToPcbSvg } from "circuit-to-svg"
+import { fp } from "../src/footprinter"
+
+test("jst_ph_4 generates 4 pads", () => {
+ const circuitJson = fp.string("jst_ph_4").circuitJson()
+
+ const platedHoles = circuitJson.filter((e) => e.type === "pcb_plated_hole")
+ expect(platedHoles.length).toBe(4)
+
+ const svgContent = convertCircuitJsonToPcbSvg(circuitJson)
+ expect(svgContent).toMatchSvgSnapshot(import.meta.path)
+})
diff --git a/tests/kicad-parity/__snapshots__/jst_ph_4.snap.svg b/tests/kicad-parity/__snapshots__/jst_ph_4.snap.svg
new file mode 100644
index 00000000..4e22b9e2
--- /dev/null
+++ b/tests/kicad-parity/__snapshots__/jst_ph_4.snap.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/tests/kicad-parity/__snapshots__/jst_ph_4_boolean_difference.snap.svg b/tests/kicad-parity/__snapshots__/jst_ph_4_boolean_difference.snap.svg
new file mode 100644
index 00000000..bc378818
--- /dev/null
+++ b/tests/kicad-parity/__snapshots__/jst_ph_4_boolean_difference.snap.svg
@@ -0,0 +1,9 @@
+
\ No newline at end of file
diff --git a/tests/kicad-parity/jst_ph4_kicad_parity.test.ts b/tests/kicad-parity/jst_ph4_kicad_parity.test.ts
new file mode 100644
index 00000000..7c04248c
--- /dev/null
+++ b/tests/kicad-parity/jst_ph4_kicad_parity.test.ts
@@ -0,0 +1,18 @@
+import { expect, test } from "bun:test"
+import { compareFootprinterVsKicad } from "../fixtures/compareFootprinterVsKicad"
+import { convertCircuitJsonToPcbSvg } from "circuit-to-svg"
+
+test("parity/jst_ph_4", async () => {
+ const { avgRelDiff, combinedFootprintElements, booleanDifferenceSvg } =
+ await compareFootprinterVsKicad(
+ "jst_ph_4",
+ "Connector_JST.pretty/JST_PH_B4B-PH-K_1x04_P2.00mm_Vertical.circuit.json",
+ )
+
+ const svgContent = convertCircuitJsonToPcbSvg(combinedFootprintElements)
+ expect(svgContent).toMatchSvgSnapshot(import.meta.path, "jst_ph_4")
+ expect(booleanDifferenceSvg).toMatchSvgSnapshot(
+ import.meta.path,
+ "jst_ph_4_boolean_difference",
+ )
+}, 10000)