--- title: Script description: The Script Surface — Segments, Role Cues, Dual Text, Selections, Moments and text projections. --- # Script The ` ``` The import `@narratage/script@1` activates the Script Surface. The `id` attribute lets other components refer to the Script and its parts. ## Segments Segments are ordered blocks of spoken content. The tag name **is** the id — it must be unique within a Script. ```svml ``` - A Segment can be self-closing (``). An empty Segment has structure but no speech tokens; it does not imply silence or any default duration. - Segments cannot nest — every Segment is a top-level child of ` ``` ### Syntax | Marker | Meaning | |---|---| | `@id` | Open, right-absorbing (starts at the next word) | | `~@id` | Open, left-absorbing (starts at the previous word's end) | | `@/id` | Close, left-absorbing (ends at the previous word's end) | | `@/id~` | Close, right-absorbing (ends at the next word's start) | The `~` suffix/prefix controls whether the boundary snaps to the left or right. Default open is right-absorbing; default close is left-absorbing. ### Non-contiguous Selections The same id can appear multiple times to create a Selection with gaps: ```svml @beat First point. @/beat Then something else. @beat Third point. @/beat ``` `{story.selection.beat}` now covers two disjoint ranges. ### Crossing Selections Selections are not required to nest like XML tags. They can cross each other: ```svml @a One @b two @/a three @/b. ``` Selection markers are zero-width and never appear in any text projection. They compile into `SelectionSet` values containing `Range[]`. Script itself contains no seconds or frame numbers — timing comes from WhisperX alignment. Other components reference Selections via `{story.selection.problem}` to bind visual content to semantic moments in the narrative. ## Moments Moments are named time **points** (not ranges): ```svml @ranking! Image generation, video generation, captions and B-roll all become reusable components. ``` | Marker | Meaning | |---|---| | `@id!` | Right-absorbing (point at the next word's start) | | `~@id!` | Left-absorbing (point at the previous word's end) | Moments compile into `MomentSet` values containing `Point[]`. Selection and Moment share the same name namespace — the same id cannot be used for both. Other components reference Moments via `{story.moment.ranking}`. ## Slots Variable interpolation for templated Scripts: ```svml Meet <${product} | ${product_pronunciation}>. ``` Slot ids are 1–64 characters, starting with a letter or underscore. Binding values are literal text — they cannot inject SVML syntax. Slots are parsed first, then bound. ## Comments and escaping ```svml Follow us \@svml on social media. ``` Reserved syntax starters must be escaped: | Escape | Produces | |---|---| | `\@` | literal `@` | | `\<` | literal `<` | | `\${` | literal `${` | | `\\` | literal `\` | Inside Dual Text, also escape `\|` and `\>`. ## Combination example A complete Script using all constructs together: ```svml ``` This Script declares: - Four Segments: `hook`, `meeting`, `evidence`, `payoff` - One Role Cue: `HOST` (consistent across all Segments) - One Dual Text: `` (displayed as "BCC", spoken as "B C C") - Three Selections: `whole` (entire Script), `problem`, `solution`, `emphasis` - One Moment: `ranking` (marks the instant "After the first recap") Downstream components reference these by name: `{story.segment.hook.dialogue}` for generation, `{story.selection.problem}` for B-roll timing, `{story.moment.ranking}` for a visual card reveal.