@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.
Files changed (46) hide show
  1. package/CHANGELOG.md +97 -0
  2. package/CLA.md +8 -5
  3. package/COMMERCIAL-LICENSE.md +23 -28
  4. package/LANGUAGE.md +194 -60
  5. package/README.md +89 -39
  6. package/THIRD-PARTY-NOTICES.md +68 -4
  7. package/TRADEMARKS.md +16 -10
  8. package/dist/cli.js +773 -297
  9. package/dist/evaluator.d.cts +26 -0
  10. package/dist/evaluator.d.ts +26 -0
  11. package/dist/export/dxf.d.cts +1 -1
  12. package/dist/export/dxf.d.ts +1 -1
  13. package/dist/export/svg.d.cts +2 -0
  14. package/dist/export/svg.d.ts +2 -0
  15. package/dist/font.d.cts +3 -0
  16. package/dist/font.d.ts +3 -0
  17. package/dist/functions.d.cts +21 -2
  18. package/dist/functions.d.ts +21 -2
  19. package/dist/index.cjs +14 -14
  20. package/dist/index.d.cts +2 -2
  21. package/dist/index.d.ts +2 -2
  22. package/dist/index.js +14 -14
  23. package/dist/lexer.d.cts +4 -1
  24. package/dist/lexer.d.ts +4 -1
  25. package/dist/parser.d.cts +1 -1
  26. package/dist/parser.d.ts +1 -1
  27. package/dist/render.d.cts +3 -2
  28. package/dist/render.d.ts +3 -2
  29. package/dist/values.d.cts +10 -2
  30. package/dist/values.d.ts +10 -2
  31. package/dist/wasm.d.cts +1 -0
  32. package/dist/wasm.d.ts +1 -0
  33. package/docs/cli.md +69 -28
  34. package/docs/compatibility.md +40 -65
  35. package/docs/customizer.md +40 -28
  36. package/docs/desktop.md +96 -0
  37. package/docs/getting-started.md +48 -31
  38. package/docs/javascript.md +108 -51
  39. package/docs/kerf.md +36 -39
  40. package/docs/layers.md +71 -37
  41. package/docs/openscad.md +52 -48
  42. package/docs/parts-and-sheets.md +45 -31
  43. package/docs/versions.md +20 -30
  44. package/docs/webassembly.md +131 -0
  45. package/fonts/OFL.txt +92 -0
  46. package/package.json +10 -6
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
@@ -1,6 +1,6 @@
1
1
  import type { Program } from './ast.cjs';
2
2
  import { type Comment } from './lexer.cjs';
