@mylasertools/kerfscript 0.0.0-stage → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/CLA.md +76 -0
  3. package/COMMERCIAL-LICENSE.md +63 -0
  4. package/LANGUAGE.md +398 -0
  5. package/LICENSE +661 -0
  6. package/README.md +187 -2
  7. package/THIRD-PARTY-NOTICES.md +124 -0
  8. package/TRADEMARKS.md +45 -0
  9. package/dist/ast.d.cts +160 -0
  10. package/dist/ast.d.ts +160 -0
  11. package/dist/cli.d.cts +1 -0
  12. package/dist/cli.d.ts +1 -0
  13. package/dist/cli.js +19416 -0
  14. package/dist/customizer.d.cts +19 -0
  15. package/dist/customizer.d.ts +19 -0
  16. package/dist/evaluator.d.cts +129 -0
  17. package/dist/evaluator.d.ts +129 -0
  18. package/dist/export/dxf.d.cts +3 -0
  19. package/dist/export/dxf.d.ts +3 -0
  20. package/dist/export/svg.d.cts +15 -0
  21. package/dist/export/svg.d.ts +15 -0
  22. package/dist/functions.d.cts +4 -0
  23. package/dist/functions.d.ts +4 -0
  24. package/dist/geometry.d.cts +44 -0
  25. package/dist/geometry.d.ts +44 -0
  26. package/dist/index.cjs +44 -0
  27. package/dist/index.d.cts +10 -0
  28. package/dist/index.d.ts +10 -0
  29. package/dist/index.js +44 -0
  30. package/dist/joinery.d.cts +7 -0
  31. package/dist/joinery.d.ts +7 -0
  32. package/dist/lexer.d.cts +28 -0
  33. package/dist/lexer.d.ts +28 -0
  34. package/dist/parser.d.cts +6 -0
  35. package/dist/parser.d.ts +6 -0
  36. package/dist/paths.d.cts +28 -0
  37. package/dist/paths.d.ts +28 -0
  38. package/dist/render.d.cts +58 -0
  39. package/dist/render.d.ts +58 -0
  40. package/dist/stdlib.d.cts +1 -0
  41. package/dist/stdlib.d.ts +1 -0
  42. package/dist/text.d.cts +36 -0
  43. package/dist/text.d.ts +36 -0
  44. package/dist/values.d.cts +25 -0
  45. package/dist/values.d.ts +25 -0
  46. package/docs/cli.md +76 -0
  47. package/docs/compatibility.md +64 -0
  48. package/docs/customizer.md +74 -0
  49. package/docs/getting-started.md +115 -0
  50. package/docs/javascript.md +153 -0
  51. package/docs/kerf.md +67 -0
  52. package/docs/layers.md +108 -0
  53. package/docs/openscad.md +71 -0
  54. package/docs/parts-and-sheets.md +82 -0
  55. package/docs/versions.md +33 -0
  56. package/package.json +86 -4
