@mylasertools/kerfscript 0.0.0-stage → 0.2.0
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/CHANGELOG.md +42 -0
- package/CLA.md +73 -0
- package/COMMERCIAL-LICENSE.md +68 -0
- package/LANGUAGE.md +295 -0
- package/LICENSE +661 -0
- package/README.md +148 -2
- package/THIRD-PARTY-NOTICES.md +69 -0
- package/TRADEMARKS.md +39 -0
- package/dist/ast.d.cts +160 -0
- package/dist/ast.d.ts +160 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +19226 -0
- package/dist/customizer.d.cts +19 -0
- package/dist/customizer.d.ts +19 -0
- package/dist/evaluator.d.cts +106 -0
- package/dist/evaluator.d.ts +106 -0
- package/dist/export/dxf.d.cts +3 -0
- package/dist/export/dxf.d.ts +3 -0
- package/dist/export/svg.d.cts +13 -0
- package/dist/export/svg.d.ts +13 -0
- package/dist/functions.d.cts +4 -0
- package/dist/functions.d.ts +4 -0
- package/dist/geometry.d.cts +44 -0
- package/dist/geometry.d.ts +44 -0
- package/dist/index.cjs +44 -0
- package/dist/index.d.cts +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +44 -0
- package/dist/joinery.d.cts +7 -0
- package/dist/joinery.d.ts +7 -0
- package/dist/lexer.d.cts +28 -0
- package/dist/lexer.d.ts +28 -0
- package/dist/parser.d.cts +6 -0
- package/dist/parser.d.ts +6 -0
- package/dist/paths.d.cts +28 -0
- package/dist/paths.d.ts +28 -0
- package/dist/render.d.cts +57 -0
- package/dist/render.d.ts +57 -0
- package/dist/stdlib.d.cts +1 -0
- package/dist/stdlib.d.ts +1 -0
- package/dist/text.d.cts +36 -0
- package/dist/text.d.ts +36 -0
- package/dist/values.d.cts +25 -0
- package/dist/values.d.ts +25 -0
- package/docs/cli.md +61 -0
- package/docs/compatibility.md +89 -0
- package/docs/customizer.md +62 -0
- package/docs/getting-started.md +98 -0
- package/docs/javascript.md +98 -0
- package/docs/kerf.md +70 -0
- package/docs/layers.md +74 -0
- package/docs/openscad.md +67 -0
- package/docs/parts-and-sheets.md +68 -0
- package/docs/versions.md +43 -0
- package/package.json +85 -4
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Getting started
|
|
2
|
+
|
|
3
|
+
This guide takes you from an empty file to a cut file in about ten minutes.
|
|
4
|
+
You need nothing installed: the [playground](https://kerfscript.mylasertools.com/playground/)
|
|
5
|
+
runs KerfScript in your browser.
|
|
6
|
+
|
|
7
|
+
## Your first part
|
|
8
|
+
|
|
9
|
+
Open the playground, clear the editor and type:
|
|
10
|
+
|
|
11
|
+
```kerf
|
|
12
|
+
rect([80, 50], r = 4);
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
That is a rounded rectangle, 80 by 50 mm. Units are always millimetres. A
|
|
16
|
+
shape that is not on any other layer is **cut**, so this is a part you could
|
|
17
|
+
cut out now.
|
|
18
|
+
|
|
19
|
+
## Holes
|
|
20
|
+
|
|
21
|
+
`difference()` keeps the first shape and removes the rest from it:
|
|
22
|
+
|
|
23
|
+
```kerf
|
|
24
|
+
difference() {
|
|
25
|
+
rect([80, 50], r = 4);
|
|
26
|
+
translate([10, 25]) circle(d = 5);
|
|
27
|
+
translate([70, 25]) circle(d = 5);
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
`translate([x, y])` moves what follows it. The y axis points up, and
|
|
32
|
+
`rect()` starts at `[0, 0]` unless you pass `center = true`.
|
|
33
|
+
|
|
34
|
+
## Engraving and scoring
|
|
35
|
+
|
|
36
|
+
Wrap shapes in `engrave()` to engrave their area, or `score()` to mark their
|
|
37
|
+
outline without cutting through:
|
|
38
|
+
|
|
39
|
+
```kerf
|
|
40
|
+
difference() {
|
|
41
|
+
rect([80, 50], r = 4);
|
|
42
|
+
translate([10, 25]) circle(d = 5);
|
|
43
|
+
translate([70, 25]) circle(d = 5);
|
|
44
|
+
}
|
|
45
|
+
score() translate([20, 10]) rect([40, 30], r = 2);
|
|
46
|
+
engrave() translate([40, 25]) text("Oak", size = 10, halign = "center", valign = "center");
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Engraving and scoring are clipped to the material, so nothing is marked over
|
|
50
|
+
a hole or off the edge. [Layers](layers.md) explains the rest.
|
|
51
|
+
|
|
52
|
+
## Settings
|
|
53
|
+
|
|
54
|
+
A top-level variable with a comment in square brackets becomes a slider:
|
|
55
|
+
|
|
56
|
+
```kerf
|
|
57
|
+
width = 80; // [40:5:200]
|
|
58
|
+
height = 50; // [30:5:120]
|
|
59
|
+
label = "Oak";
|
|
60
|
+
|
|
61
|
+
difference() {
|
|
62
|
+
rect([width, height], r = 4);
|
|
63
|
+
translate([10, height / 2]) circle(d = 5);
|
|
64
|
+
translate([width - 10, height / 2]) circle(d = 5);
|
|
65
|
+
}
|
|
66
|
+
engrave() translate([width / 2, height / 2])
|
|
67
|
+
text(label, size = 10, halign = "center", valign = "center");
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Move a slider in the playground and the number in the code changes with it.
|
|
71
|
+
[Settings](customizer.md) covers groups, captions and menus.
|
|
72
|
+
|
|
73
|
+
## Kerf
|
|
74
|
+
|
|
75
|
+
The laser burns away a thin line of material, the **kerf**. Tell KerfScript
|
|
76
|
+
how wide it is and parts come out the size you typed:
|
|
77
|
+
|
|
78
|
+
```kerf
|
|
79
|
+
$kerf = 0.15;
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Cut the [calibration square](../examples/calibration-square.kerf) once to
|
|
83
|
+
measure yours. [Kerf](kerf.md) explains how.
|
|
84
|
+
|
|
85
|
+
## Getting the file
|
|
86
|
+
|
|
87
|
+
In the playground, press **SVG** or **DXF**. Open the SVG in your laser
|
|
88
|
+
software: cut lines are red, score lines blue and engraving black, each on its
|
|
89
|
+
own layer. Set power, speed and the order of operations there, as you would
|
|
90
|
+
for any other file. [Laser software](compatibility.md) has notes for the
|
|
91
|
+
programs we have checked.
|
|
92
|
+
|
|
93
|
+
## Next
|
|
94
|
+
|
|
95
|
+
- [Layers](layers.md): cut, score, engrave and your own layers
|
|
96
|
+
- [Parts and sheets](parts-and-sheets.md): several pieces, quantities, materials
|
|
97
|
+
- [Coming from OpenSCAD](openscad.md): what is the same and what is not
|
|
98
|
+
- [Language reference](../LANGUAGE.md): everything in one page
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# JavaScript API
|
|
2
|
+
|
|
3
|
+
The same interpreter that runs the command line and the playground is a
|
|
4
|
+
TypeScript library with no native code. It runs in browsers, web workers,
|
|
5
|
+
Node.js and edge runtimes.
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm install @mylasertools/kerfscript
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## render()
|
|
12
|
+
|
|
13
|
+
```js
|
|
14
|
+
import { render } from '@mylasertools/kerfscript';
|
|
15
|
+
|
|
16
|
+
const result = render(source, {
|
|
17
|
+
params: { width: 200 },
|
|
18
|
+
fonts: { Inter: await (await fetch('/Inter.ttf')).arrayBuffer() },
|
|
19
|
+
defaultFont: 'Inter',
|
|
20
|
+
sheet: [600, 400],
|
|
21
|
+
});
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Options
|
|
25
|
+
|
|
26
|
+
| Option | Meaning |
|
|
27
|
+
| ------------- | ------------------------------------------------------------------------------------ |
|
|
28
|
+
| `params` | setting values by name, overriding the top-level assignments |
|
|
29
|
+
| `fonts` | font files by name, as `ArrayBuffer` or `Uint8Array` |
|
|
30
|
+
| `defaultFont` | font used when `text()` names none |
|
|
31
|
+
| `resolve` | `(path) => source` for `use <path>` and `include <path>` beyond the standard library |
|
|
32
|
+
| `kerf` | override kerf compensation for every part |
|
|
33
|
+
| `layout` | `"pack"` or `"none"` |
|
|
34
|
+
| `sheet` | `[width, height]` in mm |
|
|
35
|
+
| `gap` | space between packed parts |
|
|
36
|
+
| `margin` | space around the sheet edge (default: `gap`) |
|
|
37
|
+
| `guides` | include guide layer geometry |
|
|
38
|
+
| `maxSteps` | step limit before the program is stopped |
|
|
39
|
+
|
|
40
|
+
### Result
|
|
41
|
+
|
|
42
|
+
| Field | Contents |
|
|
43
|
+
| ----------------- | ---------------------------------------------------------------------------------------------------------- |
|
|
44
|
+
| `svg` | every sheet in one SVG, for previews |
|
|
45
|
+
| `width`, `height` | size of that combined SVG in mm |
|
|
46
|
+
| `sheets` | one entry per sheet: `width`, `height`, `material`, `thickness`, `svg`, `dxf`, `paths`, `items` |
|
|
47
|
+
| `parts` | `name`, `qty`, `width`, `height`, `pieces`, `cutLength`, `thickness`, `kerf`, `material` |
|
|
48
|
+
| `paths` | per layer: `name`, `mode`, `color`, `d` (all path data), `regions` (closed outlines), `lines` (open lines) |
|
|
49
|
+
| `layers` | the layer definitions in output order |
|
|
50
|
+
| `warnings` | problems that did not stop the render |
|
|
51
|
+
| `echoes` | `echo()` output |
|
|
52
|
+
|
|
53
|
+
`paths` is for apps that draw the result themselves. Fill `regions` with the
|
|
54
|
+
even-odd rule on `fill` layers, and stroke `lines`.
|
|
55
|
+
|
|
56
|
+
## parameters()
|
|
57
|
+
|
|
58
|
+
```js
|
|
59
|
+
import { parameters } from '@mylasertools/kerfscript';
|
|
60
|
+
|
|
61
|
+
parameters(source).parameters;
|
|
62
|
+
// [{ name, caption, group, type, initial, min, max, step, options, span }]
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
`type` is `"number"`, `"string"` or `"boolean"`; a list of numbers is
|
|
66
|
+
`"number"` with a list `initial`, as in OpenSCAD's parameter JSON. `span` is
|
|
67
|
+
`[start, end]`, the offsets of the value in the source, so an editor can change
|
|
68
|
+
a value without touching anything else:
|
|
69
|
+
|
|
70
|
+
```js
|
|
71
|
+
const p = parameters(source).parameters.find((p) => p.name === 'width');
|
|
72
|
+
const next = source.slice(0, p.span[0]) + '200' + source.slice(p.span[1]);
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Errors
|
|
76
|
+
|
|
77
|
+
Errors are thrown as `KerfError` with `line` and `col`. They also carry
|
|
78
|
+
`echoes`, the `echo()` output up to the error, and `missingFonts` when a font
|
|
79
|
+
was not supplied, so an app can load those fonts and render again.
|
|
80
|
+
|
|
81
|
+
```js
|
|
82
|
+
import { KerfError, render } from '@mylasertools/kerfscript';
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
render(source, { fonts });
|
|
86
|
+
} catch (e) {
|
|
87
|
+
if (e instanceof KerfError && e.missingFonts) {
|
|
88
|
+
// load e.missingFonts, then render again
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Running untrusted code
|
|
94
|
+
|
|
95
|
+
Programs cannot read files or the network: `use` and `include` reach only the
|
|
96
|
+
standard library and whatever your `resolve` returns. Step and recursion limits
|
|
97
|
+
stop runaway programs. A render is still ordinary synchronous work, so run
|
|
98
|
+
it in a web worker, and stop the worker if it takes too long.
|
package/docs/kerf.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Kerf
|
|
2
|
+
|
|
3
|
+
The laser beam burns away a thin line of material as it cuts. That width is
|
|
4
|
+
the **kerf**, usually somewhere between 0.05 and 0.3 mm depending on the
|
|
5
|
+
machine, the lens, the material and its thickness. Without compensation every
|
|
6
|
+
part comes out smaller than drawn by about one kerf, and every hole bigger.
|
|
7
|
+
For a sign that hardly matters. For finger joints and press fits it decides
|
|
8
|
+
whether the box holds together.
|
|
9
|
+
|
|
10
|
+
## Setting it
|
|
11
|
+
|
|
12
|
+
```kerf
|
|
13
|
+
$kerf = 0.15;
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
KerfScript offsets every cut outline outward by half the kerf when it writes
|
|
17
|
+
the file. The beam then runs half a kerf outside the part and burns away
|
|
18
|
+
material that was never part of it, so the part ends up the size you typed.
|
|
19
|
+
Holes are offset inward the same way, so they end up the size you typed too.
|
|
20
|
+
|
|
21
|
+
Only closed outlines on cut layers are offset. Engraving, scoring and open cut
|
|
22
|
+
lines (like a living hinge) are left as drawn.
|
|
23
|
+
|
|
24
|
+
You can set the kerf for one material only, together with its thickness:
|
|
25
|
+
|
|
26
|
+
```kerf
|
|
27
|
+
material(thickness = 4, kerf = 0.12, name = "birch") {
|
|
28
|
+
part("side", qty = 2) finger_rect([100, 60], "out");
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
On the command line, `--kerf 0.1` overrides the value for every part.
|
|
33
|
+
|
|
34
|
+
## Measuring your kerf
|
|
35
|
+
|
|
36
|
+
1. Cut the [calibration square](../examples/calibration-square.kerf) with
|
|
37
|
+
`$kerf = 0`.
|
|
38
|
+
2. Measure the outside of the square with calipers, across the middle.
|
|
39
|
+
3. Your kerf is `100 - measured`. If the square measures 99.82 mm, use
|
|
40
|
+
`$kerf = 0.18`.
|
|
41
|
+
4. Cut it again with that value. The square should now be 100 mm and the hole
|
|
42
|
+
20 mm. If the square is still small and the hole big, raise `$kerf` a
|
|
43
|
+
little; if the square is big, lower it.
|
|
44
|
+
|
|
45
|
+
Measure each material you use. Thicker material usually has a wider kerf, and
|
|
46
|
+
the kerf can differ between the top and bottom face.
|
|
47
|
+
|
|
48
|
+
## Checking a fit
|
|
49
|
+
|
|
50
|
+
For joints, the [kerf and fit test](../examples/kerf-test.kerf) cuts a row of
|
|
51
|
+
slots from slightly narrower to slightly wider than `$thickness`. Push a scrap
|
|
52
|
+
of the same sheet into each slot:
|
|
53
|
+
|
|
54
|
+
- if the slot marked `0` is snug, your kerf and thickness are right;
|
|
55
|
+
- if a `+` slot fits best, the sheet is thicker than `$thickness` says
|
|
56
|
+
(plywood often is);
|
|
57
|
+
- if a `-` slot fits best, it is thinner.
|
|
58
|
+
|
|
59
|
+
Set `$thickness` to the thickness you measured rather than the one on the
|
|
60
|
+
label, and joints follow.
|
|
61
|
+
|
|
62
|
+
## Limits
|
|
63
|
+
|
|
64
|
+
- A hole, slot or notch narrower than the kerf cannot be cut: the beam is
|
|
65
|
+
wider than the gap, so compensation closes it. KerfScript warns when that
|
|
66
|
+
happens to a hole.
|
|
67
|
+
- Thin bridges and fingers come out the right size but are fragile, and can
|
|
68
|
+
char in thin material. Keep them several times wider than the kerf.
|
|
69
|
+
- The beam is not perfectly straight in thick material, so cut faces taper a
|
|
70
|
+
little. Compensation works on the average width.
|
package/docs/layers.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Layers
|
|
2
|
+
|
|
3
|
+
Every shape in KerfScript is on a layer, and the layer decides what the
|
|
4
|
+
laser does with it. Shapes that are not wrapped in a layer module are on
|
|
5
|
+
`cut`.
|
|
6
|
+
|
|
7
|
+
## The built-in layers
|
|
8
|
+
|
|
9
|
+
| Layer | Wrap shapes in | Colour in the file | What the laser does |
|
|
10
|
+
| --------- | -------------- | ------------------ | ------------------------------------------------- |
|
|
11
|
+
| `engrave` | `engrave()` | black `#000000` | engraves the area of the shapes |
|
|
12
|
+
| `score` | `score()` | blue `#0000ff` | marks lines and outlines without cutting through |
|
|
13
|
+
| `cut` | `cut()` | red `#ff0000` | cuts the outlines through, with kerf compensation |
|
|
14
|
+
| `guide` | `guide()` | light blue | nothing; shown only when you ask for guide lines |
|
|
15
|
+
|
|
16
|
+
```kerf
|
|
17
|
+
difference() {
|
|
18
|
+
circle(d = 90);
|
|
19
|
+
circle(d = 6);
|
|
20
|
+
}
|
|
21
|
+
engrave() difference() { circle(d = 74); circle(d = 68); }
|
|
22
|
+
score() circle(d = 84);
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
`#` and `%` in front of a module call move it to the guide layer, which is
|
|
26
|
+
handy for checking where something is without cutting it.
|
|
27
|
+
|
|
28
|
+
## Areas and lines
|
|
29
|
+
|
|
30
|
+
Layers hold two kinds of geometry:
|
|
31
|
+
|
|
32
|
+
- **Areas** come from shapes like `rect()`, `circle()` and `text()`. On
|
|
33
|
+
`engrave` the area is filled; on `cut` and `score` its outline is followed.
|
|
34
|
+
- **Lines** come from `line()`, `polyline()`, `arc()` and `living_hinge()`.
|
|
35
|
+
They are followed as they are, on any layer. On `cut` they are cut through,
|
|
36
|
+
which is how a living hinge is made.
|
|
37
|
+
|
|
38
|
+
`stroke(width)` turns lines into areas, for engraving a line of a given
|
|
39
|
+
width. `outline()` turns areas into their outline lines.
|
|
40
|
+
|
|
41
|
+
## The material
|
|
42
|
+
|
|
43
|
+
When a part is finished, KerfScript takes the union of everything on the cut
|
|
44
|
+
layer as the **material**. Then:
|
|
45
|
+
|
|
46
|
+
- engraving and scoring are clipped to the material, so nothing is marked
|
|
47
|
+
inside a hole or off the part;
|
|
48
|
+
- cut lines are clipped to the material too;
|
|
49
|
+
- if the material falls apart into separate pieces, you get a warning,
|
|
50
|
+
because that usually means a missing bridge.
|
|
51
|
+
|
|
52
|
+
## Your own layers
|
|
53
|
+
|
|
54
|
+
`layer(name, mode, color)` makes a layer of your own, for example a second
|
|
55
|
+
engraving pass at a different power:
|
|
56
|
+
|
|
57
|
+
```kerf
|
|
58
|
+
rect([60, 40]);
|
|
59
|
+
layer("deep", mode = "fill", color = "#00aa00") translate([10, 10]) rect([20, 20]);
|
|
60
|
+
engrave() translate([40, 20]) circle(d = 12);
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Modes are `"cut"`, `"line"` (score), `"fill"` (engrave) and `"guide"`.
|
|
64
|
+
|
|
65
|
+
## Order in the file
|
|
66
|
+
|
|
67
|
+
Layers are written in this order: engrave, your own layers, score, cut,
|
|
68
|
+
guide. Within the cut layer, holes and inner cuts come before outer outlines,
|
|
69
|
+
so a part does not drop out before its holes are cut.
|
|
70
|
+
|
|
71
|
+
That order is a good default, but it does not control your machine. Most
|
|
72
|
+
laser software sorts and orders operations itself. Check the cut order, and
|
|
73
|
+
set power, speed and passes for each layer, in your laser software before you
|
|
74
|
+
run the job.
|
package/docs/openscad.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Coming from OpenSCAD
|
|
2
|
+
|
|
3
|
+
KerfScript borrows OpenSCAD's syntax on purpose: if you have written
|
|
4
|
+
OpenSCAD, you can read KerfScript and write it within minutes. It is not a
|
|
5
|
+
drop-in replacement. It only makes flat parts, and a few rules are different.
|
|
6
|
+
OpenSCAD files do not run unchanged.
|
|
7
|
+
|
|
8
|
+
## The same
|
|
9
|
+
|
|
10
|
+
- Statements, modules, functions, `for`, `if`, `let`, `each`, list
|
|
11
|
+
comprehensions, ranges like `[0:2:10]`, function literals.
|
|
12
|
+
- `children()`, `children(i)` and `$children`.
|
|
13
|
+
- Special variables that start with `$` are dynamically scoped, and `$fn`,
|
|
14
|
+
`$fa` and `$fs` set curve resolution.
|
|
15
|
+
- 2D shapes: `square()` (also called `rect()`), `circle(r)` or `circle(d =)`,
|
|
16
|
+
`polygon(points, paths)`, `text()`.
|
|
17
|
+
- Transforms: `translate`, `rotate`, `scale`, `mirror`, `multmatrix`.
|
|
18
|
+
- Combining: `union`, `difference`, `intersection`, `hull`, `offset(r)`,
|
|
19
|
+
`offset(delta, chamfer)`.
|
|
20
|
+
- `echo()`, `assert()`, `use <...>` and `include <...>`.
|
|
21
|
+
- Customizer comments: `// [40:5:400]`, `/* [Group] */`, `/* [Hidden] */`,
|
|
22
|
+
and captions on the line above. Tools that read OpenSCAD settings read
|
|
23
|
+
these.
|
|
24
|
+
|
|
25
|
+
## Different
|
|
26
|
+
|
|
27
|
+
| | OpenSCAD | KerfScript |
|
|
28
|
+
| ----------- | --------------------------------------------- | --------------------------------------------------------------- |
|
|
29
|
+
| Output | a solid, as STL, 3MF and more | a cut file, as SVG or DXF |
|
|
30
|
+
| Dimensions | 3D, and 2D for export | 2D only |
|
|
31
|
+
| Assignments | the last one in a scope wins everywhere in it | run in order; a later one takes effect from that line |
|
|
32
|
+
| Errors | many mistakes give `undef` and a warning | type mistakes stop the program, naming the line |
|
|
33
|
+
| `color()` | colours a shape | not available; use `cut()`, `score()`, `engrave()` or `layer()` |
|
|
34
|
+
| Fonts | system fonts | only fonts you pass in, so a file renders the same everywhere |
|
|
35
|
+
| Libraries | any file on disk | the standard library and whatever the host allows |
|
|
36
|
+
|
|
37
|
+
## Not in KerfScript
|
|
38
|
+
|
|
39
|
+
3D modules (`cube`, `sphere`, `cylinder`, `polyhedron`,
|
|
40
|
+
`linear_extrude`, `rotate_extrude`, `projection`), `minkowski`, `resize`,
|
|
41
|
+
`color`, `import`, `surface` and `render`. Each stops with an error that
|
|
42
|
+
names it, so you find out at once.
|
|
43
|
+
|
|
44
|
+
## Only in KerfScript
|
|
45
|
+
|
|
46
|
+
- Layers: `cut()`, `score()`, `engrave()`, `guide()` and `layer()`.
|
|
47
|
+
See [Layers](layers.md).
|
|
48
|
+
- Kerf compensation with `$kerf`. See [Kerf](kerf.md).
|
|
49
|
+
- Parts, quantities, materials and sheet packing: `part()`, `material()`,
|
|
50
|
+
`$sheet`, `$gap`. See [Parts and sheets](parts-and-sheets.md).
|
|
51
|
+
- Joinery that reads `$thickness`: `finger_rect`, `finger_holes`, `tslot`,
|
|
52
|
+
`living_hinge`.
|
|
53
|
+
- Lines as well as areas: `line()`, `polyline()`, `arc()`, `path()`,
|
|
54
|
+
`stroke()` and `outline()`.
|
|
55
|
+
- Shapes OpenSCAD lacks: `ellipse`, `regular_polygon`, `star`, rounded
|
|
56
|
+
`rect(r =)`.
|
|
57
|
+
- `text_width()` and `text_metrics()`, to size a part to its text.
|
|
58
|
+
|
|
59
|
+
## Porting a 2D design
|
|
60
|
+
|
|
61
|
+
1. Drop `linear_extrude()` and any 3D parts.
|
|
62
|
+
2. Replace `color()` with the layer the shape belongs on.
|
|
63
|
+
3. Check assignments: code that relied on a later assignment overriding an
|
|
64
|
+
earlier one should assign once.
|
|
65
|
+
4. Pass the fonts your `text()` calls use.
|
|
66
|
+
5. Add `$kerf` and `$thickness`, and replace hand-made finger joints with
|
|
67
|
+
`finger_rect()` if you want them to follow the material.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Parts and sheets
|
|
2
|
+
|
|
3
|
+
A design often has more than one piece. KerfScript lets you name each piece,
|
|
4
|
+
say how many you need and what it is cut from, and lays them out on sheets.
|
|
5
|
+
|
|
6
|
+
## Parts
|
|
7
|
+
|
|
8
|
+
```kerf
|
|
9
|
+
part("side", qty = 2) rect([100, 60]);
|
|
10
|
+
part("base") rect([100, 100]);
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
`part(name, qty = 1)` makes a named part. Everything inside it is one piece
|
|
14
|
+
with its own layers. Shapes outside any part form one part called `part`.
|
|
15
|
+
|
|
16
|
+
Parts show up in the part list with their size and cut length, which the
|
|
17
|
+
playground and `kerf check` print.
|
|
18
|
+
|
|
19
|
+
## Materials
|
|
20
|
+
|
|
21
|
+
Each part records `$thickness`, `$kerf` and `$material` where it is made.
|
|
22
|
+
`material()` sets all three for the parts inside it:
|
|
23
|
+
|
|
24
|
+
```kerf
|
|
25
|
+
material(thickness = 3, kerf = 0.15, name = "plywood") {
|
|
26
|
+
part("front") rect([100, 60]);
|
|
27
|
+
part("back") rect([100, 60]);
|
|
28
|
+
}
|
|
29
|
+
material(thickness = 2, kerf = 0.1, name = "acrylic") {
|
|
30
|
+
part("window") rect([80, 40]);
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Sheets
|
|
35
|
+
|
|
36
|
+
With the default `$layout = "pack"`, KerfScript:
|
|
37
|
+
|
|
38
|
+
1. groups parts by material and thickness,
|
|
39
|
+
2. copies each part `qty` times,
|
|
40
|
+
3. turns a part 90° when that makes it fit,
|
|
41
|
+
4. packs them in rows onto sheets of `$sheet` (600 by 400 mm by default),
|
|
42
|
+
with `$gap` millimetres between parts and around the edge.
|
|
43
|
+
|
|
44
|
+
A part bigger than the sheet gives a warning. With `$layout = "none"` parts
|
|
45
|
+
stay where your program put them.
|
|
46
|
+
|
|
47
|
+
```kerf
|
|
48
|
+
$sheet = [300, 200];
|
|
49
|
+
$gap = 4;
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## One file per sheet
|
|
53
|
+
|
|
54
|
+
The design above makes two sheets: one of plywood and one of acrylic. The
|
|
55
|
+
combined SVG shows every sheet stacked one above the other, which is useful
|
|
56
|
+
for a preview but is **not** a cutting job: the sheets are different
|
|
57
|
+
materials.
|
|
58
|
+
|
|
59
|
+
Cut each sheet as its own job:
|
|
60
|
+
|
|
61
|
+
- On the command line, `--split` writes one file per sheet
|
|
62
|
+
(`design-1.svg`, `design-2.svg`, ...). `kerf check` lists the sheets with
|
|
63
|
+
their material and thickness.
|
|
64
|
+
- From JavaScript, `result.sheets` has an SVG and a DXF for each sheet, with
|
|
65
|
+
its `material` and `thickness`.
|
|
66
|
+
|
|
67
|
+
Before cutting, check that each file's material and thickness match the
|
|
68
|
+
sheet in your machine.
|
package/docs/versions.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Versions
|
|
2
|
+
|
|
3
|
+
KerfScript has two version numbers.
|
|
4
|
+
|
|
5
|
+
- The **language version** (now 0.1) covers what `.kerf` files mean: the
|
|
6
|
+
syntax, the built-in modules and functions, and the rules for layers, kerf
|
|
7
|
+
and parts. The [language reference](../LANGUAGE.md) describes one language
|
|
8
|
+
version.
|
|
9
|
+
- The **package version** (now 0.2.0) is the version of the interpreter, the
|
|
10
|
+
`kerf` command and the JavaScript API. It changes more often: bug fixes,
|
|
11
|
+
new output options and API additions do not change the language.
|
|
12
|
+
|
|
13
|
+
The site footer, `kerf --version` and the `VERSION` and `LANGUAGE_VERSION`
|
|
14
|
+
exports show both.
|
|
15
|
+
|
|
16
|
+
## Before 1.0
|
|
17
|
+
|
|
18
|
+
KerfScript is young, and the language may still change before 1.0. What we
|
|
19
|
+
promise in the meantime:
|
|
20
|
+
|
|
21
|
+
- **Changes are written down.** Every change that can alter what a file
|
|
22
|
+
produces is listed in the changelog under the version that made it.
|
|
23
|
+
- **Files keep running where we can manage it.** A program that worked keeps
|
|
24
|
+
working, or stops with an error that says what to change. It does not
|
|
25
|
+
silently start cutting something different.
|
|
26
|
+
- **Geometry changes are called out.** If the same file starts producing
|
|
27
|
+
different geometry, for example after a packing or text layout fix, the
|
|
28
|
+
changelog says which designs are affected.
|
|
29
|
+
- **Breaking changes raise the language version.** Package releases within
|
|
30
|
+
one language version do not remove or rename anything in the language.
|
|
31
|
+
|
|
32
|
+
## From 1.0
|
|
33
|
+
|
|
34
|
+
From language version 1.0, `.kerf` files written for 1.x keep producing the
|
|
35
|
+
same parts in every later 1.x interpreter, apart from bug fixes listed in the
|
|
36
|
+
changelog. New features are additions. Anything that would change existing
|
|
37
|
+
files waits for 2.0.
|
|
38
|
+
|
|
39
|
+
## Pinning a version
|
|
40
|
+
|
|
41
|
+
Hosts that store designs, like MyLaserTools, record which interpreter
|
|
42
|
+
version a design was published with, so a stored design can be checked
|
|
43
|
+
against later versions before it is upgraded.
|
package/package.json
CHANGED
|
@@ -1,6 +1,87 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mylasertools/kerfscript",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "KerfScript: a programming language for laser cutting. Write parametric 2D parts with cut, score and engrave layers, kerf compensation and joinery, and export SVG or DXF.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "AGPL-3.0-only",
|
|
7
|
+
"author": "MyLaserTools",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/mylasertools-com/kerfscript.git"
|
|
11
|
+
},
|
|
12
|
+
"bugs": "https://github.com/mylasertools-com/kerfscript/issues",
|
|
13
|
+
"keywords": [
|
|
14
|
+
"kerfscript",
|
|
15
|
+
"laser-cutting",
|
|
16
|
+
"parametric",
|
|
17
|
+
"cad",
|
|
18
|
+
"programming-language",
|
|
19
|
+
"svg",
|
|
20
|
+
"dxf",
|
|
21
|
+
"finger-joints",
|
|
22
|
+
"living-hinge",
|
|
23
|
+
"kerf"
|
|
24
|
+
],
|
|
25
|
+
"sideEffects": false,
|
|
26
|
+
"main": "./dist/index.cjs",
|
|
27
|
+
"module": "./dist/index.js",
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"import": {
|
|
32
|
+
"types": "./dist/index.d.ts",
|
|
33
|
+
"default": "./dist/index.js"
|
|
34
|
+
},
|
|
35
|
+
"require": {
|
|
36
|
+
"types": "./dist/index.d.cts",
|
|
37
|
+
"default": "./dist/index.cjs"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"./cli": "./dist/cli.js",
|
|
41
|
+
"./package.json": "./package.json"
|
|
42
|
+
},
|
|
43
|
+
"bin": {
|
|
44
|
+
"kerf": "dist/cli.js"
|
|
45
|
+
},
|
|
46
|
+
"files": [
|
|
47
|
+
"dist",
|
|
48
|
+
"README.md",
|
|
49
|
+
"docs",
|
|
50
|
+
"LANGUAGE.md",
|
|
51
|
+
"LICENSE",
|
|
52
|
+
"COMMERCIAL-LICENSE.md",
|
|
53
|
+
"THIRD-PARTY-NOTICES.md",
|
|
54
|
+
"CHANGELOG.md",
|
|
55
|
+
"TRADEMARKS.md",
|
|
56
|
+
"CLA.md"
|
|
57
|
+
],
|
|
58
|
+
"engines": {
|
|
59
|
+
"node": ">=20"
|
|
60
|
+
},
|
|
61
|
+
"publishConfig": {
|
|
62
|
+
"access": "public",
|
|
63
|
+
"registry": "https://registry.npmjs.org/"
|
|
64
|
+
},
|
|
65
|
+
"scripts": {
|
|
66
|
+
"build": "node scripts/stdlib.mjs && tsc -p tsconfig.json && node scripts/build.mjs",
|
|
67
|
+
"test": "node --test",
|
|
68
|
+
"check": "npm run build && npm test",
|
|
69
|
+
"examples": "node scripts/examples.mjs",
|
|
70
|
+
"site": "npm run build && npm --prefix site run build",
|
|
71
|
+
"site:serve": "npm --prefix site run preview",
|
|
72
|
+
"prepack": "npm run check",
|
|
73
|
+
"format": "prettier --write .",
|
|
74
|
+
"format:check": "prettier --check .",
|
|
75
|
+
"compat": "node scripts/compat.mjs"
|
|
76
|
+
},
|
|
77
|
+
"devDependencies": {
|
|
78
|
+
"@types/node": "20.19.43",
|
|
79
|
+
"clipper2-ts": "2.0.1-18",
|
|
80
|
+
"esbuild": "0.25.12",
|
|
81
|
+
"marked": "15.0.12",
|
|
82
|
+
"opentype.js": "1.3.4",
|
|
83
|
+
"prettier": "3.6.2",
|
|
84
|
+
"typescript": "5.9.3"
|
|
85
|
+
},
|
|
86
|
+
"homepage": "https://kerfscript.mylasertools.com"
|
|
87
|
+
}
|