# `AshTypst.Resource`
[🔗](https://github.com/frankdugan3/ash_typst/blob/v0.4.0/lib/ash_typst/resource.ex#L1)

Spark DSL extension for rendering Typst templates as Ash generic actions.

This extension adds a `typst` DSL section to your Ash resource where you can
declare reusable templates and render actions. Each render action is transformed
into an Ash generic action that compiles and exports a Typst document, returning
an `AshTypst.Document` struct.

## Usage

Add the extension to your resource:

    defmodule MyApp.Invoice do
      use Ash.Resource,
        domain: MyApp.Domain,
        extensions: [AshTypst.Resource]

      # Opt this resource into the encoding protocol so `read` results can be
      # serialized to Typst and injected into your templates.
      @derive AshTypst.Code

      typst do
        root "priv/typst"

        template :invoice do
          source "invoice.typ"
          inputs %{"company" => "Acme Corp"}
        end

        template :receipt do
          # ~TYPST sigil is auto-imported in template blocks
          markup ~TYPST"""
          #import "data.typ": record, args
          = Receipt #args.receipt_number
          *Customer:* #record.name
          """
        end

        render :generate_pdf do
          template :invoice
          format :pdf

          argument :invoice_id, :string, allow_nil?: false

          read :one do
            filter expr(id == ^arg(:invoice_id))
            load [:line_items, :customer]
          end

          pdf_options do
            pdf_standards [:pdf_a_2b]
          end
        end
      end
    end

Then call the action like any other Ash generic action:

    input = Ash.ActionInput.for_action(MyApp.Invoice, :generate_pdf, %{invoice_id: "123"})
    {:ok, %AshTypst.Document{format: :pdf, data: pdf_binary}} = Ash.run_action(input)

## How It Works

1. **Templates** are declared in the `typst` section. Each template has either an
   inline `markup` string (the `~TYPST` sigil is auto-imported inside `template`
   blocks) or a `source` file path relative to the `root` directory.

2. **Render actions** reference a template and specify an output `format` (`:pdf`,
   `:svg`, or `:html`). They can optionally declare arguments, a `read` to fetch
   resource data, and format-specific options like `pdf_options`.

3. At compile time, the `BuildActions` transformer converts each render entity into
   a standard `Ash.Resource.Actions.Action`.

4. At runtime, the action implementation creates a context, sets the template,
   injects data (arguments and/or read results) into a virtual file, compiles, and
   exports in the requested format.

## Data Injection

The render action injects data into a virtual file (default `"data.typ"`) that your
template can `#import`:

- **No read**: only `args` (a dictionary of action arguments) is available.
- **Read `:one`**: both `record` (the single resource) and `args` are available.
- **Read `:many`**: `records` (an array, streamed in batches) and `args` are available.

Any render action that declares a `read` encodes the fetched resource records
via the `AshTypst.Code` protocol, so the resource must opt in by adding
`@derive AshTypst.Code` (see the usage example above). Deriving serializes the
resource's public fields; for custom serialization, implement the protocol
directly with `defimpl AshTypst.Code, for: MyApp.Invoice`.

## DSL Reference

For the complete DSL reference with all options, see `d:AshTypst.Resource`.

# `typst`
*macro* 

---

*Consult [api-reference.md](api-reference.md) for complete listing*
