altium-to-circuit-json 0.0.83 → 0.0.85

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/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { LayerRef, SourceSimpleChip, SourcePort, AnyCircuitElement, SourceNet, SourceTrace } from 'circuit-json';
2
- import { AltiumPcbDocument, AltiumRecord, AltiumPadRecord, AltiumSchDoc, AltiumPrjPcb } from 'altiumts';
2
+ import { AltiumPcbDocument, AltiumPrjPcb, AltiumRecord, AltiumPadRecord, AltiumSchDoc } from 'altiumts';
3
3
 
4
4
  declare class PcbCopperLayerMap {
5
5
  readonly layers: LayerRef[];
@@ -19,6 +19,7 @@ interface ConvertAltiumPcbDocOptions {
19
19
  includeSilkscreen?: boolean;
20
20
  includeTraces?: boolean;
21
21
  includeVias?: boolean;
22
+ project?: AltiumPrjPcb;
22
23
  }
23
24
  interface PcbNetContext {
24
25
  elements: Array<SourceNet | SourceTrace>;
package/dist/index.js CHANGED
@@ -465,15 +465,6 @@ function createPcbConversionContext({
465
465
  };
466
466
  }
467
467
 
468
- // lib/schematic/document/constants.ts
469
- var SCHEMATIC_SHEET_ID = "schematic_sheet_altium";
470
- var SCHEMATIC_UNIT_TO_MILLIMETERS = 10.16 / 1.1;
471
- var SCHEMATIC_SHEET_INSET = 5 / SCHEMATIC_UNIT_TO_MILLIMETERS;
472
- var SCHEMATIC_SHEET_WIDTH = 297 / SCHEMATIC_UNIT_TO_MILLIMETERS;
473
- var SCHEMATIC_SHEET_HEIGHT = 210 / SCHEMATIC_UNIT_TO_MILLIMETERS;
474
- var SCHEMATIC_SHEET_INNER_WIDTH = SCHEMATIC_SHEET_WIDTH - SCHEMATIC_SHEET_INSET * 2;
475
- var SCHEMATIC_SHEET_INNER_HEIGHT = SCHEMATIC_SHEET_HEIGHT - SCHEMATIC_SHEET_INSET * 2;
476
-
477
468
  // lib/schematic/geometry/getAveragePoint.ts
478
469
  function getAveragePoint(points) {
479
470
  if (points.length === 0) return { x: 0, y: 0 };
@@ -616,6 +607,15 @@ function unscaleLength(lengthMillimeters, altiumUnitsToMillimetersScale) {
616
607
  }).x;
617
608
  }
618
609
 
610
+ // lib/schematic/document/constants.ts
611
+ var SCHEMATIC_SHEET_ID = "schematic_sheet_altium";
612
+ var SCHEMATIC_UNIT_TO_MILLIMETERS = 10.16 / 1.1;
613
+ var SCHEMATIC_SHEET_INSET = 5 / SCHEMATIC_UNIT_TO_MILLIMETERS;
614
+ var SCHEMATIC_SHEET_WIDTH = 297 / SCHEMATIC_UNIT_TO_MILLIMETERS;
615
+ var SCHEMATIC_SHEET_HEIGHT = 210 / SCHEMATIC_UNIT_TO_MILLIMETERS;
616
+ var SCHEMATIC_SHEET_INNER_WIDTH = SCHEMATIC_SHEET_WIDTH - SCHEMATIC_SHEET_INSET * 2;
617
+ var SCHEMATIC_SHEET_INNER_HEIGHT = SCHEMATIC_SHEET_HEIGHT - SCHEMATIC_SHEET_INSET * 2;
618
+
619
619
  // lib/schematic/document/getPositiveNumber.ts
620
620
  function getPositiveNumber(candidate, fallback) {
621
621
  const parsed = Number(candidate);
@@ -623,11 +623,43 @@ function getPositiveNumber(candidate, fallback) {
623
623
  }
624
624
 
625
625
  // lib/schematic/document/getAltiumSheetDimensions.ts
626
+ var STANDARD_SHEET_SIZES = [
627
+ { width: 1150, height: 760 },
628
+ { width: 1550, height: 1110 },
629
+ { width: 2230, height: 1570 },
630
+ { width: 3150, height: 2230 },
631
+ { width: 4460, height: 3150 },
632
+ { width: 950, height: 750 },
633
+ { width: 1500, height: 950 },
634
+ { width: 2e3, height: 1500 },
635
+ { width: 3200, height: 2e3 },
636
+ { width: 4200, height: 3200 },
637
+ { width: 1100, height: 850 },
638
+ { width: 1400, height: 850 },
639
+ { width: 1700, height: 1100 },
640
+ { width: 990, height: 790 },
641
+ { width: 1540, height: 990 },
642
+ { width: 2060, height: 1560 },
643
+ { width: 3260, height: 2060 },
644
+ { width: 4280, height: 3280 }
645
+ ];
626
646
  function getAltiumSheetDimensions(sheetRecord) {
627
- return {
647
+ const customDimensions = {
628
648
  width: getPositiveNumber(sheetRecord?.getCaseInsensitive("CUSTOMX"), 1e3),
629
649
  height: getPositiveNumber(sheetRecord?.getCaseInsensitive("CUSTOMY"), 800)
630
650
  };
651
+ const sheetStyle = sheetRecord?.getCaseInsensitive("SHEETSTYLE");
652
+ if (sheetRecord?.getCaseInsensitive("USECUSTOMSHEET") === "T" || sheetStyle === void 0) {
653
+ return customDimensions;
654
+ }
655
+ const standardDimensions = STANDARD_SHEET_SIZES[Number(sheetStyle)];
656
+ if (!standardDimensions) {
657
+ throw new RangeError(
658
+ `Unsupported Altium schematic sheet style: ${sheetStyle}`
659
+ );
660
+ }
661
+ const isPortrait = Number(sheetRecord?.getCaseInsensitive("WORKSPACEORIENTATION") ?? 0) !== 0;
662
+ return isPortrait ? { width: standardDimensions.height, height: standardDimensions.width } : standardDimensions;
631
663
  }
632
664
 
633
665
  // lib/schematic/document/createSheetBorder.ts
@@ -650,12 +682,26 @@ function createSheetBorder(sheetRecord, scale5) {
650
682
 
651
683
  // lib/schematic/document/addSchematicSheet.ts
652
684
  function addSchematicSheet(context) {
685
+ const scaledSheetWidth = scaleLength(
686
+ context.sheetDimensions.width,
687
+ context.scale
688
+ );
689
+ const scaledSheetHeight = scaleLength(
690
+ context.sheetDimensions.height,
691
+ context.scale
692
+ );
693
+ const usesCustomSheet = context.sheetRecord?.getCaseInsensitive("USECUSTOMSHEET") === "T";
694
+ const sheetDimensions = usesCustomSheet ? {
695
+ sheet_width: scaledSheetWidth * SCHEMATIC_UNIT_TO_MILLIMETERS,
696
+ sheet_height: scaledSheetHeight * SCHEMATIC_UNIT_TO_MILLIMETERS
697
+ } : {};
653
698
  context.elements.push({
654
699
  type: "schematic_sheet",
655
700
  schematic_sheet_id: SCHEMATIC_SHEET_ID,
656
701
  name: context.options.sheetName ?? "Altium schematic",
657
702
  outline_color: "#334155",
658
- sheet_index: 0
703
+ sheet_index: 0,
704
+ ...sheetDimensions
659
705
  });
660
706
  if (context.options.includeSheetBorder === true) {
661
707
  context.elements.push(createSheetBorder(context.sheetRecord, context.scale));
@@ -5982,16 +6028,98 @@ function convertPcbMechanicalText({
5982
6028
  };
5983
6029
  }
5984
6030
 
6031
+ // lib/pcb/text/getProjectTextReplacements.ts
6032
+ function getProjectTextReplacements(project) {
6033
+ const replacements = [];
6034
+ for (const section of project.sections) {
6035
+ if (/^PARAMETER\d+$/iu.test(section.name)) {
6036
+ const name = section.entries.find(
6037
+ (entry) => entry.key.toUpperCase() === "NAME"
6038
+ )?.value;
6039
+ const text = section.entries.find(
6040
+ (entry) => entry.key.toUpperCase() === "VALUE"
6041
+ )?.value;
6042
+ if (name && text !== void 0 && text !== "*") {
6043
+ replacements.push({ name, text });
6044
+ }
6045
+ continue;
6046
+ }
6047
+ if (!/^PARAMETERS?$/iu.test(section.name)) continue;
6048
+ for (const entry of section.entries) {
6049
+ const separatorIndex = entry.value.indexOf("=");
6050
+ if (separatorIndex <= 0) continue;
6051
+ const name = entry.value.slice(0, separatorIndex).trim();
6052
+ const text = entry.value.slice(separatorIndex + 1);
6053
+ if (name && text !== "*") replacements.push({ name, text });
6054
+ }
6055
+ }
6056
+ return replacements;
6057
+ }
6058
+
6059
+ // lib/pcb/text/escapeRegularExpression.ts
6060
+ function escapeRegularExpression(text) {
6061
+ return text.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
6062
+ }
6063
+
6064
+ // lib/pcb/text/replaceMatchingSpecialString.ts
6065
+ function replaceMatchingSpecialString({
6066
+ isQuoted,
6067
+ replacement,
6068
+ text
6069
+ }) {
6070
+ const escapedName = escapeRegularExpression(replacement.name);
6071
+ const quotedExpression = new RegExp(`'\\.${escapedName}'`, "giu");
6072
+ if (isQuoted) {
6073
+ return text.replace(quotedExpression, () => replacement.text);
6074
+ }
6075
+ const exactReference = `.${replacement.name}`.toLowerCase();
6076
+ return text.split("'").map(
6077
+ (segment, index) => index % 2 === 0 && segment.toLowerCase() === exactReference ? replacement.text : segment
6078
+ ).join("'");
6079
+ }
6080
+
6081
+ // lib/pcb/text/resolvePcbProjectSpecialStrings.ts
6082
+ function resolvePcbProjectSpecialStrings({
6083
+ project,
6084
+ text
6085
+ }) {
6086
+ if (!project || !text.includes(".")) return text;
6087
+ let resolvedText = text;
6088
+ const replacements = getProjectTextReplacements(project).sort(
6089
+ (first, second) => second.name.length - first.name.length
6090
+ );
6091
+ for (const replacement of replacements) {
6092
+ resolvedText = replaceMatchingSpecialString({
6093
+ isQuoted: false,
6094
+ replacement,
6095
+ text: resolvedText
6096
+ });
6097
+ }
6098
+ for (const replacement of replacements) {
6099
+ resolvedText = replaceMatchingSpecialString({
6100
+ isQuoted: true,
6101
+ replacement,
6102
+ text: resolvedText
6103
+ });
6104
+ }
6105
+ return resolvedText;
6106
+ }
6107
+
5985
6108
  // lib/pcb/silkscreen/convertPcbSilkscreenText.ts
5986
6109
  function convertPcbSilkscreenText({
5987
- document,
6110
+ context,
5988
6111
  record,
5989
6112
  recordIndex
5990
6113
  }) {
5991
6114
  if (!record.position || !record.text) return void 0;
6115
+ const { document, options } = context;
5992
6116
  const component = document.getComponentForRecord(record);
5993
6117
  const specialString = record.text.trim().toLowerCase();
5994
- const text = specialString === ".designator" ? component?.designator : specialString === ".comment" ? component?.comment : record.text;
6118
+ const componentText = specialString === ".designator" ? component?.designator : specialString === ".comment" ? component?.comment : record.text;
6119
+ const text = resolvePcbProjectSpecialStrings({
6120
+ project: options.project,
6121
+ text: componentText ?? ""
6122
+ });
5995
6123
  if (!text) return void 0;
5996
6124
  return {
5997
6125
  type: "pcb_silkscreen_text",
@@ -6481,7 +6609,7 @@ function convertPcbRecords(context) {
6481
6609
  if (isOverlayLayer(record.layer)) {
6482
6610
  if (options.includeSilkscreen === false) continue;
6483
6611
  if (isHiddenPcbComponentText({ document, record })) continue;
6484
- const text = convertPcbSilkscreenText({ document, record, recordIndex });
6612
+ const text = convertPcbSilkscreenText({ context, record, recordIndex });
6485
6613
  if (text) elements.push(text);
6486
6614
  } else {
6487
6615
  const text = convertPcbCopperText({ layerMap, record, recordIndex });