Overview
ScriptPub — SPUB for short — is a standard for formatting a single
structured text work — a screenplay, a stage play, a story, poetry, any text
with a repeating shape — as one self-contained, standards-correct HTML
file: a .spub.html. The file describes how the work is structured,
displayed, edited, and printed, using three primitives — sections,
blocks, and marks — and it does so with the web platform’s own
machinery, not a parallel one.
Built-in HTML and CSS store everything
SPUB deliberately invents as little as possible. Everything standard HTML and CSS can already express is expressed that way, natively:
- Metadata is schema.org JSON-LD in the head — one
<script type="application/ld+json">island speaking a prepared CreativeWork/Book vocabulary, with<title>,<html lang>, and the canonical/icon links derived from it. See Metadata. - Styling lives in the document stylesheet — one real
<style>element with real CSS: rules,@mediaconditions,@page. See The stylesheet. - Sections are semantic body-level elements —
<header>,<nav>,<main>,<footer>,<section>, with standard DPUB-ARIA roles. See Sections & divisions. - Block and mark identity is a CSS selector — a kind declares
selector: "h3.scene"and is recognized by CSS selector matching, exactly as its stylesheet rule already targets it. See Kind inference. - Page breaks and keeps are real CSS —
break-before/break-after/break-insidein the sheet or on an element’sstyleattribute; there is no structured pagination directive.
Every fact has one machine-readable home. The metadata island is the only
home of metadata, the sheet the only home of styling, the DOM the only home
of sections. (Presentation may restate metadata — the <title> tag and a
title page both show the title — but those are derived or authored display,
never a second source machines read.) What remains — block types, marks,
editor flow, foreign-syntax export spellings — is a minimal JSON island:
the one <script type="application/json"> element holding only what HTML and
CSS cannot express. A file whose config is trivial omits the island entirely.
The payoff is the zero-tooling property: a bare .spub.html is a proper,
accessible web page. Open it from disk in any browser and it renders styled,
themed light/dark, semantically sectioned, and screen-reader navigable — with
no ScriptPub software anywhere.
Status — pre-release (0.1). ScriptPub is an early draft, still in active development and not yet released. Nothing here is frozen and there is no backward-compatibility guarantee yet: the standard is free to change shape until 1.0. This documentation is the source of truth for it; the implementation lives in the
@script-pub/formatpackage. The on-the-wire model counter isscriptpub: 6— one constant version, independent of this 0.1 release status.
Scope — one work, one file
This specification defines exactly one thing: the formatting of a single
text work as one .spub.html file — its head, its config island, its
stylesheet, its body. That is the whole surface.
Everything around the file is the Script Pub App’s concern, documented
with the app, not here: libraries of works, format presets,
multi-file works and their assembly, conversion to and from foreign formats
(Markdown, Fountain, FDX, EPUB, DOCX, …), export packaging, device targeting,
and reading/writing user interfaces. The format keeps only the hooks those
features need — for example the spub:preset island term that records which
app-managed preset a work’s format was seeded from, and the per-kind
foreign-syntax spellings the
app’s converters read.
The canonical model
A .spub.html file parses into one canonical model:
{ config, content, sections?, css? }
config— the minimalFormatConfigplus the in-memorymeta.content— one flat, ordered stream of blocks.sections— the resolved section spans over that stream.css— the document’s own stylesheet text.
Design principles
- The file is the format. One
.spub.htmlholds the work, its metadata, its structure, and its design — self-contained, portable, diffable text. - Standard mechanisms only. Recognition is CSS selector matching;
precedence is CSS specificity; theming is
light-dark()andcolor-scheme; breaks are CSS fragmentation. The spec adds vocabulary, not machinery. - Every fact has one machine-readable home. Metadata in its island, styling in the sheet, sections in the DOM, the rest in the minimal config island. Presentation may restate a fact; machines read one place.
- Structure is flat; nesting is bounded. The content is a flat stream. Sections are body-level spans, never nested. The only real nesting — grids — is exactly one level deep. See The document model.
- Content and kind round-trip losslessly. Anything matching no selector is the default Text block, shown and saved verbatim. Attributes are a fixed, closed vocabulary.
- The format is data. Block types, marks, and styling are editable configuration — nothing is hardcoded and no genre is built in.
How to read these docs
| Start here | Then |
|---|---|
The file — the normative anatomy of a .spub.html, with a complete minimal example. |
Document model — the canonical { config, content, sections } shape, blocks, runs, the three shapes. |
Configuration — the minimal FormatConfig and the in-memory Meta. |
Metadata — the JSON-LD island: the prepared schema.org vocabulary, the spub: context, the fallback tier. |
| Sections & divisions — semantic body-level elements, the standard vocabulary, matter. | Blocks — block types, selectors, behavior, indexes, editor flow. |
| Marks & links — inline formatting and references. | Kind inference — selector matching, specificity, foreign-syntax spellings. |
| Attributes — the fixed attribute vocabulary. | Media — images, audio, video; figures; narration. |
| Mathematics — atomic TeX/MathML expressions. | The stylesheet — the spub-base layer and the document’s own rules. |
| Conditions — @media + app-state adaptation. | Settings — the --spub-* custom-property vocabulary. |
| Translations, drafts & revisions — metadata-linked documents. | Glossary — every term, precisely. |