@mylasertools/kerfscript 0.2.0 → 0.2.1
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 +18 -0
- package/CLA.md +8 -5
- package/COMMERCIAL-LICENSE.md +23 -28
- package/LANGUAGE.md +149 -46
- package/README.md +68 -29
- package/THIRD-PARTY-NOTICES.md +55 -0
- package/TRADEMARKS.md +16 -10
- package/dist/cli.js +273 -83
- package/dist/evaluator.d.cts +23 -0
- package/dist/evaluator.d.ts +23 -0
- package/dist/export/svg.d.cts +2 -0
- package/dist/export/svg.d.ts +2 -0
- package/dist/index.cjs +14 -14
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +14 -14
- package/dist/render.d.cts +2 -1
- package/dist/render.d.ts +2 -1
- package/docs/cli.md +43 -28
- package/docs/compatibility.md +40 -65
- package/docs/customizer.md +40 -28
- package/docs/getting-started.md +48 -31
- package/docs/javascript.md +106 -51
- package/docs/kerf.md +36 -39
- package/docs/layers.md +71 -37
- package/docs/openscad.md +52 -48
- package/docs/parts-and-sheets.md +45 -31
- package/docs/versions.md +20 -30
- package/package.json +5 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.1
|
|
4
|
+
|
|
5
|
+
- Memory limits, so a program cannot make a browser tab run out of memory:
|
|
6
|
+
part copies, circle segments and polygon corners, list and string sizes,
|
|
7
|
+
all list items together, `text()` length, shape points, exported points
|
|
8
|
+
and sheets. Each stops the program with an error that says what to change.
|
|
9
|
+
Defaults are in `DEFAULT_LIMITS` and the `limits` render option changes
|
|
10
|
+
them. Every example stays well under them.
|
|
11
|
+
- A list or string that grows past what JavaScript can hold now gives a
|
|
12
|
+
KerfScript error instead of a `RangeError`.
|
|
13
|
+
- Lists are checked while they are built, so `each` in a long loop, list
|
|
14
|
+
arithmetic and matrix products stop at the limit instead of first filling
|
|
15
|
+
memory. Strings joined with `+`, strings from functions and `echo()` text
|
|
16
|
+
count toward `maxListItems` too, and a repeated unknown argument warning
|
|
17
|
+
is shown once.
|
|
18
|
+
- The commercial licence for closed-source apps and services is free: email
|
|
19
|
+
hi@mylasertools.com.
|
|
20
|
+
|
|
3
21
|
## 0.2.0 (2026-10-28)
|
|
4
22
|
|
|
5
23
|
First public release.
|
package/CLA.md
CHANGED
|
@@ -7,9 +7,12 @@ Thank you for contributing to KerfScript. This agreement lets MyLaserTools
|
|
|
7
7
|
commercial licences, including licences we may sell. You keep the copyright in
|
|
8
8
|
your contribution.
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
This agreement applies to a Contribution when you add the signature
|
|
11
|
+
statement below to the pull request that contains it. A Contribution is
|
|
12
|
+
material you intentionally submit in that signed pull request for inclusion
|
|
13
|
+
in KerfScript. Issue reports, ideas, unsigned pull requests and other
|
|
14
|
+
communications do not grant rights under this agreement. Sign each pull
|
|
15
|
+
request you want us to consider for inclusion.
|
|
13
16
|
|
|
14
17
|
## 1. Copyright licence
|
|
15
18
|
|
|
@@ -62,12 +65,12 @@ trademarks.
|
|
|
62
65
|
|
|
63
66
|
## How to sign
|
|
64
67
|
|
|
65
|
-
Add this
|
|
68
|
+
Add this statement to each pull request description, using your legal name:
|
|
66
69
|
|
|
67
70
|
```text
|
|
68
71
|
I have read the KerfScript CLA 1.0 and agree to it for my contributions.
|
|
69
72
|
Name: <your name> GitHub: <your handle> Date: <YYYY-MM-DD>
|
|
70
73
|
```
|
|
71
74
|
|
|
72
|
-
If You contribute on behalf of a company, contact
|
|
75
|
+
If You contribute on behalf of a company, contact hi@mylasertools.com for
|
|
73
76
|
the company version first.
|
package/COMMERCIAL-LICENSE.md
CHANGED
|
@@ -1,35 +1,24 @@
|
|
|
1
1
|
# Licensing
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2026 MyLaserTools.
|
|
3
|
+
Copyright (c) 2026 MyLaserTools.
|
|
4
|
+
|
|
5
|
+
**KerfScript is free to use, including for commercial work.** Write programs,
|
|
6
|
+
cut and sell what you make, and sell your `.kerf` designs and the files they
|
|
7
|
+
produce. You don't need to ask us for any of that.
|
|
4
8
|
|
|
5
9
|
KerfScript is dual licensed. You can use it under **either**:
|
|
6
10
|
|
|
7
11
|
1. **The GNU Affero General Public License, version 3 only** (`AGPL-3.0-only`,
|
|
8
12
|
full text in [LICENSE](LICENSE)), together with the additional permission
|
|
9
13
|
below, or
|
|
10
|
-
2. **A commercial licence** from MyLaserTools
|
|
11
|
-
|
|
12
|
-
## What the AGPL means for you
|
|
14
|
+
2. **A commercial licence** from MyLaserTools, which is **free**.
|
|
13
15
|
|
|
14
|
-
Free
|
|
15
|
-
|
|
16
|
-
- write KerfScript programs and cut, sell or share what you make with them
|
|
17
|
-
- use the `kerf` command line tool, or the library inside software you only run
|
|
18
|
-
for yourself
|
|
19
|
-
- build open source software on KerfScript and publish its complete source code
|
|
20
|
-
under the AGPL
|
|
16
|
+
## Free commercial licence
|
|
21
17
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
not want to publish that service's complete source code under the AGPL
|
|
27
|
-
- want to change KerfScript without sharing your changes
|
|
28
|
-
|
|
29
|
-
The AGPL treats letting people use the software over a network like
|
|
30
|
-
distributing it: if you modify KerfScript or build it into a service that
|
|
31
|
-
others use, you must offer those users the complete corresponding source code
|
|
32
|
-
of the whole program under the AGPL.
|
|
18
|
+
Want to build KerfScript into a closed-source app, plugin, machine, firmware
|
|
19
|
+
or online service? The commercial licence costs nothing. Just email
|
|
20
|
+
hi@mylasertools.com with your name or company and what you are building, and
|
|
21
|
+
we will send it to you.
|
|
33
22
|
|
|
34
23
|
## Additional permission: your designs are yours
|
|
35
24
|
|
|
@@ -45,15 +34,21 @@ that:
|
|
|
45
34
|
|
|
46
35
|
This permission covers your programs and their output only. It does not cover
|
|
47
36
|
the KerfScript interpreter, its tools, or modified copies of the standard
|
|
48
|
-
library, which remain under the AGPL.
|
|
37
|
+
library, which remain under the AGPL unless you have the commercial licence.
|
|
49
38
|
|
|
50
|
-
##
|
|
39
|
+
## What the AGPL means for you
|
|
51
40
|
|
|
52
|
-
|
|
53
|
-
terms: closed source use, use in hosted services, private modifications and
|
|
54
|
-
support options. Terms and pricing are set per agreement.
|
|
41
|
+
Under the AGPL you can:
|
|
55
42
|
|
|
56
|
-
|
|
43
|
+
- write KerfScript programs and cut, sell or share what you make with them
|
|
44
|
+
- run the interpreter, including a modified copy, privately or in internal
|
|
45
|
+
tools without publishing those private changes
|
|
46
|
+
- use an unmodified copy on a server
|
|
47
|
+
- distribute software that includes KerfScript, as long as you share its
|
|
48
|
+
source code under the AGPL
|
|
49
|
+
|
|
50
|
+
If you would rather not share your source code, ask for the free commercial
|
|
51
|
+
licence.
|
|
57
52
|
|
|
58
53
|
## Trademarks
|
|
59
54
|
|
package/LANGUAGE.md
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
# KerfScript language reference
|
|
2
2
|
|
|
3
3
|
Language version 0.1. Copyright (c) 2026 MyLaserTools. This document is
|
|
4
|
-
licensed under [CC BY
|
|
4
|
+
licensed under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/).
|
|
5
5
|
"KerfScript" is a trademark of MyLaserTools, see [TRADEMARKS.md](TRADEMARKS.md).
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
group them into **parts**, and the renderer compensates for the **kerf**, packs
|
|
10
|
-
parts onto **sheets** and writes SVG or DXF.
|
|
7
|
+
This reference covers KerfScript syntax, built-in modules and functions.
|
|
8
|
+
For a first project, follow [Getting started](docs/getting-started.md).
|
|
11
9
|
|
|
12
|
-
|
|
10
|
+
Programs build 2D shapes, assign them to cut, score or engrave layers, and
|
|
11
|
+
group them into parts. Rendering applies kerf compensation, arranges the
|
|
12
|
+
parts on sheets and produces SVG or DXF files.
|
|
13
|
+
|
|
14
|
+
Lengths are in millimetres and angles are in degrees. Positive x points
|
|
15
|
+
right; positive y points up.
|
|
13
16
|
|
|
14
17
|
```kerf
|
|
15
18
|
// A coaster with a hole, an engraved ring and a scored border.
|
|
@@ -49,7 +52,8 @@ Points are lists `[x, y]`. `p.x` and `p.y` read the first two items.
|
|
|
49
52
|
|
|
50
53
|
## Expressions
|
|
51
54
|
|
|
52
|
-
|
|
55
|
+
Operators are listed from lowest to highest precedence. Use parentheses
|
|
56
|
+
to change the order of evaluation.
|
|
53
57
|
|
|
54
58
|
| Operator | Meaning |
|
|
55
59
|
| ------------------- | -------------------------------------------------------------------------------------------------------------- |
|
|
@@ -64,14 +68,19 @@ From lowest to highest precedence:
|
|
|
64
68
|
| `a ^ b` | power, right associative and tighter than unary minus |
|
|
65
69
|
| `f(x)` `a[i]` `a.x` | call, index, member |
|
|
66
70
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
71
|
+
Unsupported combinations, such as a list plus a number or `undef + 1`,
|
|
72
|
+
produce an error at the source line.
|
|
73
|
+
|
|
74
|
+
In conditions, `false`, `0`, `""`, `[]` and `undef` count as false.
|
|
70
75
|
|
|
71
|
-
`let (a = 1, b = a + 1) expr`
|
|
76
|
+
Use `let (a = 1, b = a + 1) expr` to define names for one expression.
|
|
77
|
+
Each binding can use the ones before it.
|
|
72
78
|
|
|
73
79
|
### List comprehensions
|
|
74
80
|
|
|
81
|
+
Build a list with `for`, filter items with `if`, or insert the contents of
|
|
82
|
+
another list with `each`:
|
|
83
|
+
|
|
75
84
|
```kerf
|
|
76
85
|
squares = [for (i = [1:5]) i * i];
|
|
77
86
|
odd = [for (i = [1:9]) if (i % 2) i];
|
|
@@ -81,6 +90,10 @@ flat = [each [1, 2], 3];
|
|
|
81
90
|
|
|
82
91
|
## Statements
|
|
83
92
|
|
|
93
|
+
Assignments and function definitions end with a semicolon. Modules create
|
|
94
|
+
geometry and can receive child statements. In the syntax below, `...`
|
|
95
|
+
stands for the body of a statement:
|
|
96
|
+
|
|
84
97
|
```kerf
|
|
85
98
|
name = expr; // assignment
|
|
86
99
|
function name(a, b = 2) = expr; // function
|
|
@@ -111,13 +124,15 @@ Arguments can be positional or named: `rect([20, 10], r = 2)`.
|
|
|
111
124
|
|
|
112
125
|
### Modifiers
|
|
113
126
|
|
|
114
|
-
|
|
115
|
-
layer
|
|
127
|
+
Place `*` before a module call to disable it. Use `#` or `%` to move its
|
|
128
|
+
geometry to the guide layer. Guides are included only when requested in
|
|
129
|
+
the render options.
|
|
116
130
|
|
|
117
131
|
### children()
|
|
118
132
|
|
|
119
|
-
Inside a module, `children()` renders
|
|
120
|
-
|
|
133
|
+
Inside a module, `children()` renders all child statements passed by the
|
|
134
|
+
caller. `children(i)` selects one child, using a zero-based index.
|
|
135
|
+
`$children` is the number of children.
|
|
121
136
|
|
|
122
137
|
```kerf
|
|
123
138
|
module hang_hole(d = 5) {
|
|
@@ -142,7 +157,7 @@ module hang_hole(d = 5) {
|
|
|
142
157
|
|
|
143
158
|
Every shape is on a layer. Shapes not wrapped in a layer module are on `cut`.
|
|
144
159
|
|
|
145
|
-
| Layer | Mode | Colour |
|
|
160
|
+
| Layer | Mode | Colour | Intended operation |
|
|
146
161
|
| --------- | ----- | --------- | ---------------------------------------------------- |
|
|
147
162
|
| `engrave` | fill | `#000000` | the area is engraved |
|
|
148
163
|
| `score` | line | `#0000ff` | lines and shape outlines are marked, not cut through |
|
|
@@ -154,11 +169,14 @@ cut() ... engrave() ... score() ... guide() ...
|
|
|
154
169
|
layer("pocket", mode = "fill", color = "#00aa00") ...
|
|
155
170
|
```
|
|
156
171
|
|
|
157
|
-
`layer(name, mode, color)`
|
|
158
|
-
`"fill"`
|
|
159
|
-
cut, guide, so machines engrave before cutting.
|
|
172
|
+
Use `layer(name, mode, color)` to define a custom layer. Its mode is
|
|
173
|
+
`"cut"`, `"line"`, `"fill"` or `"guide"`.
|
|
160
174
|
|
|
161
|
-
|
|
175
|
+
Files list layers in this order: engrave, custom layers, score, cut, guide.
|
|
176
|
+
Set the actual operation order, power and speed in your laser software.
|
|
177
|
+
See [Laser software](docs/compatibility.md) for import details.
|
|
178
|
+
|
|
179
|
+
When a part is rendered:
|
|
162
180
|
|
|
163
181
|
- The part's **material** is the union of its cut layer shapes.
|
|
164
182
|
- Engrave, score and custom layers are clipped to the material, so nothing is
|
|
@@ -170,6 +188,9 @@ Rules applied when a part is finished:
|
|
|
170
188
|
|
|
171
189
|
## Parts and sheets
|
|
172
190
|
|
|
191
|
+
Use `part()` to name a component and set its quantity. Wrap parts in
|
|
192
|
+
`material()` when they share a thickness, kerf and material name:
|
|
193
|
+
|
|
173
194
|
```kerf
|
|
174
195
|
material(thickness = 4, kerf = 0.12, name = "birch") {
|
|
175
196
|
part("side", qty = 2) finger_rect([100, 60], "out");
|
|
@@ -182,9 +203,12 @@ material(thickness = 4, kerf = 0.12, name = "birch") {
|
|
|
182
203
|
- Shapes outside any part form one part named `part`.
|
|
183
204
|
- `material(thickness, kerf, name) { ... }` sets those special variables for
|
|
184
205
|
its children.
|
|
185
|
-
- With `$layout = "pack"
|
|
186
|
-
`qty` times
|
|
187
|
-
|
|
206
|
+
- With `$layout = "pack"`, parts are grouped by material and thickness and
|
|
207
|
+
repeated `qty` times. They are arranged in rows on sheets of `$sheet` and
|
|
208
|
+
may be rotated 90° to fit. Parts larger than the sheet produce a warning.
|
|
209
|
+
|
|
210
|
+
See [Parts and sheets](docs/parts-and-sheets.md) for spacing, layout and
|
|
211
|
+
export examples.
|
|
188
212
|
|
|
189
213
|
## Built-in modules
|
|
190
214
|
|
|
@@ -204,11 +228,20 @@ material(thickness = 4, kerf = 0.12, name = "birch") {
|
|
|
204
228
|
| `polyline(points, closed = false)` | |
|
|
205
229
|
| `arc(r, start = 0, end = 90)` | arc line, angles in degrees |
|
|
206
230
|
|
|
231
|
+
Supply geometry as children of a shape-processing module, for example
|
|
232
|
+
`translate([10, 0]) circle(d = 5);`. Fonts used by `text()` must be supplied
|
|
233
|
+
by the application or through the [command line](docs/cli.md).
|
|
234
|
+
|
|
207
235
|
### Transforms
|
|
208
236
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
237
|
+
| Module | Effect |
|
|
238
|
+
| --- | --- |
|
|
239
|
+
| `translate([x, y])` | Move geometry by x and y |
|
|
240
|
+
| `rotate(a, center = [x, y])` | Rotate by `a` degrees around a point; the default centre is the origin |
|
|
241
|
+
| `scale(s)` | Scale both axes by the same factor |
|
|
242
|
+
| `scale([sx, sy])` | Scale each axis separately |
|
|
243
|
+
| `mirror([nx, ny])` | Reflect across a line through the origin, perpendicular to this vector |
|
|
244
|
+
| `multmatrix(m)` | Apply a 2 × 3 transformation matrix |
|
|
212
245
|
|
|
213
246
|
### Combining
|
|
214
247
|
|
|
@@ -233,31 +266,80 @@ origin with that normal), `multmatrix(m)` with a 2x3 matrix.
|
|
|
233
266
|
|
|
234
267
|
### Other
|
|
235
268
|
|
|
236
|
-
|
|
237
|
-
|
|
269
|
+
| Module | Effect |
|
|
270
|
+
| --- | --- |
|
|
271
|
+
| `echo(...)` | Report values without creating geometry |
|
|
272
|
+
| `assert(cond, message)` | Stop with `message` when `cond` is false |
|
|
273
|
+
| `children(i)` | Render a child passed to the current module; omit `i` to render all children |
|
|
238
274
|
|
|
239
275
|
## Built-in functions
|
|
240
276
|
|
|
241
|
-
|
|
242
|
-
|
|
277
|
+
Functions return values. The examples below use positional arguments.
|
|
278
|
+
|
|
279
|
+
### Numbers and vectors
|
|
280
|
+
|
|
281
|
+
| Function | Result |
|
|
282
|
+
| --- | --- |
|
|
283
|
+
| `abs(x)`, `sign(x)` | Absolute value, or sign as -1, 0 or 1 |
|
|
284
|
+
| `floor(x)`, `ceil(x)`, `round(x)` | Round down, up or to the nearest integer |
|
|
285
|
+
| `sqrt(x)`, `pow(x, y)` | Square root, or x raised to y |
|
|
286
|
+
| `exp(x)`, `ln(x)` | Exponential with base e, or natural logarithm |
|
|
287
|
+
| `log(x)`, `log(base, x)` | Base-10 logarithm, or logarithm with a chosen base |
|
|
288
|
+
| `sin(a)`, `cos(a)`, `tan(a)` | Trigonometric functions with angles in degrees |
|
|
289
|
+
| `asin(x)`, `acos(x)`, `atan(x)`, `atan2(y, x)` | Inverse trigonometric functions, returning degrees |
|
|
290
|
+
| `min(values)`, `max(values)` | Minimum or maximum of a list; also accept separate values |
|
|
291
|
+
| `clamp(x, low, high)` | Limit x to the given interval |
|
|
292
|
+
| `lerp(a, b, t)` | Interpolate between numbers or vectors; t = 0 gives a, t = 1 gives b |
|
|
293
|
+
| `norm(v)` | Length of a vector |
|
|
294
|
+
| `cross(a, b)` | Cross product; a scalar for 2D vectors or a vector for 3D vectors |
|
|
295
|
+
|
|
296
|
+
### Lists and strings
|
|
297
|
+
|
|
298
|
+
| Function | Result |
|
|
299
|
+
| --- | --- |
|
|
300
|
+
| `len(value)` | Number of items in a list or characters in a string |
|
|
301
|
+
| `concat(...)` | Join lists and individual values into one list |
|
|
302
|
+
| `reverse(value)` | Reverse a list or string |
|
|
303
|
+
| `sum(values)` | Sum a list of numbers |
|
|
304
|
+
| `slice(value, start = 0, end)` | Extract part of a list or string; `end` is exclusive and defaults to its length |
|
|
305
|
+
| `str(...)` | Convert values to text and join them |
|
|
306
|
+
| `chr(...)`, `ord(text)` | Convert Unicode code points to text, or read the first character's code point |
|
|
307
|
+
| `upper(text)`, `lower(text)` | Change letter case |
|
|
308
|
+
| `split(text, separator = " ")` | Split text into a list of strings |
|
|
309
|
+
| `join(values, separator = "")` | Join values into a string |
|
|
310
|
+
| `search(value, list)` | Index of the first equal item, or `undef` if absent; also searches characters in strings |
|
|
311
|
+
| `contains(value, item)` | Whether a list contains an item or a string contains a substring |
|
|
312
|
+
| `lookup(x, table)` | Interpolate in a table of `[x, y]` pairs; use the nearest endpoint outside the table's range |
|
|
313
|
+
|
|
314
|
+
### Types
|
|
315
|
+
|
|
316
|
+
`is_num(value)`, `is_string(value)`, `is_bool(value)`, `is_list(value)`,
|
|
317
|
+
`is_undef(value)` and `is_function(value)` return a boolean.
|
|
318
|
+
`type_of(value)` returns the type name as a string.
|
|
319
|
+
|
|
320
|
+
### Random values
|
|
321
|
+
|
|
322
|
+
`rands(min, max, count, seed = 1)` returns a list of numbers between the
|
|
323
|
+
bounds. The same seed gives the same sequence.
|
|
243
324
|
|
|
244
|
-
|
|
245
|
-
join search contains lookup`.
|
|
325
|
+
### Text measurements
|
|
246
326
|
|
|
247
|
-
|
|
327
|
+
`text_width(text, size, font)` returns the advance width, including glyph
|
|
328
|
+
spacing. `text_metrics(text, size, font)` returns
|
|
329
|
+
`[advance, [[x0, y0], [x1, y1]], ascent, descent]`.
|
|
248
330
|
|
|
249
|
-
|
|
331
|
+
Both require the font to be available to the renderer, just like `text()`.
|
|
250
332
|
|
|
251
|
-
|
|
252
|
-
`text_metrics(text, size, font)` returns `[advance, [[x0, y0], [x1, y1]], ascent, descent]`.
|
|
333
|
+
### Joint dimensions
|
|
253
334
|
|
|
254
|
-
|
|
255
|
-
`finger_rect`
|
|
335
|
+
`finger_count(length, finger)` returns the odd finger count used by
|
|
336
|
+
`finger_rect()` for an edge of that length.
|
|
256
337
|
|
|
257
338
|
## Customizer comments
|
|
258
339
|
|
|
259
|
-
Top-level assignments with a
|
|
260
|
-
|
|
340
|
+
Top-level assignments with a literal number, string, boolean or numeric
|
|
341
|
+
list can appear as editable settings. Comments supply captions, ranges,
|
|
342
|
+
choices and groups:
|
|
261
343
|
|
|
262
344
|
```kerf
|
|
263
345
|
/* [Size] */ // group for the following parameters
|
|
@@ -269,12 +351,13 @@ count = 3; // [2, 3, 4] choices
|
|
|
269
351
|
/* [Hidden] */ // not listed
|
|
270
352
|
```
|
|
271
353
|
|
|
272
|
-
|
|
273
|
-
|
|
354
|
+
These comments follow OpenSCAD's customizer format. Read
|
|
355
|
+
[Settings](docs/customizer.md) for supported controls, or use `kerf params`
|
|
356
|
+
to inspect the settings in a file.
|
|
274
357
|
|
|
275
358
|
## Standard library
|
|
276
359
|
|
|
277
|
-
`use <kerf/box>`:
|
|
360
|
+
Load the box modules with `use <kerf/box>`:
|
|
278
361
|
|
|
279
362
|
- `box([w, d, h], lid = false, finger)` makes the six (or five) panels of a
|
|
280
363
|
finger-jointed box as parts `bottom`, `lid`, `front`, `back`, `left`,
|
|
@@ -290,6 +373,26 @@ KerfScript parameters.
|
|
|
290
373
|
|
|
291
374
|
## Limits
|
|
292
375
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
376
|
+
The interpreter limits call depth to 1,000 for modules and 2,000 for
|
|
377
|
+
functions. Expanded ranges are limited to 1,000,000 items. The default
|
|
378
|
+
evaluation limit is 5,000,000 steps; applications can change it with
|
|
379
|
+
`maxSteps`. Exceeding a limit stops evaluation with an error.
|
|
380
|
+
|
|
381
|
+
Programs are also limited in how much memory they can ask for:
|
|
382
|
+
|
|
383
|
+
| Limit | Default | What it counts |
|
|
384
|
+
| --- | --- | --- |
|
|
385
|
+
| `maxParts` | 10,000 | copies of all parts, adding up every `qty` |
|
|
386
|
+
| `maxSegments` | 10,000 | segments in one circle, ellipse or arc, and corners in one polygon |
|
|
387
|
+
| `maxListLength` | 1,000,000 | items in one list, or characters in one string |
|
|
388
|
+
| `maxListItems` | 3,000,000 | items in all lists the program builds, plus 4 for each list, one for every 8 characters of the strings it builds or echoes |
|
|
389
|
+
| `maxTextLength` | 2,000 | characters in one `text()` |
|
|
390
|
+
| `maxPoints` | 2,000,000 | points in all shapes the modules make, plus 100 for each shape |
|
|
391
|
+
| `maxOutputPoints` | 1,000,000 | points in the exported files, counting every copy |
|
|
392
|
+
| `maxSheets` | 200 | sheets in the layout |
|
|
393
|
+
|
|
394
|
+
Applications can change them with the `limits` render option.
|
|
395
|
+
|
|
396
|
+
Geometry operations also take time. Applications that render user programs
|
|
397
|
+
should run them in a worker with a timeout; see the
|
|
398
|
+
[JavaScript API](docs/javascript.md#running-untrusted-code).
|
package/README.md
CHANGED
|
@@ -1,17 +1,38 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://kerfscript.mylasertools.com"><img src=".github/readme/banner.png" alt="KerfScript, a programming language for laser cutting" width="840"></a>
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://www.npmjs.com/package/@mylasertools/kerfscript"><img src="https://img.shields.io/npm/v/@mylasertools/kerfscript?color=d8361f&label=npm" alt="npm version"></a>
|
|
7
|
+
<a href="COMMERCIAL-LICENSE.md"><img src="https://img.shields.io/badge/licence-AGPL--3.0%20or%20free%20commercial-1f1a17" alt="Licence: AGPL-3.0 or free commercial"></a>
|
|
8
|
+
<a href="LANGUAGE.md"><img src="https://img.shields.io/badge/language-0.1-e3c69a" alt="Language version 0.1"></a>
|
|
9
|
+
<a href="https://kerfscript.mylasertools.com/playground/"><img src="https://img.shields.io/badge/try%20it-playground-5a3519" alt="Try it in the playground"></a>
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
<p align="center">
|
|
13
|
+
<a href="https://kerfscript.mylasertools.com">Website</a> ·
|
|
14
|
+
<a href="https://kerfscript.mylasertools.com/playground/">Playground</a> ·
|
|
15
|
+
<a href="https://kerfscript.mylasertools.com/models/">Models</a> ·
|
|
16
|
+
<a href="https://kerfscript.mylasertools.com/docs/">Docs</a> ·
|
|
17
|
+
<a href="https://www.npmjs.com/package/@mylasertools/kerfscript">npm</a>
|
|
18
|
+
</p>
|
|
9
19
|
|
|
10
20
|
Write a part once as code, change a number, and get a new cut file. KerfScript
|
|
11
21
|
is to laser cutters what OpenSCAD is to 3D printers, except it was designed for
|
|
12
22
|
flat parts from the start: cut, score and engrave layers, kerf compensation,
|
|
13
23
|
finger joints, living hinges, parts and sheets are part of the language.
|
|
14
24
|
|
|
25
|
+
<p align="center">
|
|
26
|
+
<a href="https://kerfscript.mylasertools.com/playground/?model=fractal-tree"><img src=".github/readme/playground.gif" alt="Moving a slider in the playground changes the number in the code and redraws the fractal tree" width="840"></a>
|
|
27
|
+
<br><sub>The <a href="https://kerfscript.mylasertools.com/playground/">playground</a> runs the interpreter in your browser. A comment after a number turns it into a slider.</sub>
|
|
28
|
+
</p>
|
|
29
|
+
|
|
30
|
+
## Example
|
|
31
|
+
|
|
32
|
+
<table>
|
|
33
|
+
<tr>
|
|
34
|
+
<td width="50%" valign="top">
|
|
35
|
+
|
|
15
36
|
```kerf
|
|
16
37
|
use <kerf/box>
|
|
17
38
|
|
|
@@ -28,6 +49,13 @@ $kerf = 0.15; // [0:0.01:0.5]
|
|
|
28
49
|
box([width, depth, height], lid = lid);
|
|
29
50
|
```
|
|
30
51
|
|
|
52
|
+
</td>
|
|
53
|
+
<td width="50%" valign="top">
|
|
54
|
+
<img src=".github/readme/model-box.png" alt="Six finger-jointed panels of a box, packed on a sheet">
|
|
55
|
+
</td>
|
|
56
|
+
</tr>
|
|
57
|
+
</table>
|
|
58
|
+
|
|
31
59
|
```sh
|
|
32
60
|
npx @mylasertools/kerfscript render box.kerf -o box.svg -D width=200
|
|
33
61
|
```
|
|
@@ -37,6 +65,35 @@ millimetre SVG with one layer per operation. Output is checked automatically
|
|
|
37
65
|
in Inkscape; see [docs/compatibility.md](docs/compatibility.md) for what has
|
|
38
66
|
and has not been tested in other laser software.
|
|
39
67
|
|
|
68
|
+
## Made with KerfScript
|
|
69
|
+
|
|
70
|
+
Every model is a file in [examples/](examples). Open one on the website to
|
|
71
|
+
turn it around in 3D, change its settings and download the SVG or DXF, or copy
|
|
72
|
+
it as the start of your own design.
|
|
73
|
+
|
|
74
|
+
<table>
|
|
75
|
+
<tr>
|
|
76
|
+
<td width="33%" valign="top"><a href="https://kerfscript.mylasertools.com/models/hadal/"><img src="site/public/3d/hadal.webp" alt="Hadal sculpture, assembled"></a><br><b><a href="https://kerfscript.mylasertools.com/models/hadal/">Hadal sculpture</a></b><br><sub>13 slotted parts, ribs computed from lists</sub></td>
|
|
77
|
+
<td width="33%" valign="top"><a href="https://kerfscript.mylasertools.com/models/tilt-maze/"><img src="site/public/3d/tilt-maze.webp" alt="Tilt maze, assembled"></a><br><b><a href="https://kerfscript.mylasertools.com/models/tilt-maze/">Tilt maze</a></b><br><sub>a new maze for every seed, by recursion</sub></td>
|
|
78
|
+
<td width="33%" valign="top"><a href="https://kerfscript.mylasertools.com/models/topo-island/"><img src="site/public/3d/topo-island.webp" alt="Layered island, assembled"></a><br><b><a href="https://kerfscript.mylasertools.com/models/topo-island/">Layered island</a></b><br><sub>contours traced from a height formula</sub></td>
|
|
79
|
+
</tr>
|
|
80
|
+
<tr>
|
|
81
|
+
<td width="33%" valign="top"><a href="https://kerfscript.mylasertools.com/models/fractal-tree/"><img src="site/public/3d/fractal-tree.webp" alt="Fractal tree, assembled"></a><br><b><a href="https://kerfscript.mylasertools.com/models/fractal-tree/">Fractal tree</a></b><br><sub>a module that calls itself</sub></td>
|
|
82
|
+
<td width="33%" valign="top"><a href="https://kerfscript.mylasertools.com/models/round-badge/"><img src="site/public/3d/round-badge.webp" alt="Round badge, assembled"></a><br><b><a href="https://kerfscript.mylasertools.com/models/round-badge/">Round badge</a></b><br><sub>text set letter by letter around a circle</sub></td>
|
|
83
|
+
<td width="33%" valign="top"><a href="https://kerfscript.mylasertools.com/models/winterlight/"><img src="site/public/3d/winterlight.webp" alt="Winterlight ornaments, assembled"></a><br><b><a href="https://kerfscript.mylasertools.com/models/winterlight/">Winterlight ornaments</a></b><br><sub>one-piece ornaments with scored detail</sub></td>
|
|
84
|
+
</tr>
|
|
85
|
+
<tr>
|
|
86
|
+
<td width="33%" valign="top"><a href="https://kerfscript.mylasertools.com/models/xenospora/"><img src="site/public/3d/xenospora.webp" alt="Xenospora seed pod, assembled"></a><br><b><a href="https://kerfscript.mylasertools.com/models/xenospora/">Xenospora seed pod</a></b><br><sub>16 parts on 3 sheets, one file per sheet</sub></td>
|
|
87
|
+
<td width="33%" valign="top"><a href="https://kerfscript.mylasertools.com/models/solstice/"><img src="site/public/3d/solstice.webp" alt="Solstice lantern, assembled"></a><br><b><a href="https://kerfscript.mylasertools.com/models/solstice/">Solstice lantern</a></b><br><sub>tabs, slots and a fit test piece</sub></td>
|
|
88
|
+
<td width="33%" valign="top"><a href="https://kerfscript.mylasertools.com/models/box/"><img src="site/public/3d/box.webp" alt="Finger-jointed box, assembled"></a><br><b><a href="https://kerfscript.mylasertools.com/models/box/">Finger-jointed box</a></b><br><sub>six panels from one library call</sub></td>
|
|
89
|
+
</tr>
|
|
90
|
+
<tr>
|
|
91
|
+
<td width="33%" valign="top"><a href="https://kerfscript.mylasertools.com/models/wave-cathedral/"><img src="site/public/3d/wave-cathedral.webp" alt="Wave Cathedral, assembled"></a><br><b><a href="https://kerfscript.mylasertools.com/models/wave-cathedral/">Wave Cathedral</a></b><br><sub>17 different ribs from one formula</sub></td>
|
|
92
|
+
<td width="33%" valign="top"><a href="https://kerfscript.mylasertools.com/models/gift-tags/"><img src="site/public/3d/gift-tags.webp" alt="Gift tags from a list, assembled"></a><br><b><a href="https://kerfscript.mylasertools.com/models/gift-tags/">Gift tags from a list</a></b><br><sub>one tag per name, each name fitted</sub></td>
|
|
93
|
+
<td width="33%" valign="top"><a href="https://kerfscript.mylasertools.com/models/umbra/"><img src="site/public/3d/umbra.webp" alt="Umbra shadow machine, assembled"></a><br><b><a href="https://kerfscript.mylasertools.com/models/umbra/">Umbra shadow machine</a></b><br><sub>six fins whose shadows make one dragon</sub></td>
|
|
94
|
+
</tr>
|
|
95
|
+
</table>
|
|
96
|
+
|
|
40
97
|
## Why a new language
|
|
41
98
|
|
|
42
99
|
- **Laser concepts are built in.** `engrave()`, `score()` and `cut()` put
|
|
@@ -107,25 +164,6 @@ Errors are thrown as `KerfError` with `line` and `col`.
|
|
|
107
164
|
- [examples/](examples): every model on the website, including a
|
|
108
165
|
calibration square and a kerf test
|
|
109
166
|
|
|
110
|
-
## Website
|
|
111
|
-
|
|
112
|
-
kerfscript.mylasertools.com is an Astro site in [site/](site), deployed to
|
|
113
|
-
Cloudflare as a static assets Worker. Every model picture and the guides are
|
|
114
|
-
built from [examples/](examples), [docs/](docs) and LANGUAGE.md by this
|
|
115
|
-
version of KerfScript.
|
|
116
|
-
|
|
117
|
-
```sh
|
|
118
|
-
npm --prefix site install
|
|
119
|
-
npm run site # build KerfScript, then the site into site/dist
|
|
120
|
-
npm run site:serve # preview on http://localhost:4321
|
|
121
|
-
npm --prefix site run deploy
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
## Checking output
|
|
125
|
-
|
|
126
|
-
`npm run compat` renders a reference set of models and opens every SVG and
|
|
127
|
-
DXF in Inkscape to check sizes, layers and fills.
|
|
128
|
-
|
|
129
167
|
## Community
|
|
130
168
|
|
|
131
169
|
Bug reports, cut reports and ideas are welcome; see
|
|
@@ -141,8 +179,9 @@ KerfScript is free software under the
|
|
|
141
179
|
that makes **your `.kerf` designs and the files KerfScript generates yours to
|
|
142
180
|
license and sell however you like**.
|
|
143
181
|
|
|
144
|
-
|
|
145
|
-
|
|
182
|
+
Building KerfScript into a closed-source app, machine or service? The
|
|
183
|
+
[commercial licence](COMMERCIAL-LICENSE.md#free-commercial-licence) is free:
|
|
184
|
+
just email hi@mylasertools.com.
|
|
146
185
|
|
|
147
186
|
"KerfScript" is a trademark of MyLaserTools; see [TRADEMARKS.md](TRADEMARKS.md).
|
|
148
187
|
Contributions need the [CLA](CLA.md); see [CONTRIBUTING.md](CONTRIBUTING.md).
|
package/THIRD-PARTY-NOTICES.md
CHANGED
|
@@ -62,6 +62,61 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
|
62
62
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
+
## tiny-inflate 1.0.3 (bundled, part of opentype.js)
|
|
66
|
+
|
|
67
|
+
Source: https://github.com/foliojs/tiny-inflate
|
|
68
|
+
|
|
69
|
+
```text
|
|
70
|
+
MIT License
|
|
71
|
+
|
|
72
|
+
Copyright (c) 2015-present Devon Govett
|
|
73
|
+
|
|
74
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
75
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
76
|
+
in the Software without restriction, including without limitation the rights
|
|
77
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
78
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
79
|
+
furnished to do so, subject to the following conditions:
|
|
80
|
+
|
|
81
|
+
The above copyright notice and this permission notice shall be included in all
|
|
82
|
+
copies or substantial portions of the Software.
|
|
83
|
+
|
|
84
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
85
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
86
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
87
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
88
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
89
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
90
|
+
SOFTWARE.
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## string.prototype.codepointat 0.2.1 (bundled, part of opentype.js)
|
|
94
|
+
|
|
95
|
+
Source: https://github.com/mathiasbynens/String.prototype.codePointAt
|
|
96
|
+
|
|
97
|
+
```text
|
|
98
|
+
Copyright Mathias Bynens <https://mathiasbynens.be/>
|
|
99
|
+
|
|
100
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
101
|
+
a copy of this software and associated documentation files (the
|
|
102
|
+
"Software"), to deal in the Software without restriction, including
|
|
103
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
104
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
105
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
106
|
+
the following conditions:
|
|
107
|
+
|
|
108
|
+
The above copyright notice and this permission notice shall be
|
|
109
|
+
included in all copies or substantial portions of the Software.
|
|
110
|
+
|
|
111
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
112
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
113
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
114
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
115
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
116
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
117
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
118
|
+
```
|
|
119
|
+
|
|
65
120
|
## Atkinson Hyperlegible (test fixture only, not published to npm)
|
|
66
121
|
|
|
67
122
|
`test/fixtures/AtkinsonHyperlegible-Regular.ttf`, Copyright 2020 Braille
|