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

Persistent Typst rendering context.

A context wraps a Rust-side `SystemWorld` that keeps fonts, virtual files,
and the compiled document in memory. The typical lifecycle is:

1. `new/1` — create a context (scans fonts, sets root path)
2. `set_markup/2` — load a Typst template
3. Optionally inject data via `set_virtual_file/3`, `stream_virtual_file/4`, or `set_inputs/2`
4. `compile/1` — compile the markup into a paged document
5. `render_svg/2` or `export_pdf/2` — render output from the compiled document
   (`export_html/2` and `export_bundle/2` compile on their own)

Steps 2-5 can be repeated without re-creating the context. Fonts and
virtual files persist until explicitly changed.

For short-lived, request-scoped rendering (e.g. a preview endpoint),
consider `AshTypst.ContextPool.with_context/2`, which reuses contexts
across callers instead of creating one per render.

## Thread safety

Each function acquires internal locks, so a single context can be shared
across processes. However, concurrent `compile` and `set_markup` calls on
the same context will serialize — design your pipeline accordingly.

# `append_virtual_file`

Append a chunk to a virtual file (creates it if new).

Does **not** invalidate the compiled document — call `compile/1`
after streaming is complete.

# `clear_virtual_file`

Remove a virtual file. Invalidates the compiled document.

# `clear_virtual_files`

Remove all virtual files. Invalidates the compiled document.

# `compile`

Compile the current markup.

Returns `{:ok, %CompileResult{}}` with the page count and warnings,
or `{:error, %CompileError{}}` with diagnostics.

# `export_bundle`

Export the document as a multi-file bundle.

The `bundle` target lets a single Typst project emit multiple documents and
assets. The template declares its outputs with top-level [`document`] and
[`asset`] elements. Each takes the destination path as its first positional
argument, for example:

```typ
#document("index.html", title: [Home])[
  = Home
  See the #link("about.html")[about page].
]
#document("about.html", title: [About])[= About]
#asset("logo.svg", read("logo.svg", encoding: none))
```

Performs its own compilation (separate from `compile/1`). Returns
`{:ok, %AshTypst.BundleResult{}}` whose `files` is a map of relative path (no
leading slash) to the rendered binary content, e.g. `%{"index.html" => "...",
"about.html" => "..."}`, and whose `warnings` is a list of
`AshTypst.Diagnostic` warnings.

Documents within the bundle are exported according to their declared format
(HTML, PDF, SVG, or PNG); assets are emitted verbatim.

## Options

  * `:pretty` — format HTML/SVG documents in a human-readable way (default
    `false`, i.e. minified)
  * `:render_bleed` — include bleed margins for SVG documents (default
    `false`)

[`document`]: https://typst.app/docs/reference/model/document/
[`asset`]: https://typst.app/docs/reference/data-loading/asset/

# `export_html`

Export the document as HTML.

Performs its own compilation (separate from `compile/1`).

## Options

  * `:pretty` — format the HTML in a human-readable way (default `false`,
    i.e. minified)

# `export_pdf`

Export the compiled document as a PDF binary.

## Options

  * `:pages` — page range string like `"1-3,5,7-9"` (1-indexed)
  * `:pdf_standards` — list of standards, e.g. `[:pdf_a_2b]`
  * `:document_id` — stable identifier for caching

# `font_families`

List font families available in this context.

# `new`

Create a new context.

Font scan results are cached process-wide per `{font_paths,
ignore_system_fonts}` combination, so creating additional contexts with
the same font configuration is cheap and shares already-loaded font
data. Fonts installed after the first scan are not picked up until
`AshTypst.refresh_fonts/0` is called.

## Options

  * `:root` — directory templates may read real files from (imports,
    images, data files). Defaults to `nil`, which disables filesystem
    access entirely: only virtual files and packages are available, and
    any other file reference fails to compile. Set this explicitly to
    let templates read from disk. Access is sandboxed to the root —
    paths cannot escape it (e.g. via `..`).
  * `:font_paths` — additional font directories to search
  * `:ignore_system_fonts` — skip system fonts (default `false`)

> #### Security {: .warning}
>
> Everything under `:root` becomes readable by any template compiled in
> this context. Point it at a directory containing only template assets —
> never at `"."` or a directory with secrets (`.env`, config files, etc.).

# `render_svg`

Render a page of the compiled document as SVG.

## Options

  * `:page` — zero-indexed page number (default `0`)
  * `:pretty` — format the SVG in a human-readable way (default `false`, i.e.
    minified)
  * `:render_bleed` — expand the rendered area beyond the page bounds to
    include bleed margins, useful when preparing documents for print
    (default `false`)

# `set_input`

Set a single `sys.inputs` key/value pair.

# `set_inputs`

Replace all `sys.inputs` with the given map of string keys/values.

# `set_markup`

Set the main Typst markup. Invalidates any compiled document.

# `set_virtual_file`

Set (or overwrite) a virtual file with text content. Invalidates the compiled document.

# `set_virtual_file_binary`

Set (or overwrite) a virtual file with raw binary content. Invalidates the compiled document.

Use this for non-text files like images (PNG, SVG) that Typst reads via
`#image(read("name", encoding: none))`.

# `stream_virtual_file`

Stream an Elixir enumerable into a virtual file as a Typst array.

Each element is encoded via `AshTypst.Code.encode/2` and batched
to Rust for memory efficiency.

## Options

  * `:variable_name` — the `#let` binding name (default `"data"`)
  * `:context` — encoding context passed to `AshTypst.Code.encode/2`
  * `:batch_size` — records per NIF call (default `100`)

---

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