Recusive docs (#4023)
updates updates updates updates updates updates better updates array of updates updates updates updates Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
		| @ -17,7 +17,7 @@ arrayReduce(array: [u64], start: Sketch, reduce_fn: FunctionParam) -> Sketch | ||||
|  | ||||
| | Name | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `array` | [`[u64]`](/docs/kcl/types/[u64]) |  | Yes | | ||||
| | `array` | `[u64]` |  | Yes | | ||||
| | `start` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes | | ||||
| | `reduce_fn` | `FunctionParam` |  | Yes | | ||||
|  | ||||
|  | ||||
| @ -17,7 +17,7 @@ line(delta: [number], sketch: Sketch, tag?: TagDeclarator) -> Sketch | ||||
|  | ||||
| | Name | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `delta` | [`[number]`](/docs/kcl/types/[number]) |  | Yes | | ||||
| | `delta` | `[number]` |  | Yes | | ||||
| | `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes | | ||||
| | `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) |  | No | | ||||
|  | ||||
|  | ||||
| @ -17,7 +17,7 @@ lineTo(to: [number], sketch: Sketch, tag?: TagDeclarator) -> Sketch | ||||
|  | ||||
| | Name | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `to` | [`[number]`](/docs/kcl/types/[number]) |  | Yes | | ||||
| | `to` | `[number]` |  | Yes | | ||||
| | `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes | | ||||
| | `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) |  | No | | ||||
|  | ||||
|  | ||||
| @ -17,7 +17,7 @@ loft(sketches: [Sketch], data?: LoftData) -> Solid | ||||
|  | ||||
| | Name | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `sketches` | [`[Sketch]`](/docs/kcl/types/[Sketch]) |  | Yes | | ||||
| | `sketches` | [`[Sketch]`](/docs/kcl/types/Sketch) |  | Yes | | ||||
| | `data` | [`LoftData`](/docs/kcl/types/LoftData) | Data for a loft. | No | | ||||
|  | ||||
| ### Returns | ||||
|  | ||||
| @ -21,7 +21,7 @@ max(args: [number]) -> number | ||||
|  | ||||
| | Name | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `args` | [`[number]`](/docs/kcl/types/[number]) |  | Yes | | ||||
| | `args` | `[number]` |  | Yes | | ||||
|  | ||||
| ### Returns | ||||
|  | ||||
|  | ||||
| @ -21,7 +21,7 @@ min(args: [number]) -> number | ||||
|  | ||||
| | Name | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `args` | [`[number]`](/docs/kcl/types/[number]) |  | Yes | | ||||
| | `args` | `[number]` |  | Yes | | ||||
|  | ||||
| ### Returns | ||||
|  | ||||
|  | ||||
| @ -23,7 +23,7 @@ mirror2d(data: Mirror2dData, sketch_set: SketchSet) -> [Sketch] | ||||
|  | ||||
| ### Returns | ||||
|  | ||||
| [`[Sketch]`](/docs/kcl/types/[Sketch])  | ||||
| [`[Sketch]`](/docs/kcl/types/Sketch)  | ||||
|  | ||||
|  | ||||
| ### Examples | ||||
|  | ||||
| @ -22,7 +22,7 @@ patternCircular2d(data: CircularPattern2dData, sketch_set: SketchSet) -> [Sketch | ||||
|  | ||||
| ### Returns | ||||
|  | ||||
| [`[Sketch]`](/docs/kcl/types/[Sketch])  | ||||
| [`[Sketch]`](/docs/kcl/types/Sketch)  | ||||
|  | ||||
|  | ||||
| ### Examples | ||||
|  | ||||
| @ -22,7 +22,7 @@ patternCircular3d(data: CircularPattern3dData, solid_set: SolidSet) -> [Solid] | ||||
|  | ||||
| ### Returns | ||||
|  | ||||
| [`[Solid]`](/docs/kcl/types/[Solid])  | ||||
| [`[Solid]`](/docs/kcl/types/Solid)  | ||||
|  | ||||
|  | ||||
| ### Examples | ||||
|  | ||||
| @ -22,7 +22,7 @@ patternLinear2d(data: LinearPattern2dData, sketch_set: SketchSet) -> [Sketch] | ||||
|  | ||||
| ### Returns | ||||
|  | ||||
| [`[Sketch]`](/docs/kcl/types/[Sketch])  | ||||
| [`[Sketch]`](/docs/kcl/types/Sketch)  | ||||
|  | ||||
|  | ||||
| ### Examples | ||||
|  | ||||
| @ -22,7 +22,7 @@ patternLinear3d(data: LinearPattern3dData, solid_set: SolidSet) -> [Solid] | ||||
|  | ||||
| ### Returns | ||||
|  | ||||
| [`[Solid]`](/docs/kcl/types/[Solid])  | ||||
| [`[Solid]`](/docs/kcl/types/Solid)  | ||||
|  | ||||
|  | ||||
| ### Examples | ||||
|  | ||||
| @ -25,7 +25,7 @@ patternTransform(total_instances: u32, transform_function: FunctionParam, solid_ | ||||
|  | ||||
| ### Returns | ||||
|  | ||||
| [`[Solid]`](/docs/kcl/types/[Solid])  | ||||
| [`[Solid]`](/docs/kcl/types/Solid)  | ||||
|  | ||||
|  | ||||
| ### Examples | ||||
|  | ||||
| @ -21,7 +21,7 @@ polar(data: PolarCoordsData) -> [number] | ||||
|  | ||||
| ### Returns | ||||
|  | ||||
| [`[number]`](/docs/kcl/types/[number])  | ||||
| `[number]`  | ||||
|  | ||||
|  | ||||
| ### Examples | ||||
|  | ||||
| @ -21,7 +21,7 @@ profileStart(sketch: Sketch) -> [number] | ||||
|  | ||||
| ### Returns | ||||
|  | ||||
| [`[number]`](/docs/kcl/types/[number])  | ||||
| `[number]`  | ||||
|  | ||||
|  | ||||
| ### Examples | ||||
|  | ||||
| @ -17,7 +17,7 @@ startProfileAt(to: [number], sketch_surface: SketchSurface, tag?: TagDeclarator) | ||||
|  | ||||
| | Name | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `to` | [`[number]`](/docs/kcl/types/[number]) |  | Yes | | ||||
| | `to` | `[number]` |  | Yes | | ||||
| | `sketch_surface` | [`SketchSurface`](/docs/kcl/types/SketchSurface) | A sketch type. | Yes | | ||||
| | `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) |  | No | | ||||
|  | ||||
|  | ||||
| @ -17,7 +17,7 @@ startSketchAt(data: [number]) -> Sketch | ||||
|  | ||||
| | Name | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `data` | [`[number]`](/docs/kcl/types/[number]) |  | Yes | | ||||
| | `data` | `[number]` |  | Yes | | ||||
|  | ||||
| ### Returns | ||||
|  | ||||
|  | ||||
| @ -17,7 +17,7 @@ tangentialArcTo(to: [number], sketch: Sketch, tag?: TagDeclarator) -> Sketch | ||||
|  | ||||
| | Name | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `to` | [`[number]`](/docs/kcl/types/[number]) |  | Yes | | ||||
| | `to` | `[number]` |  | Yes | | ||||
| | `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes | | ||||
| | `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) |  | No | | ||||
|  | ||||
|  | ||||
| @ -17,7 +17,7 @@ tangentialArcToRelative(delta: [number], sketch: Sketch, tag?: TagDeclarator) -> | ||||
|  | ||||
| | Name | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `delta` | [`[number]`](/docs/kcl/types/[number]) |  | Yes | | ||||
| | `delta` | `[number]` |  | Yes | | ||||
| | `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes | | ||||
| | `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) |  | No | | ||||
|  | ||||
|  | ||||
| @ -13,17 +13,10 @@ Data to draw an angled line. | ||||
| An angle and length with explicitly named parameters | ||||
|  | ||||
|  | ||||
| **Type:** `object` | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ## Properties | ||||
|  | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `angle` |`number` (`double`)| The angle of the line (in degrees). | No | | ||||
| | `length` |`number` (`double`)| The length of the line. | No | | ||||
|  | ||||
|  | ||||
| ---- | ||||
|  | ||||
| @ -16,8 +16,8 @@ Data for drawing an angled line that intersects with a given line. | ||||
|  | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `angle` |`number` (`double`)| The angle of the line. | No | | ||||
| | `intersectTag` |`object`| The tag of the line to intersect with. | No | | ||||
| | `offset` |`number` (`double`)| The offset from the intersecting line. | No | | ||||
| | `angle` |`number`| The angle of the line. | No | | ||||
| | `intersectTag` |[`TagIdentifier`](/docs/kcl/types#tag-identifier)| The tag of the line to intersect with. | No | | ||||
| | `offset` |`number`| The offset from the intersecting line. | No | | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -16,7 +16,7 @@ Data to draw an angled line to a point. | ||||
|  | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `angle` |`number` (`double`)| The angle of the line. | No | | ||||
| | `to` |`number` (`double`)| The point to draw to. | No | | ||||
| | `angle` |`number`| The angle of the line. | No | | ||||
| | `to` |`number`| The point to draw to. | No | | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -22,9 +22,9 @@ Angles and radius with an optional tag. | ||||
|  | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `angleStart` |`number` (`double`)| The start angle. | No | | ||||
| | `angleEnd` |`number` (`double`)| The end angle. | No | | ||||
| | `radius` |`number` (`double`)| The radius. | No | | ||||
| | `angleStart` |`number`| The start angle. | No | | ||||
| | `angleEnd` |`number`| The end angle. | No | | ||||
| | `radius` |`number`| The radius. | No | | ||||
|  | ||||
|  | ||||
| ---- | ||||
| @ -40,9 +40,9 @@ Center, to and radius with an optional tag. | ||||
|  | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `center` |`array`| The center. | No | | ||||
| | `to` |`array`| The to point. | No | | ||||
| | `radius` |`number` (`double`)| The radius. | No | | ||||
| | `center` |`[number, number]`| The center. | No | | ||||
| | `to` |`[number, number]`| The to point. | No | | ||||
| | `radius` |`number`| The radius. | No | | ||||
|  | ||||
|  | ||||
| ---- | ||||
|  | ||||
| @ -16,8 +16,8 @@ Data to draw a bezier curve. | ||||
|  | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `to` |`array`| The to point. | No | | ||||
| | `control1` |`array`| The first control point. | No | | ||||
| | `control2` |`array`| The second control point. | No | | ||||
| | `to` |`[number, number]`| The to point. | No | | ||||
| | `control1` |`[number, number]`| The first control point. | No | | ||||
| | `control2` |`[number, number]`| The second control point. | No | | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -16,7 +16,7 @@ Data for chamfers. | ||||
|  | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `length` |`number` (`double`)| The length of the chamfer. | No | | ||||
| | `tags` |`array`| The tags of the paths you want to chamfer. | No | | ||||
| | `length` |`number`| The length of the chamfer. | No | | ||||
| | `tags` |`[` **anyOf:** `string` **OR** [`TagIdentifier`](/docs/kcl/types#tag-identifier) `]`| The tags of the paths you want to chamfer. | No | | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -16,7 +16,7 @@ Data for drawing an circle | ||||
|  | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `center` |`array`| The center of the circle. | No | | ||||
| | `radius` |`number` (`double`)| The circle radius | No | | ||||
| | `center` |`[number, number]`| The center of the circle. | No | | ||||
| | `radius` |`number`| The circle radius | No | | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -16,9 +16,9 @@ Data for a circular pattern on a 2D sketch. | ||||
|  | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `repetitions` |`integer` (`uint32`)| The number of repetitions. Must be greater than 0. This excludes the original entity. For example, if `repetitions` is 1, the original entity will be copied once. | No | | ||||
| | `center` |`array`| The center about which to make the pattern. This is a 2D vector. | No | | ||||
| | `arcDegrees` |`number` (`double`)| The arc angle (in degrees) to place the repetitions. Must be greater than 0. | No | | ||||
| | `repetitions` |`integer`| The number of repetitions. Must be greater than 0. This excludes the original entity. For example, if `repetitions` is 1, the original entity will be copied once. | No | | ||||
| | `center` |`[number, number]`| The center about which to make the pattern. This is a 2D vector. | No | | ||||
| | `arcDegrees` |`number`| The arc angle (in degrees) to place the repetitions. Must be greater than 0. | No | | ||||
| | `rotateDuplicates` |`boolean`| Whether or not to rotate the duplicates as they are copied. | No | | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -16,10 +16,10 @@ Data for a circular pattern on a 3D model. | ||||
|  | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `repetitions` |`integer` (`uint32`)| The number of repetitions. Must be greater than 0. This excludes the original entity. For example, if `repetitions` is 1, the original entity will be copied once. | No | | ||||
| | `axis` |`array`| The axis around which to make the pattern. This is a 3D vector. | No | | ||||
| | `center` |`array`| The center about which to make the pattern. This is a 3D vector. | No | | ||||
| | `arcDegrees` |`number` (`double`)| The arc angle (in degrees) to place the repetitions. Must be greater than 0. | No | | ||||
| | `repetitions` |`integer`| The number of repetitions. Must be greater than 0. This excludes the original entity. For example, if `repetitions` is 1, the original entity will be copied once. | No | | ||||
| | `axis` |`[number, number, number]`| The axis around which to make the pattern. This is a 3D vector. | No | | ||||
| | `center` |`[number, number, number]`| The center about which to make the pattern. This is a 3D vector. | No | | ||||
| | `arcDegrees` |`number`| The arc angle (in degrees) to place the repetitions. Must be greater than 0. | No | | ||||
| | `rotateDuplicates` |`boolean`| Whether or not to rotate the duplicates as they are copied. | No | | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -46,18 +46,10 @@ The end face after you extruded. This could also be known as the top face. But w | ||||
| A tag for the face. | ||||
|  | ||||
|  | ||||
| **Type:** `object` | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ## Properties | ||||
|  | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `value` |`string`|  | No | | ||||
| | `info` |`object`| Engine information for a tag. | No | | ||||
| | `__meta` |`array`|  | No | | ||||
|  | ||||
|  | ||||
| ---- | ||||
|  | ||||
| @ -16,8 +16,8 @@ Data for fillets. | ||||
|  | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `radius` |`number` (`double`)| The radius of the fillet. | No | | ||||
| | `tags` |`array`| The tags of the paths you want to fillet. | No | | ||||
| | `tolerance` |`number` (`double`)| The tolerance for the fillet. | No | | ||||
| | `radius` |`number`| The radius of the fillet. | No | | ||||
| | `tags` |`[` **anyOf:** `string` **OR** [`TagIdentifier`](/docs/kcl/types#tag-identifier) `]`| The tags of the paths you want to fillet. | No | | ||||
| | `tolerance` |`number`| The tolerance for the fillet. | No | | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -16,9 +16,9 @@ Data for helices. | ||||
|  | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `revolutions` |`number` (`double`)| Number of revolutions. | No | | ||||
| | `angleStart` |`number` (`double`)| Start angle (in degrees). | No | | ||||
| | `revolutions` |`number`| Number of revolutions. | No | | ||||
| | `angleStart` |`number`| Start angle (in degrees). | No | | ||||
| | `ccw` |`boolean`| Is the helix rotation counter clockwise? The default is `false`. | No | | ||||
| | `length` |`number` (`double`)| Length of the helix. If this argument is not provided, the height of the solid is used. | No | | ||||
| | `length` |`number`| Length of the helix. If this argument is not provided, the height of the solid is used. | No | | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -57,7 +57,7 @@ Wavefront OBJ format. | ||||
| |----------|------|-------------|----------| | ||||
| | `type` |enum: `obj`|  | No | | ||||
| | `coords` |`object`| Co-ordinate system of input data. Defaults to the [KittyCAD co-ordinate system. | No | | ||||
| | `units` |`oneOf`| The units of the input data. This is very important for correct scaling and when calculating physics properties like mass, etc. Defaults to millimeters. | No | | ||||
| | `units` |**oneOf:** enum: `cm` **OR** enum: `ft` **OR** enum: `in` **OR** enum: `m` **OR** enum: `mm` **OR** enum: `yd`| The units of the input data. This is very important for correct scaling and when calculating physics properties like mass, etc. Defaults to millimeters. | No | | ||||
|  | ||||
|  | ||||
| ---- | ||||
| @ -75,7 +75,7 @@ The PLY Polygon File Format. | ||||
| |----------|------|-------------|----------| | ||||
| | `type` |enum: `ply`|  | No | | ||||
| | `coords` |`object`| Co-ordinate system of input data. Defaults to the [KittyCAD co-ordinate system. | No | | ||||
| | `units` |`oneOf`| The units of the input data. This is very important for correct scaling and when calculating physics properties like mass, etc. Defaults to millimeters. | No | | ||||
| | `units` |**oneOf:** enum: `cm` **OR** enum: `ft` **OR** enum: `in` **OR** enum: `m` **OR** enum: `mm` **OR** enum: `yd`| The units of the input data. This is very important for correct scaling and when calculating physics properties like mass, etc. Defaults to millimeters. | No | | ||||
|  | ||||
|  | ||||
| ---- | ||||
| @ -125,7 +125,7 @@ ST**ereo**L**ithography format. | ||||
| |----------|------|-------------|----------| | ||||
| | `type` |enum: `stl`|  | No | | ||||
| | `coords` |`object`| Co-ordinate system of input data. Defaults to the [KittyCAD co-ordinate system. | No | | ||||
| | `units` |`oneOf`| The units of the input data. This is very important for correct scaling and when calculating physics properties like mass, etc. Defaults to millimeters. | No | | ||||
| | `units` |**oneOf:** enum: `cm` **OR** enum: `ft` **OR** enum: `in` **OR** enum: `m` **OR** enum: `mm` **OR** enum: `yd`| The units of the input data. This is very important for correct scaling and when calculating physics properties like mass, etc. Defaults to millimeters. | No | | ||||
|  | ||||
|  | ||||
| ---- | ||||
|  | ||||
| @ -16,8 +16,8 @@ Data for an imported geometry. | ||||
|  | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `id` |`string` (`uuid`)| The ID of the imported geometry. | No | | ||||
| | `value` |`array`| The original file paths. | No | | ||||
| | `__meta` |`array`|  | No | | ||||
| | `id` |`string`| The ID of the imported geometry. | No | | ||||
| | `value` |`[` `string` `]`| The original file paths. | No | | ||||
| | `__meta` |`[` `object` `]`|  | No | | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -16,8 +16,8 @@ Data for a linear pattern on a 2D sketch. | ||||
|  | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `repetitions` |`integer` (`uint32`)| The number of repetitions. Must be greater than 0. This excludes the original entity. For example, if `repetitions` is 1, the original entity will be copied once. | No | | ||||
| | `distance` |`number` (`double`)| The distance between each repetition. This can also be referred to as spacing. | No | | ||||
| | `axis` |`array`| The axis of the pattern. This is a 2D vector. | No | | ||||
| | `repetitions` |`integer`| The number of repetitions. Must be greater than 0. This excludes the original entity. For example, if `repetitions` is 1, the original entity will be copied once. | No | | ||||
| | `distance` |`number`| The distance between each repetition. This can also be referred to as spacing. | No | | ||||
| | `axis` |`[number, number]`| The axis of the pattern. This is a 2D vector. | No | | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -16,8 +16,8 @@ Data for a linear pattern on a 3D model. | ||||
|  | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `repetitions` |`integer` (`uint32`)| The number of repetitions. Must be greater than 0. This excludes the original entity. For example, if `repetitions` is 1, the original entity will be copied once. | No | | ||||
| | `distance` |`number` (`double`)| The distance between each repetition. This can also be referred to as spacing. | No | | ||||
| | `axis` |`array`| The axis of the pattern. | No | | ||||
| | `repetitions` |`integer`| The number of repetitions. Must be greater than 0. This excludes the original entity. For example, if `repetitions` is 1, the original entity will be copied once. | No | | ||||
| | `distance` |`number`| The distance between each repetition. This can also be referred to as spacing. | No | | ||||
| | `axis` |`[number, number, number]`| The axis of the pattern. | No | | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -16,9 +16,9 @@ Data for a loft. | ||||
|  | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `vDegree` |`integer` (`uint32`)| Degree of the interpolation. Must be greater than zero. For example, use 2 for quadratic, or 3 for cubic interpolation in the V direction. This defaults to 2, if not specified. | No | | ||||
| | `vDegree` |`integer`| Degree of the interpolation. Must be greater than zero. For example, use 2 for quadratic, or 3 for cubic interpolation in the V direction. This defaults to 2, if not specified. | No | | ||||
| | `bezApproximateRational` |`boolean`| Attempt to approximate rational curves (such as arcs) using a bezier. This will remove banding around interpolations between arcs and non-arcs.  It may produce errors in other scenarios Over time, this field won't be necessary. | No | | ||||
| | `baseCurveIndex` |`integer` (`uint32`)| This can be set to override the automatically determined topological base curve, which is usually the first section encountered. | No | | ||||
| | `tolerance` |`number` (`double`)| Tolerance for the loft operation. | No | | ||||
| | `baseCurveIndex` |`integer`| This can be set to override the automatically determined topological base curve, which is usually the first section encountered. | No | | ||||
| | `tolerance` |`number`| Tolerance for the loft operation. | No | | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -16,6 +16,6 @@ Data for a mirror. | ||||
|  | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `axis` |`anyOf`| Axis to use as mirror. | No | | ||||
| | `axis` |**anyOf:** **oneOf:** enum: `X` **OR** enum: `Y` **OR** enum: `-X` **OR** enum: `-Y` **OR** `object` **OR** **anyOf:** `string` **OR** [`TagIdentifier`](/docs/kcl/types#tag-identifier)| Axis to use as mirror. | No | | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -16,7 +16,7 @@ Data for polar coordinates. | ||||
|  | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `angle` |`number` (`double`)| The angle of the line (in degrees). | No | | ||||
| | `length` |`number` (`double`)| The length of the line. | No | | ||||
| | `angle` |`number`| The angle of the line (in degrees). | No | | ||||
| | `length` |`number`| The length of the line. | No | | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -16,8 +16,8 @@ Data for revolution surfaces. | ||||
|  | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `angle` |`number` (`double`)| Angle to revolve (in degrees). Default is 360. | No | | ||||
| | `axis` |`anyOf`| Axis of revolution. | No | | ||||
| | `tolerance` |`number` (`double`)| Tolerance for the revolve operation. | No | | ||||
| | `angle` |`number`| Angle to revolve (in degrees). Default is 360. | No | | ||||
| | `axis` |**anyOf:** **oneOf:** enum: `X` **OR** enum: `Y` **OR** enum: `-X` **OR** enum: `-Y` **OR** `object` **OR** **anyOf:** `string` **OR** [`TagIdentifier`](/docs/kcl/types#tag-identifier)| Axis of revolution. | No | | ||||
| | `tolerance` |`number`| Tolerance for the revolve operation. | No | | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -16,7 +16,7 @@ Data for shells. | ||||
|  | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `thickness` |`number` (`double`)| The thickness of the shell. | No | | ||||
| | `faces` |`array`| The faces you want removed. | No | | ||||
| | `thickness` |`number`| The thickness of the shell. | No | | ||||
| | `faces` |`[` **anyOf:** **oneOf:** enum: `start` **OR** enum: `end` **OR** [`TagIdentifier`](/docs/kcl/types#tag-identifier) `]`| The faces you want removed. | No | | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -16,11 +16,11 @@ A sketch is a collection of paths. | ||||
|  | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `id` |`string` (`uuid`)| The id of the sketch (this will change when the engine's reference to it changes. | No | | ||||
| | `value` |`array`| The paths in the sketch. | No | | ||||
| | `on` |`oneOf`| What the sketch is on (can be a plane or a face). | No | | ||||
| | `id` |`string`| The id of the sketch (this will change when the engine's reference to it changes. | No | | ||||
| | `value` |`[` **oneOf:** `object` **OR** `object` **OR** `object` **OR** `object` **OR** `object` **OR** `object` **OR** `object` `]`| The paths in the sketch. | No | | ||||
| | `on` |**oneOf:** `object` **OR** `object`| What the sketch is on (can be a plane or a face). | No | | ||||
| | `start` |`object`| The starting path. | No | | ||||
| | `tags` |`object`| Tag identifiers that have been declared in this sketch. | No | | ||||
| | `__meta` |`array`| Metadata. | No | | ||||
| | `__meta` |`[` `object` `]`| Metadata. | No | | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -15,90 +15,6 @@ Data for a plane. | ||||
|  | ||||
|  | ||||
|  | ||||
| **This schema accepts exactly one of the following:** | ||||
|  | ||||
| The XY plane. | ||||
|  | ||||
|  | ||||
| **enum:** `XY` | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ---- | ||||
| The opposite side of the XY plane. | ||||
|  | ||||
|  | ||||
| **enum:** `-XY` | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ---- | ||||
| The XZ plane. | ||||
|  | ||||
|  | ||||
| **enum:** `XZ` | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ---- | ||||
| The opposite side of the XZ plane. | ||||
|  | ||||
|  | ||||
| **enum:** `-XZ` | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ---- | ||||
| The YZ plane. | ||||
|  | ||||
|  | ||||
| **enum:** `YZ` | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ---- | ||||
| The opposite side of the YZ plane. | ||||
|  | ||||
|  | ||||
| **enum:** `-YZ` | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ---- | ||||
| A defined plane. | ||||
|  | ||||
|  | ||||
| **Type:** `object` | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ## Properties | ||||
|  | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `plane` |`object`|  | No | | ||||
|  | ||||
|  | ||||
| ---- | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -116,14 +32,14 @@ An solid is a collection of extrude surfaces. | ||||
|  | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `id` |`string` (`uuid`)| The id of the solid. | No | | ||||
| | `value` |`array`| The extrude surfaces. | No | | ||||
| | `id` |`string`| The id of the solid. | No | | ||||
| | `value` |`[` **oneOf:** `object` **OR** `object` **OR** `object` **OR** `object` `]`| The extrude surfaces. | No | | ||||
| | `sketch` |`object`| The sketch. | No | | ||||
| | `height` |`number` (`double`)| The height of the solid. | No | | ||||
| | `startCapId` |`string` (`uuid`)| The id of the extrusion start cap | No | | ||||
| | `endCapId` |`string` (`uuid`)| The id of the extrusion end cap | No | | ||||
| | `edgeCuts` |`array`| Chamfers or fillets on this solid. | No | | ||||
| | `__meta` |`array`| Metadata. | No | | ||||
| | `height` |`number`| The height of the solid. | No | | ||||
| | `startCapId` |`string`| The id of the extrusion start cap | No | | ||||
| | `endCapId` |`string`| The id of the extrusion end cap | No | | ||||
| | `edgeCuts` |`[` **oneOf:** `object` **OR** `object` `]`| Chamfers or fillets on this solid. | No | | ||||
| | `__meta` |`[` `object` `]`| Metadata. | No | | ||||
|  | ||||
|  | ||||
| ---- | ||||
|  | ||||
| @ -30,13 +30,13 @@ A plane. | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `type` |enum: `plane`|  | No | | ||||
| | `id` |`string` (`uuid`)| The id of the plane. | No | | ||||
| | `value` |`oneOf`| Type for a plane. | No | | ||||
| | `id` |`string`| The id of the plane. | No | | ||||
| | `value` |**oneOf:** enum: `XY`, `XZ`, `YZ` **OR** enum: `Custom`| Type for a plane. | No | | ||||
| | `origin` |`object`| Origin of the plane. | No | | ||||
| | `xAxis` |`object`| What should the plane’s X axis be? | No | | ||||
| | `yAxis` |`object`| What should the plane’s Y axis be? | No | | ||||
| | `zAxis` |`object`| The z-axis (normal). | No | | ||||
| | `__meta` |`array`|  | No | | ||||
| | `__meta` |`[` `object` `]`|  | No | | ||||
|  | ||||
|  | ||||
| ---- | ||||
| @ -53,13 +53,13 @@ A face. | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `type` |enum: `face`|  | No | | ||||
| | `id` |`string` (`uuid`)| The id of the face. | No | | ||||
| | `id` |`string`| The id of the face. | No | | ||||
| | `value` |`string`| The tag of the face. | No | | ||||
| | `xAxis` |`object`| What should the face’s X axis be? | No | | ||||
| | `yAxis` |`object`| What should the face’s Y axis be? | No | | ||||
| | `zAxis` |`object`| The z-axis (normal). | No | | ||||
| | `solid` |`object`| The solid the face is on. | No | | ||||
| | `__meta` |`array`|  | No | | ||||
| | `__meta` |`[` `object` `]`|  | No | | ||||
|  | ||||
|  | ||||
| ---- | ||||
| @ -80,12 +80,12 @@ A sketch is a collection of paths. | ||||
|  | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `id` |`string` (`uuid`)| The id of the sketch (this will change when the engine's reference to it changes. | No | | ||||
| | `value` |`array`| The paths in the sketch. | No | | ||||
| | `on` |`oneOf`| What the sketch is on (can be a plane or a face). | No | | ||||
| | `id` |`string`| The id of the sketch (this will change when the engine's reference to it changes. | No | | ||||
| | `value` |`[` **oneOf:** `object` **OR** `object` **OR** `object` **OR** `object` **OR** `object` **OR** `object` **OR** `object` `]`| The paths in the sketch. | No | | ||||
| | `on` |**oneOf:** `object` **OR** `object`| What the sketch is on (can be a plane or a face). | No | | ||||
| | `start` |`object`| The starting path. | No | | ||||
| | `tags` |`object`| Tag identifiers that have been declared in this sketch. | No | | ||||
| | `__meta` |`array`| Metadata. | No | | ||||
| | `__meta` |`[` `object` `]`| Metadata. | No | | ||||
|  | ||||
|  | ||||
| ---- | ||||
|  | ||||
| @ -24,12 +24,12 @@ A sketch is a collection of paths. | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `type` |enum: `sketch`|  | No | | ||||
| | `id` |`string` (`uuid`)| The id of the sketch (this will change when the engine's reference to it changes. | No | | ||||
| | `value` |`array`| The paths in the sketch. | No | | ||||
| | `on` |`oneOf`| What the sketch is on (can be a plane or a face). | No | | ||||
| | `id` |`string`| The id of the sketch (this will change when the engine's reference to it changes. | No | | ||||
| | `value` |`[` **oneOf:** `object` **OR** `object` **OR** `object` **OR** `object` **OR** `object` **OR** `object` **OR** `object` `]`| The paths in the sketch. | No | | ||||
| | `on` |**oneOf:** `object` **OR** `object`| What the sketch is on (can be a plane or a face). | No | | ||||
| | `start` |`object`| The starting path. | No | | ||||
| | `tags` |`object`| Tag identifiers that have been declared in this sketch. | No | | ||||
| | `__meta` |`array`| Metadata. | No | | ||||
| | `__meta` |`[` `object` `]`| Metadata. | No | | ||||
|  | ||||
|  | ||||
| ---- | ||||
|  | ||||
| @ -24,13 +24,13 @@ A plane. | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `type` |enum: `plane`|  | No | | ||||
| | `id` |`string` (`uuid`)| The id of the plane. | No | | ||||
| | `value` |`oneOf`| Type for a plane. | No | | ||||
| | `id` |`string`| The id of the plane. | No | | ||||
| | `value` |**oneOf:** enum: `XY`, `XZ`, `YZ` **OR** enum: `Custom`| Type for a plane. | No | | ||||
| | `origin` |`object`| Origin of the plane. | No | | ||||
| | `xAxis` |`object`| What should the plane’s X axis be? | No | | ||||
| | `yAxis` |`object`| What should the plane’s Y axis be? | No | | ||||
| | `zAxis` |`object`| The z-axis (normal). | No | | ||||
| | `__meta` |`array`|  | No | | ||||
| | `__meta` |`[` `object` `]`|  | No | | ||||
|  | ||||
|  | ||||
| ---- | ||||
| @ -47,13 +47,13 @@ A face. | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `type` |enum: `face`|  | No | | ||||
| | `id` |`string` (`uuid`)| The id of the face. | No | | ||||
| | `id` |`string`| The id of the face. | No | | ||||
| | `value` |`string`| The tag of the face. | No | | ||||
| | `xAxis` |`object`| What should the face’s X axis be? | No | | ||||
| | `yAxis` |`object`| What should the face’s Y axis be? | No | | ||||
| | `zAxis` |`object`| The z-axis (normal). | No | | ||||
| | `solid` |`object`| The solid the face is on. | No | | ||||
| | `__meta` |`array`|  | No | | ||||
| | `__meta` |`[` `object` `]`|  | No | | ||||
|  | ||||
|  | ||||
| ---- | ||||
|  | ||||
| @ -16,13 +16,13 @@ An solid is a collection of extrude surfaces. | ||||
|  | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `id` |`string` (`uuid`)| The id of the solid. | No | | ||||
| | `value` |`array`| The extrude surfaces. | No | | ||||
| | `id` |`string`| The id of the solid. | No | | ||||
| | `value` |`[` **oneOf:** `object` **OR** `object` **OR** `object` **OR** `object` `]`| The extrude surfaces. | No | | ||||
| | `sketch` |`object`| The sketch. | No | | ||||
| | `height` |`number` (`double`)| The height of the solid. | No | | ||||
| | `startCapId` |`string` (`uuid`)| The id of the extrusion start cap | No | | ||||
| | `endCapId` |`string` (`uuid`)| The id of the extrusion end cap | No | | ||||
| | `edgeCuts` |`array`| Chamfers or fillets on this solid. | No | | ||||
| | `__meta` |`array`| Metadata. | No | | ||||
| | `height` |`number`| The height of the solid. | No | | ||||
| | `startCapId` |`string`| The id of the extrusion start cap | No | | ||||
| | `endCapId` |`string`| The id of the extrusion end cap | No | | ||||
| | `edgeCuts` |`[` **oneOf:** `object` **OR** `object` `]`| Chamfers or fillets on this solid. | No | | ||||
| | `__meta` |`[` `object` `]`| Metadata. | No | | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -24,14 +24,14 @@ An solid is a collection of extrude surfaces. | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `type` |enum: `solid`|  | No | | ||||
| | `id` |`string` (`uuid`)| The id of the solid. | No | | ||||
| | `value` |`array`| The extrude surfaces. | No | | ||||
| | `id` |`string`| The id of the solid. | No | | ||||
| | `value` |`[` **oneOf:** `object` **OR** `object` **OR** `object` **OR** `object` `]`| The extrude surfaces. | No | | ||||
| | `sketch` |`object`| The sketch. | No | | ||||
| | `height` |`number` (`double`)| The height of the solid. | No | | ||||
| | `startCapId` |`string` (`uuid`)| The id of the extrusion start cap | No | | ||||
| | `endCapId` |`string` (`uuid`)| The id of the extrusion end cap | No | | ||||
| | `edgeCuts` |`array`| Chamfers or fillets on this solid. | No | | ||||
| | `__meta` |`array`| Metadata. | No | | ||||
| | `height` |`number`| The height of the solid. | No | | ||||
| | `startCapId` |`string`| The id of the extrusion start cap | No | | ||||
| | `endCapId` |`string`| The id of the extrusion end cap | No | | ||||
| | `edgeCuts` |`[` **oneOf:** `object` **OR** `object` `]`| Chamfers or fillets on this solid. | No | | ||||
| | `__meta` |`[` `object` `]`| Metadata. | No | | ||||
|  | ||||
|  | ||||
| ---- | ||||
|  | ||||
| @ -21,8 +21,8 @@ Data to draw a tangential arc. | ||||
|  | ||||
| | Property | Type | Description | Required | | ||||
| |----------|------|-------------|----------| | ||||
| | `radius` |`number` (`double`)| Radius of the arc. Not to be confused with Raiders of the Lost Ark. | No | | ||||
| | `offset` |`number` (`double`)| Offset of the arc, in degrees. | No | | ||||
| | `radius` |`number`| Radius of the arc. Not to be confused with Raiders of the Lost Ark. | No | | ||||
| | `offset` |`number`| Offset of the arc, in degrees. | No | | ||||
|  | ||||
|  | ||||
| ---- | ||||
|  | ||||
| @ -1,8 +1,9 @@ | ||||
| use std::collections::HashMap; | ||||
| use std::collections::{BTreeMap, HashMap}; | ||||
|  | ||||
| use anyhow::Result; | ||||
| use base64::Engine; | ||||
| use convert_case::Casing; | ||||
| use handlebars::Renderable; | ||||
| use itertools::Itertools; | ||||
| use serde_json::json; | ||||
|  | ||||
| @ -34,7 +35,42 @@ fn init_handlebars() -> Result<handlebars::Handlebars<'static>> { | ||||
|  | ||||
|     // Register the 'basename' helper | ||||
|     hbs.register_helper( | ||||
|         "basename", | ||||
|         "times", | ||||
|         Box::new( | ||||
|             |h: &handlebars::Helper, | ||||
|              hb: &handlebars::Handlebars, | ||||
|              ctx: &handlebars::Context, | ||||
|              rc: &mut handlebars::RenderContext, | ||||
|              out: &mut dyn handlebars::Output| | ||||
|              -> handlebars::HelperResult { | ||||
|                 let n = h.param(0).and_then(|v| v.value().as_u64()).ok_or_else(|| { | ||||
|                     handlebars::RenderErrorReason::Other( | ||||
|                         "times helper expects an integer as first parameter".to_string(), | ||||
|                     ) | ||||
|                 })?; | ||||
|  | ||||
|                 let template = h | ||||
|                     .template() | ||||
|                     .ok_or_else(|| handlebars::RenderErrorReason::Other("times helper expects a block".to_string()))?; | ||||
|  | ||||
|                 for i in 0..n { | ||||
|                     let mut local_ctx = ctx.clone(); | ||||
|                     let mut rc = rc.clone(); | ||||
|                     let m = local_ctx.data_mut().as_object_mut().unwrap(); | ||||
|                     m.insert("@index".to_string(), handlebars::JsonValue::Number(i.into())); | ||||
|                     if i == 0 { | ||||
|                         m.insert("@first".to_string(), handlebars::JsonValue::Bool(true)); | ||||
|                     } | ||||
|                     template.render(hb, &local_ctx, &mut rc, out)?; | ||||
|                 } | ||||
|  | ||||
|                 Ok(()) | ||||
|             }, | ||||
|         ), | ||||
|     ); | ||||
|  | ||||
|     hbs.register_helper( | ||||
|         "lte", | ||||
|         Box::new( | ||||
|             |h: &handlebars::Helper, | ||||
|              _: &handlebars::Handlebars, | ||||
| @ -42,9 +78,47 @@ fn init_handlebars() -> Result<handlebars::Handlebars<'static>> { | ||||
|              _: &mut handlebars::RenderContext, | ||||
|              out: &mut dyn handlebars::Output| | ||||
|              -> handlebars::HelperResult { | ||||
|                 let param = h.param(0).and_then(|v| v.value().as_str()).unwrap_or(""); | ||||
|                 let basename = param.split('/').last().unwrap_or(""); | ||||
|                 out.write(basename)?; | ||||
|                 let a = h.param(0).and_then(|v| v.value().as_f64()).ok_or_else(|| { | ||||
|                     handlebars::RenderErrorReason::Other("lte helper expects a number as first parameter".to_string()) | ||||
|                 })?; | ||||
|  | ||||
|                 let b = h.param(1).and_then(|v| v.value().as_f64()).ok_or_else(|| { | ||||
|                     handlebars::RenderErrorReason::Other("lte helper expects a number as second parameter".to_string()) | ||||
|                 })?; | ||||
|  | ||||
|                 let result = a <= b; | ||||
|                 out.write(if result { "true" } else { "false" })?; | ||||
|  | ||||
|                 Ok(()) | ||||
|             }, | ||||
|         ), | ||||
|     ); | ||||
|  | ||||
|     hbs.register_helper( | ||||
|         "neq", | ||||
|         Box::new( | ||||
|             |h: &handlebars::Helper, | ||||
|              _: &handlebars::Handlebars, | ||||
|              _: &handlebars::Context, | ||||
|              _: &mut handlebars::RenderContext, | ||||
|              out: &mut dyn handlebars::Output| | ||||
|              -> handlebars::HelperResult { | ||||
|                 let param1 = h | ||||
|                     .param(0) | ||||
|                     .ok_or_else(|| { | ||||
|                         handlebars::RenderErrorReason::Other("neq helper expects two parameters".to_string()) | ||||
|                     })? | ||||
|                     .value(); | ||||
|                 let param2 = h | ||||
|                     .param(1) | ||||
|                     .ok_or_else(|| { | ||||
|                         handlebars::RenderErrorReason::Other("neq helper expects two parameters".to_string()) | ||||
|                     })? | ||||
|                     .value(); | ||||
|  | ||||
|                 let result = param1 != param2; | ||||
|                 out.write(if result { "true" } else { "false" })?; | ||||
|  | ||||
|                 Ok(()) | ||||
|             }, | ||||
|         ), | ||||
| @ -94,6 +168,50 @@ fn init_handlebars() -> Result<handlebars::Handlebars<'static>> { | ||||
|         ), | ||||
|     ); | ||||
|  | ||||
|     hbs.register_helper( | ||||
|         "pretty_enum", | ||||
|         Box::new( | ||||
|             |h: &handlebars::Helper, | ||||
|              _: &handlebars::Handlebars, | ||||
|              _: &handlebars::Context, | ||||
|              _: &mut handlebars::RenderContext, | ||||
|              out: &mut dyn handlebars::Output| | ||||
|              -> handlebars::HelperResult { | ||||
|                 if let Some(enum_value) = h.param(0) { | ||||
|                     if let Some(array) = enum_value.value().as_array() { | ||||
|                         let pretty_options = array | ||||
|                             .iter() | ||||
|                             .filter_map(|v| v.as_str()) | ||||
|                             .map(|s| format!("`{}`", s)) | ||||
|                             .collect::<Vec<_>>() | ||||
|                             .join(", "); | ||||
|                         out.write(&pretty_options)?; | ||||
|                         return Ok(()); | ||||
|                     } | ||||
|                 } | ||||
|                 out.write("Invalid enum")?; | ||||
|                 Ok(()) | ||||
|             }, | ||||
|         ), | ||||
|     ); | ||||
|  | ||||
|     hbs.register_helper( | ||||
|         "pretty_ref", | ||||
|         Box::new( | ||||
|             |h: &handlebars::Helper, | ||||
|              _: &handlebars::Handlebars, | ||||
|              _: &handlebars::Context, | ||||
|              _: &mut handlebars::RenderContext, | ||||
|              out: &mut dyn handlebars::Output| | ||||
|              -> handlebars::HelperResult { | ||||
|                 let param = h.param(0).and_then(|v| v.value().as_str()).unwrap_or(""); | ||||
|                 let basename = param.split('/').last().unwrap_or(""); | ||||
|                 out.write(&format!("`{}`", basename))?; | ||||
|                 Ok(()) | ||||
|             }, | ||||
|         ), | ||||
|     ); | ||||
|  | ||||
|     // Register helper to remove newlines from a string. | ||||
|     hbs.register_helper( | ||||
|         "remove_newlines", | ||||
| @ -157,11 +275,11 @@ fn generate_index(combined: &HashMap<String, Box<dyn StdLibFn>>) -> Result<()> { | ||||
|     Ok(()) | ||||
| } | ||||
|  | ||||
| fn generate_function(internal_fn: Box<dyn StdLibFn>) -> Result<()> { | ||||
| fn generate_function(internal_fn: Box<dyn StdLibFn>) -> Result<BTreeMap<String, schemars::schema::Schema>> { | ||||
|     let hbs = init_handlebars()?; | ||||
|  | ||||
|     if internal_fn.unpublished() { | ||||
|         return Ok(()); | ||||
|         return Ok(BTreeMap::new()); | ||||
|     } | ||||
|  | ||||
|     let fn_name = internal_fn.name(); | ||||
| @ -194,23 +312,17 @@ fn generate_function(internal_fn: Box<dyn StdLibFn>) -> Result<()> { | ||||
|         .collect(); | ||||
|  | ||||
|     // Generate the type markdown files for each argument. | ||||
|     let mut types = Vec::new(); | ||||
|     let mut types = BTreeMap::new(); | ||||
|     for arg in internal_fn.args() { | ||||
|         if !arg.is_primitive()? { | ||||
|             generate_type(&arg.type_, &arg.schema)?; | ||||
|             if !types.contains(&arg.type_.to_string()) { | ||||
|                 types.push(arg.type_.to_string()); | ||||
|             } | ||||
|             add_to_types(&arg.type_, &arg.schema, &mut types)?; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Generate the type markdown for the return value. | ||||
|     if let Some(ret) = internal_fn.return_value() { | ||||
|         if !ret.is_primitive()? { | ||||
|             generate_type(&ret.type_, &ret.schema)?; | ||||
|             if !types.contains(&ret.type_.to_string()) { | ||||
|                 types.push(ret.type_.to_string()); | ||||
|             } | ||||
|             add_to_types(&ret.type_, &ret.schema, &mut types)?; | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -240,28 +352,102 @@ fn generate_function(internal_fn: Box<dyn StdLibFn>) -> Result<()> { | ||||
|     }); | ||||
|  | ||||
|     let mut output = hbs.render("function", &data)?; | ||||
|     // Fix the links to the types. | ||||
|     output = cleanup_type_links(&output, types.keys().cloned().collect()); | ||||
|  | ||||
|     expectorate::assert_contents(format!("../../../docs/kcl/{}.md", fn_name), &output); | ||||
|  | ||||
|     Ok(types) | ||||
| } | ||||
|  | ||||
| fn cleanup_static_links(output: &str) -> String { | ||||
|     let mut cleaned_output = output.to_string(); | ||||
|     // Fix the links to the types. | ||||
|     let link = format!("[`{}`](/docs/kcl/types#tag-declaration)", "TagDeclarator"); | ||||
|     cleaned_output = cleaned_output.replace("`TagDeclarator`", &link); | ||||
|     let link = format!("[`{}`](/docs/kcl/types#tag-identifier)", "TagIdentifier"); | ||||
|     cleaned_output = cleaned_output.replace("`TagIdentifier`", &link); | ||||
|  | ||||
|     cleaned_output | ||||
| } | ||||
|  | ||||
| // Fix the links to the types. | ||||
| fn cleanup_type_links(output: &str, types: Vec<String>) -> String { | ||||
|     let mut cleaned_output = output.to_string(); | ||||
|     // Fix the links to the types. | ||||
|     for type_name in types { | ||||
|         let formatted_type_name = format!("`{}`", type_name); | ||||
|         if type_name == "TagDeclarator" { | ||||
|             let link = format!("[`{}`](/docs/kcl/types#tag-declaration)", "TagDeclarator"); | ||||
|             output = output.replace(&formatted_type_name, &link); | ||||
|         } else if type_name == "TagIdentifier" { | ||||
|             let link = format!("[`{}`](/docs/kcl/types#tag-identifier)", "TagIdentifier"); | ||||
|             output = output.replace(&formatted_type_name, &link); | ||||
|         if type_name == "TagDeclarator" || type_name == "TagIdentifier" { | ||||
|             continue; | ||||
|         } else { | ||||
|             let link = format!("[`{}`](/docs/kcl/types/{})", type_name, type_name); | ||||
|             output = output.replace(&formatted_type_name, &link); | ||||
|             let link = format!("(/docs/kcl/types/{})", type_name); | ||||
|             cleaned_output = | ||||
|                 cleaned_output.replace(&format!("`{}`", type_name), &format!("[`{}`]{}", type_name, &link)); | ||||
|             // Do the same for the type with brackets. | ||||
|             cleaned_output = | ||||
|                 cleaned_output.replace(&format!("`[{}]`", type_name), &format!("[`[{}]`]{}", type_name, link)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     expectorate::assert_contents(format!("../../../docs/kcl/{}.md", fn_name), &output); | ||||
|     // Cleanup our weird number arrays. | ||||
|     // TODO: This is a hack for the handlebars template being too complex. | ||||
|     cleaned_output = cleaned_output.replace("`[, `number`, `number`]`", "`[number, number]`"); | ||||
|     cleaned_output = cleaned_output.replace("`[, `number`, `number`, `number`]`", "`[number, number, number]`"); | ||||
|  | ||||
|     cleanup_static_links(&cleaned_output) | ||||
| } | ||||
|  | ||||
| fn add_to_types( | ||||
|     name: &str, | ||||
|     schema: &schemars::schema::Schema, | ||||
|     types: &mut BTreeMap<String, schemars::schema::Schema>, | ||||
| ) -> Result<()> { | ||||
|     if name.is_empty() { | ||||
|         return Err(anyhow::anyhow!("Empty type name")); | ||||
|     } | ||||
|  | ||||
|     let schemars::schema::Schema::Object(o) = schema else { | ||||
|         return Err(anyhow::anyhow!( | ||||
|             "Failed to get object schema, should have not been a primitive" | ||||
|         )); | ||||
|     }; | ||||
|  | ||||
|     // If we have an array we want to generate the type markdown files for each item in the | ||||
|     // array. | ||||
|     if let Some(array) = &o.array { | ||||
|         // Recursively generate the type markdown files for each item in the array. | ||||
|         if let Some(items) = &array.items { | ||||
|             match items { | ||||
|                 schemars::schema::SingleOrVec::Single(item) => { | ||||
|                     if is_primitive(item)?.is_some() { | ||||
|                         return Ok(()); | ||||
|                     } | ||||
|                     return add_to_types(name.trim_start_matches('[').trim_end_matches(']'), item, types); | ||||
|                 } | ||||
|                 schemars::schema::SingleOrVec::Vec(items) => { | ||||
|                     for item in items { | ||||
|                         if is_primitive(item)?.is_some() { | ||||
|                             continue; | ||||
|                         } | ||||
|                         add_to_types(name.trim_start_matches('[').trim_end_matches(']'), item, types)?; | ||||
|                     } | ||||
|                     return Ok(()); | ||||
|                 } | ||||
|             } | ||||
|         } else { | ||||
|             return Err(anyhow::anyhow!("Failed to get array items")); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     types.insert(name.to_string(), schema.clone()); | ||||
|  | ||||
|     Ok(()) | ||||
| } | ||||
|  | ||||
| fn generate_type(name: &str, schema: &schemars::schema::Schema) -> Result<()> { | ||||
| fn generate_type( | ||||
|     name: &str, | ||||
|     schema: &schemars::schema::Schema, | ||||
|     types: &BTreeMap<String, schemars::schema::Schema>, | ||||
| ) -> Result<()> { | ||||
|     if name.is_empty() { | ||||
|         return Err(anyhow::anyhow!("Empty type name")); | ||||
|     } | ||||
| @ -287,14 +473,14 @@ fn generate_type(name: &str, schema: &schemars::schema::Schema) -> Result<()> { | ||||
|                     if is_primitive(item)?.is_some() { | ||||
|                         return Ok(()); | ||||
|                     } | ||||
|                     return generate_type(name.trim_start_matches('[').trim_end_matches(']'), item); | ||||
|                     return generate_type(name.trim_start_matches('[').trim_end_matches(']'), item, types); | ||||
|                 } | ||||
|                 schemars::schema::SingleOrVec::Vec(items) => { | ||||
|                     for item in items { | ||||
|                         if is_primitive(item)?.is_some() { | ||||
|                             continue; | ||||
|                         } | ||||
|                         generate_type(name.trim_start_matches('[').trim_end_matches(']'), item)?; | ||||
|                         generate_type(name.trim_start_matches('[').trim_end_matches(']'), item, types)?; | ||||
|                     } | ||||
|                     return Ok(()); | ||||
|                 } | ||||
| @ -315,8 +501,12 @@ fn generate_type(name: &str, schema: &schemars::schema::Schema) -> Result<()> { | ||||
|         return Err(anyhow::anyhow!("Type name is not pascal cased: {}", name)); | ||||
|     } | ||||
|  | ||||
|     // Make sure the types directory exists. | ||||
|     std::fs::create_dir_all(TYPES_DIR)?; | ||||
|     let new_schema = recurse_and_create_references(name, schema, types)?; | ||||
|     let schemars::schema::Schema::Object(o) = new_schema else { | ||||
|         return Err(anyhow::anyhow!( | ||||
|             "Failed to get object schema, should have not been a primitive" | ||||
|         )); | ||||
|     }; | ||||
|  | ||||
|     let hbs = init_handlebars()?; | ||||
|  | ||||
| @ -333,8 +523,10 @@ fn generate_type(name: &str, schema: &schemars::schema::Schema) -> Result<()> { | ||||
|  | ||||
|     let data = json!(schemars::schema::Schema::Object(object)); | ||||
|  | ||||
|     let output = hbs.render("type", &data)?; | ||||
|     std::fs::write(format!("{}/{}.md", TYPES_DIR, name), output)?; | ||||
|     let mut output = hbs.render("type", &data)?; | ||||
|     // Fix the links to the types. | ||||
|     output = cleanup_type_links(&output, types.keys().cloned().collect()); | ||||
|     expectorate::assert_contents(format!("{}/{}.md", TYPES_DIR, name), &output); | ||||
|  | ||||
|     Ok(()) | ||||
| } | ||||
| @ -370,20 +562,130 @@ fn clean_function_name(name: &str) -> String { | ||||
|     fn_name | ||||
| } | ||||
|  | ||||
| /// Check if a schema is the same as another schema, but don't check the description. | ||||
| fn is_same_schema(sa: &schemars::schema::Schema, sb: &schemars::schema::Schema) -> bool { | ||||
|     let schemars::schema::Schema::Object(a) = sa else { | ||||
|         return sa == sb; | ||||
|     }; | ||||
|  | ||||
|     let schemars::schema::Schema::Object(b) = sb else { | ||||
|         return sa == sb; | ||||
|     }; | ||||
|  | ||||
|     let mut a = a.clone(); | ||||
|     a.metadata = None; | ||||
|     let mut b = b.clone(); | ||||
|     b.metadata = None; | ||||
|  | ||||
|     a == b | ||||
| } | ||||
|  | ||||
| /// Recursively create references for types we already know about. | ||||
| fn recurse_and_create_references( | ||||
|     name: &str, | ||||
|     schema: &schemars::schema::Schema, | ||||
|     types: &BTreeMap<String, schemars::schema::Schema>, | ||||
| ) -> Result<schemars::schema::Schema> { | ||||
|     let schemars::schema::Schema::Object(o) = schema else { | ||||
|         return Err(anyhow::anyhow!( | ||||
|             "Failed to get object schema, should have not been a primitive" | ||||
|         )); | ||||
|     }; | ||||
|  | ||||
|     // Check if this is the type we already know about. | ||||
|     for (n, s) in types { | ||||
|         if is_same_schema(schema, s) && name != n && !n.starts_with("[") { | ||||
|             // Return a reference to the type. | ||||
|             let sref = schemars::schema::Schema::new_ref(n.to_string()); | ||||
|             // Add the existing metadata to the reference. | ||||
|             let schemars::schema::Schema::Object(ro) = sref else { | ||||
|                 return Err(anyhow::anyhow!( | ||||
|                     "Failed to get object schema, should have not been a primitive" | ||||
|                 )); | ||||
|             }; | ||||
|             let mut ro = ro.clone(); | ||||
|             ro.metadata = o.metadata.clone(); | ||||
|  | ||||
|             return Ok(schemars::schema::Schema::Object(ro)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     let mut obj = o.clone(); | ||||
|  | ||||
|     // If we have an object iterate over the properties and recursively create references. | ||||
|     if let Some(object) = &mut obj.object { | ||||
|         for (_, value) in object.properties.iter_mut() { | ||||
|             let new_value = recurse_and_create_references(name, value, types)?; | ||||
|             *value = new_value; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // If we have an array iterate over the items and recursively create references. | ||||
|     if let Some(array) = &mut obj.array { | ||||
|         if let Some(items) = &mut array.items { | ||||
|             match items { | ||||
|                 schemars::schema::SingleOrVec::Single(item) => { | ||||
|                     let new_item = recurse_and_create_references(name, item, types)?; | ||||
|                     *item = Box::new(new_item); | ||||
|                 } | ||||
|                 schemars::schema::SingleOrVec::Vec(items) => { | ||||
|                     for item in items { | ||||
|                         let new_item = recurse_and_create_references(name, item, types)?; | ||||
|                         *item = new_item; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // If we have subschemas iterate over them and recursively create references. | ||||
|     if let Some(subschema) = &mut obj.subschemas { | ||||
|         // Do anyOf. | ||||
|         if let Some(any_of) = &mut subschema.any_of { | ||||
|             for item in any_of { | ||||
|                 let new_item = recurse_and_create_references(name, item, types)?; | ||||
|                 *item = new_item; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Do allOf. | ||||
|         if let Some(all_of) = &mut subschema.all_of { | ||||
|             for item in all_of { | ||||
|                 let new_item = recurse_and_create_references(name, item, types)?; | ||||
|                 *item = new_item; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Do oneOf. | ||||
|         if let Some(one_of) = &mut subschema.one_of { | ||||
|             for item in one_of { | ||||
|                 let new_item = recurse_and_create_references(name, item, types)?; | ||||
|                 *item = new_item; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     Ok(schemars::schema::Schema::Object(obj.clone())) | ||||
| } | ||||
|  | ||||
| #[test] | ||||
| fn test_generate_stdlib_markdown_docs() { | ||||
|     // Clean the old files. | ||||
|     std::fs::remove_dir_all(TYPES_DIR).unwrap_or_default(); | ||||
|  | ||||
|     let stdlib = StdLib::new(); | ||||
|     let combined = stdlib.combined(); | ||||
|  | ||||
|     // Generate the index which is the table of contents. | ||||
|     generate_index(&combined).unwrap(); | ||||
|  | ||||
|     let mut types = BTreeMap::new(); | ||||
|     for key in combined.keys().sorted() { | ||||
|         let internal_fn = combined.get(key).unwrap(); | ||||
|         generate_function(internal_fn.clone()).unwrap(); | ||||
|         let fn_types = generate_function(internal_fn.clone()).unwrap(); | ||||
|         types.extend(fn_types); | ||||
|     } | ||||
|  | ||||
|     // Generate the type markdown files. | ||||
|     for (name, schema) in &types { | ||||
|         generate_type(name, schema, &types).unwrap(); | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -1,7 +1,17 @@ | ||||
| {{~ #if $ref ~}} | ||||
| [{{basename $ref}}](#{{lowercase (basename $ref)}}){{else if anyOf ~}} | ||||
| `anyOf`{{else if oneOf ~}} | ||||
| `oneOf`{{else if allOf ~}} | ||||
| `allOf`{{else if enum ~}} | ||||
| enum: {{pretty_enum enum}}{{else ~}} | ||||
| `{{type}}`{{#if format}} (`{{format}}`){{/if}}{{~/if~}} | ||||
| {{pretty_ref $ref}}{{else if anyOf ~}} | ||||
| **anyOf:** {{#each anyOf}}{{> propertyType this}}{{#unless @last}} **OR** {{/unless}}{{/each}}{{else if oneOf ~}} | ||||
| **oneOf:** {{#each oneOf}}{{> propertyType this}}{{#unless @last}} **OR** {{/unless}}{{/each}}{{else if allOf ~}} | ||||
| **allOf:** {{#each allOf}}{{> propertyType this}}{{#unless @last}} **OR** {{/unless}}{{/each}}{{else if enum ~}} | ||||
| enum: {{pretty_enum enum}}{{else if items ~}} | ||||
| {{~ #if maxItems ~}} | ||||
| {{~ #if (lte maxItems 3) ~}} | ||||
| `[{{#times maxItems ~}} | ||||
| {{~ #if @first ~}}{{else ~}}, {{/if ~}}{{> propertyType ../items}}{{/times}}]`{{else ~}} | ||||
| `[` {{ > propertyType items }} `]` | ||||
| {{~ /if ~}}{{else ~}}`[` {{ > propertyType items }} `]` | ||||
| {{~ /if ~}}{{else ~}} | ||||
| `{{type}}{{~ #if format }}{{#if neq format "double" }} ({{format}}){{/if}} | ||||
| {{~ /if ~}}` | ||||
| {{~/if~}} | ||||
|  | ||||
|  | ||||
| @ -1,7 +1,5 @@ | ||||
| {{ | ||||
| #if | ||||
|  $ref}} | ||||
| [{{basename $ref}}](#{{lowercase (basename $ref)}}) | ||||
| {{#if $ref}} | ||||
| {{pretty_ref $ref}} | ||||
| {{else if anyOf}} | ||||
| **anyOf** | ||||
| {{else if oneOf}} | ||||
|  | ||||
		Reference in New Issue
	
	Block a user