# Package entrypoints

> Every importable path and what lives behind it.

Source: https://docxcelerate.com/docs/reference/entrypoints/

The package ships compiled output with type declarations. Every entrypoint below
is declared in `exports`, so they resolve in Node and in bundlers without deep
imports into `dist/`.

## docxcelerate

The main surface: the document builder, artifact helpers, derivers, runtime
types, and every type in the document domain.

```ts
import {
  buildDocument,
  buildProjectPreviewDocument,
  cleanMinimalDocumentStyle,
  dataRef,
  derive,
  type DocumentModel,
  type ParagraphNode,
} from "docxcelerate";
```

## docxcelerate/document

Document project definition — the entrypoint a scaffolded `document.project.ts`
uses. The CLI and the scaffolded filenames still say `document`; the API does not.

```ts
import { defineDocumentProject } from "docxcelerate/document";
```

## docxcelerate/template

The authoring surface: the elements, the hooks, and `template` itself. This is
what a component file imports.

```ts
import {
  Document,
  Graph,
  Image,
  Paragraph,
  Section,
  TableOfContents,
  template,
  useAvailableTokens,
  useFormat,
  usePlaceholderData,
  useSetPlaceholders,
  useSetPrompts,
  useShared,
  useState,
} from "docxcelerate/template";
```

Each element name is also a component type, so `const Greeting: Paragraph =
() => <Paragraph … />` names what a component returns and rejects returning the
wrong kind.

Its JSX runtime is exposed at `docxcelerate/template/jsx-runtime` (and
`.../jsx-dev-runtime`), which is what `jsxImportSource` resolves to.

## docxcelerate/docx

DOCX construction.

```ts
import { createDocxBlob, createDocxDocument, renderDocxBytes } from "docxcelerate/docx";
```

There is one renderer, and it writes Word files. To show a document on a screen,
pack it and read the file back with a DOCX viewer — the preview app your
workspace is scaffolded with does that over `docx-preview`, and so do the
previews on this site. A second renderer laying the model out in HTML would be a
second answer to what a document looks like, and the one nobody opens in Word is
the one that drifts.

## docxcelerate/preview

Finishing a preview that `docx-preview` has laid out.

```ts
import { readPackedParagraphs, readPackedTables, settleDocxPreview } from "docxcelerate/preview";

const packed = new Uint8Array(await blob.arrayBuffer());
await renderAsync(packed, body, head, { breakPages: true });
settleDocxPreview(
  body,
  model,
  await readPackedParagraphs(packed),
  await readPackedTables(packed),
);
```

`docx-preview` does not read everything a `.docx` says. It drops a field run, so
a footer Word prints as "1 / 2" arrives as a bare slash. It looks for a table's
indent under an attribute that never carries it. It reads `w:spacing` only when
the parent is `w:pPr`, so a run's letter spacing never reaches the page. It
writes a paragraph border without the gap the border holds its text off by. It
draws every row of a table as a plain row, so nothing says which of them is the
heading that repeats at the top of each page. And it puts a picture in an
element a paragraph may not contain, which survives in a DOM and does not
survive being written down.

`settleDocxPreview` puts each of those back. Every one of them is a fact the
packed file already declares and Word already draws — nothing here is a
stylesheet, and nothing invents a layout. A preview patched with CSS that Word
cannot reproduce is a preview that lies, which is the one thing reading the file
back exists to prevent.

Three of them can only be recovered from the file, so `readPackedParagraphs`
and `readPackedTables` read the bytes and settle is handed the result.
Recomputing them from the style that produced the document would put a second
copy of the packer's arithmetic beside the first, and the copy nobody opens in
Word is the one free to drift. Reading is asynchronous because inflating is;
settle stays synchronous, because it mutates a DOM somebody is about to measure.

`readPackedTables` reads one fact per table: how many rows it opens with that
repeat. Settle moves those into a `<thead>`, which is what the element already
means, and the paginator copies them onto each new sheet — so a table running
over three pages keeps its column headings on all three, the way Word prints it.

Call it after `renderAsync` and before the container is measured or serialised.
It works the same in a browser as in a `jsdom`, and the scaffolded preview app
already does this for you.

### Charts

