/// Shared OOXML document models for native Word/PPT parsing. library; class OfficeTextRun { const OfficeTextRun({ required this.text, this.x = 0, this.y = 0, this.width = 0, this.height = 0, this.fontSize = 18, }); final String text; final double x; final double y; final double width; final double height; final double fontSize; } class OfficeImage { const OfficeImage({ required this.bytesPath, this.x = 0, this.y = 0, this.width = 0, this.height = 0, }); final String bytesPath; final double x; final double y; final double width; final double height; } class OfficeSlide { const OfficeSlide({ required this.index, required this.width, required this.height, this.runs = const [], this.images = const [], this.plainText = '', }); final int index; final double width; final double height; final List runs; final List images; final String plainText; } class ParsedPptx { const ParsedPptx({ required this.sourcePath, required this.slides, }); final String sourcePath; final List slides; String get allText => slides.map((s) => '--- Slide ${s.index + 1} ---\n${s.plainText}').join('\n\n'); /// Alias used by [PptxService.extractText]. String get plainText => allText; } enum DocBlockType { heading, paragraph, tableRow, image } class DocBlock { const DocBlock({ required this.type, required this.text, this.level = 0, this.imagePath, }); final DocBlockType type; final String text; final int level; final String? imagePath; } class ParsedDocx { const ParsedDocx({ required this.sourcePath, required this.blocks, }); final String sourcePath; final List blocks; String get plainText => blocks.map((b) => b.text).where((t) => t.isNotEmpty).join('\n'); }