@mylasertools/kerfscript 0.2.1 → 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 +81 -2
- package/LANGUAGE.md +95 -64
- package/README.md +21 -10
- package/THIRD-PARTY-NOTICES.md +13 -4
- package/dist/cli.js +529 -243
- package/dist/evaluator.d.cts +3 -0
- package/dist/evaluator.d.ts +3 -0
- package/dist/export/dxf.d.cts +1 -1
- package/dist/export/dxf.d.ts +1 -1
- 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 +11 -11
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +11 -11
- 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 +1 -1
- package/dist/render.d.ts +1 -1
- 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 +46 -20
- package/docs/compatibility.md +3 -3
- package/docs/customizer.md +9 -9
- package/docs/desktop.md +96 -0
- package/docs/javascript.md +29 -27
- package/docs/layers.md +6 -6
- package/docs/openscad.md +9 -9
- package/docs/versions.md +2 -2
- package/docs/webassembly.md +131 -0
- package/fonts/OFL.txt +92 -0
- package/package.json +6 -3
package/dist/lexer.d.cts
CHANGED
|
@@ -3,7 +3,9 @@ export interface Pos {
|
|
|
3
3
|
line: number;
|
|
4
4
|
col: number;
|
|
5
5
|
offset: number;
|
|
6
|
+
file?: string;
|
|
6
7
|
}
|
|
8
|
+
export declare const where: (pos: Pos, col?: boolean) => string;
|
|
7
9
|
export interface Token {
|
|
8
10
|
type: TokenType;
|
|
9
11
|
value: string;
|
|
@@ -20,9 +22,10 @@ export declare class KerfError extends Error {
|
|
|
20
22
|
col?: number;
|
|
21
23
|
echoes: string[];
|
|
22
24
|
missingFonts?: string[];
|
|
25
|
+
file?: string;
|
|
23
26
|
constructor(message: string, pos?: Pos);
|
|
24
27
|
}
|
|
25
|
-
export declare function tokenize(src: string): {
|
|
28
|
+
export declare function tokenize(src: string, file?: string): {
|
|
26
29
|
tokens: Token[];
|
|
27
30
|
comments: Comment[];
|
|
28
31
|
};
|
package/dist/lexer.d.ts
CHANGED
|
@@ -3,7 +3,9 @@ export interface Pos {
|
|
|
3
3
|
line: number;
|
|
4
4
|
col: number;
|
|
5
5
|
offset: number;
|
|
6
|
+
file?: string;
|
|
6
7
|
}
|
|
8
|
+
export declare const where: (pos: Pos, col?: boolean) => string;
|
|
7
9
|
export interface Token {
|
|
8
10
|
type: TokenType;
|
|
9
11
|
value: string;
|
|
@@ -20,9 +22,10 @@ export declare class KerfError extends Error {
|
|
|
20
22
|
col?: number;
|
|
21
23
|
echoes: string[];
|
|
22
24
|
missingFonts?: string[];
|
|
25
|
+
file?: string;
|
|
23
26
|
constructor(message: string, pos?: Pos);
|
|
24
27
|
}
|
|
25
|
-
export declare function tokenize(src: string): {
|
|
28
|
+
export declare function tokenize(src: string, file?: string): {
|
|
26
29
|
tokens: Token[];
|
|
27
30
|
comments: Comment[];
|
|
28
31
|
};
|
package/dist/parser.d.cts
CHANGED
package/dist/parser.d.ts
CHANGED
package/dist/render.d.cts
CHANGED
|
@@ -2,7 +2,7 @@ import { type LayerDef, type Limits } from './evaluator.cjs';
|
|
|
2
2
|
import { type LayerPath } from './export/svg.cjs';
|
|
3
3
|
import { type Layer } from './geometry.cjs';
|
|
4
4
|
import { type FontSource } from './text.cjs';
|
|
5
|
-
import type
|
|
5
|
+
import { type Value } from './values.cjs';
|
|
6
6
|
export interface RenderOptions {
|
|
7
7
|
params?: Record<string, Value>;
|
|
8
8
|
fonts?: Record<string, FontSource>;
|
package/dist/render.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { type LayerDef, type Limits } from './evaluator.js';
|
|
|
2
2
|
import { type LayerPath } from './export/svg.js';
|
|
3
3
|
import { type Layer } from './geometry.js';
|
|
4
4
|
import { type FontSource } from './text.js';
|
|
5
|
-
import type
|
|
5
|
+
import { type Value } from './values.js';
|
|
6
6
|
export interface RenderOptions {
|
|
7
7
|
params?: Record<string, Value>;
|
|
8
8
|
fonts?: Record<string, FontSource>;
|
package/dist/values.d.cts
CHANGED
|
@@ -16,10 +16,18 @@ export type Value = number | string | boolean | undefined | Value[] | Range | Cl
|
|
|
16
16
|
export declare const isRange: (v: Value) => v is Range;
|
|
17
17
|
export declare const isFn: (v: Value) => v is Closure;
|
|
18
18
|
export declare const isNum: (v: Value) => v is number;
|
|
19
|
+
export declare const own: <T>(o: Record<string, T> | undefined, key: string) => T | undefined;
|
|
20
|
+
export declare function checkSetting(name: string, v: unknown, depth?: number): void;
|
|
19
21
|
export declare function rangeValues(r: Range, limit: number): number[];
|
|
20
22
|
export declare function truthy(v: Value): boolean;
|
|
21
|
-
export declare function equals(a: Value, b: Value): boolean;
|
|
23
|
+
export declare function equals(a: Value, b: Value, step?: () => void): boolean;
|
|
22
24
|
export declare function typeName(v: Value): string;
|
|
25
|
+
export declare function write(v: Value, max: number, quote?: boolean): {
|
|
26
|
+
text: string;
|
|
27
|
+
whole: boolean;
|
|
28
|
+
};
|
|
29
|
+
export declare function joinText(vs: Value[], sep: string, max: number): string | undefined;
|
|
23
30
|
export declare function show(v: Value): string;
|
|
24
|
-
export declare
|
|
31
|
+
export declare const toText: (v: Value) => string;
|
|
32
|
+
export declare function toNumber(v: Value): number;
|
|
25
33
|
export declare function fmt(n: number): string;
|
package/dist/values.d.ts
CHANGED
|
@@ -16,10 +16,18 @@ export type Value = number | string | boolean | undefined | Value[] | Range | Cl
|
|
|
16
16
|
export declare const isRange: (v: Value) => v is Range;
|
|
17
17
|
export declare const isFn: (v: Value) => v is Closure;
|
|
18
18
|
export declare const isNum: (v: Value) => v is number;
|
|
19
|
+
export declare const own: <T>(o: Record<string, T> | undefined, key: string) => T | undefined;
|
|
20
|
+
export declare function checkSetting(name: string, v: unknown, depth?: number): void;
|
|
19
21
|
export declare function rangeValues(r: Range, limit: number): number[];
|
|
20
22
|
export declare function truthy(v: Value): boolean;
|
|
21
|
-
export declare function equals(a: Value, b: Value): boolean;
|
|
23
|
+
export declare function equals(a: Value, b: Value, step?: () => void): boolean;
|
|
22
24
|
export declare function typeName(v: Value): string;
|
|
25
|
+
export declare function write(v: Value, max: number, quote?: boolean): {
|
|
26
|
+
text: string;
|
|
27
|
+
whole: boolean;
|
|
28
|
+
};
|
|
29
|
+
export declare function joinText(vs: Value[], sep: string, max: number): string | undefined;
|
|
23
30
|
export declare function show(v: Value): string;
|
|
24
|
-
export declare
|
|
31
|
+
export declare const toText: (v: Value) => string;
|
|
32
|
+
export declare function toNumber(v: Value): number;
|
|
25
33
|
export declare function fmt(n: number): string;
|
package/dist/wasm.d.cts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/wasm.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/docs/cli.md
CHANGED
|
@@ -14,6 +14,30 @@ You can also run it through `npx`:
|
|
|
14
14
|
npx @mylasertools/kerfscript render box.kerf -o box.svg
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
+
## Without Node.js
|
|
18
|
+
|
|
19
|
+
The [releases](https://github.com/mylasertools/kerfscript/releases) page has a
|
|
20
|
+
standalone `kerf` for Windows, macOS and Linux (x64 and arm64) that needs no
|
|
21
|
+
Node.js: `kerf-<version>-<os>-<arch>.zip` or `.tar.gz`, and
|
|
22
|
+
`kerfscript-cli-<version>-linux-<arch>.deb` or `.rpm`. It has the
|
|
23
|
+
Atkinson Hyperlegible font built in, like the npm package.
|
|
24
|
+
|
|
25
|
+
| System | Install |
|
|
26
|
+
| ---------------- | ------------------------------------------------------------------------------------------------------------- |
|
|
27
|
+
| macOS, Linux | `brew install mylasertools/tap/kerfscript` |
|
|
28
|
+
| Windows | `winget install MyLaserTools.KerfScript.CLI`, or `choco install kerfscript` |
|
|
29
|
+
| Windows (Scoop) | `scoop bucket add mylasertools https://github.com/mylasertools/scoop-bucket`, then `scoop install kerfscript` |
|
|
30
|
+
| Linux (Snap) | `sudo snap install kerfscript`; the command is `kerfscript.kerf` |
|
|
31
|
+
| Arch Linux (AUR) | `kerfscript-bin` |
|
|
32
|
+
| macOS (MacPorts) | `sudo port install kerfscript` |
|
|
33
|
+
| Docker | `docker run --rm -v "$PWD:/work" --user "$(id -u):$(id -g)" ghcr.io/mylasertools/kerfscript render box.kerf` |
|
|
34
|
+
|
|
35
|
+
Package manager listings follow each release as they are approved. The
|
|
36
|
+
binaries are not signed yet. On macOS, Homebrew and MacPorts install them
|
|
37
|
+
without a warning; a downloaded `kerf` needs
|
|
38
|
+
`xattr -d com.apple.quarantine kerf` once. On Windows, SmartScreen may warn
|
|
39
|
+
the first time.
|
|
40
|
+
|
|
17
41
|
Save a `.kerf` file from the [models](https://kerfscript.mylasertools.com/models/)
|
|
18
42
|
to try these commands.
|
|
19
43
|
|
|
@@ -31,21 +55,21 @@ reports parts, dimensions, cut lengths, sheets and warnings.
|
|
|
31
55
|
|
|
32
56
|
## Options
|
|
33
57
|
|
|
34
|
-
| Option
|
|
35
|
-
|
|
|
36
|
-
| `-o, --out <file>`
|
|
37
|
-
| `-D name=value`
|
|
38
|
-
| `-p, --params <file>` | Load parameter values from a JSON file
|
|
39
|
-
| `--font <file.ttf>`
|
|
40
|
-
| `--kerf <mm>`
|
|
41
|
-
| `--sheet <W>x<H>`
|
|
42
|
-
| `--gap <mm>`
|
|
43
|
-
| `--margin <mm>`
|
|
44
|
-
| `--no-pack`
|
|
45
|
-
| `--guides`
|
|
46
|
-
| `--split`
|
|
47
|
-
| `-h, --help`
|
|
48
|
-
| `-v, --version`
|
|
58
|
+
| Option | Use |
|
|
59
|
+
| --------------------- | ------------------------------------------------------------------------- |
|
|
60
|
+
| `-o, --out <file>` | Output path ending in `.svg`, `.dxf` or `.json`; defaults to `<file>.svg` |
|
|
61
|
+
| `-D name=value` | Override a parameter; repeat for multiple values |
|
|
62
|
+
| `-p, --params <file>` | Load parameter values from a JSON file |
|
|
63
|
+
| `--font <file.ttf>` | Supply a font file; repeat for multiple fonts. `Atkinson` is built in |
|
|
64
|
+
| `--kerf <mm>` | Override kerf for every part |
|
|
65
|
+
| `--sheet <W>x<H>` | Set the sheet width and height in millimetres |
|
|
66
|
+
| `--gap <mm>` | Set spacing between parts |
|
|
67
|
+
| `--margin <mm>` | Set spacing at sheet edges; defaults to the gap |
|
|
68
|
+
| `--no-pack` | Keep the positions defined in the program |
|
|
69
|
+
| `--guides` | Include the guide layer |
|
|
70
|
+
| `--split` | Export one file per sheet |
|
|
71
|
+
| `-h, --help` | Show command help |
|
|
72
|
+
| `-v, --version` | Show version numbers |
|
|
49
73
|
|
|
50
74
|
`-D` accepts KerfScript values, including numbers, quoted strings, booleans
|
|
51
75
|
and lists. For example: `-D width=200` or `-D 'name="Ada"'`.
|
|
@@ -68,9 +92,11 @@ a non-zero exit code.
|
|
|
68
92
|
|
|
69
93
|
## Fonts
|
|
70
94
|
|
|
71
|
-
|
|
72
|
-
|
|
95
|
+
The CLI has one font built in, Atkinson Hyperlegible, as `Atkinson`: the same
|
|
96
|
+
font and name as the playground. Text that names no font uses it.
|
|
73
97
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
98
|
+
Supply other font files with `--font`. The CLI does not look up fonts
|
|
99
|
+
installed on your system. `--font Inter-Bold.ttf` makes the font available
|
|
100
|
+
as `Inter-Bold`. A design can request it with `font = "Inter-Bold"`. The
|
|
101
|
+
first supplied font becomes the default for text that does not name one, and
|
|
102
|
+
`Atkinson` stays available.
|
package/docs/compatibility.md
CHANGED
|
@@ -22,9 +22,9 @@ and operation order.
|
|
|
22
22
|
|
|
23
23
|
## Checked
|
|
24
24
|
|
|
25
|
-
| Program
|
|
26
|
-
|
|
|
27
|
-
| Inkscape | 1.4.2
|
|
25
|
+
| Program | Version | SVG | DXF | Checks |
|
|
26
|
+
| -------- | ------- | ------ | ------ | -------------------------------- |
|
|
27
|
+
| Inkscape | 1.4.2 | Passed | Passed | Dimensions, layers and SVG fills |
|
|
28
28
|
|
|
29
29
|
Six reference models passed these import checks on 28 October 2026.
|
|
30
30
|
Drawing dimensions matched within 0.02 mm, including kerf compensation.
|
package/docs/customizer.md
CHANGED
|
@@ -38,15 +38,15 @@ do not get their own controls.
|
|
|
38
38
|
|
|
39
39
|
Put a range or choice list after the assignment:
|
|
40
40
|
|
|
41
|
-
| Comment after the value
|
|
42
|
-
|
|
|
43
|
-
| `// [40:5:400]`
|
|
44
|
-
| `// [40:400]`
|
|
45
|
-
| `// [200]`
|
|
46
|
-
| `// [2, 3, 4]`
|
|
47
|
-
| `// [round:Round, square:Square]` | Menu with a label for each value
|
|
48
|
-
| No comment on a boolean
|
|
49
|
-
| No comment on a string
|
|
41
|
+
| Comment after the value | Control |
|
|
42
|
+
| --------------------------------- | ------------------------------------ |
|
|
43
|
+
| `// [40:5:400]` | Slider from 40 to 400, in steps of 5 |
|
|
44
|
+
| `// [40:400]` | Slider from 40 to 400 |
|
|
45
|
+
| `// [200]` | Number with an upper limit of 200 |
|
|
46
|
+
| `// [2, 3, 4]` | Choice of 2, 3 or 4 |
|
|
47
|
+
| `// [round:Round, square:Square]` | Menu with a label for each value |
|
|
48
|
+
| No comment on a boolean | Checkbox |
|
|
49
|
+
| No comment on a string | Text field |
|
|
50
50
|
|
|
51
51
|
`/* [Size] */` starts a group named Size. `/* [Hidden] */` hides the
|
|
52
52
|
settings that follow it, until another group begins.
|
package/docs/desktop.md
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Desktop app
|
|
2
|
+
|
|
3
|
+
The KerfScript app is the [playground](https://kerfscript.mylasertools.com/playground/)
|
|
4
|
+
on your computer: the same editor, settings and preview, with your designs
|
|
5
|
+
saved as `.kerf` files. It works offline.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
Download the app for your system from the
|
|
10
|
+
[releases](https://github.com/mylasertools/kerfscript/releases):
|
|
11
|
+
|
|
12
|
+
| System | File |
|
|
13
|
+
| ------- | ---------------------------------------------------------------------------- |
|
|
14
|
+
| Windows | `kerfscript-desktop-<version>-windows-x64-setup.exe`, or the `.msi` |
|
|
15
|
+
| macOS | `kerfscript-desktop-<version>-macos-universal.dmg` (Apple silicon and Intel) |
|
|
16
|
+
| Linux | `.AppImage`, `.deb` or `.rpm`, for x64 or arm64 |
|
|
17
|
+
|
|
18
|
+
Package manager listings (winget, Chocolatey, Flathub and the AUR) follow as
|
|
19
|
+
each one is approved.
|
|
20
|
+
|
|
21
|
+
The app is not signed with an Apple or Microsoft certificate yet:
|
|
22
|
+
|
|
23
|
+
- **macOS** says the app cannot be checked for malicious software. Open it
|
|
24
|
+
once with right click → **Open**, or run
|
|
25
|
+
`xattr -d com.apple.quarantine /Applications/KerfScript.app`.
|
|
26
|
+
- **Windows** SmartScreen may say it protected your PC. Choose
|
|
27
|
+
**More info** → **Run anyway**.
|
|
28
|
+
|
|
29
|
+
## Files
|
|
30
|
+
|
|
31
|
+
| Action | Keys |
|
|
32
|
+
| --------------------- | --------------------------------------------- |
|
|
33
|
+
| Open a `.kerf` file | Ctrl+O (⌘O on a Mac), or the **Open…** button |
|
|
34
|
+
| Save | Ctrl+S |
|
|
35
|
+
| Save under a new name | Ctrl+Shift+S, or **Save as…** |
|
|
36
|
+
|
|
37
|
+
Double-click a `.kerf` file to open it in the app. The title bar shows the
|
|
38
|
+
file name, or Untitled, and a dot when there are unsaved changes. The app asks
|
|
39
|
+
before it closes, or opens another design or an example over them, also for a
|
|
40
|
+
design you have not saved yet. A design can be up to 1,000,000 characters
|
|
41
|
+
long, the same as in the playground. Saving writes the whole file before it
|
|
42
|
+
replaces the old one, so a full disk or a crash cannot leave half a design.
|
|
43
|
+
|
|
44
|
+
SVG, DXF and sheet ZIP exports open a save dialog in the design's folder.
|
|
45
|
+
On Linux, a name typed without `.kerf`, `.svg`, `.dxf` or `.zip` gets it, and
|
|
46
|
+
the app asks before replacing a file of that name.
|
|
47
|
+
|
|
48
|
+
## LightBurn
|
|
49
|
+
|
|
50
|
+
**Open in LightBurn** sends the cut file straight to
|
|
51
|
+
[LightBurn](https://lightburnsoftware.com) 2.2 or later, through LightBurn's
|
|
52
|
+
[REST API](https://github.com/LightBurnSoftware/LightBurn-REST). With several
|
|
53
|
+
sheets, each sheet in the cut files list has its own **LightBurn** link.
|
|
54
|
+
|
|
55
|
+
LightBurn has to be open on the same computer. The first time, LightBurn
|
|
56
|
+
asks whether to allow KerfScript; choose **Allow** within 30 seconds. The
|
|
57
|
+
window may open behind KerfScript. KerfScript asks only to send files: it
|
|
58
|
+
cannot read your projects, change cut settings or start the laser.
|
|
59
|
+
|
|
60
|
+
The file opens as a new LightBurn project, as if you had used File → Open,
|
|
61
|
+
and LightBurn asks first if your current project has unsaved changes. Check
|
|
62
|
+
the layers and cut settings in LightBurn before you run the job.
|
|
63
|
+
|
|
64
|
+
To stop KerfScript sending files, remove it in LightBurn under
|
|
65
|
+
Settings → Extensions → Manage API Authorizations.
|
|
66
|
+
|
|
67
|
+
LightBurn is a trademark of LightBurn Software, Inc. KerfScript is not made,
|
|
68
|
+
endorsed or certified by LightBurn Software.
|
|
69
|
+
|
|
70
|
+
## Libraries
|
|
71
|
+
|
|
72
|
+
`use <path>` and `include <path>` find files in the open design's folder and
|
|
73
|
+
the folders below it: with the design at `projects/box.kerf`,
|
|
74
|
+
`use <lib/tabs>` reads `projects/lib/tabs.kerf`. Unlike the
|
|
75
|
+
[command line](cli.md), the app reads only `.kerf` files, and not from folders
|
|
76
|
+
above the design's, such as `use <../shared/tabs>`; keep them next to the
|
|
77
|
+
design or in a folder below it. That way a design you download cannot read
|
|
78
|
+
other files on your computer. Standard library paths such as `use <kerf/box>` work
|
|
79
|
+
everywhere. A design that has not been saved yet can only use the standard
|
|
80
|
+
library.
|
|
81
|
+
|
|
82
|
+
## Fonts
|
|
83
|
+
|
|
84
|
+
`text()` uses Atkinson Hyperlegible, as in the playground. The app does not
|
|
85
|
+
read fonts installed on your system yet; use the [command line](cli.md) with
|
|
86
|
+
`--font` for other fonts.
|
|
87
|
+
|
|
88
|
+
## About and licences
|
|
89
|
+
|
|
90
|
+
**About** shows the app's version, a link to its source code, and the
|
|
91
|
+
licences of KerfScript and of everything built into the app.
|
|
92
|
+
|
|
93
|
+
## Sharing
|
|
94
|
+
|
|
95
|
+
**Copy web link** copies a link that opens your code in the playground on the
|
|
96
|
+
website, so people without the app can see it.
|
package/docs/javascript.md
CHANGED
|
@@ -31,20 +31,20 @@ changing the source string.
|
|
|
31
31
|
|
|
32
32
|
### Options
|
|
33
33
|
|
|
34
|
-
| Option
|
|
35
|
-
|
|
|
36
|
-
| `params`
|
|
37
|
-
| `fonts`
|
|
38
|
-
| `defaultFont` | Name to use when `text()` does not specify a font
|
|
39
|
-
| `resolve`
|
|
40
|
-
| `kerf`
|
|
41
|
-
| `layout`
|
|
42
|
-
| `sheet`
|
|
43
|
-
| `gap`
|
|
44
|
-
| `margin`
|
|
45
|
-
| `guides`
|
|
46
|
-
| `maxSteps`
|
|
47
|
-
| `limits`
|
|
34
|
+
| Option | Value |
|
|
35
|
+
| ------------- | ---------------------------------------------------------------------- |
|
|
36
|
+
| `params` | Parameter values keyed by name |
|
|
37
|
+
| `fonts` | Font files keyed by name, as `ArrayBuffer` or `Uint8Array` |
|
|
38
|
+
| `defaultFont` | Name to use when `text()` does not specify a font |
|
|
39
|
+
| `resolve` | `(path) => source` callback for libraries outside the standard library |
|
|
40
|
+
| `kerf` | Kerf override for every part, in millimetres |
|
|
41
|
+
| `layout` | `"pack"` or `"none"` |
|
|
42
|
+
| `sheet` | `[width, height]` in millimetres |
|
|
43
|
+
| `gap` | Space between parts, in millimetres |
|
|
44
|
+
| `margin` | Space at sheet edges, in millimetres; defaults to `gap` |
|
|
45
|
+
| `guides` | Whether to include guide geometry |
|
|
46
|
+
| `maxSteps` | Evaluation step limit |
|
|
47
|
+
| `limits` | Memory limits, see below; any you leave out keep their default |
|
|
48
48
|
|
|
49
49
|
Supply a font for programs that use text:
|
|
50
50
|
|
|
@@ -61,16 +61,16 @@ The URL should point to a font file provided by your application.
|
|
|
61
61
|
|
|
62
62
|
### Result
|
|
63
63
|
|
|
64
|
-
| Field
|
|
65
|
-
|
|
|
66
|
-
| `svg`
|
|
67
|
-
| `width`, `height` | Combined SVG dimensions in millimetres
|
|
68
|
-
| `sheets`
|
|
69
|
-
| `parts`
|
|
70
|
-
| `paths`
|
|
71
|
-
| `layers`
|
|
72
|
-
| `warnings`
|
|
73
|
-
| `echoes`
|
|
64
|
+
| Field | Contents |
|
|
65
|
+
| ----------------- | ------------------------------------------------------------------------------------- |
|
|
66
|
+
| `svg` | Combined SVG containing all sheets |
|
|
67
|
+
| `width`, `height` | Combined SVG dimensions in millimetres |
|
|
68
|
+
| `sheets` | Each sheet's dimensions, material, thickness, SVG, DXF, paths and placed items |
|
|
69
|
+
| `parts` | Part names, quantities, dimensions, piece counts, cut lengths and material properties |
|
|
70
|
+
| `paths` | Layer paths with `name`, `mode`, `color`, `d`, `regions` and `lines` |
|
|
71
|
+
| `layers` | Layer definitions in output order |
|
|
72
|
+
| `warnings` | Problems that did not stop the render |
|
|
73
|
+
| `echoes` | Output from the program's `echo()` calls |
|
|
74
74
|
|
|
75
75
|
Use `result.svg` for a combined preview. Use `result.sheets[i].svg` or
|
|
76
76
|
`.dxf` to export individual sheets, particularly when they use different
|
|
@@ -136,9 +136,11 @@ Run browser renders in a web worker so they do not block the page. Set a
|
|
|
136
136
|
timeout and terminate the worker if it takes too long. Evaluation limits
|
|
137
137
|
bound program steps and recursion, but geometry work also takes time.
|
|
138
138
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
points, exported points and sheets.
|
|
139
|
+
Size limits stop a program before it builds more than a browser tab can
|
|
140
|
+
usually hold: part copies, circle segments, list sizes, text length, shape
|
|
141
|
+
points, exported points and sheets. They bound what a program makes, not
|
|
142
|
+
every byte the renderer uses, so keep the worker's timeout as well, and run
|
|
143
|
+
programs you did not write where the page can end them. The defaults are in
|
|
142
144
|
[Limits](../LANGUAGE.md#limits) and in `DEFAULT_LIMITS`. Lower them with the
|
|
143
145
|
`limits` option if your worker has little memory:
|
|
144
146
|
|
package/docs/layers.md
CHANGED
|
@@ -6,12 +6,12 @@ software. Unassigned shapes go on the `cut` layer.
|
|
|
6
6
|
|
|
7
7
|
## The built-in layers
|
|
8
8
|
|
|
9
|
-
| Layer
|
|
10
|
-
|
|
|
11
|
-
| `engrave` | `engrave()`
|
|
12
|
-
| `score`
|
|
13
|
-
| `cut`
|
|
14
|
-
| `guide`
|
|
9
|
+
| Layer | Wrap shapes in | Colour in the file | Intended operation |
|
|
10
|
+
| --------- | -------------- | ------------------ | -------------------------- |
|
|
11
|
+
| `engrave` | `engrave()` | black `#000000` | Fill an area |
|
|
12
|
+
| `score` | `score()` | blue `#0000ff` | Mark a line or outline |
|
|
13
|
+
| `cut` | `cut()` | red `#ff0000` | Cut through the material |
|
|
14
|
+
| `guide` | `guide()` | light blue | Show construction geometry |
|
|
15
15
|
|
|
16
16
|
This coaster has a cut outline and hole, an engraved ring and a scored border:
|
|
17
17
|
|
package/docs/openscad.md
CHANGED
|
@@ -23,15 +23,15 @@ See the [language reference](../LANGUAGE.md) for supported arguments.
|
|
|
23
23
|
|
|
24
24
|
## Different
|
|
25
25
|
|
|
26
|
-
| Feature
|
|
27
|
-
|
|
|
28
|
-
| Geometry
|
|
29
|
-
| Output
|
|
30
|
-
| Assignments | The last assignment in a scope applies throughout that scope | Assignments take effect in order
|
|
31
|
-
| Type errors | Many produce `undef` and a warning
|
|
32
|
-
| `color()`
|
|
33
|
-
| Fonts
|
|
34
|
-
| Libraries
|
|
26
|
+
| Feature | OpenSCAD | KerfScript |
|
|
27
|
+
| ----------- | ------------------------------------------------------------ | ---------------------------------------------------------- |
|
|
28
|
+
| Geometry | 3D and 2D | 2D parts for laser cutting |
|
|
29
|
+
| Output | 3D formats and 2D exports | SVG and DXF with operation layers |
|
|
30
|
+
| Assignments | The last assignment in a scope applies throughout that scope | Assignments take effect in order |
|
|
31
|
+
| Type errors | Many produce `undef` and a warning | Stop evaluation with an error |
|
|
32
|
+
| `color()` | Sets a shape's colour | Use `cut()`, `score()`, `engrave()` or `layer()` |
|
|
33
|
+
| Fonts | Looks up system fonts | Uses fonts supplied by the application or CLI |
|
|
34
|
+
| Libraries | Can load local files | Loads the standard library and sources allowed by the host |
|
|
35
35
|
|
|
36
36
|
Assignment order is especially important when adapting a design. A value
|
|
37
37
|
assigned later in a KerfScript program does not change earlier geometry.
|
package/docs/versions.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Versions
|
|
2
2
|
|
|
3
|
-
KerfScript 0.
|
|
3
|
+
KerfScript 0.3.0 implements language version 0.1. The package version tracks
|
|
4
4
|
the software release; the language version tracks the syntax and behavior
|
|
5
5
|
of `.kerf` programs.
|
|
6
6
|
|
|
@@ -30,4 +30,4 @@ files used with a design. Applications that store designs should retain
|
|
|
30
30
|
that information and compare the output before upgrading the interpreter.
|
|
31
31
|
|
|
32
32
|
Pin the npm package to an exact version when your application needs a fixed
|
|
33
|
-
renderer, for example `@mylasertools/kerfscript@0.
|
|
33
|
+
renderer, for example `@mylasertools/kerfscript@0.3.0`.
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# WebAssembly
|
|
2
|
+
|
|
3
|
+
`kerfscript.wasm` runs KerfScript from any language that can host a
|
|
4
|
+
WebAssembly module: Python, Rust, Go, C#, Java, Ruby and others. It is a
|
|
5
|
+
WASI (preview 1) module built from the same source as the JavaScript package,
|
|
6
|
+
so it makes the same SVG and DXF files, byte for byte.
|
|
7
|
+
|
|
8
|
+
For JavaScript applications, use the [JavaScript API](javascript.md)
|
|
9
|
+
instead: it is smaller and faster.
|
|
10
|
+
|
|
11
|
+
## Getting the module
|
|
12
|
+
|
|
13
|
+
Download `kerfscript-<version>.wasm` from the
|
|
14
|
+
[releases](https://github.com/mylasertools/kerfscript/releases) page and save
|
|
15
|
+
it as `kerfscript.wasm`, or get `kerfscript-wasm-<version>.zip`, which has the
|
|
16
|
+
module with this guide and its licences. You can also build it from the
|
|
17
|
+
repository with [Javy](https://github.com/bytecodealliance/javy):
|
|
18
|
+
|
|
19
|
+
```sh
|
|
20
|
+
npm run build
|
|
21
|
+
npm run wasm # writes dist/kerfscript.wasm
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Set `JAVY` to the javy binary if it is not on the `PATH`.
|
|
25
|
+
|
|
26
|
+
## How it works
|
|
27
|
+
|
|
28
|
+
The module reads one JSON request from standard input, writes one JSON
|
|
29
|
+
response to standard output and exits. Start a fresh instance for each
|
|
30
|
+
request. From a shell, with [Wasmtime](https://wasmtime.dev):
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
echo '{"source": "rect([80, 50]);"}' | wasmtime run kerfscript.wasm
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Request
|
|
37
|
+
|
|
38
|
+
| Field | Value |
|
|
39
|
+
| ------------- | --------------------------------------------------------------------------- |
|
|
40
|
+
| `command` | `"render"` (default), `"params"`, `"version"` or `"licenses"` |
|
|
41
|
+
| `source` | The program, as a string |
|
|
42
|
+
| `params` | Parameter values keyed by name |
|
|
43
|
+
| `files` | Libraries for `include` and `use`, keyed by path: `{"lib/tab.kerf": "..."}` |
|
|
44
|
+
| `fonts` | Font files keyed by name, base64 encoded. `Atkinson` is built in |
|
|
45
|
+
| `defaultFont` | Name to use when `text()` does not specify a font |
|
|
46
|
+
| `kerf` | Kerf override for every part, in millimetres |
|
|
47
|
+
| `layout` | `"pack"` (default) or `"none"` |
|
|
48
|
+
| `sheet` | Sheet size `[width, height]` in millimetres |
|
|
49
|
+
| `gap` | Space between packed parts |
|
|
50
|
+
| `margin` | Space between the parts and the sheet edge |
|
|
51
|
+
| `guides` | `true` to include guide layer geometry |
|
|
52
|
+
|
|
53
|
+
These match the [render() options](javascript.md#options). A path in `files`
|
|
54
|
+
can leave out `.kerf`, as in the program.
|
|
55
|
+
|
|
56
|
+
### Response
|
|
57
|
+
|
|
58
|
+
Every response has `ok`. When it is `false`, `error` holds the message and
|
|
59
|
+
`echoes` holds what the program echoed before it stopped. The module never
|
|
60
|
+
exits with an error code for a bad program.
|
|
61
|
+
|
|
62
|
+
- `render`: `svg` (all sheets, for preview), `width`, `height`, `parts`,
|
|
63
|
+
`warnings`, `echoes` and `sheets`. Each sheet has `width`, `height`,
|
|
64
|
+
`material`, `thickness`, `svg` and `dxf`; write one file per sheet to cut.
|
|
65
|
+
- `params`: `parameters`, as from [`parameters()`](javascript.md).
|
|
66
|
+
- `version`: `version` (package) and `language`.
|
|
67
|
+
- `licenses`: `files`, the licence texts of the module and of everything
|
|
68
|
+
built into it, keyed by file name: `LICENSE`, `COMMERCIAL-LICENSE.md`,
|
|
69
|
+
`THIRD-PARTY-NOTICES.md`, `THIRD-PARTY-LICENSES.md` (the JavaScript engine
|
|
70
|
+
and its Rust crates) and `OFL.txt`. The release ZIP has the same files.
|
|
71
|
+
|
|
72
|
+
## Python
|
|
73
|
+
|
|
74
|
+
With the [`wasmtime`](https://pypi.org/project/wasmtime/) package:
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
import json, os, tempfile
|
|
78
|
+
from wasmtime import Engine, Linker, Module, Store, WasiConfig
|
|
79
|
+
|
|
80
|
+
engine = Engine()
|
|
81
|
+
module = Module.from_file(engine, "kerfscript.wasm")
|
|
82
|
+
linker = Linker(engine)
|
|
83
|
+
linker.define_wasi()
|
|
84
|
+
|
|
85
|
+
def kerf(request):
|
|
86
|
+
with tempfile.TemporaryDirectory() as d:
|
|
87
|
+
inp, out = os.path.join(d, "in.json"), os.path.join(d, "out.json")
|
|
88
|
+
with open(inp, "w", encoding="utf-8") as f:
|
|
89
|
+
json.dump(request, f)
|
|
90
|
+
wasi = WasiConfig()
|
|
91
|
+
wasi.stdin_file = inp
|
|
92
|
+
wasi.stdout_file = out
|
|
93
|
+
store = Store(engine)
|
|
94
|
+
store.set_wasi(wasi)
|
|
95
|
+
linker.instantiate(store, module).exports(store)["_start"](store)
|
|
96
|
+
with open(out, encoding="utf-8") as f:
|
|
97
|
+
return json.load(f)
|
|
98
|
+
|
|
99
|
+
result = kerf({"source": "w = 80; rect([w, 50]);", "params": {"w": 120}})
|
|
100
|
+
for i, sheet in enumerate(result["sheets"]):
|
|
101
|
+
with open(f"sheet-{i + 1}.svg", "w", encoding="utf-8", newline="") as f:
|
|
102
|
+
f.write(sheet["svg"])
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Compile the module once and reuse it; each request only needs a new `Store`.
|
|
106
|
+
|
|
107
|
+
## Node.js
|
|
108
|
+
|
|
109
|
+
The JavaScript package is the better fit in Node.js, but the module also runs
|
|
110
|
+
under `node:wasi`, which is how the test suite checks it:
|
|
111
|
+
|
|
112
|
+
```js
|
|
113
|
+
import { closeSync, openSync, readFileSync, writeFileSync } from 'node:fs';
|
|
114
|
+
import { WASI } from 'node:wasi';
|
|
115
|
+
|
|
116
|
+
const module = await WebAssembly.compile(readFileSync('kerfscript.wasm'));
|
|
117
|
+
writeFileSync('in.json', JSON.stringify({ source: 'rect([80, 50]);' }));
|
|
118
|
+
const stdin = openSync('in.json', 'r');
|
|
119
|
+
const stdout = openSync('out.json', 'w');
|
|
120
|
+
const wasi = new WASI({ version: 'preview1', stdin, stdout, returnOnExit: true });
|
|
121
|
+
wasi.start(await WebAssembly.instantiate(module, wasi.getImportObject()));
|
|
122
|
+
closeSync(stdin);
|
|
123
|
+
closeSync(stdout);
|
|
124
|
+
console.log(JSON.parse(readFileSync('out.json', 'utf8')).svg);
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Performance
|
|
128
|
+
|
|
129
|
+
The module carries its own JavaScript engine (QuickJS), so it is about 2 MB
|
|
130
|
+
and renders roughly three to five times slower than Node.js. The example
|
|
131
|
+
designs take well under a second.
|