Configuration
A work’s format is a FormatConfig — the config half of the
canonical model. Since v5 it is minimal: it holds only
what standard HTML and CSS cannot express. Everything else lives natively in
the .spub.html file:
- metadata → the HTML head (
Metabelow is the in-memory shape; it is never serialized as JSON), - styling → the document stylesheet,
- sections → semantic body-level elements (Sections),
- block identity → CSS selectors (
BlockDef.selector, Kind inference), - page breaking → real CSS
break-before/break-after/break-insidein the sheet or on an element’sstyleattribute.
Data never appears in two places.
FormatConfig
{
"scriptpub": 5,
"blocks": [ … ],
"marks": [ … ],
"syntax": { "html": { "newline": "br" } },
"revisions": [ … ]
}
| Field | Type | Required | Description |
|---|---|---|---|
scriptpub |
5 |
✓ | The wire version — the one version this revision reads and emits. The format is pre-release; there is no cross-version compatibility machinery. |
meta |
Meta |
✓ | Work metadata — the in-memory model of the HTML head (below). Serialized only as head markup, never in the JSON island. |
blocks |
BlockDef[] |
✓ | The block types. Recognition precedence is CSS selector specificity; definition order breaks ties. See Blocks. |
marks |
MarkDef[] |
✓ | The inline mark types (same precedence rules as blocks). See Marks & links. |
syntax |
SyntaxSettings |
Document-wide adapter settings, keyed by syntax id (below). | |
revisions |
RevisionDef[] |
Named revision passes. See Translations, drafts & revisions. | |
| — | Appearance is NOT config: reusable styles, typography, conditions, page geometry, and settings live in the document stylesheet; one-off direct formatting lives in content attrs.style. |
The JSON island in a file carries only scriptpub, blocks, marks,
syntax, and revisions — and is omitted entirely
when the config is trivial (nothing declared beyond the built-in vocabulary).
scriptpubis the model-version counter, not the release number. The standard is pre-release (0.1) — see the Overview. This revision’s counter is the constant5; earlier counters (2–4) and their lowest-version-emission rules are gone with the pre-release model change.
BlockDef
The full block-type shape — see Blocks for semantics:
| Field | Type | Required | Description |
|---|---|---|---|
id |
string |
✓ | Unique kind id. One class-safe token. |
label |
string |
Display label; default: the id. | |
shape |
"text" | "void" | "grid" |
Content shape; default "text". |
|
grid |
{ cols? } |
Grid authoring defaults — the column count a new instance is created with. | |
default |
boolean |
true on at most one declared block (the fallback for content matching no selector); the built-in p is the default when none claims it. More than one is invalid. |
|
selector |
string |
✓* | The kind’s CSS selector — recognition AND spelling in the file. Required unless default is true. See Kind inference. |
behavior |
BlockBehavior |
Structural flags (below). | |
indexes |
IndexDef[] |
Navigator index groups this kind feeds. | |
editor |
BlockEditor |
Editing behavior — shortcut, placeholder, Enter/Tab flow, allowed sections. | |
syntax |
Record<string, BlockSyntax> |
Foreign-syntax spellings (md / fountain / fdx / txt), keyed by syntax id — recognition on import, canonical spelling on export. The html spelling is selector, never an entry here. |
BlockBehavior
Structural flags — all optional. Page breaking and keep options are not
here: they are real CSS fragmentation properties in the sheet or on an
element’s style attribute.
| Field | Type | Default | Description |
|---|---|---|---|
outline |
boolean |
false |
Show blocks of this kind in the outline / navigator. A kind with outline is a division. |
rank |
number |
Outline nesting rank (1 = top). Only meaningful with outline. The division structure lives here — separate from sections. |
|
numbered |
boolean |
false |
Automatic running number. |
restartNumbering |
boolean |
false |
On a numbered division, restart its count at 1 whenever a coarser division (lower rank) appears — a play’s scenes reset each act. Off = the count runs continuously (screenplay style). |
summary |
boolean |
false |
Summarizes the division it opens (navigator). |
printing |
boolean |
true |
false = the block exists in the file but never prints or renders for reading — writer-only notes (Fountain [[…]], boneyard /* … */). |
more |
string | true |
Foot-of-page text when the block breaks across pages; true = "(MORE)". |
|
resumed |
string | true |
Text appended to a repeated/continued cue; true = "(CONT'D)". Applies after a page break AND to a consecutive same-index block of this kind. |
IndexDef
| Field | Type | Required | Description |
|---|---|---|---|
label |
string |
✓ | Group label in the sidebar (e.g. "Characters"). |
pattern |
string (regex) |
✓ | Regex source run against the block’s text; matches collect. |
BlockEditor
| Field | Type | Description |
|---|---|---|
shortcut |
string |
Keyboard shortcut, e.g. "Mod-1" (Mod = ⌘/Ctrl). |
placeholder |
string |
Ghost text in an empty block. |
enter |
string |
Kind of the next block on Enter (a block id). |
tab |
string |
Kind this block cycles to on Tab. |
shiftTab |
string |
Kind this block cycles to on Shift-Tab. |
sections |
string[] |
Allowed section ids (sectioned documents only) — standard or custom. Omitted = anywhere. Edge blocks exempt. |
MarkDef
| Field | Type | Required | Description |
|---|---|---|---|
id |
string |
✓ | Unique mark id. One class-safe token. |
label |
string |
Display label; default: the id. | |
selector |
string |
The mark’s CSS selector — recognition AND spelling (e.g. "em", "u.underline"). Same rules as a block’s selector. |
|
editor |
{ shortcut? } |
Keyboard shortcut, e.g. "Mod-b". |
|
syntax |
Record<string, MarkSyntax> |
Foreign-syntax spellings, keyed by syntax id. |
See Marks & links.
Meta
Meta is the in-memory model of the JSON-LD metadata island — the html
adapter spells every key as an island term; the config island never carries
it. Only title is required. See Metadata for the term
mapping and the fallback tier.
| Field | Type | Description |
|---|---|---|
title* |
string |
The work’s title → island name (and the derived <title>). |
titleTranscription |
string |
Pronounceable Latin transcription of title, used for generated slugs when the title’s writing system cannot normalize to ASCII. Not a translated title. → spub:titleTranscription. |
internationalTitle |
string |
A broadly recognized title used outside the work’s own language. title remains in the document’s language. → alternateName. |
indexAs |
string |
The title’s INDEX form — how the work files in an ordered list when that differs from title. Standard practice drops a leading article in the work’s own language (“The Monkey’s Paw” → “Monkey’s Paw”). Absent = index by title. → spub:indexAs. |
credit |
string |
Credit line (“Written by”). → spub:credit. |
author |
string | string[] |
Author display name(s) → island author strings. |
authorTranscription |
string |
Pronounceable Latin transcription of author, for a name written in a non-Latin script. → spub:authorTranscription. |
authorIndexAs |
string |
The author’s INDEX form — how the author files in an ordered catalogue when that differs from author (“Albert Einstein” files as “Einstein, Albert”). Absent = index by author. Maps to the creator file-as refinement in EPUB. → spub:authorIndexAs. |
source |
string |
Source line (“Based on …”) — a human-readable bibliographic note. → spub:source.note. |
sourceUrl |
string |
Stable HTTP(S) landing page for the primary source used to prepare this rendition. → spub:source.url. |
sourceAccessed |
string |
RFC 3339 date-time at which sourceUrl was accessed. → spub:source.accessed. |
draft |
string |
Draft label / date (labels a draft). → spub:draft. |
contact |
string |
Contact block. → spub:contact. |
copyright |
string |
Copyright notice. → copyrightNotice. |
license |
string |
License — URL or text. → license. |
year |
string |
Year of writing / publication — an opaque string. → datePublished. |
description |
string |
One-line description. → description. |
keywords |
string |
Subject tags, comma-separated in memory. → keywords, an array. Structured subjects say the same thing with a vocabulary; both are read wherever tags are shown. |
added |
string |
RFC 3339 date the work entered the library carrying it. A library whose store keeps its own timestamps uses those instead. → spub:added. |
modified |
string |
RFC 3339 date this edition was last edited, reformatted, or reconverted. Absent on a work unchanged since it was added. → dateModified. |
uri |
string |
Canonical URL — the document’s stable public identity. → @id (and the derived canonical link). |
cover |
string |
Cover image path (relative preferred). → image (and the derived icon link). See Media. |
coverAlt |
string |
Accessible description of the cover — the ImageObject’s description. |
narration |
string |
Default narration audio path. → spub:narration. |
narrator |
string |
Narrator display name. → spub:narrator. |
preset |
string |
The preset this work’s format was seeded from — a scriptpub: uri or any URL. → spub:preset. Presets themselves are app-managed; the format records only this reference. |
language |
string |
BCP-47 tag; default "en". → inLanguage (and the derived <html lang>). |
entities |
MetaEntity[] |
Structured agent records — authors, contributors, publishers, translators, narrators with their filing/role qualifiers. → Person/Organization objects under the relation’s term. |
subjects |
MetaSubject[] |
Subject statements — bare tags or vocabulary terms. → about. |
identifiers |
MetaIdentifier[] |
Identifier statements (ISBN, DOI, URN, …). → identifier. |
statements |
MetaStatement[] |
The lossless bibliographic remainder, in source order. → spub:statements. |
links |
MetaLink[] |
Linked metadata and alternate representations. → spub:links. |
bibComplete |
boolean |
When true, the structured groups + statements/links are the complete package projection rather than supplements. → spub:complete. |
schemaProps |
Record<string, unknown> |
Additional schema.org properties (the EPUB a11y set, hand-authored extras), preserved verbatim as native island terms. |
vocab |
Record<string, string> |
Extra @context term declarations for non-reserved vocabularies. |
translator |
string |
Translator display credit, beside translationOf. → island translator string. |
translationOf |
string |
Reference to the original this document translates. → translationOfWork. |
draftOf |
string |
Reference to the document this is a draft of. → spub:draftOf. |
notes |
string |
Free notes. → spub:notes. |
| (custom) | unknown |
Any additional keys, preserved verbatim with their JSON values. → spub:<key>. kind, parts, and library are reserved for the app’s structural keys. |
MetaEntity is { relation, name, type?, id?, fileAs?, transcription?, role?, roleScheme?, attributes? }, MetaSubject is { value, id?, authority?, term? }, MetaIdentifier is { value, id?, scheme?, primary? },
MetaStatement is { property, value, form?, id?, primary?, refines?, scheme?, authority?, language?, direction?, attributes? }, and MetaLink is
{ href, rel[], id?, mediaType?, language?, properties?, refines?, attributes? } — see Metadata for the field semantics and
island spellings.
SyntaxSettings & RevisionDef
syntax holds document-wide adapter settings keyed by syntax id. Only html
is pinned in this draft; other ids are open:
SyntaxSettings = { html?: HtmlSettings, [id: string]: unknown }
HtmlSettings = { newline?: "br" | "literal" } // in-block newline encoding; default "br"
revisions holds the named production passes — see
Revisions:
RevisionDef = { id: string, label?: string, color?: string, date?: string }