Skip to content

Maintain one-word-one-span while editing (merge spans on join) #394

Description

@maboa

Summary

Keep the transcript at one word per timed <span> as the user edits, so timings stay attached to the right words and manual fixes to stray fragments "just work". Three cases:

  1. Edit a letter inside a word → stays the same span (already holds via contenteditable).
  2. Split — type a space inside a word → split into one span per word. Already implemented: splitWordSpan (js/editor-core.js, on blur) divides the original [data-m, data-d] by syllable/vowel-group weight (deliberately not letter count).
  3. Join — delete the space between two words → merge the two spans into one. This is the gap: today the space is removed but the two <span>s remain, leaving two data-m windows behind one visual word.

Why it matters

This is the general, deterministic fix for split-word fragments (E+ditor, Hypera+udio) regardless of source — cloud engine, SRT/VTT import, or manual paste: the user just deletes the space and the editor merges the spans correctly. It removes the need for a fragile auto-detector.

Merge rule (inverse of the split)

Merging span A (m_a, d_a) with the following span B (m_b, d_b):

  • merged data-m = m_a
  • merged data-d = (m_b + d_b) − m_a
  • merged text = A + B with the internal space removed (keep the trailing space)
  • generalises to N joined spans: start of the first, end of the last.

Runs on blur, mirroring the existing split pass; touches only affected spans.

Notes

  • Case 1 already holds; add a guard/test so an edit can't silently orphan or duplicate a span.
  • Optional/secondary: a best-effort "tidy" that flags likely ASR fragments — but with join-merge in place that's convenience, not the mechanism, and must stay conservative (don't merge real short words: "I am", "a cat").
  • The local Parakeet worker's -based subword merge is unaffected (clean signal, keeps working).
  • Reference: the default demo transcript's fragments were fixed by hand twice using the merge rule above.
  • Related: Add Parakeet (HuggingFace) as a cloud STT option #307 (Parakeet HF), Add in-browser speaker diarization to the local Parakeet/Whisper tabs #329 (transcript quality).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions