Skip to content

Commit a14900a

Browse files
committed
more control
1 parent 1ab2ec3 commit a14900a

File tree

3 files changed

+135
-43
lines changed

3 files changed

+135
-43
lines changed

README.md

Lines changed: 117 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ TPS bridges this gap: it is human-readable markdown that any text editor can ope
3535
| **Word** | An individual token with optional per-word properties (emphasis, volume, pause). |
3636
| **WPM** | Words Per Minute — the reading speed. |
3737
| **Edit Point** | A marker indicating a natural place to stop or start an editing session. |
38-
| **Emotion** | A predefined mood preset that controls visual styling (colors) and presentation hints. |
38+
| **Emotion** | A predefined delivery style that controls tone, energy, and visual presentation. |
3939

4040
## File Structure
4141

@@ -241,36 +241,43 @@ A breath mark indicates where the speaker should take a breath. Unlike pauses, b
241241
[pronunciation:KAM-uhl]camel[/pronunciation] # Simple guide
242242
```
243243

244-
#### Stress Marks
244+
#### Syllable Stress
245245

246-
Three ways to mark word stress, from simplest to most detailed:
247-
248-
**Inline tag** — wrap the stressed part of a word with `[stress]`:
246+
**Inline wrap** — wrap the stressed part of a word:
249247

250248
```markdown
251249
develop[stress]me[/stress]nt # Stress on "me"
252250
[stress]in[/stress]frastructure # Stress on "in"
253251
```
254252

255-
The simplest approach. The tag can wrap a single letter or a syllable — whatever part needs emphasis. Renderers should visually distinguish the stressed portion (e.g., underline, bold, or color).
253+
The tag can wrap a single letter or a syllable. Renderers should visually distinguish the stressed portion (e.g., larger font size, underline, or bold).
256254

257-
**Inline accent**place an acute accent (`´`) on the stressed vowel directly in the word:
255+
**Stress guide**full syllable breakdown with a parameter:
258256

259257
```markdown
260-
developmént # Stress on the "e" in "-ment"
261-
ínfrastructure # Stress on the first "i"
258+
[stress:de-VE-lop-ment]development[/stress]
259+
[stress:IN-fra-struc-ture]infrastructure[/stress]
262260
```
263261

264-
No tags needed — the accent is visible in the text itself. Parsers should recognize acute-accented vowels (`á`, `é`, `í`, `ó`, `ú`) as stress markers. The renderer may display the accent or strip it after applying visual stress.
262+
Hyphens separate syllables. The stressed syllable is **UPPERCASE**, unstressed are lowercase. Renderers should display the guide as a tooltip or overlay — not replace the word. Use this for complex or unfamiliar words where the reader needs the full pronunciation map.
265263

266-
**Stress guide tag** — for full syllable breakdown when the reader needs more guidance:
264+
#### Delivery Mode Tags
267265

268266
```markdown
269-
[stress:de-VE-lop-ment]development[/stress]
270-
[stress:IN-fra-struc-ture]infrastructure[/stress]
267+
[sarcasm]Oh, that went really well[/sarcasm] # Say the opposite of what you mean
268+
[aside]By the way, we also support webhooks[/aside] # Parenthetical, "to the audience"
269+
[rhetorical]Isn't that exactly what we need?[/rhetorical] # Question delivered as statement
270+
[building]Each phrase gets bigger. And bigger. And BIGGER.[/building] # Gradually rising energy
271271
```
272272

273-
The guide string uses hyphens to separate syllables. The stressed syllable is written in **UPPERCASE**; unstressed syllables are lowercase. Renderers should display the stress guide as a tooltip, subtitle, or overlay — not replace the word itself.
273+
Delivery mode tags describe **how** to deliver a passage, beyond emotion and volume:
274+
275+
| Tag | Delivery | Use when |
276+
|-----|----------|----------|
277+
| `[sarcasm]` | Say it straight, but mean the opposite. Deadpan or exaggerated. | Comedy, skepticism, irony. |
278+
| `[aside]` | Step out of the main narrative. Lower energy, more intimate. | Parenthetical comments, tangents, notes to audience. |
279+
| `[rhetorical]` | Deliver as a statement with question syntax. No rising intonation. | Rhetorical questions that don't expect answers. |
280+
| `[building]` | Start at lower energy, gradually increase through the passage. | Reveals, motivational build-ups, crescendo moments. |
274281

275282
## Keyword Reference
276283

@@ -303,6 +310,15 @@ Renderers map each emotion to a visual style (colors, background, text treatment
303310
| `soft` | Quieter, gentler delivery |
304311
| `whisper` | Whispered, intimate delivery |
305312

313+
### Delivery Modes
314+
315+
| Keyword | Delivery | Use when |
316+
|---------|----------|----------|
317+
| `sarcasm` | Say it straight, but mean the opposite. Deadpan or exaggerated. | Comedy, skepticism, irony. |
318+
| `aside` | Step out of the main narrative. Lower energy, more intimate. | Parenthetical comments, tangents, notes to audience. |
319+
| `rhetorical` | Deliver as a statement with question syntax. No rising intonation. | Rhetorical questions that don't expect answers. |
320+
| `building` | Start at lower energy, gradually increase through the passage. | Reveals, motivational build-ups, crescendo moments. |
321+
306322
### Inline Tags
307323

308324
| Tag | Syntax | Description |
@@ -326,11 +342,14 @@ Renderers map each emotion to a visual style (colors, background, text treatment
326342
| **Whisper** | `[whisper]text[/whisper]` | Whispered delivery |
327343
| **Phonetic** | `[phonetic:IPA]text[/phonetic]` | IPA pronunciation guide |
328344
| **Pronunciation** | `[pronunciation:guide]text[/pronunciation]` | Simple pronunciation guide |
329-
| **Stress (wrap)** | `develop[stress]me[/stress]nt` | Wrap stressed part of a word |
330-
| **Stress (accent)** | `developmént` | Acute accent on stressed vowel |
331-
| **Stress (guide)** | `[stress:de-VE-lop-ment]text[/stress]` | Full syllable breakdown (UPPERCASE = stressed) |
345+
| **Stress (wrap)** | `develop[stress]me[/stress]nt` | Stressed part of a word |
346+
| **Stress (guide)** | `[stress:de-VE-lop-ment]word[/stress]` | Full syllable breakdown |
332347
| **Breath** | `[breath]` | Natural breath point (no added time) |
333-
| **Emotion** | `[warm]text[/warm]`, `[urgent]...[/urgent]`, etc. | Inline emotion/delivery override (see Emotions table) |
348+
| **Sarcasm** | `[sarcasm]text[/sarcasm]` | Deadpan/ironic delivery |
349+
| **Aside** | `[aside]text[/aside]` | Parenthetical, "to the audience" |
350+
| **Rhetorical** | `[rhetorical]text[/rhetorical]` | Question delivered as statement |
351+
| **Building** | `[building]text[/building]` | Gradually rising energy/crescendo |
352+
| **Emotion** | `[warm]text[/warm]`, `[urgent]...[/urgent]`, etc. | Inline emotion override (see Emotions table) |
334353

335354
### Speed Presets
336355

@@ -400,9 +419,13 @@ For any word, the effective WPM is determined by (highest priority first):
400419

401420
When emotion changes between segments or blocks, renderers should apply a smooth visual transition (recommended: 3-second fade between color schemes).
402421

403-
### Inline Emotion Precedence
422+
### Tag Precedence
423+
424+
**Emotion:** When inline emotion tags are nested, the **innermost tag wins** for the enclosed span. Block-level emotion serves as the default styling; inline emotion tags override it for their span only.
425+
426+
**Volume vs. emotion:** Volume and emotion are **independent dimensions**. `[soft]` inside an `Urgent` block means: deliver with urgent tone but at lower volume. They do not conflict — volume controls loudness, emotion controls tone.
404427

405-
When inline emotion tags are nested, the **innermost tag wins** for the enclosed span. Block-level emotion serves as the default styling; inline emotion tags override it for their span only.
428+
**Delivery modes** (`[sarcasm]`, `[aside]`, `[rhetorical]`, `[building]`) override the current emotion for their span. They are specialized delivery instructions that take priority over the block emotion.
406429

407430
### Phrase Boundaries
408431

@@ -411,7 +434,9 @@ A **phrase** is a unit of text delimited by:
411434
- Pause markers: `/`, `//`, `[pause:...]`
412435
- Block or segment boundaries
413436

