Skip to main content

Classify

The classify stage (crates/classify) turns each trimmed line of extracted text into a labeled ClassifiedLine.

pub fn classify_line(line: &str) -> ClassifiedLine

Labels​

  • LineKind — Heading, StageDirection, Dialog, or Noise.
  • HeadingKind — Act, Scene, or Division, for heading lines.

Every rule-matched line gets confidence: 1.0; a non-empty line matching no rule is Dialog with a nominal confidence: 0.5, leaving room for a future machine-learning fallback.

Rules, in order​

  1. Noise — empty lines, or lines made only of digits, whitespace, ASCII punctuation, or the separator characters —/–. This covers page numbers and running headers.
  2. Heading — matches an act, scene, or division header (checked before the character-name rule so ACT I is not mistaken for a name).
  3. Stage direction — fully parenthesized (...), bracketed [...], or asterisk-delimited *...* lines.
  4. Standalone character name — all-caps names such as HAMLET, LORD POLONIUS, O'BRIEN, THE GHOST, or a lone label like HAMLET:. These are classified as noise: they are speaker labels, not content.
  5. Speaker-prefixed dialog — a line beginning with an all-caps name (optionally with a parenthetical note) and a delimiter is stripped to its spoken body and classified as confident Dialog.
  6. Fallback — anything else is nominal Dialog.

Header patterns​

KindMatches (case-insensitive)
ActACT + a token, e.g. ACT I, ACT 1., Act III.
SceneSCENE + a token, e.g. SCENE 1, SCENE i..
DivisionPROLOGUE, EPILOGUE, INTERMISSION, INTERLUDE, CURTAIN CALL.

Speaker-label stripping​

strip_speaker_prefix recognizes the script convention of an all-caps name (optionally joined by spaces, apostrophes, hyphens, or periods) followed by a parenthetical note and a delimiter (:, full-width :, or an em-dash —):

PENNY: I'm Penny. → I'm Penny.
HAMLET: To be, or not to be? → To be, or not to be?
GRU (to himself): Wrong window.→ Wrong window.
LORD POLONIUS: (waving) Go. → (waving) Go.
PENNY — I'm back. → I'm back.

Natural speech starting with a capitalized word (Note: this is important.) is not stripped; only all-caps names are.

Regexes​

The patterns are compiled once with OnceLock:

  • SPEAKER_NAME — [A-Z]+(?:[\s'.-]+[A-Z]+)*.
  • Act / scene / division headers, stage directions, and character names as described above.

rules.rs contains an extensive test suite documenting each rule and edge case.