3
- export declare function parse(src: string): {
3
+ export declare function parse(src: string, file?: string): {
4
4
  program: Program;
5
5
  comments: Comment[];
6
6
  };
package/dist/parser.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { Program } from './ast.js';
2
2
  import { type Comment } from './lexer.js';
3
- export declare function parse(src: string): {
3
+ export declare function parse(src: string, file?: string): {
4
4
  program: Program;
5
5
  comments: Comment[];
6
6
  };
package/dist/render.d.cts CHANGED
@@ -1,8 +1,8 @@
1
- import { type LayerDef } from './evaluator.cjs';
1
+ 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 { Value } from './values.cjs';
5
+ import { type Value } from './values.cjs';
6
6
  export interface RenderOptions {
7
7
  params?: Record<string, Value>;
8
8
  fonts?: Record<string, FontSource>;
@@ -15,6 +15,7 @@ export interface RenderOptions {
15
15
  margin?: number;
16
16
  guides?: boolean;
17
17
  maxSteps?: number;
18
+ limits?: Partial<Limits>;
18
19
  }
19
20
  export interface PartInfo {
20
21
  name: string;
package/dist/render.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { type LayerDef } from './evaluator.js';
1
+ 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 { Value } from './values.js';
5
+ import { type Value } from './values.js';
6
6
  export interface RenderOptions {
7
7
  params?: Record<string, Value>;
8
8
  fonts?: Record<string, FontSource>;
@@ -15,6 +15,7 @@ export interface RenderOptions {
15
15
  margin?: number;
16
16
  guides?: boolean;
17
17
  maxSteps?: number;
18
+ limits?: Partial<Limits>;
18
19
  }
19
20
  export interface PartInfo {
20
21
  name: string;
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 function str(v: Value): string;
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 function str(v: Value): string;
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;
@@ -0,0 +1 @@
1
+ export {};
package/dist/wasm.d.ts ADDED
@@ -0,0 +1 @@
1
+ export {};
package/docs/cli.md CHANGED
@@ -1,61 +1,102 @@
1
1
  # Command line
2
2
 
3
- The `kerf` command renders `.kerf` files to SVG, DXF or JSON. It needs
4
- Node.js 20 or newer and comes with the `@mylasertools/kerfscript` npm
5
- package.
3
+ Use the `kerf` command to export designs, change parameters and inspect
4
+ parts from your terminal. Install the package with Node.js 20 or newer:
6
5
 
7
6
  ```sh
8
7
  npm install --global @mylasertools/kerfscript
9
8
  kerf render box.kerf -o box.svg
10
9
  ```
11
10
 
12
- Or without installing:
11
+ You can also run it through `npx`:
13
12
 
14
13
  ```sh
15
14
  npx @mylasertools/kerfscript render box.kerf -o box.svg
16
15
  ```
17
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
+
41
+ Save a `.kerf` file from the [models](https://kerfscript.mylasertools.com/models/)
42
+ to try these commands.
43
+
18
44
  ## Commands
19
45
 
20
46
  ```sh
21
47
  kerf render <file.kerf> [-o out.svg] [options]
22
- kerf params <file.kerf> # settings as JSON
23
- kerf check <file.kerf> # parts, sizes, cut length, sheets and warnings
48
+ kerf params <file.kerf>
49
+ kerf check <file.kerf>
24
50
  ```
25
51
 
52
+ `render` exports SVG, DXF or JSON, using the output file's extension to
53
+ choose the format. `params` lists the editable settings as JSON. `check`
54
+ reports parts, dimensions, cut lengths, sheets and warnings.
55
+
26
56
  ## Options
27
57
 
28
- | Option | What it does |
29
- | --------------------- | ---------------------------------------------------------------------- |
30
- | `-o, --out <file>` | output file, `.svg`, `.dxf` or `.json`; default `<file>.svg` |
31
- | `-D name=value` | set a setting; the value is KerfScript: `40`, `"Oak"`, `true`, `[1,2]` |
32
- | `-p, --params <file>` | JSON file of setting values |
33
- | `--font <file.ttf>` | font for `text()`; repeat for more fonts. The name is the file name |
34
- | `--kerf <mm>` | override kerf compensation for every part |
35
- | `--sheet <W>x<H>` | sheet size for packing, in mm |
36
- | `--gap <mm>` | space between packed parts |
37
- | `--margin <mm>` | space between the parts and the sheet edge (default: the gap) |
38
- | `--no-pack` | keep parts where the program placed them |
39
- | `--guides` | include guide layer geometry |
40
- | `--split` | write one file per sheet (`out-1.svg`, `out-2.svg`, ...) |
41
- | `-h, --help` | show help |
42
- | `-v, --version` | show the 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 |
73
+
74
+ `-D` accepts KerfScript values, including numbers, quoted strings, booleans
75
+ and lists. For example: `-D width=200` or `-D 'name="Ada"'`.
43
76
 
44
77
  ## Examples
45
78
 
46
79
  ```sh
47
- kerf render sign.kerf -D 'name="Ada"' --font Inter-Bold.ttf -o ada.svg
80
+ kerf render name-sign.kerf -D 'name="Ada"' --font Inter-Bold.ttf -o ada.svg
48
81
  kerf render box.kerf --sheet 400x300 --kerf 0.12 --split -o box.svg
49
82
  kerf render box.kerf -o box.dxf
50
83
  kerf check box.kerf
51
84
  ```
52
85
 
53
- Warnings go to standard error and do not stop the render. Errors stop it with
54
- the line and column, and a non-zero exit code.
86
+ For multiple sheets, `--split` creates numbered files such as `box-1.svg`
87
+ and `box-2.svg`. Use it for DXF exports of a design with several sheets.
88
+
89
+ Warnings are written to standard error and allow rendering to continue.
90
+ An error stops the command, reports its location when available and returns
91
+ a non-zero exit code.
55
92
 
56
93
  ## Fonts
57
94
 
58
- KerfScript does not ship fonts and never reads system fonts, so a file
59
- renders the same everywhere. Pass the fonts a design uses with `--font`. A
60
- design that asks for `font = "Inter-Bold"` needs `--font Inter-Bold.ttf`; the
61
- first font given is the default.
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.
97
+
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.
@@ -1,89 +1,64 @@
1
1
  # Laser software
2
2
 
3
- KerfScript writes ordinary SVG and DXF files, so any program that reads
4
- those can open them. This page says what we have actually checked, in which
5
- version, and what you still need to set up yourself.
3
+ Export SVG or DXF from KerfScript, then set up the cutting job in your laser
4
+ software. Check the imported size and layers before assigning power, speed
5
+ and operation order.
6
6
 
7
7
  ## What is in the files
8
8
 
9
9
  **SVG**
10
10
 
11
- - Size in millimetres (`width="100mm"`), with a matching `viewBox`, so one
12
- unit is one millimetre.
13
- - One group per layer, marked as an Inkscape layer and named after it:
14
- `engrave`, your own layers, `score`, `cut`, `guide`.
15
- - Cut lines red `#ff0000`, score lines blue `#0000ff`, 0.1 mm hairline
16
- strokes. Engraved areas are filled black `#000000` with the even-odd rule.
17
- - Holes and inner cuts come before outer outlines.
11
+ - Millimetre dimensions with a matching `viewBox`.
12
+ - Named layer groups for engraving, scoring, cutting and any custom layers.
13
+ - Red cut paths, blue score paths and black filled engraving.
14
+ - Inner cut paths before outer outlines in the file.
18
15
 
19
16
  **DXF**
20
17
 
21
- - R12 (AC1009) polylines, units set to millimetres.
22
- - One DXF layer per KerfScript layer, in capitals (`CUT`, `SCORE`,
23
- `ENGRAVE`), with matching AutoCAD colours.
24
- - DXF R12 has no fills. Engraved areas arrive as outlines; set that layer to
25
- fill in your laser software.
26
- - A DXF holds one sheet. Use `--split` for designs with several sheets.
18
+ - R12 polylines with millimetre units.
19
+ - Named layers such as `CUT`, `SCORE` and `ENGRAVE`.
20
+ - Engraving as outlines. Set the engraving layer to fill in your laser software.
21
+ - One sheet per file. Use the CLI's `--split` option for several sheets.
27
22
 
28
23
  ## Checked
29
24
 
30
- | Program | Version | SVG | DXF | How |
31
- | -------- | ------- | --- | --- | --------------------------- |
32
- | Inkscape | 1.4.2 | yes | yes | automatic, `npm run compat` |
25
+ | Program | Version | SVG | DXF | Checks |
26
+ | -------- | ------- | ------ | ------ | -------------------------------- |
27
+ | Inkscape | 1.4.2 | Passed | Passed | Dimensions, layers and SVG fills |
33
28
 
34
- `npm run compat` renders six reference models (the calibration square, the
35
- kerf test, a six-panel finger-jointed box, a living hinge card, a coaster
36
- with an engraved ring, and a jigsaw puzzle), opens every SVG and DXF in
37
- Inkscape from the command line, and checks that:
38
-
39
- - the size of the drawing matches KerfScript's geometry within 0.02 mm,
40
- kerf compensation included;
41
- - every layer arrives as a layer with the right name;
42
- - engraved layers are filled in the SVG.
43
-
44
- All six passed in both formats on 28 October 2026.
29
+ Six reference models passed these import checks on 28 October 2026.
30
+ Drawing dimensions matched within 0.02 mm, including kerf compensation.
31
+ These results cover file imports; they do not establish a fit for a
32
+ particular machine or material.
45
33
 
46
34
  ## Not checked yet
47
35
 
48
- We have not yet run the reference set through **LightBurn**, **xTool
49
- Studio** or **xTool Creative Space**, **RDWorks** or **LaserGRBL**, and we
50
- have not cut it on machines outside MyLaserTools. Until we have, treat them as
51
- untested: they read standard SVG and DXF, but each imports colours, layers
52
- and fills its own way.
53
-
54
- If you try one, we would like to hear what happened. The checklist below is
55
- what we look at.
36
+ LightBurn, xTool Studio, xTool Creative Space, RDWorks and LaserGRBL have
37
+ not yet been verified with the reference models. Import handling can differ
38
+ between programs, especially for units, layer colours and fills.
56
39
 
57
40
  ## Checklist for a new program
58
41
 
59
- Open `calibration-square.svg` and `box.svg` from the
60
- [models](https://kerfscript.mylasertools.com/models/) and check:
61
-
62
- 1. **Size.** The square is 100.15 mm wide with the default 0.15 mm kerf
63
- (100 mm plus compensation), not 26.4 mm or 377.95 mm. If it is wrong, the
64
- program ignored the millimetre units; look for an import DPI or unit
65
- setting.
66
- 2. **Layers.** Cut, score and engrave arrive as separate layers or colours,
67
- so each can get its own power and speed.
68
- 3. **Fill.** The engraved text on the square is filled, not just outlined.
69
- 4. **Holes.** The hole in the square is cut, and engraving does not appear
70
- inside it.
71
- 5. **Order.** The program's cut order cuts holes before outlines. Most
72
- programs have an "inner shapes first" option; turn it on.
73
- 6. **Parts.** All six box panels arrive, none overlapping.
42
+ Download the calibration square and box from the
43
+ [models](https://kerfscript.mylasertools.com/models/) and check their imports:
74
44
 
75
- ## What the file does not decide
45
+ 1. **Size:** the calibration square's cut path is 100.15 mm wide with
46
+ `$kerf = 0.15`, allowing for a finished 100 mm square. If the imported
47
+ size differs, check the unit and DPI settings.
48
+ 2. **Layers:** cutting, scoring and engraving can be assigned separate operations.
49
+ 3. **Fill:** engraved text has filled letters. For DXF, select fill in the
50
+ engraving layer's settings.
51
+ 4. **Holes:** cut holes remain open and contain no engraving.
52
+ 5. **Order:** the job preview cuts inner paths before outer outlines.
53
+ 6. **Parts:** the box contains all six panels without overlaps.
76
54
 
77
- The file describes geometry and layers. Your laser software decides how the
78
- machine runs it:
55
+ ## What the file does not decide
79
56
 
80
- - **Order of operations.** Layer order in an SVG is a hint. Most programs
81
- sort operations themselves; check that engraving runs before cutting and
82
- inner cuts before outer ones.
83
- - **Power, speed, passes and focus** for each layer and material.
84
- - **Material and thickness.** KerfScript records them per sheet; make sure
85
- the file you send matches the sheet in the machine.
86
- - **Kerf.** If your laser software also applies kerf offset, turn one of them
87
- off, or parts will be compensated twice.
57
+ Set power, speed, passes and focus for your machine and material. Check the
58
+ job preview for engraving before cutting and holes before outer outlines;
59
+ laser software can reorder the paths in a file.
88
60
 
89
- Always run a test on scrap before cutting good material.
61
+ For multiple sheets, use a separate file and matching material settings for
62
+ each sheet. If KerfScript has already applied kerf compensation, leave the
63
+ laser software's kerf offset at zero. Test the job on scrap before cutting
64
+ the final material.
@@ -1,9 +1,8 @@
1
1
  # Settings
2
2
 
3
- Top-level variables with a plain value become **settings**: sliders, menus,
4
- checkboxes and text boxes in the playground, on MyLaserTools, and in any tool
5
- that reads OpenSCAD customizer comments. The format is the same as
6
- OpenSCAD's.
3
+ Expose dimensions, text and other choices as controls beside your design.
4
+ Comments define sliders and menus, while the variable values provide their
5
+ defaults. KerfScript uses OpenSCAD's customizer comment format.
7
6
 
8
7
  ```kerf
9
8
  /* [Size] */
@@ -24,39 +23,52 @@ wall = 3;
24
23
  rect([width, depth]);
25
24
  ```
26
25
 
26
+ This example defines several control types. The rectangle uses `width`
27
+ and `depth`; the other variables illustrate settings you can use elsewhere
28
+ in a design.
29
+
27
30
  ## What becomes a setting
28
31
 
29
- A top-level assignment whose value is a number, a string, `true` or `false`,
30
- or a list of numbers. An expression like `width / 2` is not a setting; it is
31
- worked out from the others.
32
+ A variable declared at the top level becomes a setting when its value is a
33
+ number, string, boolean or list of numbers. Variables defined by expressions,
34
+ such as `half_width = width / 2`, are calculated from the other values and
35
+ do not get their own controls.
32
36
 
33
37
  ## Comments
34
38
 
35
- | Comment after the value | Control |
36
- | --------------------------------- | ----------------------------- |
37
- | `// [40:5:400]` | slider from 40 to 400, step 5 |
38
- | `// [40:400]` | slider from 40 to 400 |
39
- | `// [200]` | number up to 200 |
40
- | `// [2, 3, 4]` | menu of those values |
41
- | `// [round:Round, square:Square]` | menu with labels |
42
- | none, on `true` or `false` | checkbox |
43
- | none, on a string | text box |
44
-
45
- - `/* [Group name] */` starts a group for the settings below it.
46
- `/* [Hidden] */` hides the ones that follow.
47
- - A `//` comment on its own line just above a setting is its caption.
48
- A comment at the end of the line before does not count.
49
- - Put a blank line between a file's opening comment and its first setting,
50
- so the opening comment is not taken as that setting's caption.
39
+ Put a range or choice list after the assignment:
40
+
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
+
51
+ `/* [Size] */` starts a group named Size. `/* [Hidden] */` hides the
52
+ settings that follow it, until another group begins.
53
+
54
+ A `//` comment immediately above a variable supplies its caption. Keep the
55
+ file's introductory comment separate with a blank line so it does not
56
+ become the first setting's caption.
51
57
 
52
58
  ## Changing settings without editing the file
53
59
 
60
+ The CLI accepts values with `-D` or a JSON file with `--params`:
61
+
54
62
  ```sh
55
- kerf render box.kerf -D width=200 -D 'label="Oak"'
56
- kerf render box.kerf --params oak.json
63
+ kerf render box.kerf -D width=200
64
+ kerf render box.kerf --params box-settings.json
57
65
  kerf params box.kerf
58
66
  ```
59
67
 
60
- `-D` values are KerfScript values, so strings need their quotes. `kerf params`
61
- prints the settings as JSON. From JavaScript, pass `params` to `render()` and
62
- read them with `parameters()`; see [JavaScript API](javascript.md).
68
+ `box-settings.json` can contain `{"width": 200, "lid": false}`.
69
+ Use `kerf params` to list a design's settings as JSON.
70
+
71
+ String values need quotes, for example `-D 'label="Oak"'` for a design
72
+ with a `label` setting. In JavaScript, pass values through `render()`'s
73
+ `params` option and read the settings with `parameters()`. See the
74
+ [JavaScript API](javascript.md).
@@ -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.