Skip to main content
A cue connects a spoken phrase to something that happens on a page, such as an element that appears. Read this page when you choose a phrase, or when a cue does not resolve or starts on the wrong word. Writing for the ear is the guide for writing phrases. The scaffold’s section 1 shows one cue, 1.1bowl, in script.md, cues.json, and deck/index.html.
  1. You write the cue phrase in cues.json, and the cue id in the page.
  2. The beats stage resolves each cue phrase to a cue time, in seconds after the section start. The cue time of 1.1bowl is the start of the word “bowl”.
  3. The beats stage writes the cue times to build/audio/beats.json.
  4. The recorder passes the cue times to the page as ?beats=, and the page fires each cue at its time.
  5. decktalk verify checks 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

The beats stage matches a cue phrase against the section’s spoken words with these rules:
  1. It splits the phrase and the spoken words on whitespace only.
  2. 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.
  3. Matching ignores case, unless case_sensitive is true.
  4. A phrase token with no characters left is ignored. For example, the phrase learning rate η matches as learning rate.
  5. A hyphenated word is one token. “zig-zag” becomes zigzag, so the phrase “zig zag” does not match it.
  6. The stage looks through the spoken words, in order, for a run that matches the phrase token for token. occurrence picks the run, and the default is the first. When the phrase matches more than once and the cue does not set occurrence, the stage warns and names each match with its time.
  7. The cue time is the start of the run’s first word, plus the offset key, rounded to hundredths of a second.
  8. $start is 0.0 s plus the offset key. A negative result stays negative, and the page fires it at t=0.
  9. $end is the end of the section’s last spoken word, plus the offset key.
The page matches 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 in cues.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. The beats 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.
To fix an unknown id, add it to the page, or fix the id in 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 the beats 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 knobs works, and so does a verb with its object, such as steps downhill. A connective such as “and then” does not.
  • If a word repeats in the section, use two or three words, or set occurrence. Set occurrence to 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 $end to 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