Which AST to emit, and when to go standalone
A parser takes file bytes and answers with a typed message. This page explains
the three ways it can answer and why a shared AST is the default. The exact
contract is in SPEC.md section 4; where this page and SPEC.md differ,
SPEC.md wins.
Three extension kinds
| Kind | plugin.json |
stdin | stdout |
|---|---|---|---|
| Parser with a shared viewer | "viewer": "poka-<shape>-viewer" |
PreviewRequest |
one *Ast message |
| Standalone parser | no viewer field |
PreviewRequest |
a full PreviewResponse |
| Viewer | "file_extension": "" |
a *Ast message |
HTML |
A viewer belongs to the viewers repo. A parser author chooses between the first two.
Why a shared viewer is the default
The host runs the parser, pipes its output into the viewer and wraps the HTML that comes back. As a result:
- The parser has no HTML. It decodes the format and fills a typed structure. A typical parser is a few dozen to a few hundred lines of format logic.
- One fix reaches every format. A better table renderer improves every
parser that emits a
TableAst. - Desktop, web and mobile look the same, because the viewer is shared and the host renders its output identically everywhere.
Pick the AST by the shape of the content
Choose the AST for what the user needs to see, not for how the file is stored.
The proto (core/proto/preview.proto) defines the set, among them TableAst,
WorkbookAst, TextAst, TreeAst, SlideDeckAst, Drawing2DAst,
Scene3DAst, ImageWithMetaAst, ImagePagesAst, DiffAst, EbookAst,
ChartAst and MetadataCardAst.
- A file of rows and columns is a
TableAst, even if it is binary. - A file of nested keys, an XML or a container listing is a
TreeAst. - A file you can only identify, with a header and a few fields, is a
MetadataCardAst. That is a thin result; see Depth tiers. - A drawing is a
Drawing2DAst, a model is aScene3DAst.
One AST type per plugin. Every success path emits the type the manifest's
viewer decodes. A parser that emits TreeAst on one branch and
ImageWithMetaAst on another breaks the viewer on the branch the manifest does
not name. The failure path is the one exception: it answers with an
ErrorResponse, which the host shows before the viewer runs.
When to go standalone
Go standalone only when the format needs a response type no shared AST covers,
for example an SVG, an image, a PDF or a drawing the host draws itself. A
standalone parser writes the whole PreviewResponse, so it also owns
escaping, theming and limits. That is more code and more risk, and it is the
exception: most manifests declare a shared viewer.
Two cases look like standalone but are not. A parser with a viewer may answer
with a complete PreviewResponse when its content has no shared shape (a text
fallback, or several tabs through a MultiView). SPEC.md section 4 lists
them. The manifest still names a viewer.
See also
SPEC.md— manifest, ABI and output contract.- Write a parser
- Honesty in output