Spaces:
Running
Running
| """Parse uploaded course material into plain text. | |
| Supports PDF, PPTX, DOCX, and plain text files. | |
| """ | |
| import io | |
| def parse_pdf(data): | |
| """Extract text from PDF bytes using PyMuPDF.""" | |
| import fitz # PyMuPDF | |
| text_parts = [] | |
| with fitz.open(stream=data, filetype="pdf") as document: | |
| for page in document: | |
| text_parts.append(page.get_text()) | |
| return "\n".join(text_parts) | |
| def parse_pptx(data): | |
| """Extract text from PPTX bytes, slide by slide.""" | |
| from pptx import Presentation | |
| presentation = Presentation(io.BytesIO(data)) | |
| text_parts = [] | |
| for index, slide in enumerate(presentation.slides, start=1): | |
| text_parts.append(f"[Slide {index}]") | |
| for shape in slide.shapes: | |
| if shape.has_text_frame: | |
| for paragraph in shape.text_frame.paragraphs: | |
| line = "".join(run.text for run in paragraph.runs) | |
| if line.strip(): | |
| text_parts.append(line) | |
| return "\n".join(text_parts) | |
| def parse_docx(data): | |
| """Extract text from DOCX bytes.""" | |
| from docx import Document | |
| document = Document(io.BytesIO(data)) | |
| return "\n".join(p.text for p in document.paragraphs if p.text.strip()) | |
| def parse_material(filename, data): | |
| """Pick the right parser based on file extension and return plain text.""" | |
| lower = filename.lower() | |
| if lower.endswith(".pdf"): | |
| return parse_pdf(data) | |
| if lower.endswith(".pptx"): | |
| return parse_pptx(data) | |
| if lower.endswith(".docx"): | |
| return parse_docx(data) | |
| if lower.endswith(".txt") or lower.endswith(".md"): | |
| return data.decode("utf-8", errors="ignore") | |
| raise ValueError(f"Unsupported file type: {filename}") | |
| def clean_text(text): | |
| """Strip extra whitespace and blank lines.""" | |
| lines = [line.strip() for line in text.splitlines()] | |
| non_empty = [line for line in lines if line] | |
| return "\n".join(non_empty) | |