from __future__ import annotations def chunk_text(text: str, limit: int, mode: str = "paragraph") -> list[str]: if len(text) <= limit: return [text] if mode == "length": return _chunk_by_length(text, limit) if mode == "newline": return _chunk_by_newline(text, limit) return _chunk_by_paragraph(text, limit) def _chunk_by_paragraph(text: str, limit: int) -> list[str]: chunks = [] paragraphs = text.split("\n\n") for para in paragraphs: if len(para) <= limit: chunks.append(para) continue sentences = para.replace("\n", " ").split(". ") current = "" for sentence in sentences: sep = ". " if current else "" candidate = f"{current}{sep}{sentence}" if current and len(candidate) + 1 > limit: chunks.append(current + ".") current = sentence else: current = candidate if current: if not current.endswith("."): current += "." chunks.append(current) merged = [] for chunk in chunks: if merged and len(merged[-1]) + len(chunk) + 2 <= limit: merged[-1] = f"{merged[-1]}\n\n{chunk}" else: merged.append(chunk) return merged def _chunk_by_length(text: str, limit: int) -> list[str]: chunks = [] for i in range(0, len(text), limit): chunks.append(text[i : i + limit]) return chunks def _chunk_by_newline(text: str, limit: int) -> list[str]: lines = text.split("\n") chunks = [] current = "" for line in lines: candidate = f"{current}\n{line}" if current else line if len(candidate) > limit and current: chunks.append(current) current = line else: current = candidate if current: chunks.append(current) return chunks