You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
An optional `#` header immediately after the front matter. It serves as the document title for display purposes. Parsers should treat it as metadata — it does not create a segment or affect WPM/emotion inheritance. If omitted, the `title` field from the front matter is used instead. If both are present, the `#` header takes precedence for display.
55
+
52
56
## Format Specification
53
57
54
58
### Front Matter (YAML)
@@ -94,22 +98,28 @@ Segments are major sections of the script.
94
98
## [SegmentName|120WPM|Emotion|Timing]
95
99
```
96
100
97
-
All parameters after the name are optional and position-dependent, separated by `|`.
101
+
All parameters after the name are optional, separated by `|`. Parameters are identified by format, not by position:
102
+
103
+
- An integer (or integer + `WPM` suffix) → **WPM**
104
+
- A known emotion keyword → **Emotion**
105
+
- A time pattern (`MM:SS` or `MM:SS-MM:SS`) → **Timing**
106
+
107
+
This means parameters can appear in any order and unneeded ones can simply be omitted — no empty `||` slots required.
98
108
99
109
**Examples:**
100
-
-`## [Intro|140WPM|Warm]`
101
-
-`## [Urgent Update|150WPM|Urgent|0:30-1:10]`
102
-
-`## [Overview||Neutral]` — inherits default WPM
110
+
-`## [Intro|Warm]` — inherits base WPM, sets emotion
111
+
-`## [Urgent Update|145WPM|Urgent|0:30-1:10]` — overrides WPM, sets emotion and timing
-`## [Simple Segment]` — name only, inherits everything
104
114
105
115
**Segment Parameters:**
106
116
107
-
|Position |Parameter | Format | Description |
108
-
|----------|-----------|--------|-------------|
109
-
|1 |**Name**| free text | Human-readable label shown in editors. Required. |
110
-
|2 |**WPM**|`NNN` or `NNNWPM`| Integer speed override. Omit or leave empty to inherit. |
111
-
|3 |**Emotion**| preset name | Emotion preset (see table below). Defaults to `Neutral`. |
112
-
|4 |**Timing**|`MM:SS` or `MM:SS-MM:SS`| Duration hint. Stored for tooling; playback computes timing from word counts. |
117
+
| Parameter | Format | Description |
118
+
|-----------|--------|-------------|
119
+
|**Name**| free text | Human-readable label shown in editors. Required (first value before the first `\|`). |
120
+
|**WPM**|`NNN` or `NNNWPM`| Integer speed override. Omit to inherit. |
121
+
|**Emotion**| preset name | Emotion preset (see table below). Omit to inherit (defaults to `Neutral` at document level). |
122
+
|**Timing**|`MM:SS` or `MM:SS-MM:SS`| Duration hint. Stored for tooling; playback computes timing from word counts. |
113
123
114
124
**Leading text:** Content between a segment header and its first block is preserved as introductory text that inherits the segment's speed and emotion.
115
125
@@ -122,17 +132,18 @@ Blocks are topic groups within a segment.
122
132
```
123
133
124
134
**Examples:**
125
-
-`### [Opening Block|140WPM]`
126
-
-`### [Speed Variations|140WPM|Focused]`
127
-
-`### [Happy Section]`
135
+
-`### [Opening Block]` — inherits segment WPM and emotion
@@ -176,7 +187,7 @@ Inline markers are embedded within phrase text to control presentation.
176
187
|`[fast]`| 1.25× | 175 |
177
188
|`[xfast]`| 1.5× | 210 |
178
189
179
-
**Note:** All relative speed tags are **relative to the base speed**, not absolute values. Tags stack multiplicatively when nested: `[xslow][slow]text[/slow][/xslow]` = base × 0.6 × 0.8 = 48% of base.
190
+
**Note:** All relative speed tags are **relative to the base speed**, not absolute values. The multiplier is calculated as `1 + (offset / 100)`. For example, `slow` with offset `-20` → multiplier `1 + (-20/100)` = `0.8`. Tags stack multiplicatively when nested: `[xslow][slow]text[/slow][/xslow]` = base × 0.6 × 0.8 = 48% of base.
180
191
181
192
#### Runtime Speed Control
182
193
@@ -211,6 +222,17 @@ The **+/−** buttons on the reading page change the **base speed** for the curr
[stress:de-VE-lop-ment]development[/stress] # Stressed syllable in UPPERCASE
229
+
[stress:IN-fra-struc-ture]infrastructure[/stress]
230
+
```
231
+
232
+
The guide string uses hyphens to separate syllables. The stressed syllable is written in **UPPERCASE**; unstressed syllables are lowercase. For words with secondary stress, use an acute accent on the vowel: `[stress:rè-su-MÉ]résumé[/stress]`.
233
+
234
+
Renderers should display the stress guide as a tooltip, subtitle, or overlay — not replace the word itself.
235
+
214
236
## Keyword Reference
215
237
216
238
### Emotions (case-insensitive)
@@ -249,7 +271,7 @@ Colors are **semantic names** — renderers map them to actual hex values approp
249
271
|`white`| #F8F9FA | High | Default text on dark BG |
250
272
|`gray`| #ADB5BD | Medium | Subdued, secondary text |
251
273
252
-
> **Note:**`black` is **not a valid inline color** — it is invisible on the dark teleprompter background. Parsers strip `[black]` tags and render content unstyled.
274
+
> **Note:**`black` is **not a valid inline color** — it is invisible on the dark teleprompter background. Parsers should strip `[black]` tags and render the enclosed content unstyled (no color applied).
253
275
254
276
`highlight` is a **formatting tag**, not a color — it applies a semi-transparent yellow **background overlay**: `[highlight]key point[/highlight]`.
255
277
@@ -264,14 +286,16 @@ Colors are **semantic names** — renderers map them to actual hex values approp
264
286
|**Markdown emphasis**|`*text*`| Converted to emphasis level 1 |
265
287
|**Strong emphasis**|`**text**`| Converted to emphasis level 2 |
|**Color**|`[red]text[/red]`, `[green]...[/green]`, etc. | Apply color styling (see Colors table) |
276
300
|**Emotion**|`[warm]text[/warm]`, `[urgent]...[/urgent]`, etc. | Apply emotion-based color styling (see Emotions table) |
277
301
@@ -301,7 +325,7 @@ All speed presets are **relative to base_wpm** — they apply a multiplier, not
301
325
|----------|--------|-------|
302
326
|`\[`|`[`| Literal bracket in text |
303
327
|`\]`|`]`| Literal bracket in text |
304
-
|`\|`|`\|`| Literal pipe in segment/block names |
328
+
|`\|`| `|` | Literal pipe in segment/block names |
305
329
|`\/`|`/`| Literal slash (not a pause) |
306
330
|`\*`|`*`| Literal asterisk (not emphasis) |
307
331
|`\\`|`\`| Literal backslash |
@@ -319,11 +343,13 @@ Properties flow downward through the hierarchy. Each level can override its pare
319
343
320
344
If a child omits a value, it inherits from its nearest ancestor.
321
345
346
+
**Best practice:** Only specify WPM or emotion when they **differ** from the inherited value. If `base_wpm` is 140 and a segment runs at 140 WPM, omit the WPM parameter — `## [Intro|Warm]` not `## [Intro|140WPM|Warm]`. Similarly, if a block's emotion matches its parent segment, omit it — `### [Details]` not `### [Details|140WPM|Warm]`. Redundant declarations add noise and make overrides harder to spot.
347
+
322
348
### WPM Resolution
323
349
324
350
For any word, the effective WPM is determined by (highest priority first):
325
351
326
-
1. Inline speed tag (`[180WPM]...[/180WPM]`, `[xslow]`, `[slow]`, `[fast]`, `[xfast]`)
352
+
1. Inline speed tag (`[150WPM]...[/150WPM]`, `[xslow]`, `[slow]`, `[normal]`, `[fast]`, `[xfast]`)
327
353
2. Block header WPM
328
354
3. Segment header WPM
329
355
4.`base_wpm` from front matter
@@ -341,19 +367,44 @@ For any word, the effective WPM is determined by (highest priority first):
341
367
342
368
When emotion changes between segments or blocks, renderers should apply a smooth visual transition (recommended: 3-second fade between color schemes).
343
369
370
+
### Color and Emotion Precedence
371
+
372
+
When inline color and emotion tags are nested, the **innermost tag wins** for the enclosed span. For example, `[warm][red]text[/red][/warm]` renders "text" in red, not the warm emotion color. Block-level emotion serves as the default styling; inline tags override it for their span only.
373
+
374
+
### Phrase Boundaries
375
+
376
+
A **phrase** is a unit of text delimited by:
377
+
- Sentence-ending punctuation: `.``?``!`
378
+
- Pause markers: `/`, `//`, `[pause:...]`
379
+
- Block or segment boundaries
380
+
381
+
Phrases are the smallest unit for timing calculation. Words within a phrase are counted for WPM computation using whitespace tokenization: each whitespace-separated token counts as one word. Hyphenated words (e.g., `state-of-the-art`) count as one word. Tags and tag syntax are not counted.
382
+
344
383
### Tag Nesting
345
384
346
385
- Tags must be properly closed: `[red]text[/red]`.
347
386
- Tags must not cross-nest: `[red][emphasis]text[/red][/emphasis]` is **invalid**.
If a TPS file has no `##` segment headers, the entire content (after front matter) is treated as a single implicit segment with `Neutral` emotion and default WPM.
353
404
354
-
### Simple Segment Headers
405
+
### Simple Headers
355
406
356
-
Plain markdown `## Title` headers (without `[...]` brackets) are also recognized as segments with default (neutral) emotion and inherited WPM.
407
+
Plain markdown `## Title`and `### Title`headers (without `[...]` brackets) are also recognized as segments and blocks respectively, with default (neutral) emotion and inherited WPM.
357
408
358
409
## Rendering Context
359
410
@@ -362,7 +413,7 @@ TPS is designed for **teleprompter use** — text is always rendered on a **dark
362
413
### Dark Background Rules
363
414
364
415
1.**Text base color** is white/light (`#F8F9FA` or similar). All inline colors must be **lighter variants** that contrast well against dark backgrounds.
365
-
2.**`black` is not a valid inline color** — it would be invisible. Renderers should map`[black]`to `gray` or ignore it.
416
+
2.**`black` is not a valid inline color** — it would be invisible. Renderers should strip`[black]`tags and render the enclosed content unstyled.
366
417
3.**Minimum contrast** — all color keywords must produce at least **WCAG AA 4.5:1** contrast ratio against the dark background.
367
418
4.**Emotion color schemes** (background, text, accent) are pre-defined per emotion. They are not raw hex values — they are tuned for the dark rendering context with appropriate alpha channels.
368
419
5.**`highlight`** uses a semi-transparent yellow background overlay, not a text color change.
@@ -382,6 +433,8 @@ The Actor profile targets natural spoken delivery — reading aloud from a telep
382
433
383
434
**Default `base_wpm`: 140** — sits in the middle of the standard range. Most people read comfortably at 130–150 WPM from a teleprompter.
384
435
436
+
**Duration formula:**`phrase_duration_ms = (word_count / effective_wpm) × 60000`. Total duration is the sum of all phrase durations plus all pause durations.
437
+
385
438
**Advice for script authors:**
386
439
- Start at 130 WPM for new speakers, increase gradually.
387
440
- Use `[xslow]...[/xslow]` for critical warnings or very important statements.
@@ -431,22 +484,24 @@ speed_offsets:
431
484
author: Jane Doe
432
485
---
433
486
434
-
## [Intro|140WPM|Warm]
487
+
# Product Launch
488
+
489
+
## [Intro|Warm]
435
490
436
-
### [Opening Block|140WPM]
491
+
### [Opening Block]
437
492
Good morning everyone, / and [emphasis]welcome[/emphasis] to what I believe /
438
493
will be a [green]transformative moment[/green] for our company. //
439
494
440
495
[pause:2s]
441
496
442
-
### [Purpose Block|150WPM]
497
+
### [Purpose Block|145WPM]
443
498
[emphasis]Today[/emphasis], / we're not just launching a product – /
444
499
we're introducing a [highlight]solution[/highlight] that will [emphasis]revolutionize[/emphasis] /
445
-
how our customers interact with technology. //
500
+
how our customers interact with [stress:tech-NO-lo-gy]technology[/stress]. //
446
501
447
-
## [Problem|150WPM|Concerned]
502
+
## [Problem|135WPM|Concerned]
448
503
449
-
### [Statistics Block|150WPM|Neutral]
504
+
### [Statistics Block|Neutral]
450
505
But first, / let's address the [xslow][red]elephant in the room[/red][/xslow]. /
451
506
Our industry has been [emphasis]struggling[/emphasis] with a fundamental problem. //
452
507
@@ -456,18 +511,18 @@ According to recent studies, /
456
511
[slow][emphasis]73% of users abandon[/emphasis] applications within the first three interactions[/slow] /
457
512
due to [highlight]complexity and poor user experience[/highlight]. //
458
513
459
-
### [Impact Block|140WPM]
514
+
### [Impact Block]
460
515
This affects [emphasis]millions[/emphasis] of people worldwide, /
461
516
costing businesses [red]billions in revenue[/red] annually. //
462
517
463
-
## [Solution|160WPM|Focused]
518
+
## [Solution|Focused]
464
519
465
-
### [Introduction Block|150WPM]
520
+
### [Introduction Block]
466
521
That's where our [blue][emphasis]new platform[/emphasis][/blue] comes in. /
467
522
We've developed a [green]local-first teleprompter workflow[/green] that /
468
523
[highlight]simplifies complex processes[/highlight] and [emphasis]enhances user experience[/emphasis]. //
469
524
470
-
### [Benefits Block|160WPM|Excited]
525
+
### [Benefits Block|150WPM|Excited]
471
526
With our solution, / you can expect a [green][emphasis]50% reduction[/emphasis][/green] in user abandonment /
472
527
and a [green][emphasis]30% increase[/emphasis][/green] in engagement. //
473
528
@@ -479,6 +534,16 @@ and a [green][emphasis]30% increase[/emphasis][/green] in engagement. //
479
534
[edit_point:medium]
480
535
```
481
536
537
+
## Examples
538
+
539
+
The [`examples/`](examples/) directory contains sample TPS files demonstrating the format:
|[`advanced.tps`](examples/advanced.tps)| All format features — speed controls, inline WPM, colors, emotions, pronunciation, edit points, tag nesting. |
545
+
|[`multi-segment.tps`](examples/multi-segment.tps)| Multi-segment script with varying speed and emotion across segments. |
0 commit comments