@mylasertools/kerfscript 0.2.0 → 0.3.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 +97 -0
- package/CLA.md +8 -5
- package/COMMERCIAL-LICENSE.md +23 -28
- package/LANGUAGE.md +194 -60
- package/README.md +89 -39
- package/THIRD-PARTY-NOTICES.md +68 -4
- package/TRADEMARKS.md +16 -10
- package/dist/cli.js +773 -297
- package/dist/evaluator.d.cts +26 -0
- package/dist/evaluator.d.ts +26 -0
- package/dist/export/dxf.d.cts +1 -1
- package/dist/export/dxf.d.ts +1 -1
- package/dist/export/svg.d.cts +2 -0
- package/dist/export/svg.d.ts +2 -0
- package/dist/font.d.cts +3 -0
- package/dist/font.d.ts +3 -0
- package/dist/functions.d.cts +21 -2
- package/dist/functions.d.ts +21 -2
- 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/lexer.d.cts +4 -1
- package/dist/lexer.d.ts +4 -1
- package/dist/parser.d.cts +1 -1
- package/dist/parser.d.ts +1 -1
- package/dist/render.d.cts +3 -2
- package/dist/render.d.ts +3 -2
- package/dist/values.d.cts +10 -2
- package/dist/values.d.ts +10 -2
- package/dist/wasm.d.cts +1 -0
- package/dist/wasm.d.ts +1 -0
- package/docs/cli.md +69 -28
- package/docs/compatibility.md +40 -65
- package/docs/customizer.md +40 -28
- package/docs/desktop.md +96 -0
- package/docs/getting-started.md +48 -31
- package/docs/javascript.md +108 -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/docs/webassembly.md +131 -0
- package/fonts/OFL.txt +92 -0
- package/package.json +10 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,102 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.0 (2026-10-30)
|
|
4
|
+
|
|
5
|
+
- `kerfscript.wasm`: a WASI module that runs KerfScript from Python, Rust,
|
|
6
|
+
Go, C# and other languages. It takes a JSON request on standard input and
|
|
7
|
+
writes SVG, DXF, parts and warnings as JSON. `"command": "licenses"`
|
|
8
|
+
returns the licence texts of the module and of the JavaScript engine built
|
|
9
|
+
into it. Build it with `npm run wasm`; see
|
|
10
|
+
[docs/webassembly.md](docs/webassembly.md).
|
|
11
|
+
- A desktop app for Windows, macOS and Linux: the playground with `.kerf`
|
|
12
|
+
files on disk (Open, Save, Save as, double-click to open; Save as adds
|
|
13
|
+
`.kerf` to a name without it and asks before replacing a file of that
|
|
14
|
+
name), exports through a save dialog, `use`/`include` libraries read from
|
|
15
|
+
the design's folder and the folders below it (`.kerf` files only), and an
|
|
16
|
+
About window with the source link and the licences of everything in the
|
|
17
|
+
app. Saving writes the whole file before it replaces the old one, and the
|
|
18
|
+
app asks about unsaved changes before it closes, also on ⌘Q.
|
|
19
|
+
Installers: Windows setup and MSI, a universal macOS dmg, and an AppImage,
|
|
20
|
+
`.deb` and `.rpm` for Linux x64 and arm64; Flathub, winget, Chocolatey and
|
|
21
|
+
AUR manifests. See [docs/desktop.md](docs/desktop.md).
|
|
22
|
+
- Open in LightBurn in the desktop app: sends the cut file (or one sheet) to
|
|
23
|
+
LightBurn 2.2 or later through its REST API. KerfScript asks LightBurn only
|
|
24
|
+
for permission to send files, and talks to it directly, past any proxy
|
|
25
|
+
set on the computer.
|
|
26
|
+
- Chocolatey and MacPorts manifests for the command line.
|
|
27
|
+
- The playground does not load a shared link, draft or file longer than
|
|
28
|
+
1,000,000 characters, and stops unpacking a compressed link at that size.
|
|
29
|
+
Any code the editor runs fits in a link, whatever its script, and a link
|
|
30
|
+
that cannot be opened says why in the console. Code over the limit is not
|
|
31
|
+
coloured or read for settings, and Copy link refuses it. A link to an
|
|
32
|
+
empty design opens it, instead of the draft.
|
|
33
|
+
- Settings for a list, such as `size = [10, 20]`, keep numbers changed in the
|
|
34
|
+
code since the settings were drawn, instead of putting the old ones back.
|
|
35
|
+
An empty or half-typed number box leaves the code as it is.
|
|
36
|
+
- The playground renders the newest code after fast edits to a slow design,
|
|
37
|
+
instead of stopping with "Stopped after 15 seconds", and keeps working
|
|
38
|
+
when the number of sheets drops to one in the laser file view. Edits after
|
|
39
|
+
opening a shared link or moving a slider on an example are kept on reload.
|
|
40
|
+
- The website's licence page, and `assets/THIRD-PARTY-NOTICES.md` next to
|
|
41
|
+
`kerfscript.js`, have the notices of the libraries bundled in its
|
|
42
|
+
JavaScript.
|
|
43
|
+
- Standalone `kerf` binaries for Windows, macOS and Linux that need no
|
|
44
|
+
Node.js, with the licences of the Deno runtime built into them,
|
|
45
|
+
`kerfscript-cli` `.deb` and `.rpm` packages (which install next to the
|
|
46
|
+
desktop app), a Docker image, a snap, and Homebrew,
|
|
47
|
+
Scoop, winget and AUR manifests, all built by the release workflow with
|
|
48
|
+
SHA-256, SHA-512 and GPG signatures. Nightly builds go to a rolling
|
|
49
|
+
`nightly` prerelease. See RELEASING.md.
|
|
50
|
+
- A `kerf(1)` man page and a `text/x-kerfscript` MIME type for `*.kerf` files
|
|
51
|
+
in the Linux packages.
|
|
52
|
+
- The command line and `kerfscript.wasm` have a font built in, Atkinson
|
|
53
|
+
Hyperlegible as `Atkinson` (the playground's font), so `text()` works
|
|
54
|
+
without `--font`. The JavaScript library still takes fonts from the host.
|
|
55
|
+
- Memory limits, so a program cannot make a browser tab run out of memory:
|
|
56
|
+
part copies, circle segments and polygon corners, list and string sizes,
|
|
57
|
+
all list items together, `text()` length, shape points, exported points
|
|
58
|
+
and sheets. Each stops the program with an error that says what to change.
|
|
59
|
+
Defaults are in `DEFAULT_LIMITS` and the `limits` render option changes
|
|
60
|
+
them. Every example stays well under them. Ranges in loops and built-in
|
|
61
|
+
functions stop at `maxListLength` items, not at a fixed million.
|
|
62
|
+
- A list or string that grows past what JavaScript can hold now gives a
|
|
63
|
+
KerfScript error instead of a `RangeError`.
|
|
64
|
+
- Lists are checked while they are built, so `each` in a long loop, list
|
|
65
|
+
arithmetic and matrix products stop at the limit instead of first filling
|
|
66
|
+
memory. Strings joined with `+`, strings from functions and `echo()` text
|
|
67
|
+
count toward `maxListItems` too, and a repeated unknown argument warning
|
|
68
|
+
is shown once.
|
|
69
|
+
- `echo()`, `str()`, `join()` and `==` on lists that hold the same list many
|
|
70
|
+
times stop at the limits instead of running out of memory: text stops at
|
|
71
|
+
`maxListLength` characters while it is written, and comparing lists does
|
|
72
|
+
not compare the same pair of lists twice. Error messages, part names and
|
|
73
|
+
other settings show only the start of a long list.
|
|
74
|
+
- Comparing lists, dot products and built-in functions that go through a list
|
|
75
|
+
or string, such as `search()`, `contains()`, `max()` and `sum()`, take a
|
|
76
|
+
step for each item, so a loop over a long list stops at `maxSteps` instead
|
|
77
|
+
of running for minutes.
|
|
78
|
+
- `hull()` around named parts makes the hull of each part, the same as
|
|
79
|
+
`hull()` inside the part. It left the parts unchanged before.
|
|
80
|
+
- DXF layers whose names come out the same in DXF, such as `a b` and `a_b`,
|
|
81
|
+
stay separate layers: the later ones get `_2`, `_3` and so on. The
|
|
82
|
+
built-in layers keep `CUT`, `SCORE`, `ENGRAVE` and `GUIDE`.
|
|
83
|
+
- Built-in functions take named arguments, such as `sin(x = 30)` and
|
|
84
|
+
`pow(x = 2, y = 10)`; an unknown name gives a warning, and so does an
|
|
85
|
+
argument given both by position and by name. They were ignored before.
|
|
86
|
+
- Errors and warnings in a library name it, as in
|
|
87
|
+
`(line 3, column 5 in <lib/tabs>)`. The playground marks the line only for
|
|
88
|
+
errors in the program itself.
|
|
89
|
+
- `toString()`, `constructor()` and other names every JavaScript object has
|
|
90
|
+
are unknown functions and libraries, instead of a crash or a wrong value.
|
|
91
|
+
- `text_width()` and `text_metrics()` take a step per character, have the
|
|
92
|
+
same length limit as `text()`, and are much faster for long text.
|
|
93
|
+
- A list times a matrix of the wrong size, and `params` values that are not
|
|
94
|
+
numbers, strings, booleans or lists, are errors instead of a crash.
|
|
95
|
+
- A list times a list whose items multiply to lists is an error instead of
|
|
96
|
+
text.
|
|
97
|
+
- The commercial licence for closed-source apps and services is free: email
|
|
98
|
+
hi@mylasertools.com.
|
|
99
|
+
|
|
3
100
|
## 0.2.0 (2026-10-28)
|
|
4
101
|
|
|
5
102
|
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,22 @@ 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). The
|
|
234
|
+
playground, the command line and `kerfscript.wasm` have `Atkinson`
|
|
235
|
+
(Atkinson Hyperlegible) built in.
|
|
236
|
+
|
|
207
237
|
### Transforms
|
|
208
238
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
239
|
+
| Module | Effect |
|
|
240
|
+
| ---------------------------- | ---------------------------------------------------------------------- |
|
|
241
|
+
| `translate([x, y])` | Move geometry by x and y |
|
|
242
|
+
| `rotate(a, center = [x, y])` | Rotate by `a` degrees around a point; the default centre is the origin |
|
|
243
|
+
| `scale(v)` | Scale both axes by the number `v` |
|
|
244
|
+
| `scale([sx, sy])` | Scale each axis separately |
|
|
245
|
+
| `mirror([nx, ny])` | Reflect across a line through the origin, perpendicular to this vector |
|
|
246
|
+
| `multmatrix(m)` | Apply a 2 × 3 transformation matrix |
|
|
212
247
|
|
|
213
248
|
### Combining
|
|
214
249
|
|
|
@@ -217,7 +252,7 @@ origin with that normal), `multmatrix(m)` with a 2x3 matrix.
|
|
|
217
252
|
| `union()` / `group()` | joins children |
|
|
218
253
|
| `difference()` | removes every later child's area from every layer of the first child |
|
|
219
254
|
| `intersection()` | keeps only the area common to all children, layers of the first child kept |
|
|
220
|
-
| `hull()` | convex hull
|
|
255
|
+
| `hull()` | convex hull; each named part inside gets its own hull |
|
|
221
256
|
| `offset(r)` / `offset(delta, chamfer = false)` | grow (positive) or shrink areas; `r` rounds corners |
|
|
222
257
|
| `stroke(width)` | turns lines into areas of that width, for cutting single line art |
|
|
223
258
|
| `outline()` | turns areas into their outline lines |
|
|
@@ -233,48 +268,115 @@ origin with that normal), `multmatrix(m)` with a 2x3 matrix.
|
|
|
233
268
|
|
|
234
269
|
### Other
|
|
235
270
|
|
|
236
|
-
|
|
237
|
-
|
|
271
|
+
| Module | Effect |
|
|
272
|
+
| ---------------------------- | -------------------------------------------------------------------------------- |
|
|
273
|
+
| `echo(...)` | Report values without creating geometry |
|
|
274
|
+
| `assert(condition, message)` | Stop with `message` when `condition` is false |
|
|
275
|
+
| `children(index)` | Render a child passed to the current module; omit `index` to render all children |
|
|
238
276
|
|
|
239
277
|
## Built-in functions
|
|
240
278
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
`
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
`
|
|
279
|
+
Functions return values. Arguments can be positional or named with the
|
|
280
|
+
parameter names below, as in `pow(x = 2, y = 10)` or `log(8, base = 2)`. An
|
|
281
|
+
unknown name gives a warning. `concat`, `str` and `chr` take only positional
|
|
282
|
+
arguments.
|
|
283
|
+
|
|
284
|
+
### Numbers and vectors
|
|
285
|
+
|
|
286
|
+
| Function | Result |
|
|
287
|
+
| ---------------------------------------------- | -------------------------------------------------------------------- |
|
|
288
|
+
| `abs(x)`, `sign(x)` | Absolute value, or sign as -1, 0 or 1 |
|
|
289
|
+
| `floor(x)`, `ceil(x)`, `round(x)` | Round down, up or to the nearest integer |
|
|
290
|
+
| `sqrt(x)`, `pow(x, y)` | Square root, or x raised to y |
|
|
291
|
+
| `exp(x)`, `ln(x)` | Exponential with base e, or natural logarithm |
|
|
292
|
+
| `log(x)`, `log(base, x)` | Base-10 logarithm, or logarithm with a chosen base |
|
|
293
|
+
| `sin(x)`, `cos(x)`, `tan(x)` | Trigonometric functions with angles in degrees |
|
|
294
|
+
| `asin(x)`, `acos(x)`, `atan(x)`, `atan2(y, x)` | Inverse trigonometric functions, returning degrees |
|
|
295
|
+
| `min(values)`, `max(values)` | Minimum or maximum of a list; also accept separate values |
|
|
296
|
+
| `clamp(x, low, high)` | Limit x to the given interval |
|
|
297
|
+
| `lerp(a, b, t)` | Interpolate between numbers or vectors; t = 0 gives a, t = 1 gives b |
|
|
298
|
+
| `norm(v)` | Length of a vector |
|
|
299
|
+
| `cross(a, b)` | Cross product; a scalar for 2D vectors or a vector for 3D vectors |
|
|
300
|
+
|
|
301
|
+
### Lists and strings
|
|
302
|
+
|
|
303
|
+
| Function | Result |
|
|
304
|
+
| ------------------------------ | -------------------------------------------------------------------------------------------- |
|
|
305
|
+
| `len(value)` | Number of items in a list or characters in a string |
|
|
306
|
+
| `concat(...)` | Join lists and individual values into one list |
|
|
307
|
+
| `reverse(value)` | Reverse a list or string |
|
|
308
|
+
| `sum(values)` | Sum a list of numbers |
|
|
309
|
+
| `slice(value, start = 0, end)` | Extract part of a list or string; `end` is exclusive and defaults to its length |
|
|
310
|
+
| `str(...)` | Convert values to text and join them |
|
|
311
|
+
| `chr(...)`, `ord(text)` | Convert Unicode code points to text, or read the first character's code point |
|
|
312
|
+
| `upper(text)`, `lower(text)` | Change letter case |
|
|
313
|
+
| `split(text, separator = " ")` | Split text into a list of strings |
|
|
314
|
+
| `join(values, separator = "")` | Join values into a string |
|
|
315
|
+
| `search(value, list)` | Index of the first equal item, or `undef` if absent; also searches characters in strings |
|
|
316
|
+
| `contains(value, item)` | Whether a list contains an item or a string contains a substring |
|
|
317
|
+
| `lookup(x, table)` | Interpolate in a table of `[x, y]` pairs; use the nearest endpoint outside the table's range |
|
|
318
|
+
|
|
319
|
+
### Types
|
|
320
|
+
|
|
321
|
+
`is_num(value)`, `is_string(value)`, `is_bool(value)`, `is_list(value)`,
|
|
322
|
+
`is_undef(value)` and `is_function(value)` return a boolean.
|
|
323
|
+
`type_of(value)` returns the type name as a string.
|
|
324
|
+
|
|
325
|
+
### Random values
|
|
326
|
+
|
|
327
|
+
`rands(min, max, count, seed = 1)` returns a list of numbers between the
|
|
328
|
+
bounds. The same seed gives the same sequence.
|
|
329
|
+
|
|
330
|
+
### Text measurements
|
|
331
|
+
|
|
332
|
+
`text_width(text, size, font)` returns the advance width, including glyph
|
|
333
|
+
spacing. `text_metrics(text, size, font)` returns
|
|
334
|
+
`[advance, [[x0, y0], [x1, y1]], ascent, descent]`.
|
|
335
|
+
|
|
336
|
+
Both require the font to be available to the renderer, just like `text()`.
|
|
337
|
+
|
|
338
|
+
### Joint dimensions
|
|
339
|
+
|
|
340
|
+
`finger_count(length, finger)` returns the odd finger count used by
|
|
341
|
+
`finger_rect()` for an edge of that length.
|
|
256
342
|
|
|
257
343
|
## Customizer comments
|
|
258
344
|
|
|
259
|
-
Top-level assignments with a
|
|
260
|
-
|
|
345
|
+
Top-level assignments with a literal number, string, boolean or numeric
|
|
346
|
+
list can appear as editable settings. Comments supply captions, ranges,
|
|
347
|
+
choices and groups:
|
|
261
348
|
|
|
262
349
|
```kerf
|
|
263
|
-
/* [Size] */
|
|
264
|
-
// Outer width
|
|
265
|
-
width = 120; // [40:5:400]
|
|
266
|
-
depth = 80;
|
|
267
|
-
shape = "round"; // [round:Round, square:Square]
|
|
268
|
-
count = 3; // [2, 3, 4]
|
|
269
|
-
/* [Hidden] */
|
|
350
|
+
/* [Size] */
|
|
351
|
+
// Outer width
|
|
352
|
+
width = 120; // [40:5:400]
|
|
353
|
+
depth = 80; // [200]
|
|
354
|
+
shape = "round"; // [round:Round, square:Square]
|
|
355
|
+
count = 3; // [2, 3, 4]
|
|
356
|
+
/* [Hidden] */
|
|
357
|
+
seed = 7;
|
|
270
358
|
```
|
|
271
359
|
|
|
272
|
-
|
|
273
|
-
|
|
360
|
+
- `/* [Size] */` starts a group; the settings below it are listed under
|
|
361
|
+
_Size_.
|
|
362
|
+
- `// Outer width`, the comment line just above an assignment, is its caption.
|
|
363
|
+
- `[40:5:400]` is a slider from 40 to 400 in steps of 5; `[200]` is a slider
|
|
364
|
+
up to 200.
|
|
365
|
+
- `[round:Round, square:Square]` is a menu of values with labels; `[2, 3, 4]`
|
|
366
|
+
is a menu of values.
|
|
367
|
+
- Settings after `/* [Hidden] */` are not listed.
|
|
368
|
+
|
|
369
|
+
Nothing else may follow the brackets on the same line: with
|
|
370
|
+
`// [40:5:400] min:step:max` the setting is a plain number field, not a
|
|
371
|
+
slider.
|
|
372
|
+
|
|
373
|
+
These comments follow OpenSCAD's customizer format. Read
|
|
374
|
+
[Settings](docs/customizer.md) for supported controls, or use `kerf params`
|
|
375
|
+
to inspect the settings in a file.
|
|
274
376
|
|
|
275
377
|
## Standard library
|
|
276
378
|
|
|
277
|
-
`use <kerf/box>`:
|
|
379
|
+
Load the box modules with `use <kerf/box>`:
|
|
278
380
|
|
|
279
381
|
- `box([w, d, h], lid = false, finger)` makes the six (or five) panels of a
|
|
280
382
|
finger-jointed box as parts `bottom`, `lid`, `front`, `back`, `left`,
|
|
@@ -286,10 +388,42 @@ KerfScript parameters.
|
|
|
286
388
|
- **SVG**: millimetre units, one Inkscape layer group per KerfScript layer,
|
|
287
389
|
colours as above, 0.1 mm hairline strokes, `data-part` on every path.
|
|
288
390
|
- **DXF**: R12 (AC1009) polylines on layers named after KerfScript layers,
|
|
289
|
-
with matching AutoCAD colours.
|
|
391
|
+
with matching AutoCAD colours. Names are upper case with characters other
|
|
392
|
+
than letters, digits, `_` and `-` as `_`; when two layers come out the
|
|
393
|
+
same, the later one gets `_2`, `_3` and so on. The built-in layers keep
|
|
394
|
+
`CUT`, `SCORE`, `ENGRAVE` and `GUIDE`, so a layer of your own named `Cut`
|
|
395
|
+
becomes `CUT_2`.
|
|
290
396
|
|
|
291
397
|
## Limits
|
|
292
398
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
399
|
+
The interpreter limits call depth to 1,000 for modules and 2,000 for
|
|
400
|
+
functions. A range a loop or built-in function goes through is limited to
|
|
401
|
+
`maxListLength` items (below). The default
|
|
402
|
+
evaluation limit is 5,000,000 steps; applications can change it with
|
|
403
|
+
`maxSteps`. Comparing lists with `==`, multiplying two lists, and built-in
|
|
404
|
+
functions that go through a list or string take a step for each item;
|
|
405
|
+
`len()` of a list, `ord()`, `type_of()` and the `is_` functions take one.
|
|
406
|
+
Exceeding a limit stops evaluation with an error.
|
|
407
|
+
|
|
408
|
+
Programs are also limited in how much memory they can ask for:
|
|
409
|
+
|
|
410
|
+
| Limit | Default | What it counts |
|
|
411
|
+
| ----------------- | --------- | -------------------------------------------------------------------------------------------------------------------------- |
|
|
412
|
+
| `maxParts` | 10,000 | copies of all parts, adding up every `qty` |
|
|
413
|
+
| `maxSegments` | 10,000 | segments in one circle, ellipse or arc, and corners in one polygon |
|
|
414
|
+
| `maxListLength` | 1,000,000 | items in one list or range, or characters in one string, including the text `echo()` writes in one call |
|
|
415
|
+
| `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 |
|
|
416
|
+
| `maxTextLength` | 2,000 | characters in one `text()` |
|
|
417
|
+
| `maxPoints` | 2,000,000 | points in all shapes the modules make, plus 100 for each shape |
|
|
418
|
+
| `maxOutputPoints` | 1,000,000 | points in the exported files, counting every copy |
|
|
419
|
+
| `maxSheets` | 200 | sheets in the layout |
|
|
420
|
+
|
|
421
|
+
Applications can change them with the `limits` render option.
|
|
422
|
+
|
|
423
|
+
A list can hold the same list many times, as in `b = [a, a]`. `echo()`,
|
|
424
|
+
`str()` and `join()` write every copy out, so their text can be far longer
|
|
425
|
+
than the list; they stop with an error once it passes `maxListLength`.
|
|
426
|
+
|
|
427
|
+
Geometry operations also take time. Applications that render user programs
|
|
428
|
+
should run them in a worker with a timeout; see the
|
|
429
|
+
[JavaScript API](docs/javascript.md#running-untrusted-code).
|