Skip to content

fix(registry): caption keywords, emoji and aftershock work for words outside a-z - #7804

Merged
miguel-heygen merged 1 commit into
heygen-com:mainfrom
wonjangcloud9:fix/caption-non-latin-keywords
Nov 15, 2026
Merged

miguel-heygen merged 1 commit into
heygen-com:mainfrom
wonjangcloud9:fix/caption-non-latin-keywords

Conversation

@wonjangcloud9

Copy link
Copy Markdown
Contributor

What

caption-emoji-pop, caption-neon-accent and caption-glitch-rgb now treat a word in any script the way they treat an English one: a keyword in KEYWORDS gets its accent, a word in WORD_EMOJI gets its emoji, and a long word gets the glitch aftershock.

Why

I make Korean captions with these components. After replacing TRANSCRIPT and putting Korean words in KEYWORDS / WORD_EMOJI, nothing was accented and no emoji appeared, with no error.

The cause is how the word is normalised before the lookup:

  • caption-emoji-pop and caption-neon-accent: text.toLowerCase().replace(/[^a-z]/g, ""). "영상을" becomes "", "información" becomes "informacin", so KEYWORDS.has(...) and WORD_EMOJI[...] can never match a word written outside a-z.
  • caption-glitch-rgb: shouldAftershock counts word.text.replace(/[^\w]/g, "").length >= 7. "невероятно" counts as 0 letters, so it never pulses.

Related work

How

In each component and its demo.html, the strip pattern is now a Unicode property class with the u flag:

  • /[^a-z]/g → /[^\p{L}]/gu (and /[^a-z']/g → /[^\p{L}']/gu for the transition-word lookup)
  • /[^\w]/g → /[^\p{L}\p{N}_]/gu

The input is lowercased first, so for an English transcript the result is the same string as before. Keywords are still matched as whole words, so a Korean keyword has to be written in the form the transcript uses (영상을, not 영상).

Test plan

Unit: new packages/cli/src/registry/captionNonLatinKeywords.test.ts runs each component's inline script in happy-dom (the approach of #7690's test).

  • emoji-pop shows the emoji mapped to a Korean word.
  • emoji-pop and neon-accent give six Korean keywords the same colours as six Latin keywords with the same timing.
  • glitch-rgb schedules the same number of tweens for long Cyrillic words as for Latin words of the same lengths (and more than for short words).

On main (04ee926d) with the component changes stashed, all 4 fail (expected [] to deeply equal [ '📹' ], expected 16 to be 24, …). With the fix, vitest run src/registry/ passes 327 tests. tsc --noEmit, oxlint, oxfmt and fallow audit are clean.

Real CLI: each demo.html with a 10-word Korean transcript, KEYWORDS = ["영상을", "공개합니다", "감사합니다"] and WORD_EMOJI = { 영상을: "📹", 감사합니다: "🙏" }, then hyperframes snapshot --at 1.5,2.7,5.7.

Before

No emoji; the keywords "공개합니다." and "감사합니다." stay plain white in neon-accent.

emoji-pop before
neon-accent before

After

The emoji sit above their words; the keywords take the accent colour and size.

emoji-pop after
neon-accent after

🤖 Generated with Claude Code

…outside a-z

caption-emoji-pop and caption-neon-accent look a word up in KEYWORDS and
WORD_EMOJI after stripping everything outside a-z, and caption-glitch-rgb
counts a word's \w characters to decide on the aftershock. A Korean, Cyrillic
or accented word comes out empty or cut, so a keyword written in that script
never matches and a long word never pulses.

The three components now strip by Unicode letter (\p{L}) instead, which is
the same set for a lowercased English transcript.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>

@miguel-heygen miguel-heygen left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified at 6a1f29c: all six strip sites (3 components + their demo.html) move from a-z / \w to Unicode classes with the u flag; input is lowercased first, so an a-z transcript normalises to the same string as before and the shipped English KEYWORDS/WORD_EMOJI still match. Test runs each inline script in happy-dom and pins Korean emoji/accents and Cyrillic aftershock counts. Required checks green. The one red job, Catalog payloads (not required), fails on caption-emoji-pop/caption-neon-accent with a 404 for caption-overrides.json: the caption runtime probes that optional file, hyperframes validate ignores that 404 by design (validate.ts shouldIgnoreHttpError), and the payload verifier does not. It runs only on changed components, so it surfaces here; the regex change cannot add or remove that request.

Nit, non-blocking: \p{L} also strips combining marks (\p{M}), so in scripts that use them (Devanagari, Thai, Arabic with harakat) a transcript word like नमस्ते loses its vowel signs and no longer equals the same keyword in KEYWORDS/WORD_EMOJI. [^\p{L}\p{M}] (and \p{M} in the glitch count) would cover those scripts. Fine as a follow-up.

@miguel-heygen
miguel-heygen added this pull request to the merge queue Nov 15, 2026
Merged via the queue into heygen-com:main with commit 8dbbc1d Nov 15, 2026
71 of 72 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants