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, orNoise.HeadingKind—Act,Scene, orDivision, 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
- Noise — empty lines, or lines made only of digits, whitespace, ASCII
punctuation, or the separator characters
—/–. This covers page numbers and running headers. - Heading — matches an act, scene, or division header (checked before the
character-name rule so
ACT Iis not mistaken for a name). - Stage direction — fully parenthesized
(...), bracketed[...], or asterisk-delimited*...*lines. - Standalone character name — all-caps names such as
HAMLET,LORD POLONIUS,O'BRIEN,THE GHOST, or a lone label likeHAMLET:. These are classified as noise: they are speaker labels, not content. - 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. - Fallback — anything else is nominal
Dialog.
Header patterns
| Kind | Matches (case-insensitive) |
|---|---|
Act | ACT + a token, e.g. ACT I, ACT 1., Act III. |
Scene | SCENE + a token, e.g. SCENE 1, SCENE i.. |
Division | PROLOGUE, 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.