circuitscript 0.0.25 → 0.0.27
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/LICENSE +1 -1
- package/dist/cjs/BaseVisitor.js +16 -12
- package/dist/cjs/SemanticTokenVisitor.js +3 -3
- package/dist/cjs/antlr/CircuitScriptLexer.js +189 -166
- package/dist/cjs/antlr/CircuitScriptParser.js +1295 -719
- package/dist/cjs/draw_symbols.js +42 -14
- package/dist/cjs/execute.js +91 -30
- package/dist/cjs/export.js +91 -5
- package/dist/cjs/geometry.js +45 -26
- package/dist/cjs/globals.js +1 -2
- package/dist/cjs/helpers.js +6 -2
- package/dist/cjs/layout.js +37 -17
- package/dist/cjs/main.js +21 -9
- package/dist/cjs/objects/ClassComponent.js +8 -0
- package/dist/cjs/objects/types.js +8 -1
- package/dist/cjs/render.js +1 -1
- package/dist/cjs/visitor.js +131 -23
- package/dist/esm/BaseVisitor.mjs +17 -13
- package/dist/esm/SemanticTokenVisitor.mjs +3 -3
- package/dist/esm/antlr/CircuitScriptLexer.mjs +189 -166
- package/dist/esm/antlr/CircuitScriptParser.mjs +1287 -716
- package/dist/esm/antlr/CircuitScriptVisitor.mjs +6 -1
- package/dist/esm/draw_symbols.mjs +44 -16
- package/dist/esm/execute.mjs +90 -26
- package/dist/esm/export.mjs +89 -6
- package/dist/esm/geometry.mjs +44 -25
- package/dist/esm/globals.mjs +1 -2
- package/dist/esm/helpers.mjs +7 -3
- package/dist/esm/layout.mjs +35 -16
- package/dist/esm/main.mjs +21 -9
- package/dist/esm/objects/ClassComponent.mjs +8 -0
- package/dist/esm/objects/types.mjs +7 -0
- package/dist/esm/render.mjs +2 -2
- package/dist/esm/visitor.mjs +133 -25
- package/dist/types/BaseVisitor.d.ts +2 -5
- package/dist/types/SemanticTokenVisitor.d.ts +2 -2
- package/dist/types/antlr/CircuitScriptLexer.d.ts +29 -22
- package/dist/types/antlr/CircuitScriptParser.d.ts +121 -44
- package/dist/types/antlr/CircuitScriptVisitor.d.ts +12 -2
- package/dist/types/draw_symbols.d.ts +11 -6
- package/dist/types/execute.d.ts +6 -4
- package/dist/types/export.d.ts +27 -1
- package/dist/types/geometry.d.ts +12 -9
- package/dist/types/globals.d.ts +2 -3
- package/dist/types/layout.d.ts +5 -0
- package/dist/types/objects/ClassComponent.d.ts +5 -0
- package/dist/types/objects/Wire.d.ts +2 -1
- package/dist/types/objects/types.d.ts +6 -0
- package/dist/types/visitor.d.ts +7 -3
- package/libs/lib.cst +28 -10
- package/package.json +1 -1
package/dist/cjs/draw_symbols.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.SymbolDrawingCommands = exports.SymbolDrawing = exports.SymbolCustom = exports.PlaceHolderCommands = exports.SymbolPlaceholder = exports.SymbolText = exports.SymbolPointHidden = exports.SymbolFactory = exports.SymbolGraphic = void 0;
|
|
4
4
|
const globals_js_1 = require("./globals.js");
|
|
5
5
|
const geometry_js_1 = require("./geometry.js");
|
|
6
|
+
const PinTypes_js_1 = require("./objects/PinTypes.js");
|
|
6
7
|
const defaultSymbolLineWidth = 2;
|
|
7
8
|
class SymbolGraphic {
|
|
8
9
|
constructor() {
|
|
@@ -255,7 +256,7 @@ class SymbolText extends SymbolGraphic {
|
|
|
255
256
|
}
|
|
256
257
|
generateDrawing() {
|
|
257
258
|
const drawing = new SymbolDrawing();
|
|
258
|
-
drawing.
|
|
259
|
+
drawing.addTextbox(0, 0, this.text, {
|
|
259
260
|
fontSize: this.fontSize,
|
|
260
261
|
anchor: geometry_js_1.HorizontalAlign.Middle,
|
|
261
262
|
fontWeight: this.fontWeight,
|
|
@@ -321,13 +322,7 @@ class SymbolPlaceholder extends SymbolGraphic {
|
|
|
321
322
|
break;
|
|
322
323
|
}
|
|
323
324
|
case PlaceHolderCommands.label: {
|
|
324
|
-
const
|
|
325
|
-
const style = {};
|
|
326
|
-
keywords.forEach(item => {
|
|
327
|
-
if (keywordParams.has(item)) {
|
|
328
|
-
style[item] = keywordParams.get(item);
|
|
329
|
-
}
|
|
330
|
-
});
|
|
325
|
+
const style = this.parseLabelStyle(keywordParams);
|
|
331
326
|
positionParams = [...positionParams];
|
|
332
327
|
positionParams.push(style);
|
|
333
328
|
const labelId = positionParams[0];
|
|
@@ -340,10 +335,33 @@ class SymbolPlaceholder extends SymbolGraphic {
|
|
|
340
335
|
drawing.addLabelId(...tmpPositionParams);
|
|
341
336
|
break;
|
|
342
337
|
}
|
|
338
|
+
case PlaceHolderCommands.text: {
|
|
339
|
+
const style = this.parseLabelStyle(keywordParams);
|
|
340
|
+
const content = keywordParams.get('content');
|
|
341
|
+
let offsetX = 0;
|
|
342
|
+
let offsetY = 0;
|
|
343
|
+
if (keywordParams.has('offset')) {
|
|
344
|
+
const offset = keywordParams.get('offset');
|
|
345
|
+
offsetX = offset[0];
|
|
346
|
+
offsetY = offset[1];
|
|
347
|
+
}
|
|
348
|
+
drawing.addTextbox(offsetX, offsetY, content, style);
|
|
349
|
+
break;
|
|
350
|
+
}
|
|
343
351
|
}
|
|
344
352
|
});
|
|
345
353
|
drawing.log("=== end generate drawing ===");
|
|
346
354
|
}
|
|
355
|
+
parseLabelStyle(keywordParams) {
|
|
356
|
+
const keywords = ['fontSize', 'anchor', 'vanchor', 'angle'];
|
|
357
|
+
const style = {};
|
|
358
|
+
keywords.forEach(item => {
|
|
359
|
+
if (keywordParams.has(item)) {
|
|
360
|
+
style[item] = keywordParams.get(item);
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
return style;
|
|
364
|
+
}
|
|
347
365
|
drawPinParams(drawing, commandName, keywordParams, positionParams) {
|
|
348
366
|
drawing.log('add pin', ...positionParams);
|
|
349
367
|
const keywordDisplayPinId = 'display_pin_id';
|
|
@@ -353,6 +371,11 @@ class SymbolPlaceholder extends SymbolGraphic {
|
|
|
353
371
|
displayPinId = false;
|
|
354
372
|
}
|
|
355
373
|
let pinNameParam = null;
|
|
374
|
+
let pinType = PinTypes_js_1.PinTypes.Any;
|
|
375
|
+
if (positionParams[1].type && positionParams[1].type === globals_js_1.ReferenceTypes.pinType) {
|
|
376
|
+
pinType = positionParams[1].value;
|
|
377
|
+
positionParams = [positionParams[0], ...positionParams.slice(2)];
|
|
378
|
+
}
|
|
356
379
|
if (typeof positionParams[1] === 'string') {
|
|
357
380
|
pinNameParam = positionParams[1];
|
|
358
381
|
positionParams = [positionParams[0], ...positionParams.slice(2)];
|
|
@@ -449,6 +472,7 @@ var PlaceHolderCommands;
|
|
|
449
472
|
PlaceHolderCommands["lineWidth"] = "lineWidth";
|
|
450
473
|
PlaceHolderCommands["fill"] = "fill";
|
|
451
474
|
PlaceHolderCommands["lineColor"] = "lineColor";
|
|
475
|
+
PlaceHolderCommands["text"] = "text";
|
|
452
476
|
})(PlaceHolderCommands || (exports.PlaceHolderCommands = PlaceHolderCommands = {}));
|
|
453
477
|
class SymbolCustom extends SymbolGraphic {
|
|
454
478
|
constructor(pinDefinition) {
|
|
@@ -637,6 +661,10 @@ class SymbolDrawing {
|
|
|
637
661
|
this.items.push(geometry_js_1.Geometry.label(id, x, y, textValue, style));
|
|
638
662
|
return this;
|
|
639
663
|
}
|
|
664
|
+
addTextbox(x, y, textValue, style) {
|
|
665
|
+
this.items.push(geometry_js_1.Geometry.textbox(null, x, y, textValue, style));
|
|
666
|
+
return this;
|
|
667
|
+
}
|
|
640
668
|
addPath(...pathParts) {
|
|
641
669
|
const parts = pathParts.reduce((accum, tmp) => {
|
|
642
670
|
if (typeof tmp === "string") {
|
|
@@ -711,7 +739,7 @@ class SymbolDrawing {
|
|
|
711
739
|
let currentLineColor = '#333';
|
|
712
740
|
const pathItems = [];
|
|
713
741
|
this.items.forEach(item => {
|
|
714
|
-
if (!(item instanceof geometry_js_1.
|
|
742
|
+
if (!(item instanceof geometry_js_1.Textbox)) {
|
|
715
743
|
if (item instanceof geometry_js_1.GeometryProp) {
|
|
716
744
|
if (item.name === 'lineWidth') {
|
|
717
745
|
currentLineWidth = item.value;
|
|
@@ -726,7 +754,7 @@ class SymbolDrawing {
|
|
|
726
754
|
else {
|
|
727
755
|
let tmpResult = geometry_js_1.Geometry.groupFlip([item], this.flipX, this.flipY);
|
|
728
756
|
tmpResult = geometry_js_1.Geometry.groupRotate(tmpResult, this.angle, this.mainOrigin);
|
|
729
|
-
const { path, isClosedPolygon } = this.featuresToPath(tmpResult);
|
|
757
|
+
const { path, isClosedPolygon } = this.featuresToPath(tmpResult, this.flipX, this.flipY);
|
|
730
758
|
pathItems.push({
|
|
731
759
|
path: path,
|
|
732
760
|
lineWidth: currentLineWidth,
|
|
@@ -742,14 +770,14 @@ class SymbolDrawing {
|
|
|
742
770
|
let features = this.pins.map(item => item[1]);
|
|
743
771
|
features = geometry_js_1.Geometry.groupFlip(features, this.flipX, this.flipY);
|
|
744
772
|
features = geometry_js_1.Geometry.groupRotate(features, this.angle, this.mainOrigin);
|
|
745
|
-
const { path } = this.featuresToPath(features);
|
|
773
|
+
const { path } = this.featuresToPath(features, this.flipX, this.flipY);
|
|
746
774
|
return path;
|
|
747
775
|
}
|
|
748
776
|
getLabels() {
|
|
749
|
-
return this.items.filter(item => item instanceof geometry_js_1.
|
|
777
|
+
return this.items.filter(item => item instanceof geometry_js_1.Textbox);
|
|
750
778
|
}
|
|
751
|
-
featuresToPath(items) {
|
|
752
|
-
return geometry_js_1.Geometry.featuresToPath(items);
|
|
779
|
+
featuresToPath(items, flipX, flipY) {
|
|
780
|
+
return geometry_js_1.Geometry.featuresToPath(items, flipX, flipY);
|
|
753
781
|
}
|
|
754
782
|
getBoundingBox(excludeLabels = false) {
|
|
755
783
|
const pinFeatures = this.pins.map(pin => {
|
package/dist/cjs/execute.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getPortSide = exports.
|
|
3
|
+
exports.getPortSide = exports.ExecutionContext = void 0;
|
|
4
4
|
const globals_js_1 = require("./globals.js");
|
|
5
5
|
const ClassComponent_js_1 = require("./objects/ClassComponent.js");
|
|
6
6
|
const ExecutionScope_js_1 = require("./objects/ExecutionScope.js");
|
|
7
7
|
const Net_js_1 = require("./objects/Net.js");
|
|
8
8
|
const PinDefinition_js_1 = require("./objects/PinDefinition.js");
|
|
9
|
+
const types_js_1 = require("./objects/types.js");
|
|
9
10
|
const Wire_js_1 = require("./objects/Wire.js");
|
|
10
11
|
const Frame_js_1 = require("./objects/Frame.js");
|
|
12
|
+
const layout_js_1 = require("./layout.js");
|
|
11
13
|
class ExecutionContext {
|
|
12
14
|
constructor(name, namespace, netNamespace, executionLevel = 0, indentLevel = 0, silent = false, logger, parent) {
|
|
13
15
|
this.tmpPointId = 0;
|
|
@@ -16,6 +18,7 @@ class ExecutionContext {
|
|
|
16
18
|
this.returnValue = null;
|
|
17
19
|
this.silent = false;
|
|
18
20
|
this.__functionCache = {};
|
|
21
|
+
this.componentAngleFollowsWire = true;
|
|
19
22
|
this.name = name;
|
|
20
23
|
this.namespace = namespace;
|
|
21
24
|
this.netNamespace = netNamespace;
|
|
@@ -140,12 +143,27 @@ class ExecutionContext {
|
|
|
140
143
|
pins.forEach((pin) => {
|
|
141
144
|
component.pins.set(pin.id, pin);
|
|
142
145
|
});
|
|
146
|
+
component.arrangeProps = props.arrange ?? null;
|
|
147
|
+
component.displayProp = props.display ?? null;
|
|
148
|
+
component.widthProp = props.width ?? null;
|
|
149
|
+
component.typeProp = props.type ?? null;
|
|
150
|
+
component.copyProp = props.copy ?? false;
|
|
151
|
+
let useAngle = null;
|
|
152
|
+
if (props.angle) {
|
|
153
|
+
useAngle = props.angle % 360;
|
|
154
|
+
if (useAngle < 0) {
|
|
155
|
+
useAngle += 360;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
component.angleProp = useAngle ?? 0;
|
|
159
|
+
component.followWireOrientationProp = props.followWireOrientation;
|
|
143
160
|
const paramsMap = new Map();
|
|
144
161
|
params.forEach((param) => {
|
|
145
162
|
component.parameters.set(param.paramName, param.paramValue);
|
|
146
163
|
paramsMap.set(param.paramName, param.paramValue);
|
|
147
164
|
});
|
|
148
|
-
if (
|
|
165
|
+
if (component.typeProp === globals_js_1.ComponentTypes.net
|
|
166
|
+
|| component.typeProp === globals_js_1.ComponentTypes.label) {
|
|
149
167
|
const netName = paramsMap.get(globals_js_1.ParamKeys.net_name);
|
|
150
168
|
const priority = paramsMap.get(globals_js_1.ParamKeys.priority);
|
|
151
169
|
const result = this.resolveNet(netName, this.netNamespace);
|
|
@@ -161,12 +179,7 @@ class ExecutionContext {
|
|
|
161
179
|
this.scope.setNet(component, 1, tmpNet);
|
|
162
180
|
this.log('set net', netName, 'component', component);
|
|
163
181
|
}
|
|
164
|
-
const
|
|
165
|
-
component.arrangeProps = arrange;
|
|
166
|
-
component.displayProp = props.display ?? null;
|
|
167
|
-
component.widthProp = props.width ?? null;
|
|
168
|
-
component.typeProp = props.type ?? null;
|
|
169
|
-
const portSides = getPortSide(component.pins, arrange);
|
|
182
|
+
const portSides = getPortSide(component.pins, component.arrangeProps);
|
|
170
183
|
portSides.forEach(({ pinId, side, position }) => {
|
|
171
184
|
if (component.pins.has(pinId)) {
|
|
172
185
|
const tmpPin = component.pins.get(pinId);
|
|
@@ -183,6 +196,10 @@ class ExecutionContext {
|
|
|
183
196
|
}
|
|
184
197
|
printPoint(extra = '') {
|
|
185
198
|
let netName = globals_js_1.NoNetText;
|
|
199
|
+
if (this.scope.currentComponent === null || this.scope.currentPin === null) {
|
|
200
|
+
this.log((extra !== '' ? (extra + ' ') : '') + 'point is null');
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
186
203
|
if (this.scope.hasNet(this.scope.currentComponent, this.scope.currentPin)) {
|
|
187
204
|
netName = this.scope
|
|
188
205
|
.getNet(this.scope.currentComponent, this.scope.currentPin)
|
|
@@ -196,6 +213,7 @@ class ExecutionContext {
|
|
|
196
213
|
addComponentExisting(component, pin) {
|
|
197
214
|
const startPin = pin;
|
|
198
215
|
const nextPin = component.getNextPinAfter(startPin);
|
|
216
|
+
this.applyComponentAngleFromWire(component, pin);
|
|
199
217
|
this.toComponent(component, startPin, { addSequence: true });
|
|
200
218
|
this.log('move to next pin: ' + nextPin);
|
|
201
219
|
this.atComponent(component, nextPin, {
|
|
@@ -231,6 +249,7 @@ class ExecutionContext {
|
|
|
231
249
|
.toString());
|
|
232
250
|
}
|
|
233
251
|
const linkedNet = this.linkComponentPinNet(this.scope.currentComponent, this.scope.currentPin, component, pinId);
|
|
252
|
+
this.applyComponentAngleFromWire(component, pinId);
|
|
234
253
|
this.scope.currentComponent = component;
|
|
235
254
|
this.scope.currentPin = pinId;
|
|
236
255
|
this.scope.clearActive();
|
|
@@ -279,22 +298,22 @@ class ExecutionContext {
|
|
|
279
298
|
this.printPoint();
|
|
280
299
|
return this.getCurrentPoint();
|
|
281
300
|
}
|
|
282
|
-
|
|
283
|
-
let
|
|
301
|
+
copyComponent(component) {
|
|
302
|
+
let componentCopy = null;
|
|
284
303
|
if (!this.scope.copyIDs.has(component.instanceName)) {
|
|
285
304
|
this.scope.copyIDs.set(component.instanceName, 0);
|
|
286
305
|
}
|
|
287
306
|
const idNum = this.scope.copyIDs.get(component.instanceName);
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
307
|
+
componentCopy = component.clone();
|
|
308
|
+
componentCopy._copyID = idNum;
|
|
309
|
+
componentCopy._copyFrom = component;
|
|
291
310
|
this.scope.copyIDs.set(component.instanceName, idNum + 1);
|
|
292
311
|
const cloneInstanceName = component.instanceName + ':' + idNum;
|
|
293
|
-
this.scope.instances.set(cloneInstanceName,
|
|
294
|
-
|
|
295
|
-
this.linkComponentPinNet(component, 1,
|
|
312
|
+
this.scope.instances.set(cloneInstanceName, componentCopy);
|
|
313
|
+
componentCopy.instanceName = cloneInstanceName;
|
|
314
|
+
this.linkComponentPinNet(component, 1, componentCopy, 1);
|
|
296
315
|
this.log('created clone of net component:', cloneInstanceName);
|
|
297
|
-
return
|
|
316
|
+
return componentCopy;
|
|
298
317
|
}
|
|
299
318
|
enterBlocks(blockType) {
|
|
300
319
|
if (blockType === globals_js_1.BlockTypes.Point) {
|
|
@@ -561,7 +580,8 @@ class ExecutionContext {
|
|
|
561
580
|
}
|
|
562
581
|
else if (action === ExecutionScope_js_1.SequenceAction.At || action === ExecutionScope_js_1.SequenceAction.To) {
|
|
563
582
|
const tmpComponent = sequenceAction[1];
|
|
564
|
-
if (
|
|
583
|
+
if (tmpComponent.typeProp === globals_js_1.ComponentTypes.net
|
|
584
|
+
&& tmpComponent.parameters.get(globals_js_1.ParamKeys.net_name) === 'gnd') {
|
|
565
585
|
tmpComponent._copyID = gndCopyIdOffset + incrementGndLinkId;
|
|
566
586
|
incrementGndLinkId += 1;
|
|
567
587
|
}
|
|
@@ -678,6 +698,59 @@ class ExecutionContext {
|
|
|
678
698
|
this.scope.currentComponent.styles[key] = styles[key];
|
|
679
699
|
}
|
|
680
700
|
}
|
|
701
|
+
applyComponentAngleFromWire(component, pin) {
|
|
702
|
+
if (this.componentAngleFollowsWire
|
|
703
|
+
&& component.followWireOrientationProp
|
|
704
|
+
&& component.useWireOrientationAngle
|
|
705
|
+
&& this.scope.currentWireId !== -1) {
|
|
706
|
+
const currentWire = this.scope.wires[this.scope.currentWireId];
|
|
707
|
+
const lastSegment = currentWire.path[currentWire.path.length - 1];
|
|
708
|
+
const pinPositions = (0, layout_js_1.CalculatePinPositions)(component);
|
|
709
|
+
if (pinPositions.has(pin)) {
|
|
710
|
+
const connectedPinPos = pinPositions.get(pin);
|
|
711
|
+
let targetAngle = null;
|
|
712
|
+
switch (lastSegment.direction) {
|
|
713
|
+
case types_js_1.Direction.Down:
|
|
714
|
+
targetAngle = 90;
|
|
715
|
+
break;
|
|
716
|
+
case types_js_1.Direction.Up:
|
|
717
|
+
targetAngle = 270;
|
|
718
|
+
break;
|
|
719
|
+
case types_js_1.Direction.Right:
|
|
720
|
+
targetAngle = 0;
|
|
721
|
+
break;
|
|
722
|
+
case types_js_1.Direction.Left:
|
|
723
|
+
targetAngle = 180;
|
|
724
|
+
break;
|
|
725
|
+
default:
|
|
726
|
+
targetAngle = null;
|
|
727
|
+
}
|
|
728
|
+
if (targetAngle === null) {
|
|
729
|
+
return;
|
|
730
|
+
}
|
|
731
|
+
this.log('set component angle from wire, target angle:', targetAngle, ', component angle:', component.angleProp, 'pin angle:', connectedPinPos.angle);
|
|
732
|
+
let useAngle = (targetAngle - connectedPinPos.angle) % 360;
|
|
733
|
+
if (useAngle < 0) {
|
|
734
|
+
useAngle += 360;
|
|
735
|
+
}
|
|
736
|
+
if (useAngle === 90) {
|
|
737
|
+
component.setParam('angle', 90);
|
|
738
|
+
}
|
|
739
|
+
else if (useAngle === 180) {
|
|
740
|
+
if (component.angleProp === 0 || component.angleProp === 180) {
|
|
741
|
+
component.setParam('flipX', 1);
|
|
742
|
+
}
|
|
743
|
+
else if (component.angleProp === 90 || component.angleProp === 270) {
|
|
744
|
+
component.setParam('flipY', 1);
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
else if (useAngle === 270) {
|
|
748
|
+
component.setParam('angle', 270);
|
|
749
|
+
}
|
|
750
|
+
component.wireOrientationAngle = useAngle;
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
}
|
|
681
754
|
enterFrame() {
|
|
682
755
|
const frameId = this.scope.frames.length + 1;
|
|
683
756
|
const frameObject = new Frame_js_1.Frame(frameId);
|
|
@@ -703,18 +776,6 @@ function isWireSegmentsEndAuto(segments) {
|
|
|
703
776
|
}
|
|
704
777
|
return false;
|
|
705
778
|
}
|
|
706
|
-
function isNetComponent(component) {
|
|
707
|
-
return component.parameters.has(globals_js_1.ParamKeys.__is_net);
|
|
708
|
-
}
|
|
709
|
-
exports.isNetComponent = isNetComponent;
|
|
710
|
-
function isLabelComponent(component) {
|
|
711
|
-
return component.parameters.has(globals_js_1.ParamKeys.__is_label);
|
|
712
|
-
}
|
|
713
|
-
exports.isLabelComponent = isLabelComponent;
|
|
714
|
-
function isNetOnlyComponent(component) {
|
|
715
|
-
return isNetComponent(component) && !isLabelComponent(component);
|
|
716
|
-
}
|
|
717
|
-
exports.isNetOnlyComponent = isNetOnlyComponent;
|
|
718
779
|
function getPortSide(pins, arrangeProps) {
|
|
719
780
|
const result = [];
|
|
720
781
|
if (arrangeProps === null) {
|
package/dist/cjs/export.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.generateKiCADNetList = void 0;
|
|
3
|
+
exports.SExpObject = exports._id = exports.IdObject = exports.printTree = exports.generateKiCADNetList = void 0;
|
|
4
4
|
const globals_js_1 = require("./globals.js");
|
|
5
5
|
const ParamDefinition_js_1 = require("./objects/ParamDefinition.js");
|
|
6
6
|
function generateKiCADNetList(netlist) {
|
|
7
7
|
const componentsList = [];
|
|
8
8
|
const nets = {};
|
|
9
|
+
const missingFootprints = [];
|
|
9
10
|
netlist.forEach(entry => {
|
|
10
11
|
const { instance, pins } = entry;
|
|
11
12
|
if (instance.assignedRefDes !== null) {
|
|
@@ -25,7 +26,10 @@ function generateKiCADNetList(netlist) {
|
|
|
25
26
|
instance.parameters.get('footprint')]);
|
|
26
27
|
}
|
|
27
28
|
else {
|
|
28
|
-
|
|
29
|
+
missingFootprints.push({
|
|
30
|
+
refdes: instance.assignedRefDes,
|
|
31
|
+
instanceName: instance.instanceName
|
|
32
|
+
});
|
|
29
33
|
}
|
|
30
34
|
componentsList.push(instanceDetails);
|
|
31
35
|
for (const key in pins) {
|
|
@@ -66,18 +70,22 @@ function generateKiCADNetList(netlist) {
|
|
|
66
70
|
]);
|
|
67
71
|
counter++;
|
|
68
72
|
}
|
|
73
|
+
const dateString = new Date().toISOString().slice(0, 10);
|
|
69
74
|
const tree = [
|
|
70
75
|
Id("export"),
|
|
71
76
|
[Id("version"), "E"],
|
|
72
77
|
[Id("design"),
|
|
73
|
-
[Id("source"), "/
|
|
74
|
-
[Id("date"),
|
|
78
|
+
[Id("source"), "/unknown-file"],
|
|
79
|
+
[Id("date"), dateString],
|
|
75
80
|
[Id("tool"), "circuitscript-to-kicad"]
|
|
76
81
|
],
|
|
77
82
|
[Id('components'), ...componentsList],
|
|
78
83
|
[Id('nets'), ...netItems]
|
|
79
84
|
];
|
|
80
|
-
return
|
|
85
|
+
return {
|
|
86
|
+
tree,
|
|
87
|
+
missingFootprints
|
|
88
|
+
};
|
|
81
89
|
}
|
|
82
90
|
exports.generateKiCADNetList = generateKiCADNetList;
|
|
83
91
|
function printTree(tree, level = 0) {
|
|
@@ -99,6 +107,7 @@ function printTree(tree, level = 0) {
|
|
|
99
107
|
}
|
|
100
108
|
return "(" + output.join(" ") + ")";
|
|
101
109
|
}
|
|
110
|
+
exports.printTree = printTree;
|
|
102
111
|
function Id(name) {
|
|
103
112
|
return new IdObject(name);
|
|
104
113
|
}
|
|
@@ -107,3 +116,80 @@ class IdObject {
|
|
|
107
116
|
this.keyName = keyName;
|
|
108
117
|
}
|
|
109
118
|
}
|
|
119
|
+
exports.IdObject = IdObject;
|
|
120
|
+
function _id(key) {
|
|
121
|
+
return new IdObject(key);
|
|
122
|
+
}
|
|
123
|
+
exports._id = _id;
|
|
124
|
+
class SExpObject {
|
|
125
|
+
constructor(object) {
|
|
126
|
+
this.object = object;
|
|
127
|
+
}
|
|
128
|
+
getKey(object = null) {
|
|
129
|
+
object = object ?? this.object;
|
|
130
|
+
return object[0];
|
|
131
|
+
}
|
|
132
|
+
getValue(object = null) {
|
|
133
|
+
object = object ?? this.object;
|
|
134
|
+
return object.slice(1);
|
|
135
|
+
}
|
|
136
|
+
getJSON(object = null) {
|
|
137
|
+
object = object ?? this.object;
|
|
138
|
+
if (!Array.isArray(object)) {
|
|
139
|
+
return object;
|
|
140
|
+
}
|
|
141
|
+
const properties = {};
|
|
142
|
+
const keyName = object[0].keyName;
|
|
143
|
+
if (object.length === 2) {
|
|
144
|
+
properties[keyName] = this.getJSON(object[1]);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
const innerProps = {};
|
|
148
|
+
this.getValue(object).forEach(item => {
|
|
149
|
+
const tmpValue = this.getJSON(item);
|
|
150
|
+
if (typeof tmpValue === "object") {
|
|
151
|
+
for (const key in tmpValue) {
|
|
152
|
+
if (innerProps[key]) {
|
|
153
|
+
if (!Array.isArray(innerProps[key])) {
|
|
154
|
+
innerProps[key] = [innerProps[key]];
|
|
155
|
+
}
|
|
156
|
+
innerProps[key].push(tmpValue[key]);
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
innerProps[key] = tmpValue[key];
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
innerProps[item[0].keyName] = tmpValue;
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
properties[keyName] = innerProps;
|
|
168
|
+
}
|
|
169
|
+
return properties;
|
|
170
|
+
}
|
|
171
|
+
getWithId(id, object = null) {
|
|
172
|
+
object = object ?? this.object;
|
|
173
|
+
let result = null;
|
|
174
|
+
const key = object[0];
|
|
175
|
+
if (key.keyName === id) {
|
|
176
|
+
return object;
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
this.getValue(object).some(item => {
|
|
180
|
+
if (Array.isArray(item)) {
|
|
181
|
+
result = this.getWithId(id, item);
|
|
182
|
+
if (result !== null) {
|
|
183
|
+
return true;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return false;
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
return result;
|
|
190
|
+
}
|
|
191
|
+
print() {
|
|
192
|
+
console.log(printTree(this.object));
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
exports.SExpObject = SExpObject;
|
package/dist/cjs/geometry.js
CHANGED
|
@@ -3,16 +3,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.VerticalAlign = exports.HorizontalAlign = exports.Geometry = exports.GeometryProp = exports.Label = void 0;
|
|
6
|
+
exports.VerticalAlign = exports.HorizontalAlign = exports.Geometry = exports.GeometryProp = exports.Label = exports.Textbox = void 0;
|
|
7
7
|
const core_1 = __importDefault(require("@flatten-js/core"));
|
|
8
8
|
const sizing_js_1 = require("./sizing.js");
|
|
9
9
|
const globals_js_1 = require("./globals.js");
|
|
10
10
|
const ParamDefinition_js_1 = require("./objects/ParamDefinition.js");
|
|
11
|
-
class
|
|
11
|
+
class Textbox extends core_1.default.Polygon {
|
|
12
12
|
get box() {
|
|
13
13
|
return this.polygon.box;
|
|
14
14
|
}
|
|
15
|
-
constructor(id, text, anchorPoint, polygon, style, bounds) {
|
|
15
|
+
constructor(id, text, anchorPoint, polygon, style, bounds, label) {
|
|
16
16
|
super(polygon.vertices);
|
|
17
17
|
this.anchorPoint = [0, 0];
|
|
18
18
|
this.boundingBox = { width: -1, height: -1 };
|
|
@@ -24,8 +24,9 @@ class Label extends core_1.default.Polygon {
|
|
|
24
24
|
this.boundingBox = polygon.box;
|
|
25
25
|
this.polygon = polygon;
|
|
26
26
|
this.textMeasurementBounds = bounds;
|
|
27
|
+
this.label = label;
|
|
27
28
|
}
|
|
28
|
-
static fromPoint(id, x, y, text, style) {
|
|
29
|
+
static fromPoint(id, x, y, text, style, label) {
|
|
29
30
|
let useText;
|
|
30
31
|
if (typeof text === 'number') {
|
|
31
32
|
useText = text.toString();
|
|
@@ -38,7 +39,7 @@ class Label extends core_1.default.Polygon {
|
|
|
38
39
|
useText = text;
|
|
39
40
|
}
|
|
40
41
|
else {
|
|
41
|
-
throw 'Invalid string passed into
|
|
42
|
+
throw 'Invalid string passed into textbox';
|
|
42
43
|
}
|
|
43
44
|
const { fontSize = 10, anchor = HorizontalAlign.Left, vanchor = VerticalAlign.Bottom, fontWeight = 'regular', } = style ?? {};
|
|
44
45
|
const { width, height, box } = (0, sizing_js_1.measureTextSize2)(useText, globals_js_1.defaultFont, fontSize, fontWeight, anchor, vanchor);
|
|
@@ -50,20 +51,23 @@ class Label extends core_1.default.Polygon {
|
|
|
50
51
|
[box.x, box.y],
|
|
51
52
|
];
|
|
52
53
|
const polygon = new core_1.default.Polygon(polygonCoords);
|
|
53
|
-
return new
|
|
54
|
+
return new Textbox(id, useText, [x, y], polygon, style, box, label);
|
|
54
55
|
}
|
|
55
56
|
rotate(angle, origin) {
|
|
56
57
|
const feature = super.rotate(angle, origin);
|
|
57
|
-
return new
|
|
58
|
+
return new Textbox(this.id, this.text, this.anchorPoint, feature, this.style, this.textMeasurementBounds, this.label);
|
|
58
59
|
}
|
|
59
60
|
transform(matrix) {
|
|
60
61
|
const feature = super.transform(matrix);
|
|
61
|
-
return new
|
|
62
|
+
return new Textbox(this.id, this.text, this.anchorPoint, feature, this.style, this.textMeasurementBounds, this.label);
|
|
62
63
|
}
|
|
63
64
|
getLabelPosition() {
|
|
64
65
|
return this.anchorPoint;
|
|
65
66
|
}
|
|
66
67
|
}
|
|
68
|
+
exports.Textbox = Textbox;
|
|
69
|
+
class Label extends Textbox {
|
|
70
|
+
}
|
|
67
71
|
exports.Label = Label;
|
|
68
72
|
class GeometryProp {
|
|
69
73
|
constructor(name, value) {
|
|
@@ -80,7 +84,10 @@ class Geometry {
|
|
|
80
84
|
return new core_1.default.Line(Geometry.point(x1, y1), Geometry.point(x2, y2));
|
|
81
85
|
}
|
|
82
86
|
static label(id, x, y, text, style) {
|
|
83
|
-
return
|
|
87
|
+
return Textbox.fromPoint(id, x, y, text, style, true);
|
|
88
|
+
}
|
|
89
|
+
static textbox(id, x, y, text, style) {
|
|
90
|
+
return Textbox.fromPoint(id, x, y, text, style, false);
|
|
84
91
|
}
|
|
85
92
|
static segment(start, end) {
|
|
86
93
|
return new core_1.default.Segment(Geometry.point(start[0], start[1]), Geometry.point(end[0], end[1]));
|
|
@@ -131,12 +138,28 @@ class Geometry {
|
|
|
131
138
|
let maxX = Number.NEGATIVE_INFINITY;
|
|
132
139
|
let maxY = Number.NEGATIVE_INFINITY;
|
|
133
140
|
features.forEach(feature => {
|
|
134
|
-
const
|
|
135
|
-
|
|
141
|
+
const tmpBox = feature.box;
|
|
142
|
+
let box = {
|
|
143
|
+
xmin: tmpBox.xmin,
|
|
144
|
+
ymin: tmpBox.ymin,
|
|
145
|
+
xmax: tmpBox.xmax,
|
|
146
|
+
ymax: tmpBox.ymax
|
|
147
|
+
};
|
|
148
|
+
if (feature instanceof Textbox
|
|
149
|
+
&& feature.label
|
|
136
150
|
&& typeof feature.text === 'string'
|
|
137
151
|
&& feature.text.trim().length === 0) {
|
|
138
152
|
return;
|
|
139
153
|
}
|
|
154
|
+
if (feature instanceof Textbox && !feature.label) {
|
|
155
|
+
const [x, y] = feature.anchorPoint;
|
|
156
|
+
box = {
|
|
157
|
+
xmin: box.xmin + x,
|
|
158
|
+
ymin: box.ymin + y,
|
|
159
|
+
xmax: box.xmax + x,
|
|
160
|
+
ymax: box.ymax + y
|
|
161
|
+
};
|
|
162
|
+
}
|
|
140
163
|
if (box.xmin === undefined) {
|
|
141
164
|
throw "Invalid box!";
|
|
142
165
|
}
|
|
@@ -152,23 +175,11 @@ class Geometry {
|
|
|
152
175
|
height: maxY - minY,
|
|
153
176
|
};
|
|
154
177
|
}
|
|
155
|
-
static
|
|
156
|
-
if (feature instanceof Label) {
|
|
157
|
-
return 'label';
|
|
158
|
-
}
|
|
159
|
-
else if (feature instanceof core_1.default.Polygon) {
|
|
160
|
-
return 'polygon';
|
|
161
|
-
}
|
|
162
|
-
else if (feature instanceof core_1.default.Segment) {
|
|
163
|
-
return 'segment';
|
|
164
|
-
}
|
|
165
|
-
console.log('unknown type', feature);
|
|
166
|
-
}
|
|
167
|
-
static featuresToPath(items) {
|
|
178
|
+
static featuresToPath(items, flipX, flipY) {
|
|
168
179
|
const paths = [];
|
|
169
180
|
let isClosedPolygon = false;
|
|
170
181
|
items.forEach(item => {
|
|
171
|
-
if (item instanceof
|
|
182
|
+
if (item instanceof Textbox) {
|
|
172
183
|
return;
|
|
173
184
|
}
|
|
174
185
|
const path = [];
|
|
@@ -185,7 +196,15 @@ class Geometry {
|
|
|
185
196
|
}
|
|
186
197
|
const startPoint = getArcPointRadians(x, y, radius, item.startAngle);
|
|
187
198
|
const endPoint = getArcPointRadians(x, y, radius, useEndAngle);
|
|
188
|
-
|
|
199
|
+
let largeArcSweepFlag = 0;
|
|
200
|
+
if (useEndAngle - item.startAngle > Math.PI) {
|
|
201
|
+
largeArcSweepFlag = 1;
|
|
202
|
+
}
|
|
203
|
+
let sweepFlag = 1;
|
|
204
|
+
if (flipX === 1 && flipY === 0) {
|
|
205
|
+
sweepFlag = 0;
|
|
206
|
+
}
|
|
207
|
+
paths.push('M', startPoint[0], startPoint[1], 'A', radius, radius, 0, largeArcSweepFlag, sweepFlag, endPoint[0], endPoint[1], extraEnd);
|
|
189
208
|
}
|
|
190
209
|
else {
|
|
191
210
|
const coords = Geometry.getCoords(item);
|
package/dist/cjs/globals.js
CHANGED
|
@@ -13,8 +13,6 @@ var GlobalNames;
|
|
|
13
13
|
exports.NoNetText = 'NO_NET';
|
|
14
14
|
var ParamKeys;
|
|
15
15
|
(function (ParamKeys) {
|
|
16
|
-
ParamKeys["__is_net"] = "__is_net";
|
|
17
|
-
ParamKeys["__is_label"] = "__is_label";
|
|
18
16
|
ParamKeys["priority"] = "priority";
|
|
19
17
|
ParamKeys["net_name"] = "net_name";
|
|
20
18
|
})(ParamKeys || (exports.ParamKeys = ParamKeys = {}));
|
|
@@ -50,6 +48,7 @@ var ReferenceTypes;
|
|
|
50
48
|
ReferenceTypes["value"] = "value";
|
|
51
49
|
ReferenceTypes["variable"] = "variable";
|
|
52
50
|
ReferenceTypes["instance"] = "instance";
|
|
51
|
+
ReferenceTypes["pinType"] = "pinType";
|
|
53
52
|
})(ReferenceTypes || (exports.ReferenceTypes = ReferenceTypes = {}));
|
|
54
53
|
var BlockTypes;
|
|
55
54
|
(function (BlockTypes) {
|
package/dist/cjs/helpers.js
CHANGED
|
@@ -188,8 +188,11 @@ function renderScript(scriptData, outputPath, options) {
|
|
|
188
188
|
console.log('Error during annotation: ', err);
|
|
189
189
|
}
|
|
190
190
|
if (kicadNetlistPath) {
|
|
191
|
-
const kicadNetList = (0, export_js_1.generateKiCADNetList)(visitor.getNetList());
|
|
192
|
-
|
|
191
|
+
const { tree: kicadNetList, missingFootprints } = (0, export_js_1.generateKiCADNetList)(visitor.getNetList());
|
|
192
|
+
missingFootprints.forEach(entry => {
|
|
193
|
+
console.log(`${entry.refdes} (${entry.instanceName}) does not have footprint`);
|
|
194
|
+
});
|
|
195
|
+
(0, fs_1.writeFileSync)(kicadNetlistPath, (0, export_js_1.printTree)(kicadNetList));
|
|
193
196
|
console.log('Generated KiCad netlist file');
|
|
194
197
|
}
|
|
195
198
|
const { sequence, nets } = visitor.getGraph();
|
|
@@ -223,6 +226,7 @@ function renderScript(scriptData, outputPath, options) {
|
|
|
223
226
|
showStats && console.log('Render took:', generateSvgTimer.lap());
|
|
224
227
|
if (outputPath) {
|
|
225
228
|
(0, fs_1.writeFileSync)(outputPath, svgOutput);
|
|
229
|
+
console.log('Generated file', outputPath);
|
|
226
230
|
}
|
|
227
231
|
}
|
|
228
232
|
catch (err) {
|