/** * ReadAloudPreparer — CRAFT-05 Text-to-Speech / Read-Aloud Support * * Strips manuscript markup, measures rhythm, and detects unintentional rhymes. * * Philosophy: "Reading aloud reveals weak parts." — Hemingway / Harrison */ export interface RhythmFlag { /** 1-based line number of the first line in the paragraph */ paragraphStart: number; /** Human-readable note, e.g. "All 5 sentences within 2 words of same length" */ note: string; } export interface RhymeFlag { /** 1-based line number of the earlier sentence */ lineA: number; /** 1-based line number of the later sentence */ lineB: number; /** The two rhyming words */ words: [string, string]; } export interface ReadAloudResult { /** Prose text with all markup stripped, ready for TTS or display */ cleanText: string; /** Total word count of the clean text */ wordCount: number; /** Estimated reading time in minutes (wordCount / 150, 1 decimal place) */ estimatedMinutes: number; /** Paragraphs whose sentence lengths are suspiciously uniform */ rhythmFlags: RhythmFlag[]; /** Sentence-end word pairs that unintentionally rhyme within 3 lines */ rhymeFlags: RhymeFlag[]; } /** * Prepares a chapter file for reading aloud. * * Usage: * ```ts * const preparer = new ReadAloudPreparer('/path/to/novel'); * const result = await preparer.prepareChapter('chapters/chapter-01.md'); * ``` */ export declare class ReadAloudPreparer { private readonly projectPath; constructor(projectPath: string); /** * Read and prepare a chapter file for read-aloud / TTS. * * Steps: * 1. Read the file from `/` * 2. Strip markup via `ReadAloudPreparer.stripMarkup()` * 3. Run rhythm analysis on each paragraph * 4. Detect unintentional rhymes across sentence endings * 5. Compute word count and estimated reading time * * @param chapterFile - Relative path from projectPath, e.g. `chapters/chapter-01.md` */ prepareChapter(chapterFile: string): Promise; /** * Analyse already-loaded text (useful for testing without a real file). * Exposed as a static so tests and handlers can call it directly. * * @param raw - Raw file content (may include frontmatter, comments, etc.) */ static analyzeText(raw: string): ReadAloudResult; /** * Remove all non-prose markup from a Markdown chapter file: * - YAML frontmatter (lines between opening `---` and closing `---`) * - HTML comments (``, potentially multi-line) * - `[MARKER: ...]` patterns such as `[TK: note]`, `[TODO: note]` * - Scene delimiter lines (`--- Scene N ---`) * - Trailing whitespace and blank lines are normalised * * Plain prose text is preserved exactly. * * @param raw - Raw chapter file content * @returns Clean prose-only text */ static stripMarkup(raw: string): string; /** Count words in a clean-text string */ static _countWords(text: string): number; /** * Run rhythm and rhyme analysis on clean prose text. * Returns arrays of flags. */ static _analyze(cleanText: string): { rhythmFlags: RhythmFlag[]; rhymeFlags: RhymeFlag[]; }; /** * Extract paragraphs (groups of non-blank lines) with their 1-based * start-line numbers. */ private static _extractParagraphs; /** * Split a block of text into sentences using sentence-ending punctuation. * Sentence boundary: one or more `.!?` followed by whitespace. */ static _splitSentences(text: string): string[]; /** Count words in a single sentence */ private static _wordCount; /** Standard deviation of an array of numbers */ private static _stddev; /** * Extract the last "real" word from a sentence. * Strips trailing punctuation and returns lowercase. */ static _lastWord(sentence: string): string | null; /** * Return true if two words rhyme based on a shared suffix of at least * RHYME_SUFFIX_LENGTH characters. * Short words (suffix too short) are never flagged. * * @param a - First word (lowercase, no punctuation) * @param b - Second word (lowercase, no punctuation) */ static _rhymes(a: string, b: string): boolean; } //# sourceMappingURL=read-aloud.d.ts.map