1.1bowl, in script.md, cues.json, and deck/index.html.
- You write the cue phrase in
cues.json, and the cue id in the page. - The
beatsstage resolves each cue phrase to a cue time, in seconds after the section start. The cue time of1.1bowlis the start of the word “bowl”. - The
beatsstage writes the cue times tobuild/audio/beats.json. - The recorder passes the cue times to the page as
?beats=, and the page fires each cue at its time. decktalk verifychecks that each reveal starts on its word.
decktalk beats prints the cue times of every section. These lines come from a silent build, so
the times are estimates.
Matching rules
Thebeats stage matches a cue phrase against the section’s spoken words with these rules:
- It splits the phrase and the spoken words on whitespace only.
- Each token keeps only A to Z, a to z, 0 to 9, and the straight apostrophe. Accented letters, Greek letters, and curly apostrophes are removed.
- Matching ignores case, unless
case_sensitiveis true. - A phrase token with no characters left is ignored. For example, the phrase
learning rate ηmatches aslearning rate. - A hyphenated word is one token. “zig-zag” becomes
zigzag, so the phrase “zig zag” does not match it. - The stage looks through the spoken words, in order, for a run that matches the phrase token for token.
occurrencepicks the run, and the default is the first. When the phrase matches more than once and the cue does not setoccurrence, the stage warns and names each match with its time. - The cue time is the start of the run’s first word, plus the offset key, rounded to hundredths of a second.
$startis 0.0 s plus the offset key. A negative result stays negative, and the page fires it at t=0.$endis the end of the section’s last spoken word, plus the offset key.
data-sync text with a different rule. It ignores apostrophes, but the beats
stage keeps them. data-sync has the page’s rules.
Write a cue phrase the way the voice says it, because the spoken words come from the voice. The
scaffold’s script says “decktalk dot app”, and its slide shows decktalk.app. So the cue 5.1url
uses the phrase “decktalk dot app”. A number written in digits comes back in the form the voice
chose, so avoid digits in a cue phrase.
Stage directions are not spoken words. A [beat] becomes a dash, and a [pause N] becomes a break
tag. Neither is a word, so a phrase that spans a direction still matches.
script.md has the rules for directions.
Which sections have cues
Every section key incues.json must name a [[section]] in decktalk.toml. A section can have no
cues. A page section with no cues plays its autoplay timing in the recording. A clip section has no
narration, so the beats stage skips its cues.
Cue mismatches
A cue can disagree with its page in six ways. Thebeats stage catches the first one before the
recording. The page catches the others during the recording.
In each message,
<id> and <step> stand for real ids. The page lists its warnings in
window.__decktalk.warnings. The recorder logs each one and writes it to the sidecar. A handler that
DeckTalk.on registers for an id stops the second and third warnings for that id.
Cue ownership has the ownership rules.
The beats stage looks for each cue id in the page as a quoted literal, in single quotes, double
quotes, or backticks. So data-cue="1.1bowl", a key of a step’s cues object, and a key of an on
object all count. The stage skips clip sections, and it skips a page file that does not exist,
because the recorder reports that. The cue still resolves, and beats still writes beats.json.
These lines come from a copy of the scaffold with data-cue="5.1cap" and the "5.1cap" key
removed from deck/index.html. beats exits 1.
cues.json. If a page builds its ids at
run time, pass --allow-unknown. The page warnings are then the only check.
Unresolved cues
If thebeats stage cannot match a phrase, it notes phrase not found and exits 1. These lines come
from a copy of the scaffold whose cue 3.4name has the typo “gradient decent”.
decktalk build stops after the beats stage, because a step whose only cues are unresolved never
mounts. Fix the phrase, or pass --allow-unresolved to build without the cue. The page then warns
that the cue is not in ?beats=, and its element appears at its data-at time.
A cue that resolves past the end of the section’s audio stays, with a note. A silent build estimates
word times, so its cue times are estimates too. The table then ends with
(estimated words: times are placeholders).
Phrase choice
These guidelines help a reveal start on the right word. Writing for the ear explains each one.- Start the phrase with the word that names the thing that appears, because the cue time is the start of the first word. A noun such as
box of knobsworks, and so does a verb with its object, such assteps downhill. A connective such as “and then” does not. - If a word repeats in the section, use two or three words, or set
occurrence. Setoccurrenceto 1 to keep the first match and silence the warning. - Set a small positive offset key, 0.1 to 0.2 s, so the viewer hears the word start before the element moves.
- Use a negative offset key only when the audience must read along.
- Put a
[beat]or a[pause N]before a reveal that should feel like an event. - Cue a summary on
$endto show it as the voice stops. - Write numbers as words in the script, and show digits on the slide.
Sound on cues
A sound effect in[[mix.sfx]] names a section and a cue. The assemble stage places the sound
effect at that cue’s time. An underscore marker uses the same on, occurrence, case_sensitive,
and offset keys to raise or mute the underscore at a phrase. Sound explains both.
Terms
Next
- Write phrases that time well: Writing for the ear
- Look up every key: cues.json
- Learn which step owns a cue: The page contract