circuitscript 0.0.13 → 0.0.15
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/.gitlab-ci.yml +22 -19
- package/__tests__/helpers.ts +12 -0
- package/__tests__/renderData/script1.cst.svg +1 -1
- package/__tests__/renderData/script2.cst.svg +1 -1
- package/__tests__/renderData/script3.cst.svg +1 -1
- package/__tests__/renderData/script4.cst +27 -5
- package/__tests__/renderData/script4.cst.svg +1 -1
- package/__tests__/renderData/script5.cst.svg +1 -1
- package/__tests__/testParse.ts +37 -2
- package/build/src/draw_symbols.js +209 -67
- package/build/src/geometry.js +35 -4
- package/build/src/globals.js +2 -1
- package/build/src/helpers.js +73 -0
- package/build/src/layout.js +30 -17
- package/build/src/main.js +2 -69
- package/build/src/regenerate-tests.js +2 -2
- package/build/src/sizing.js +4 -10
- package/build/src/visitor.js +12 -4
- package/examples/example_arduino_uno.cst +390 -120
- package/examples/lib.cst +25 -28
- package/libs/lib.cst +23 -28
- package/package.json +1 -1
- package/src/draw_symbols.ts +273 -71
- package/src/geometry.ts +48 -6
- package/src/globals.ts +3 -1
- package/src/helpers.ts +114 -0
- package/src/layout.ts +42 -21
- package/src/main.ts +2 -112
- package/src/regenerate-tests.ts +2 -2
- package/src/sizing.ts +5 -8
- package/src/visitor.ts +16 -4
package/src/layout.ts
CHANGED
|
@@ -604,10 +604,6 @@ export class LayoutEngine {
|
|
|
604
604
|
if (tmpSymbol instanceof SymbolCustom && widthProp){
|
|
605
605
|
tmpSymbol.bodyWidth = widthProp;
|
|
606
606
|
}
|
|
607
|
-
|
|
608
|
-
if (component.assignedRefDes !== null){
|
|
609
|
-
tmpSymbol.setLabelValue("refdes", component.assignedRefDes);
|
|
610
|
-
}
|
|
611
607
|
|
|
612
608
|
if (!didSetAngle && component.parameters.has('_addDirection')){
|
|
613
609
|
// If there is an _addDirection specified, then the angle
|
|
@@ -683,8 +679,31 @@ export class LayoutEngine {
|
|
|
683
679
|
|
|
684
680
|
previousNode = wireName;
|
|
685
681
|
previousPin = 1;
|
|
686
|
-
|
|
687
|
-
|
|
682
|
+
|
|
683
|
+
const wireSegmentsInfo = wireSegments.map(item => {
|
|
684
|
+
const tmp: {
|
|
685
|
+
direction: string,
|
|
686
|
+
value: number,
|
|
687
|
+
valueXY?: [x: number, y: number],
|
|
688
|
+
until?: [instanceName: string, pin: number]
|
|
689
|
+
} = {
|
|
690
|
+
direction: item.direction,
|
|
691
|
+
value: item.value,
|
|
692
|
+
};
|
|
693
|
+
|
|
694
|
+
if (item.valueXY) {
|
|
695
|
+
tmp.valueXY = item.valueXY;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
if (item.until) {
|
|
699
|
+
tmp.until = [item.until[0].toString(), item.until[1]];
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
return tmp;
|
|
703
|
+
});
|
|
704
|
+
|
|
705
|
+
this.print(SequenceAction.Wire, wireId,
|
|
706
|
+
JSON.stringify(wireSegmentsInfo));
|
|
688
707
|
|
|
689
708
|
} else if (action === SequenceAction.WireJump) {
|
|
690
709
|
this.print(...sequence[i]);
|
|
@@ -1338,26 +1357,28 @@ function applyComponentParamsToSymbol(typeProp: string,
|
|
|
1338
1357
|
component: ClassComponent, symbol: SymbolGraphic): void {
|
|
1339
1358
|
|
|
1340
1359
|
if (typeProp === 'net') {
|
|
1341
|
-
symbol.setLabelValue("net_name",
|
|
1360
|
+
symbol.setLabelValue("net_name",
|
|
1361
|
+
component.parameters.get(ParamKeys.net_name) as string);
|
|
1342
1362
|
}
|
|
1343
1363
|
|
|
1344
|
-
if (component.
|
|
1345
|
-
|
|
1346
|
-
let displayString = "";
|
|
1347
|
-
const tmpValue = component.parameters.get('value');
|
|
1348
|
-
if (typeof tmpValue == 'object' && (tmpValue instanceof NumericValue)) {
|
|
1349
|
-
displayString = (tmpValue as NumericValue).toDisplayString();
|
|
1350
|
-
} else {
|
|
1351
|
-
displayString = tmpValue;
|
|
1352
|
-
}
|
|
1353
|
-
|
|
1354
|
-
symbol.setLabelValue('value', displayString);
|
|
1364
|
+
if (component.assignedRefDes !== null){
|
|
1365
|
+
symbol.setLabelValue("refdes", component.assignedRefDes);
|
|
1355
1366
|
}
|
|
1356
1367
|
|
|
1357
|
-
|
|
1368
|
+
for (const [key, value] of component.parameters) {
|
|
1369
|
+
if (key !== 'refdes' && key !== 'net_name') {
|
|
1370
|
+
let useValue: string;
|
|
1371
|
+
|
|
1372
|
+
if (typeof value == 'object' && (value instanceof NumericValue)) {
|
|
1373
|
+
useValue = (value as NumericValue).toDisplayString();
|
|
1374
|
+
} else if (typeof value === 'number') {
|
|
1375
|
+
useValue = value.toString();
|
|
1376
|
+
} else if (typeof value === 'string'){
|
|
1377
|
+
useValue = value;
|
|
1378
|
+
}
|
|
1358
1379
|
|
|
1359
|
-
|
|
1360
|
-
|
|
1380
|
+
symbol.setLabelValue(key, useValue);
|
|
1381
|
+
}
|
|
1361
1382
|
}
|
|
1362
1383
|
}
|
|
1363
1384
|
|
package/src/main.ts
CHANGED
|
@@ -4,16 +4,10 @@ import { program } from 'commander';
|
|
|
4
4
|
import figlet from 'figlet';
|
|
5
5
|
import path from 'path';
|
|
6
6
|
import { fileURLToPath } from 'url';
|
|
7
|
-
import { readFileSync, watch
|
|
7
|
+
import { readFileSync, watch } from 'fs';
|
|
8
8
|
|
|
9
|
-
import { MainVisitor } from './visitor.js';
|
|
10
9
|
import { prepareSizing } from './sizing.js';
|
|
11
|
-
import {
|
|
12
|
-
import { generateSVG2 } from './render.js';
|
|
13
|
-
import { SequenceAction } from './objects/ExecutionScope.js';
|
|
14
|
-
import { parseFileWithVisitor } from './parser.js';
|
|
15
|
-
import { generateKiCADNetList } from './export.js';
|
|
16
|
-
import { SimpleStopwatch } from './utils.js';
|
|
10
|
+
import { renderScript } from './helpers.js';
|
|
17
11
|
|
|
18
12
|
export default async function main(): Promise<void> {
|
|
19
13
|
const toolSrcPath = fileURLToPath(import.meta.url);
|
|
@@ -108,108 +102,4 @@ export default async function main(): Promise<void> {
|
|
|
108
102
|
}
|
|
109
103
|
}
|
|
110
104
|
|
|
111
|
-
|
|
112
|
-
export function renderScript(scriptData: string, outputPath: string, options): string {
|
|
113
|
-
|
|
114
|
-
const {
|
|
115
|
-
currentDirectory = null,
|
|
116
|
-
defaultLibsPath,
|
|
117
|
-
dumpNets = false,
|
|
118
|
-
dumpData = false,
|
|
119
|
-
kicadNetlistPath = null,
|
|
120
|
-
showStats = false} = options;
|
|
121
|
-
|
|
122
|
-
const visitor = new MainVisitor(true);
|
|
123
|
-
|
|
124
|
-
visitor.onImportFile = visitor.createImportFileHandler(currentDirectory, defaultLibsPath);
|
|
125
|
-
|
|
126
|
-
visitor.print('reading file');
|
|
127
|
-
visitor.print('done reading file');
|
|
128
|
-
|
|
129
|
-
const { tree, parser,
|
|
130
|
-
hasParseError, hasError,
|
|
131
|
-
parserTimeTaken,
|
|
132
|
-
lexerTimeTaken } = parseFileWithVisitor(visitor, scriptData);
|
|
133
|
-
|
|
134
|
-
showStats && console.log('Lexing took:', lexerTimeTaken);
|
|
135
|
-
showStats && console.log('Parsing took:', parserTimeTaken);
|
|
136
|
-
dumpNets && console.log(visitor.dumpNets());
|
|
137
|
-
|
|
138
|
-
dumpData && writeFileSync('dump/tree.lisp', tree.toStringTree(null, parser));
|
|
139
|
-
dumpData && writeFileSync('dump/raw-parser.txt', visitor.logger.dump());
|
|
140
|
-
|
|
141
|
-
if (hasError || hasParseError) {
|
|
142
|
-
console.log('Error while parsing');
|
|
143
|
-
return null;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
visitor.annotateComponents();
|
|
147
|
-
|
|
148
|
-
if (kicadNetlistPath) {
|
|
149
|
-
const kicadNetList = generateKiCADNetList(visitor.getNetList());
|
|
150
|
-
writeFileSync(kicadNetlistPath, kicadNetList);
|
|
151
|
-
console.log('Generated KiCad netlist file');
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
// await writeFile('dump/raw-netlist.json', JSON.stringify(visitor.dump2(), null, 2));
|
|
156
|
-
|
|
157
|
-
const { sequence, nets } = visitor.getGraph();
|
|
158
|
-
|
|
159
|
-
// const tmpInstances = visitor.getExecutor().scope.instances;
|
|
160
|
-
// for (const [instanceName, instance] of tmpInstances){
|
|
161
|
-
// console.log(instanceName);
|
|
162
|
-
// console.log(instance.pinNets);
|
|
163
|
-
// }
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
const tmpSequence = sequence.map(item => {
|
|
167
|
-
const tmp = [...item];
|
|
168
|
-
|
|
169
|
-
const action = tmp[0];
|
|
170
|
-
|
|
171
|
-
if (action === SequenceAction.Wire) {
|
|
172
|
-
tmp[2] = tmp[2].map(item2 => {
|
|
173
|
-
return [item2.direction, item2.value].join(",");
|
|
174
|
-
}).join(" ");
|
|
175
|
-
} else if (action === SequenceAction.Frame) {
|
|
176
|
-
tmp[1] = item[1].frameId;
|
|
177
|
-
|
|
178
|
-
} else if (action !== SequenceAction.WireJump) {
|
|
179
|
-
tmp[1] = item[1].instanceName;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
return tmp.join(" | ");
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
dumpData && writeFileSync('dump/raw-sequence.txt', tmpSequence.join('\n'));
|
|
186
|
-
let svgOutput: string = null;
|
|
187
|
-
|
|
188
|
-
try {
|
|
189
|
-
const layoutEngine = new LayoutEngine();
|
|
190
|
-
const layoutTimer = new SimpleStopwatch();
|
|
191
|
-
|
|
192
|
-
const graph = layoutEngine.runLayout(sequence, nets);
|
|
193
|
-
|
|
194
|
-
layoutEngine.printWarnings();
|
|
195
|
-
|
|
196
|
-
showStats && console.log('Layout took:', layoutTimer.lap());
|
|
197
|
-
|
|
198
|
-
dumpData && writeFileSync('dump/raw-layout.txt', layoutEngine.logger.dump());
|
|
199
|
-
|
|
200
|
-
const generateSvgTimer = new SimpleStopwatch();
|
|
201
|
-
svgOutput = generateSVG2(graph);
|
|
202
|
-
showStats && console.log('Render took:', generateSvgTimer.lap());
|
|
203
|
-
|
|
204
|
-
if (outputPath){
|
|
205
|
-
writeFileSync(outputPath, svgOutput);
|
|
206
|
-
}
|
|
207
|
-
} catch (err) {
|
|
208
|
-
console.log('Failed to render:');
|
|
209
|
-
console.log(err)
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
return svgOutput;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
105
|
main();
|
package/src/regenerate-tests.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
|
-
import { renderScript } from './
|
|
2
|
+
import { renderScript } from './helpers.js';
|
|
3
3
|
|
|
4
4
|
const mainDir = './__tests__/renderData/';
|
|
5
5
|
|
|
@@ -21,5 +21,5 @@ cstFiles.forEach(file => {
|
|
|
21
21
|
const outputPath = inputPath + '.svg';
|
|
22
22
|
renderScript(scriptData, outputPath, { currentDirectory: useCurrentDir });
|
|
23
23
|
|
|
24
|
-
console.log('generated ',
|
|
24
|
+
console.log('generated ', outputPath);
|
|
25
25
|
});
|
package/src/sizing.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { Box, SVG, SVGTypeMapping, registerWindow } from '@svgdotjs/svg.js';
|
|
2
2
|
import { config, createSVGWindow } from 'svgdom';
|
|
3
3
|
import { HorizontalAlign, VerticalAlign } from './geometry.js';
|
|
4
|
+
import { defaultFont } from './globals.js';
|
|
4
5
|
|
|
5
6
|
let MainCanvas = null;
|
|
6
7
|
|
|
7
8
|
const supportedFonts = {
|
|
8
9
|
// 'Roboto': 'Roboto-Regular.ttf',
|
|
9
|
-
'Inter': 'Inter-Regular.ttf',
|
|
10
|
-
'Inter-Bold': 'Inter-Bold.ttf',
|
|
10
|
+
// 'Inter': 'Inter-Regular.ttf',
|
|
11
|
+
// 'Inter-Bold': 'Inter-Bold.ttf',
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
export async function prepareSizing(fontsPath): Promise<void> {
|
|
@@ -68,18 +69,14 @@ export function measureTextSize2(text: string, fontFamily: string,
|
|
|
68
69
|
break;
|
|
69
70
|
}
|
|
70
71
|
|
|
71
|
-
|
|
72
|
-
fontFamily = 'Inter-Bold';
|
|
73
|
-
} else {
|
|
74
|
-
fontFamily = 'Inter-Regular';
|
|
75
|
-
}
|
|
72
|
+
fontFamily = defaultFont;
|
|
76
73
|
|
|
77
74
|
const tmpTextElement = MainCanvas.text(text).font({
|
|
78
75
|
family: fontFamily,
|
|
79
76
|
size: fontSize,
|
|
80
77
|
anchor: anchor,
|
|
81
78
|
'dominant-baseline': dominantBaseline,
|
|
82
|
-
|
|
79
|
+
weight: fontWeight,
|
|
83
80
|
}).fill('#333');
|
|
84
81
|
|
|
85
82
|
const textbox = tmpTextElement.bbox();
|
package/src/visitor.ts
CHANGED
|
@@ -1352,8 +1352,8 @@ export class MainVisitor extends ParseTreeVisitor<any> {
|
|
|
1352
1352
|
}
|
|
1353
1353
|
|
|
1354
1354
|
if (instance.typeProp === null){
|
|
1355
|
-
this.print('Instance has no type:', instance.instanceName);
|
|
1356
|
-
|
|
1355
|
+
this.print('Instance has no type:', instance.instanceName, ' assuming connector');
|
|
1356
|
+
instance.typeProp = 'conn';
|
|
1357
1357
|
}
|
|
1358
1358
|
|
|
1359
1359
|
if (instance.parameters.has('refdes')) {
|
|
@@ -1569,8 +1569,20 @@ class ComponentAnnotater {
|
|
|
1569
1569
|
}
|
|
1570
1570
|
|
|
1571
1571
|
getAnnotation(type: string): string | null {
|
|
1572
|
-
|
|
1573
|
-
|
|
1572
|
+
|
|
1573
|
+
// If type is unknown, then allow it to define a new range
|
|
1574
|
+
if (this.counter[type] === undefined && type.length <= 2) {
|
|
1575
|
+
for (const [, value] of Object.entries(ComponentRefDesPrefixes)) {
|
|
1576
|
+
if (value === type) {
|
|
1577
|
+
throw "Refdes prefix is already in use!";
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
|
|
1581
|
+
if (ComponentRefDesPrefixes[type] === undefined) {
|
|
1582
|
+
// Define new type and start counting
|
|
1583
|
+
ComponentRefDesPrefixes[type] = type;
|
|
1584
|
+
this.counter[type] = 1;
|
|
1585
|
+
}
|
|
1574
1586
|
}
|
|
1575
1587
|
|
|
1576
1588
|
let attempts = 100;
|