Translations, drafts & revisions

Three related concepts describe how one ScriptPub document relates to another. Translations and drafts are separate sibling documents; revisions are tracked changes within a document. All three are bound in meta or config, not in filenames.

Translations

A translation is a sibling document — one complete, standalone ScriptPub file per language, in the same syntax as the original or any other. The binding lives in meta, not the filename: the translation carries meta.translationOf (a reference to the original) and its own meta.language. Interleaving languages in one file is deliberately not supported.

  • Config is inherited. A translation’s config extends the original’s, with the same overlay-merge as companion files — deep merge, arrays by id, translation wins. A translation typically declares only deltas: translated labels, language-specific styling, its own meta.
  • Alignment is optional and block-level, via origin. A translated block may carry an origin attr — a block ref (^id) into the original. This reuses the on-demand id rule: anchoring to a source block is a targeting, so that block’s id gets persisted in the original by the ordinary mechanism. originRev beside it lets an editor track staleness when the source block changes.
  • Fallback alignment is structural — same division, same ordinal position — for unanchored translations. They lose block-precise pairing, nothing else.
  • A multi-file work translates the same way: the translation is its own <slug>.<lang> sibling — a single file or a work folder of its own. Part-by-part, spine-aligned translation is reserved for a later revision.
  • Everything downstream derives. Parallel two-column reading pairs blocks by origin; cross-language cue-name mapping falls out of origin on cue blocks (each document’s character index is in its own language, the anchors tie them together); lang / dir block attrs cover inline foreign snippets within a document.

Drafts

A draft is a sibling document too — exactly like a translation: a complete standalone file bound by meta. draftOf references the main document, and draft labels the pass (“Second draft”, “Producer polish”). Config is inherited by the same overlay-merge.

Diff and merge between drafts operate on the canonical model at the block level. That is tooling, not part of the format — the format’s job is only to bind the sibling and carry the label.

Revisions

Production-style tracked changes — Final Draft’s native turf (revision passes, colored pages, revised-asterisk margins). Unlike translations and drafts, revisions live within one document.

  • config.revisions declares the named passes:

    Field Type Required Description
    id string Unique revision id.
    label string Display label (“Pink”).
    color string Page / mark color.
    date string Date of the pass.
  • The rev attr on a block or mark references a pass — “touched in this pass.” Combined with the ins / del marks it gives full tracked changes: ins + rev = added in that pass; del + rev = removed but retained.

  • Tiered support. Revisions persist only where the syntax can store attributes — HTML (data-rev), FDX (natively), JSON. Content-derived syntaxes (plain text, Fountain, most of Markdown) have nowhere to put rev without polluting the text, so they don’t carry it.

Margin asterisks and colored-page output are a print concern (parked in this revision); the data they need is exactly rev.