# Inkhaven 1.4.9 — Reusable content blocks

_Documentation and technical writing repeats itself: the same warning, the same procedure note, the
same admonition, written out again in every place it's needed and drifting a little each time.
REUSE-1 lets you write that prose **once** as a Typst paragraph in a **Snippets** system book and
reference it anywhere with a standard Typst `#include` — assembly copies the snippets to a sidecar
so it resolves at `typst compile`. No new Typst syntax, no new content type, **self-gating** (a
project with no snippets is unaffected), **zero new dependencies**._

_Plan: [REUSE-1_PLAN.md](../PROPOSALS/REUSE-1_PLAN.md)_

## Write a snippet once

Reusable prose lives in a new **Snippets** system book. Press **`P`** under it and the title becomes
the snippet's slug; write any Typst:

```
= warning-box

#block(fill: rgb("#fee"), inset: 8pt)[*Warning.* Back up your data first.]
```

## Reference it anywhere

In your prose, reference a snippet with a normal Typst `#include` — but let inkhaven write the path.
**`Ctrl+V x`** fuzzy-picks a snippet and inserts:

```
#include "../../snippets/warning-box.typ"
```

The depth-relative `../…/snippets/` prefix is computed automatically from where the paragraph sits
in the tree — you never count directories. With the cursor **inside** an existing snippet include,
`Ctrl+V x` opens in **Replace** mode and swaps just the path (pre-selecting the current snippet).

At Book assembly (`Ctrl+B A` / `inkhaven build`) every snippet is copied to a `snippets/` directory
next to the assembled book, so the include resolves and `typst compile` drops the content inline.

## Catch broken references

Rename or delete a snippet and its references dangle — inkhaven catches it two ways:

- **As you write:** save a paragraph whose `#include` points at an undefined snippet slug and a
  diagnostic appears in the status bar, the `F8` list, and `Ctrl+V N` — *before* you assemble.
  (Validated against the live Snippets book, so it works pre-assembly with no "assemble first" noise.)
- **Across the project:** `inkhaven snippets check` scans every reference and **exits non-zero** on a
  missing snippet (CI-ready); it also reports **orphaned** snippets (defined, never referenced) as
  warnings. `--book` scopes it, `--json` for machine output.

## See the library

**`Ctrl+V Shift+X`** opens the snippets overview: every snippet with how many times it's referenced
across the project (`(N ref)` / `(unused)`); Enter jumps to its source. `inkhaven snippets list` is
the terminal equivalent. Scripts get read-only `ink.snippets.{list,get,check}`.

## Notes

- **Self-gating, zero-cost when unused:** `emit_snippets_directory` is a no-op without a Snippets
  book, and the save-time validator only runs when a buffer contains `#include`.
- Built entirely on inline Typst `#include` + the existing diagnostics pipeline + assembler — **no
  new content type, no new `NodeKind`, no new DB tables, no external/runtime crates.** The Snippets
  book is excluded from BOOK-RAG (opt back in via `book_rag.include_system_books`). New tutorial 92.
  Tests 1936 (from 1.4.8's 1926).
