/** * ProseAnalyzer — SPEC-05 Prose Analysis System * * Runs multiple categories of text analysis on chapter Markdown files: * Group A – Word-level checks (intensifiers, filter words, adverb tags, passive voice, doubled words) * Group B – Sentence rhythm (monotony detection per paragraph) * Group C – Word repetition (sliding 300-word window) * Group D – Dialogue checks (on-the-nose, purple prose) * * Code-fence content (``` or ~~~) is always skipped. */ import type { ProseAnalysisResult } from '../types/novel.js'; export declare class ProseAnalyzer { private readonly projectPath; constructor(projectPath: string); /** * Run all prose checks on a single chapter file. * * @param chapterFile - Absolute path or path relative to `projectPath/chapters/` */ analyzeChapter(chapterFile: string): Promise; /** * Run all prose checks on every `.md` file in `projectPath/chapters/`. */ analyzeAll(): Promise; /** * Run only dialogue checks (Group D) on a single chapter file. */ analyzeDialogue(chapterFile: string): Promise; /** * Analyse a raw text string and return a ProseAnalysisResult. * * @param raw - Full file contents * @param chapterFile - Filename stored in result */ _analyzeText(raw: string, chapterFile: string): ProseAnalysisResult; /** * Extract all dialogue from the text and group it by speaker name. * * Speaker is identified via patterns like: * - `"text," said Name` or `"text" said Name` * - `Name said "text"` * Unattributed dialogue is grouped under 'Unknown'. * * @param text - Raw chapter text * @returns Map from speaker name to their dialogue lines */ extractDialogueByCharacter(text: string): Map; /** * Analyze each character's dialogue voice. * * For each speaker (from extractDialogueByCharacter), computes: * - lineCount: number of dialogue lines * - avgWordLength: average character-count per word (vocabulary sophistication proxy) * - avgSentenceLength: average word count per dialogue line * - distinctivePhrases: most-repeated 2-word bigrams in that character's dialogue * * @param text - Raw chapter text */ analyzeCharacterVoices(text: string): Array<{ speaker: string; lineCount: number; avgWordLength: number; avgSentenceLength: number; distinctivePhrases: string[]; }>; /** * Count sensory words by sense category and flag visually-dominant text. * * Flag condition: visual > 80% of all sensory words AND total > 10. * * @param text - Raw chapter text */ analyzeSensoryBalance(text: string): { visual: number; auditory: number; tactile: number; olfactory: number; gustatory: number; flag: boolean; }; /** * Detect show vs tell balance in the text. * * - "Tell" indicators: state-of-being + emotion adjective patterns * - "Show" indicators: concrete action verbs * * `ratio` = show / (show + tell); undefined when both are 0. * * @param text - Raw chapter text */ analyzeShowVsTell(text: string): { showScore: number; tellScore: number; ratio: number; examples: Array<{ type: 'show' | 'tell'; text: string; }>; }; /** * Build two parallel arrays: * - `contentLines[i]` — the line text (empty string when in a code fence) * - `insideCodeFence[i]` — true when line i is inside a ``` or ~~~ block */ private _classifyLines; /** * Extract blank-line-delimited paragraphs from non-fence lines. * Returns objects with the 1-based start line and paragraph text. */ private _extractParagraphs; /** * Sliding 300-word window: flag content words (> 5 chars, not in stop list) * used more than 3 times within any window. */ private _checkRepetition; } //# sourceMappingURL=prose-analyzer.d.ts.map