414-
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.
437+
Phrases are the smallest unit for timing calculation.
438+
439+
**WPM word counting** is performed on **clean text** — after all tags and markup are stripped. The parser first removes all tag syntax (`[tag]`, `[/tag]`, `[tag:param]`), then joins any text fragments split by mid-word tags (e.g., `develop[stress]me[/stress]nt``development`), then counts words using whitespace tokenization. Each whitespace-separated token in the clean text counts as one word. Hyphenated words (e.g., `state-of-the-art`) count as one word.
415440

416441
### Tag Nesting
417442

@@ -439,17 +464,64 @@ If a TPS file has no `##` segment headers, the entire content (after front matte
439464

440465
Plain markdown `## Title` and `### Title` headers (without `[...]` brackets) are also recognized as segments and blocks respectively, with default (neutral) emotion and inherited WPM.
441466

442-
## Rendering Context
467+
## Rendering Principles
468+
469+
A TPS file is **source markup**, not display output. The teleprompter application **must** process the markup and present clean, styled text to the reader. The reader should never see raw tags like `[emphasis]` or `[slow]` on screen.
470+
471+
### Tag Visibility
443472

444-
TPS is designed for **teleprompter use** — text is always rendered on a **dark background** (typically near-black: `#1A1B2E` or similar). All color choices, contrast ratios, and visibility rules assume this context.
473+
All tags (`[emphasis]`, `[slow]`, `[loud]`, `[sarcasm]`, etc.) are **invisible in the rendered output**. The renderer applies their effects visually:
474+
475+
- `[emphasis]word[/emphasis]` → the word appears **bold** or in a distinct color
476+
- `[slow]text[/slow]` → text may appear with a pacing indicator or wider spacing
477+
- `[loud]text[/loud]` → text appears larger or bolder
478+
- `[whisper]text[/whisper]` → text appears smaller or lighter
479+
- `[sarcasm]text[/sarcasm]` → text styled with a distinct visual cue (e.g., italic + indicator)
480+
- `[building]text[/building]` → text may gradually increase in size or intensity
481+
- `[breath]` → a small visual indicator (e.g., a subtle mark or gap)
482+
- Segment/block headers → rendered as section dividers, not raw markdown
483+
484+
The reader sees only the spoken text with visual styling applied. Tags are commands for the renderer, not content for the speaker.
485+
486+
### Content Restrictions
487+
488+
TPS scripts contain **spoken text only**. Do not include:
489+
- URLs or hyperlinks — these are not spoken content
490+
- Code blocks or technical syntax — rewrite as spoken language
491+
- Images or embedded media references
492+
- Raw data tables — narrate the data instead
493+
494+
### Rendering Context
495+
496+
TPS is designed for **teleprompter use** — text is always rendered on a **dark background** (typically near-black: `#1A1B2E` or similar). All visual choices assume this context.
497+
498+
### Visual Rendering Hints
499+
500+
Renderers should use **text size, letter spacing, weight, and animation** to communicate delivery cues without the reader needing to see tags. Recommended visual mappings:
501+
502+
| Tag | Font size | Letter spacing | Weight | Other |
503+
|-----|-----------|---------------|--------|-------|
504+
| `[loud]` | Larger (120–140%) | Normal | Bold ||
505+
| `[soft]` | Smaller (80–90%) | Normal | Light | Lower opacity |
506+
| `[whisper]` | Smaller (70–80%) | Wider (+1–2px) | Light | Italic or distinct style |
507+
| `[emphasis]` | Normal | Normal | Bold ||
508+
| `[stress]` (wrap) | Larger on stressed part | Normal | Bold | Underline or distinct color |
509+
| `[stress:...]` (guide) | Normal | Normal | Normal | Tooltip/overlay with syllable guide |
510+
| `[slow]` | Normal | Wider (+1–2px) | Normal | Stretches word visually |
511+
| `[fast]` | Normal | Tighter (-0.5–1px) | Normal | Compresses word visually |
512+
| `[building]` | Gradually increasing | Normal | Gradually bolder | Animated size ramp |
513+
| `[sarcasm]` | Normal | Normal | Normal | Italic + visual indicator |
514+
| `[aside]` | Smaller (85–90%) | Normal | Light | Dimmed or offset |
515+
| `[highlight]` | Normal | Normal | Normal | Background overlay |
516+
517+
These are **recommendations**, not requirements. Renderers may adapt the visual treatment to their platform. The key principle: the reader should **feel** the delivery instruction from the visual presentation alone.
445518

446519
### Dark Background Rules
447520

448521
1. **Text base color** is white/light (`#F8F9FA` or similar).
449522
2. **Minimum contrast** — all styled text must produce at least **WCAG AA 4.5:1** contrast ratio against the dark background.
450523
3. **Emotion color schemes** (background, text, accent) are pre-defined per emotion and tuned for the dark rendering context.
451524
4. **`highlight`** uses a semi-transparent yellow background overlay, not a text color change.
452-
5. **Volume indicators**`[loud]` text should be visually larger or bolder; `[soft]` and `[whisper]` should be visually smaller or lighter.
453525

454526
## WPM Guidelines
455527

@@ -498,9 +570,23 @@ Additional validation:
498570
### Casing, Whitespace, Escaping
499571

500572
- Tags are case-insensitive; canonical form is lower-case (e.g., `[emphasis]`).
501-
- `WPM` suffix is uppercase by convention (e.g., `140WPM`).
573+
- `WPM` suffix is uppercase by convention (e.g., `140WPM`). `140wpm` is also valid — parsers should normalize.
502574
- Parameters inside headers are trimmed; `140 WPM` normalizes to `140WPM`.
503575
- Escape reserved characters in plain text with backslash: `\[`, `\]`, `\|`, `\/`, `\*`, `\\`.
576+
- Escape sequences apply **only in plain text**, not inside tag parameters or header parameters.
577+
578+
### Error Handling
579+
580+
Parsers should handle invalid input gracefully:
581+
582+
- **Unknown tag:** Treat as plain text (display the brackets and content literally).
583+
- **Unknown emotion keyword:** Parse error. Reject the keyword and use the inherited emotion.
584+
- **Unclosed tag:** Implicitly close at the end of the current block (see Tag Nesting).
585+
- **Closing tag without opening:** Ignore the closing tag.
586+
- **Invalid WPM** (< 80 or > 220): Parse error. Use the inherited WPM value.
587+
- **Malformed pause** (e.g., `[pause:abc]`): Treat as plain text.
588+
- **Cross-nested tags:** Parse error. The parser should close tags in order and report a warning.
589+
- **Duplicate parameters in headers** (e.g., two WPM values): Use the last one.
504590

505591
## Complete Example
506592

@@ -530,7 +616,7 @@ will be a [emphasis]transformative moment[/emphasis] for our company. //
530616
### [Purpose Block|145WPM]
531617
[emphasis]Today[/emphasis], / we're not just launching a product – / [breath]
532618
we're introducing a [highlight]solution[/highlight] that will [emphasis]revolutionize[/emphasis] /
533-
how our customers interact with [stress:tech-NO-lo-gy]technology[/stress]. //
619+
how our customers interact with tech[stress]no[/stress]logy. //
534620

535621
## [Problem|135WPM|Concerned]
536622

@@ -541,7 +627,7 @@ Our industry has been [emphasis]struggling[/emphasis] with a fundamental problem
541627
[edit_point:high]
542628

543629
According to recent studies, /
544-
[slow][emphasis]73% of users abandon[/emphasis] applications within the first three interactions[/slow] /
630+
[slow][emphasis]73% of users a[stress]ban[/stress]don[/emphasis] applications within the first three interactions[/slow] /
545631
due to [highlight]complexity and poor user experience[/highlight]. //
546632

547633
### [Impact Block]
@@ -552,16 +638,16 @@ costing businesses [loud][emphasis]billions[/emphasis] in revenue[/loud] annuall
552638

553639
### [Introduction Block]
554640
That's where our [emphasis]new platform[/emphasis] comes in. /
555-
We've developed a local-first téleprompter workflow that /
556-
[highlight]simplifies complex processes[/highlight] and [emphasis]enhances user experiénce[/emphasis]. //
641+
[building]We've developed a local-first teleprompter workflow that /
642+
[highlight]simplifies complex processes[/highlight] and [emphasis]enhances user experience[/emphasis].[/building] //
557643

558644
### [Benefits Block|150WPM|Excited]
559645
With our solution, / you can expect a [emphasis]50% reduction[/emphasis] in user abandonment /
560646
and a [emphasis]30% increase[/emphasis] in engagement. //
561647

562648
[pause:1s]
563649

564-
[soft]Full details are available in the handout.[/soft] /
650+
[aside]Full details are available in the handout.[/aside] /
565651
[highlight]Thank you[/highlight] for your time. //
566652

567653
[edit_point:medium]
@@ -574,7 +660,7 @@ The [`examples/`](examples/) directory contains sample TPS files demonstrating t
574660
| File | Description |
575661
|------|-------------|
576662
| [`basic.tps`](examples/basic.tps) | Minimal valid TPS file — front matter, title, segments, blocks, pauses, emphasis, simple headers, escape sequences. |
577-
| [`advanced.tps`](examples/advanced.tps) | All format features — speed controls, volume, stress marks, breath marks, emotions, pronunciation, edit points, tag nesting. |
663+
| [`advanced.tps`](examples/advanced.tps) | All format features — speed, volume, delivery modes, syllable stress, breath marks, emotions, pronunciation, edit points, tag nesting. |
578664
| [`multi-segment.tps`](examples/multi-segment.tps) | Multi-segment script with varying speed, emotion, and delivery cues across segments. |
579665

580666
## File Extension

examples/advanced.tps

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,17 +53,13 @@ And a five-second pause for dramatic effect. //
5353
[soft]And this part should be quieter, / more intimate.[/soft] /
5454
[whisper]This is a secret.[/whisper] //
5555

56-
### [Stress and Accent]
56+
### [Syllable Stress]
5757

58-
Wrap the stressed part of a word: /
59-
This is a cri[stress]ti[/stress]cal point. /
58+
Mark stress by wrapping the stressed part: /
59+
This is a [stress]cri[/stress]tical point. /
6060
The [stress]em[/stress]phasis changes [stress]mea[/stress]ning. //
6161

62-
Or use an inline accent on the vowel: /
63-
This is a critícal point. /
64-
The émphasis changes méaning. //
65-
66-
Or use the stress tag for full syllable guidance: /
62+
For complex words, / use the full syllable guide: /
6763
[stress:de-VE-lop-ment]development[/stress] /
6864
[stress:IN-fra-struc-ture]infrastructure[/stress]. //
6965

@@ -72,6 +68,16 @@ Or use the stress tag for full syllable guidance: /
7268
Long passages need breath marks / [breath] so the reader knows where to breathe /
7369
without running out of air. //
7470

71+
### [Delivery Modes]
72+
73+
[sarcasm]Oh, that went really well.[/sarcasm] //
74+
75+
[aside]By the way, we also support webhooks.[/aside] //
76+
77+
[rhetorical]Isn't that exactly what we needed?[/rhetorical] //
78+
79+
[building]We started small. / Then we grew. / Then we exploded.[/building] //
80+
7581
## [Emotion and Emphasis|Warm]
7682

7783
### [Inline Emotions]

examples/multi-segment.tps

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,13 @@ The teleprompter can adjust styling and pacing / based on these cues. //
6060

6161
### [Rising Tension|150WPM|Urgent]
6262

63-
[fast]Now the pace picks up. /
63+
[building]Now the pace picks up. /
6464
Things are getting intense. /
65-
The reader needs to feel the urgency.[/fast] //
65+
The reader needs to feel the urgency.[/building] //
6666

6767
[slow]And then we slow down / for the emotional beat.[/slow] //
6868

69-
[highlight]Contrast in pacing / is what makes a script engáging.[/highlight] //
69+
[highlight]Contrast in pacing / is what makes a script en[stress]ga[/stress]ging.[/highlight] //
7070

7171
[edit_point:high]
7272

@@ -91,6 +91,6 @@ And we end on a [emphasis]motivational[/emphasis] note. //
9191
Three moods. /
9292
One script.[/slow] //
9393

94-
[soft][highlight]That is how you structure a long TPS document.[/highlight][/soft] //
94+
[aside]That is how you structure a long TPS document.[/aside] //
9595

9696
[edit_point]

0 commit comments

Comments
 (0)