```ts
import { readPackedCharts, settleDocxPreviewCharts } from "docxcelerate/preview";

settleDocxPreviewCharts(body, await readPackedCharts(packed), draw);
```

A chart is packed as a real Word chart — a `c:chartSpace` part beside
`document.xml`, with every value cached in it — and `docx-preview` has no
reading of one at all: the string "chart" does not occur in its bundle. What it
leaves is an empty inline-block span at exactly the size the file gave the
frame, which is the half that matters most, because it is what the page is laid
out around and it is what keeps the preview paginating like Word.

`readPackedCharts` reads the rest back out of the same bytes — the type, the
categories, every series with its numbers and its colour, the key's place, the
format on the value axis. Read out of the file rather than out of the model
that produced it, for the reason everything else here is: those are decisions
the packer made from the theme, and a preview that made them again would be a
second copy of the packer's arithmetic.

`settleDocxPreviewCharts` puts what `draw` returns into each frame, in order.
The drawer is yours — a chart renderer is a large, well-solved problem, and
bundling one into a package whose only dependency is its packer would be the
wrong trade for everyone who never previews a chart. A scaffolded workspace
ships one over [ECharts](https://echarts.apache.org) in
`preview/charts.ts`; copy it, or write one over whatever your app already has.
A drawer that returns `undefined` leaves the frame empty, which is the right
answer for a chart it cannot plot: an empty frame of the right size is a gap,
and a wrong plot is a lie.

What the preview then shows is honest about what it is. The frame, the numbers,
the colours and the type are the file's; the plot inside is another renderer's
drawing of them rather than Word's. Word is the only thing that draws what Word
draws — `conformance/cases/charts/column-series` holds the frames of the two
against each other and leaves their pixels alone, deliberately.

### Pages

`docx-preview` breaks where the *file* says to — an explicit break, or a
paragraph marked to start one — and nowhere else. It does not lay text against a
page height and start a new sheet when the old one is full, so a document Word
prints on five pages arrives as one very long sheet. Everything read off that is
wrong with it: which page a paragraph is on, whether a header repeats, what a
footer's "1 of 5" should say.

```ts
import { paginateDocxPreview } from "docxcelerate/preview";

paginateDocxPreview(body);
```

It flows the body's blocks into boxes the height of the page, carries the
running furniture onto each new sheet, and recounts the page numbers. It is a
separate call from `settleDocxPreview` because it needs something to have laid
the page out — a browser, or headless Chrome. In a `jsdom` every height is zero,
which would read as "it all fits", so it declines to answer instead and tells
you why.

It breaks *between* blocks, with one exception: a table is broken between two
of its rows, which is the seam Word breaks at too, and the rows that did not fit
are carried onto the next sheet with the columns and the heading intact. A
paragraph Word would split across a sheet still moves whole.

Both are measured rather than claimed. On documents made of ordinary paragraphs
the two engines agree exactly — `conformance/cases/preview/content-pagination`.
On a table sixty rows long they take the same number of pages and put the same
rows on them, with the seam itself within one row of Word's —
`conformance/cases/preview/table-pagination`.

### Tab stops

```ts
import { applyTabStops, readPackedParagraphs } from "docxcelerate/preview";

applyTabStops(body, await readPackedParagraphs(packed));
```

A tab stop is the one paragraph property whose effect cannot be written as a
style: where the text after a tab lands depends on how wide the text *before* it
drew. So like pagination it needs a layout, and runs in the same place — before
paginating, since a line that has not found its stop is the wrong height to
measure a page against.

Put together, a preview is finished in three steps, and the order is the order:

```ts
const packed = new Uint8Array(await blob.arrayBuffer());
const paragraphs = await readPackedParagraphs(packed);
const tables = await readPackedTables(packed);

await renderAsync(packed, body, head, { breakPages: true });
settleDocxPreview(body, model, paragraphs, tables);   // no layout needed
applyTabStops(body, paragraphs);                      // needs layout
paginateDocxPreview(body);                            // needs layout, and settled heights
```

The scaffolded preview app already does all of this.

## docxcelerate/scaffold and /cli

The workspace generator and its command-line front end, for building your own
tooling on top.

```ts
import { scaffoldWorkspace } from "docxcelerate/scaffold";
```
