# Boxr
Boxr is a modular, and easy to use, package for creating cardboard cutouts in Typst.

## Usage
Create a boxr structure in your project with the following code:
```
#import "@preview/boxr:0.1.0": *

#render-structure(
  "box",
  width: 100pt,
  height: 100pt,
  depth: 100pt,
  tab-size: 20pt,
  [
    Hello from boxr!
  ]
)
```
The `render-structure` function is the main function for boxr. It either takes a path to one of the default structures provided by boxr (e.g.: `"box"`) or an unpacked json file with your own custom structure (e.g.: `json("my-structure.json")`). These describe the structure of the cutout.\
The other named arguments depend on the structure you are rendering. All unnamed arguments are passed to the structure as content and will be rendered on each box face (not triangles or tabs).

## Creating your own structures
Structures are defined in `.json` files. An example structure that just shows a box with a tab on one face is shown below:
```
{
  "variables": ["height", "width", "tab-size"],
  "width": "width",
  "height": "height + tab-size",
  "offset-x": "",
  "offset-y": "tab-size",
  "root": {
    "type": "box",
    "id": 0,
    "width": "width",
    "height": "height",
    "children": {
      "top": "tab(tab-size, tab-size)"
    }
  }
}
```
The `variables` key is a list of variable names that can be passed to the structure. These will be required to be passed to the `render-structure` function.\
The `width` and `height` keys are evaluated to calculate the width and height of the structure.\
The `offset-x` and `offset-y` keys are evaluated to place the structure in the middle of its bounds. It is relative to the root node. In this case for example, the top tab adds a `tab-size` on top of the box as opposed to the bottom, where there is no tab. So this `tab-size` is added to the `offset-y`.\
`root` denotes the first node in the structure.\
A node can be of the following types:
- `box`:
  - The root node has a `width` and a `height`. All following nodes have a `size`. Child nodes use `size` and the parent node's `width` and `height` to calculate their own width and height.
  - Can have `children` nodes.
  - Can have an `id` key that is used to place content on the face of the box. The id-th unnamed argument is placed on the face. Multiple faces can have the same id.
  - Can have a `no-fold` key. If this exists, no fold stroke will be drawn between this box and its parent.
- `triangle-<left|right>`:
  - Has a `width` and `height`.
  - `left` and `right` denote the direction the other right angled line is facing relative to the base.
  - Can have `children` nodes.
  - Can have a `no-fold` key. If this exists, no fold stroke will be drawn between this triangle and its parent.
- `tab`:
  - Is not a json object, but a string that denotes a tab. The tab is placed on the parent node.
  - Has a tab-size and a cutin-size inside the `()` separted by a `,`.
- `none`:
  - Is not a json object, but a string that denotes no node. This is useful for deleting a cut-stroke between two nodes.

Every string value in the json file (`width: "__", height: "__", ... offset-x/y: "__"` and the values between the `()` for tabs) is evaluated as regular typst code. This means that you can use all named variables passed to the structure. All inputs are converted to floats (/ pt) and the result of the evaluation will be converted back to a length.

