Format presets

A format preset is a reusable format. There is no separate file type for it: a preset is simply a ScriptPub document that is all header — a config with empty (or absent) content. Any syntax that can carry a config can carry a preset (a json file with no content key, an html file with no <main> content — both parse to content: []).

isPresetDoc(doc) === (doc.content.length === 0)

Identity — PresetRef

A preset’s identity lives in the config’s top-level preset field:

Field Type Description
name string The preset’s display name, e.g. "Screenplay". Distinct from meta.title, which titles the sample body.
uri string Stable identifier (below).

The uri scheme records where a preset comes from:

Form Meaning
scriptpub:preset/<id> A built-in preset.
scriptpub:curated/<slug> A curated preset — part of a shipped set.
scriptpub:local/<id> A user-made preset — device-scoped, not globally resolvable.
any URL A published preset resolvable at that address.

Provenance for free

Creating a script from a preset clones the preset’s config — and the preset field rides along. So every script records which preset (name + uri) it was seeded from. Editing the script’s format never rewrites the field: it is history, not a live link. Deleting a preset never touches scripts already seeded from it.

Sample body

A preset file may carry content. When it does, that body is the preset’s sample — a short demonstration script that should exercise every block kind, mark, and section the format defines. The sample is preview material for format editors and preset pickers; a script created from the preset starts empty unless the tool explicitly offers the sample as seed content. A header-only file is just a preset without a sample.

Built-in presets

Four presets ship as default instances of the format shape — each is a normal, fully editable FormatConfig:

  • Screenplay (scriptpub:preset/screenplay) — scene headings (numbered, continuous), action, character cues (with a Characters index and (CONT'D)), parentheticals, dialogue, transitions, dual dialogue, and title-page kinds.
  • Play (scriptpub:preset/play) — acts and scenes (scenes reset per act), dialogue-first, stage directions.
  • Story (scriptpub:preset/story) — chapters, justified indented paragraphs, headings, scene breaks.
  • Catalog (scriptpub:preset/catalog) — the default format for collections and library indexes: group/subgroup headings, linked list entries, annotation notes.

Anatomy of a preset file

The curated Poetry preset (scriptpub:curated/poetry) is a complete, minimal .spub.html preset — the concrete reference for the whole file shape. Abridged:

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Untitled Poem</title>
<script type="application/json" id="scriptpub">
{
  "scriptpub": 2,
  "meta": { "title": "Untitled Poem", "language": "en" },
  "preset": { "name": "Poetry", "uri": "scriptpub:curated/poetry" },
  "blocks": [
    { "id": "heading", "label": "Title",
      "behavior": { "outline": true, "rank": 1 },
      "editor": { "shortcut": "Mod-1", "enter": "line" },
      "syntax": { "html": { "match": [{ "construct": "h1" }], "write": { "tag": "h1" } },
                  "md":   { "match": [{ "construct": "heading", "level": 1 }], "write": { "construct": "heading", "level": 1 } } } },
    { "id": "line", "label": "Line", "default": true,
      "editor": { "shortcut": "Mod-2", "enter": "line" },
      "syntax": { "html": { "write": { "tag": "p" } } } },
    { "id": "stanza_break", "label": "Stanza break", "shape": "void",
      "syntax": { "html": { "match": [{ "construct": "hr" }], "write": { "tag": "hr" } } } }
  ],
  "marks": [
    { "id": "em",     "label": "Italic", "editor": { "shortcut": "Mod-i" },
      "syntax": { "html": { "write": { "tag": "em" } },     "md": { "write": { "delim": "*" } } } },
    { "id": "strong", "label": "Bold",   "editor": { "shortcut": "Mod-b" },
      "syntax": { "html": { "write": { "tag": "strong" } }, "md": { "write": { "delim": "**" } } } }
  ],
  "syntax": { "html": { "newline": "br" } }
}
</script>
<style id="scriptpub-style">
h1.heading   { font-size: 1.4rem; font-weight: bold; margin-top: 2.4rem; }
p.line       { margin-left: 4ch; }
hr.stanza_break { border: none; margin-top: 1.2rem; }
</style>
</head>
<body>
<main>
  <h1>Harbor Light</h1>
  <p>The tide keeps what the pier lets go,</p>
  <hr />
  <p>And every light that says <em>come home</em> says <strong>stay away</strong> the same.</p>
</main>
</body>
</html>

Everything above <main> is the format; <main> is the sample body. Strip that body and you have a header-only preset.