@@ -0,0 +1,115 @@
1
+ # Getting started
2
+
3
+ Make a small sign with two hanging holes and engraved text. You can follow
4
+ this guide in the [playground](https://kerfscript.mylasertools.com/playground/)
5
+ without installing anything.
6
+
7
+ ## Your first part
8
+
9
+ Clear the playground editor and enter:
10
+
11
+ ```kerf
12
+ rect([80, 50], r = 4);
13
+ ```
14
+
15
+ This draws an 80 × 50 mm rectangle with 4 mm corner radii. KerfScript uses
16
+ millimetres for lengths and degrees for angles. Shapes go on the cut layer
17
+ unless you assign another layer.
18
+
19
+ ## Holes
20
+
21
+ Replace the rectangle with this code:
22
+
23
+ ```kerf
24
+ difference() {
25
+ rect([80, 50], r = 4);
26
+ translate([10, 25]) circle(d = 5);
27
+ translate([70, 25]) circle(d = 5);
28
+ }
29
+ ```
30
+
31
+ `difference()` subtracts the two circles from the rectangle. Each hole is
32
+ 5 mm across, centred 10 mm from a side and halfway up the sign.
33
+
34
+ `translate([x, y])` moves a shape. The x axis points right and the y axis
35
+ points up. A rectangle starts at `[0, 0]`; use `center = true` to centre it
36
+ on that point.
37
+
38
+ ## Engraving and scoring
39
+
40
+ Add a scored border and engraved text:
41
+
42
+ ```kerf
43
+ difference() {
44
+ rect([80, 50], r = 4);
45
+ translate([10, 25]) circle(d = 5);
46
+ translate([70, 25]) circle(d = 5);
47
+ }
48
+ score() translate([20, 10]) rect([40, 30], r = 2);
49
+ engrave() translate([40, 25])
50
+ text("Oak", size = 10, halign = "center", valign = "center");
51
+ ```
52
+
53
+ `score()` marks the border's outline. `engrave()` fills the letters. Both
54
+ stay within the sign's cut outline, excluding the holes. The playground
55
+ supplies a font for this example.
56
+
57
+ See [Layers](layers.md) for custom layers and guide lines.
58
+
59
+ ## Settings
60
+
61
+ Give dimensions names so you can change them without editing every shape:
62
+
63
+ ```kerf
64
+ width = 80; // [40:5:200]
65
+ height = 50; // [30:5:120]
66
+ label = "Oak";
67
+
68
+ difference() {
69
+ rect([width, height], r = 4);
70
+ translate([10, height / 2]) circle(d = 5);
71
+ translate([width - 10, height / 2]) circle(d = 5);
72
+ }
73
+ engrave() translate([width / 2, height / 2])
74
+ text(label, size = 10, halign = "center", valign = "center");
75
+ ```
76
+
77
+ The comments create sliders for width and height. `[40:5:200]` means a
78
+ minimum of 40, a step of 5 and a maximum of 200. `label` becomes a text
79
+ field. The text and holes stay centred as the dimensions change.
80
+
81
+ In the playground, changing a control also updates its value in the code.
82
+ See [Settings](customizer.md) for menus, groups and captions.
83
+
84
+ ## Kerf
85
+
86
+ The beam removes some material along each cut. To account for that width,
87
+ add your measured kerf near the top of the program:
88
+
89
+ ```kerf
90
+ $kerf = 0.15;
91
+ ```
92
+
93
+ Here, `0.15` is an example in millimetres. Use the
94
+ [calibration square](../examples/calibration-square.kerf) to measure a value
95
+ for your machine and material. [Kerf](kerf.md) explains the measurement and
96
+ how it affects the exported outlines.
97
+
98
+ ## Getting the file
99
+
100
+ Choose **SVG** or **DXF** in the playground, then open the file in your laser
101
+ software. Assign the cut, score and engrave layers their power, speed and
102
+ operation order. In DXF, set engraved areas to fill.
103
+
104
+ If you used `$kerf`, leave kerf compensation off in the laser software to
105
+ avoid applying it twice. The [import guide](compatibility.md) covers sizes,
106
+ layers and tested programs.
107
+
108
+ Download **.kerf** to keep an editable copy of the design.
109
+
110
+ ## Next
111
+
112
+ - [Layers](layers.md): separate cutting, scoring and engraving.
113
+ - [Parts and sheets](parts-and-sheets.md): arrange several parts by material.
114
+ - [Coming from OpenSCAD](openscad.md): adapt an existing 2D design.
115
+ - [Language reference](../LANGUAGE.md): look up syntax and functions.
@@ -0,0 +1,153 @@
1
+ # JavaScript API
2
+
3
+ Add KerfScript rendering to a JavaScript application with the
4
+ `@mylasertools/kerfscript` package. The library runs in browsers and Node.js
5
+ and includes TypeScript definitions.
6
+
7
+ ```sh
8
+ npm install @mylasertools/kerfscript
9
+ ```
10
+
11
+ ## render()
12
+
13
+ Pass a program as a string. The result contains its geometry, files, parts
14
+ and warnings:
15
+
16
+ ```js
17
+ import { render } from '@mylasertools/kerfscript';
18
+
19
+ const source = 'width = 80; rect([width, 50]);';
20
+ const result = render(source, {
21
+ params: { width: 120 },
22
+ sheet: [600, 400],
23
+ margin: 0,
24
+ });
25
+
26
+ console.log(result.svg);
27
+ ```
28
+
29
+ This exports a 120 × 50 mm rectangle. `params` overrides `width` without
30
+ changing the source string.
31
+
32
+ ### Options
33
+
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
+
49
+ Supply a font for programs that use text:
50
+
51
+ ```js
52
+ const response = await fetch('/fonts/Inter.ttf');
53
+ const font = await response.arrayBuffer();
54
+ const result = render(source, {
55
+ fonts: { Inter: font },
56
+ defaultFont: 'Inter',
57
+ });
58
+ ```
59
+
60
+ The URL should point to a font file provided by your application.
61
+
62
+ ### Result
63
+
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
+
75
+ Use `result.svg` for a combined preview. Use `result.sheets[i].svg` or
76
+ `.dxf` to export individual sheets, particularly when they use different
77
+ materials.
78
+
79
+ For a custom preview, `d` contains all paths in a layer. `regions` contains
80
+ closed outlines and `lines` contains open paths. On a `fill` layer, draw
81
+ regions with the even-odd fill rule and draw open paths as strokes.
82
+
83
+ ## parameters()
84
+
85
+ Read a program's editable settings without rendering its geometry:
86
+
87
+ ```js
88
+ import { parameters } from '@mylasertools/kerfscript';
89
+
90
+ const source = 'width = 80; // [40:5:200]\nrect([width, 50]);';
91
+ const settings = parameters(source).parameters;
92
+ ```
93
+
94
+ Each setting includes `name`, `caption`, `group`, `type`, `initial` and
95
+ `span`. Ranges add `min`, `max` and `step`; menus add `options`.
96
+
97
+ `type` is `"number"`, `"string"` or `"boolean"`. A numeric vector has
98
+ type `"number"` and an array as its `initial` value.
99
+
100
+ `span` gives the source offsets `[start, end]` of the value. An editor can
101
+ use them to update one setting:
102
+
103
+ ```js
104
+ const width = settings.find((p) => p.name === 'width');
105
+ if (width) {
106
+ const next = source.slice(0, width.span[0]) + '120' + source.slice(width.span[1]);
107
+ }
108
+ ```
109
+
110
+ Read the settings again after editing the source; the offsets refer to the
111
+ string passed to `parameters()`.
112
+
113
+ ## Errors
114
+
115
+ Language errors use `KerfError`. Its `line` and `col` identify the source
116
+ location when available, and `echoes` contains output produced before the
117
+ error. `missingFonts` lists fonts the application needs to supply.
118
+
119
+ ```js
120
+ import { KerfError, render } from '@mylasertools/kerfscript';
121
+
122
+ try {
123
+ render('rect([80, 50]);');
124
+ } catch (error) {
125
+ if (error instanceof KerfError) {
126
+ console.error(error.message, error.line, error.col);
127
+ } else {
128
+ throw error;
129
+ }
130
+ }
131
+ ```
132
+
133
+ ## Running untrusted code
134
+
135
+ Run browser renders in a web worker so they do not block the page. Set a
136
+ timeout and terminate the worker if it takes too long. Evaluation limits
137
+ bound program steps and recursion, but geometry work also takes time.
138
+
139
+ Memory limits stop a program before it asks for more memory than a browser
140
+ tab can give: part copies, circle segments, list sizes, text length, shape
141
+ points, exported points and sheets. The defaults are in
142
+ [Limits](../LANGUAGE.md#limits) and in `DEFAULT_LIMITS`. Lower them with the
143
+ `limits` option if your worker has little memory:
144
+
145
+ ```js
146
+ import { render, DEFAULT_LIMITS } from '@mylasertools/kerfscript';
147
+
148
+ render(source, { limits: { maxPoints: DEFAULT_LIMITS.maxPoints / 2 } });
149
+ ```
150
+
151
+ KerfScript programs have no direct file or network access. `use` and
152
+ `include` can load the standard library and sources returned by your
153
+ `resolve` callback. Restrict that callback to libraries you intend to expose.
package/docs/kerf.md ADDED
@@ -0,0 +1,67 @@
1
+ # Kerf
2
+
3
+ Kerf is the width of material removed by a laser cut. Allowing for it helps
4
+ parts finish at the intended size and joints fit together. Measure it for
5
+ the material and cutting settings you use.
6
+
7
+ ## Setting it
8
+
9
+ Set `$kerf` in millimetres:
10
+
11
+ ```kerf
12
+ $kerf = 0.15;
13
+ ```
14
+
15
+ With this value, KerfScript moves an outer cut path outward by 0.075 mm and
16
+ a hole's path inward by the same amount. The offset compensates for material
17
+ removed on either side of the beam.
18
+
19
+ Only closed cut outlines receive the offset. Engraving, scoring and open
20
+ cuts such as living hinges keep their original paths.
21
+
22
+ To use a value for a particular material, set it inside `material()`:
23
+
24
+ ```kerf
25
+ material(thickness = 4, kerf = 0.12, name = "birch") {
26
+ part("side", qty = 2) finger_rect([100, 60], "out");
27
+ }
28
+ ```
29
+
30
+ On the command line, `--kerf 0.1` overrides the value for every part. Apply
31
+ kerf compensation in either KerfScript or your laser software, once per job.
32
+
33
+ ## Measuring your kerf
34
+
35
+ 1. Cut the [calibration square](../examples/calibration-square.kerf) with
36
+ `$kerf = 0`. Leave any offset in your laser software at zero too.
37
+ 2. Measure the square across the middle with calipers.
38
+ 3. Subtract that measurement from 100 mm. A square measuring 99.82 mm gives
39
+ a kerf of 0.18 mm.
40
+ 4. Set `$kerf = 0.18` and cut another sample. Check the outside against
41
+ 100 mm and the hole against 20 mm, then adjust the value if needed.
42
+
43
+ Repeat the measurement when the material or cutting settings change. Thick
44
+ material can have a different cut width at its top and bottom faces.
45
+
46
+ ## Checking a fit
47
+
48
+ After calibrating kerf, measure your sheet's thickness and set `$thickness`
49
+ to that measurement. The nominal thickness on a material label can differ
50
+ from the sheet itself.
51
+
52
+ The [kerf and fit test](../examples/kerf-test.kerf) cuts slots slightly
53
+ narrower and wider than `$thickness`. Try a scrap from the same sheet in each
54
+ slot. A positive label means a wider slot; a negative label means a narrower
55
+ one. Choose the fit you need and use the result to refine your dimensions.
56
+
57
+ Both kerf and sheet thickness affect the fit. A tight or loose slot alone
58
+ does not tell you which value needs adjusting.
59
+
60
+ ## Limits
61
+
62
+ - Compensation can close a hole or notch narrower than the kerf. KerfScript
63
+ warns when a hole disappears.
64
+ - Narrow bridges and fingers may be fragile or char during cutting even
65
+ when their dimensions are correct. Test small features in your material.
66
+ - Compensation adjusts the 2D outline. It does not remove taper from the
67
+ cut face in thick material.
package/docs/layers.md ADDED
@@ -0,0 +1,108 @@
1
+ # Layers
2
+
3
+ Layers separate cutting, scoring and engraving in the exported file. Use
4
+ them to give different parts of a design different operations in your laser
5
+ software. Unassigned shapes go on the `cut` layer.
6
+
7
+ ## The built-in layers
8
+
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
+
16
+ This coaster has a cut outline and hole, an engraved ring and a scored border:
17
+
18
+ ```kerf
19
+ difference() {
20
+ circle(d = 90);
21
+ circle(d = 6);
22
+ }
23
+ engrave() difference() { circle(d = 74); circle(d = 68); }
24
+ score() circle(d = 84);
25
+ ```
26
+
27
+ The layer describes the operation. Set its power, speed and passes in your
28
+ laser software.
29
+
30
+ Place `#` or `%` before a module call to move it to the guide layer.
31
+ Guides are excluded from the output unless you request them with
32
+ `--guides` on the command line or `guides: true` in the API.
33
+
34
+ ## Areas and lines
35
+
36
+ Shapes such as `rect()`, `circle()` and `text()` define areas. On an
37
+ engrave layer, those areas are filled. On cut and score layers, their
38
+ outlines become paths.
39
+
40
+ `line()`, `polyline()`, `arc()` and `living_hinge()` produce lines. They
41
+ remain lines on every layer. A living hinge, for example, is a pattern of
42
+ open cuts within a part.
43
+
44
+ Use `stroke(width)` to turn a line into an area of a specified width. Use
45
+ `outline()` to turn an area's boundary into lines.
46
+
47
+ ### Overlapping shapes merge
48
+
49
+ The areas inside one `score()` are merged first, like a `union()`, and
50
+ only the outline of the result is scored. Two nested circles become one
51
+ disc, so this scores a single ring:
52
+
53
+ ```kerf
54
+ circle(d = 60);
55
+ score() {
56
+ circle(d = 50);
57
+ circle(d = 40); // inside the first circle: merged away
58
+ }
59
+ ```
60
+
61
+ To score every shape's own outline, turn each one into lines first with
62
+ `outline()`. Lines are never merged, so this scores both rings:
63
+
64
+ ```kerf
65
+ circle(d = 60);
66
+ score() {
67
+ outline() circle(d = 50);
68
+ outline() circle(d = 40);
69
+ }
70
+ ```
71
+
72
+ One `outline()` around both circles would not help: it merges them before
73
+ it traces them. The same rule holds on the cut layer and on custom
74
+ layers. Use `difference()` when you want the area between two outlines,
75
+ such as a ring to engrave.
76
+
77
+ ## The material
78
+
79
+ Closed shapes on a part's cut layer define its material. KerfScript clips
80
+ engraving, scoring and open cut lines to that area, excluding holes. Start
81
+ with a cut shape when adding marks to a part.
82
+
83
+ If the cut shapes form separate pieces, KerfScript reports a warning. Check
84
+ for a missing connection or define the pieces as separate parts.
85
+
86
+ ## Your own layers
87
+
88
+ Use `layer(name, mode, color)` when you need another operation, such as a
89
+ second engraving depth:
90
+
91
+ ```kerf
92
+ rect([60, 40]);
93
+ layer("deep", mode = "fill", color = "#00aa00")
94
+ translate([10, 10]) rect([20, 20]);
95
+ engrave() translate([40, 20]) circle(d = 12);
96
+ ```
97
+
98
+ The rectangle and circle use separate engraving layers. You can assign each
99
+ a different power in your laser software. Supported modes are `"cut"`,
100
+ `"line"`, `"fill"` and `"guide"`.
101
+
102
+ ## Order in the file
103
+
104
+ KerfScript writes layers in this order: engrave, custom layers, score, cut,
105
+ then guide. Within a cut layer, inner paths precede outer outlines.
106
+
107
+ Laser software may reorder these paths. Check its job preview so engraving
108
+ runs before cutting and holes are cut before the surrounding part.
@@ -0,0 +1,71 @@
1
+ # Coming from OpenSCAD
2
+
3
+ KerfScript uses syntax familiar to OpenSCAD users, with features for laser
4
+ cutting. Existing OpenSCAD files may need changes to run in KerfScript.
5
+ This guide covers the shared syntax and the differences that affect a port.
6
+
7
+ ## The same
8
+
9
+ You can use familiar building blocks:
10
+
11
+ - Modules, functions, `for`, `if`, `let`, `each`, list comprehensions,
12
+ ranges and function literals.
13
+ - `children()`, `children(i)` and `$children`.
14
+ - Dynamically scoped `$` variables, plus `$fn`, `$fa` and `$fs` for curve
15
+ resolution.
16
+ - 2D shapes: `square()` or `rect()`, `circle()`, `polygon()` and `text()`.
17
+ - Transforms: `translate`, `rotate`, `scale`, `mirror` and `multmatrix`.
18
+ - Shape operations: `union`, `difference`, `intersection`, `hull` and `offset`.
19
+ - `echo()`, `assert()`, `use <...>` and `include <...>`.
20
+ - Customizer comments for ranges, choices, groups and captions.
21
+
22
+ See the [language reference](../LANGUAGE.md) for supported arguments.
23
+
24
+ ## Different
25
+
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
+
36
+ Assignment order is especially important when adapting a design. A value
37
+ assigned later in a KerfScript program does not change earlier geometry.
38
+
39
+ ## Not in KerfScript
40
+
41
+ KerfScript does not support `cube`, `sphere`, `cylinder`, `polyhedron`,
42
+ `linear_extrude`, `rotate_extrude` or `projection`. It also does not support
43
+ `minkowski`, `resize`, `color`, `import`, `surface` or `render`.
44
+
45
+ Calls to these modules produce an error. For a design based on an extruded
46
+ 2D outline, start with that outline and remove the extrusion.
47
+
48
+ ## Only in KerfScript
49
+
50
+ - **Operations:** `cut()`, `score()`, `engrave()`, `guide()` and `layer()`.
51
+ - **Material settings:** `$kerf` for cut compensation and `$thickness` for
52
+ material-dependent joints.
53
+ - **Parts and layout:** `part()`, `material()`, quantities, `$sheet` and `$gap`.
54
+ - **Joinery:** `finger_rect`, `finger_holes`, `tslot` and `living_hinge`.
55
+ - **Paths:** `line`, `polyline`, `arc`, `path`, `stroke` and `outline`.
56
+ - **Additional shapes:** `ellipse`, `regular_polygon`, `star` and rounded
57
+ rectangles with `rect(r = ...)`.
58
+ - **Text measurement:** `text_width()` and `text_metrics()`.
59
+
60
+ ## Porting a 2D design
61
+
62
+ 1. Keep the 2D geometry and remove extrusion or other 3D operations.
63
+ 2. Assign shapes to cut, score or engrave layers.
64
+ 3. Check repeated assignments and put each value before the code that uses it.
65
+ 4. Supply the fonts used by `text()`.
66
+ 5. Set the measured material thickness and kerf. Use the joinery modules
67
+ where they suit the design.
68
+
69
+ Render the result and check the dimensions and layers before exporting.
70
+ The [layers](layers.md), [kerf](kerf.md) and
71
+ [parts and sheets](parts-and-sheets.md) guides cover those steps.
@@ -0,0 +1,82 @@
1
+ # Parts and sheets
2
+
3
+ Use parts to name the pieces in a design, set quantities and assign
4
+ materials. KerfScript lays them out on sheets, grouping parts that use the
5
+ same material and thickness.
6
+
7
+ ## Parts
8
+
9
+ ```kerf
10
+ part("side", qty = 2) rect([100, 60]);
11
+ part("base") rect([100, 100]);
12
+ ```
13
+
14
+ This creates two side panels and one base. Each `part()` has its own layers
15
+ and appears in the parts list with dimensions and cut length. The default
16
+ quantity is one.
17
+
18
+ Shapes outside a `part()` are collected into a part named `part`.
19
+
20
+ Transforms and operations such as `translate()`, `difference()` and
21
+ `offset()` can wrap a part and change all of it. Layer wrappers such as
22
+ `score()` and `engrave()` go inside the part instead, since a whole part on
23
+ the score layer would have nothing to cut:
24
+
25
+ ```kerf
26
+ part("tag") {
27
+ rect([60, 30], r = 3);
28
+ score() translate([5, 5]) rect([50, 20]);
29
+ }
30
+ ```
31
+
32
+ ## Materials
33
+
34
+ `material()` sets the thickness, kerf and material name for its parts:
35
+
36
+ ```kerf
37
+ material(thickness = 3, kerf = 0.15, name = "plywood") {
38
+ part("front") rect([100, 60]);
39
+ part("back") rect([100, 60]);
40
+ }
41
+ material(thickness = 2, kerf = 0.1, name = "acrylic") {
42
+ part("window") rect([80, 40]);
43
+ }
44
+ ```
45
+
46
+ The two plywood panels share a sheet. The acrylic window goes on a separate
47
+ sheet. Each part records the `$thickness`, `$kerf` and `$material` values in
48
+ effect where it is defined.
49
+
50
+ ## Sheets
51
+
52
+ Set the available sheet size and spacing in millimetres:
53
+
54
+ ```kerf
55
+ $sheet = [300, 200];
56
+ $gap = 4;
57
+ ```
58
+
59
+ With the default `$layout = "pack"`, KerfScript arranges copies of each part
60
+ in rows, leaving the specified gap. It rotates a part 90° if that lets it
61
+ fit the sheet. The default sheet is 600 × 400 mm, with a 3 mm gap between
62
+ parts and at the sheet edges.
63
+
64
+ A part larger than the sheet produces a warning. Set `$layout = "none"`
65
+ to keep the positions from your code instead of packing the parts.
66
+
67
+ The CLI `--margin` option and API `margin` option let you set the edge
68
+ spacing separately from the gap between parts.
69
+
70
+ ## One file per sheet
71
+
72
+ A combined SVG stacks all sheets in one preview. For the material example
73
+ above, export the plywood and acrylic sheets separately and cut each with
74
+ the matching material settings.
75
+
76
+ - On the command line, add `--split` to write `design-1.svg`,
77
+ `design-2.svg` and so on. `kerf check` lists each sheet's material and
78
+ thickness.
79
+ - In JavaScript, `result.sheets` provides the SVG, DXF, material and
80
+ thickness for each sheet.
81
+
82
+ DXF exports contain one sheet per file.
@@ -0,0 +1,33 @@
1
+ # Versions
2
+
3
+ KerfScript 0.2.0 implements language version 0.1. The package version tracks
4
+ the software release; the language version tracks the syntax and behavior
5
+ of `.kerf` programs.
6
+
7
+ Package updates can include bug fixes, export options and JavaScript API
8
+ changes without changing the language version. Use `kerf --version` to see
9
+ both numbers, or read the `VERSION` and `LANGUAGE_VERSION` exports in JavaScript.
10
+
11
+ ## Before 1.0
12
+
13
+ The language may change before 1.0. Release notes identify changes that
14
+ affect existing programs or their output, including geometry and text layout
15
+ fixes. Removing or renaming a language feature requires a new language version.
16
+
17
+ Check the changelog when upgrading a tool that renders saved designs.
18
+
19
+ ## From 1.0
20
+
21
+ The compatibility policy for language version 1.x is to keep existing
22
+ programs working throughout that series. New features will be added without
23
+ changing existing syntax. Bug fixes that affect output will be listed in
24
+ the changelog; other breaking changes will require language version 2.0.
25
+
26
+ ## Pinning a version
27
+
28
+ For repeatable exports, record the interpreter version, settings and font
29
+ files used with a design. Applications that store designs should retain
30
+ that information and compare the output before upgrading the interpreter.
31
+
32
+ Pin the npm package to an exact version when your application needs a fixed
33
+ renderer, for example `@mylasertools/kerfscript@0.2.0`.