"""Split extracted book text into TTS-sized chunks.""" import re from typing import List from . import config def split_into_chunks(text: str, max_words: int = config.CHUNK_SIZE_WORDS) -> List[str]: """Split text into chunks of at most ``max_words`` words. Splits on sentence boundaries. Sentences longer than the limit are split further at clause punctuation (which is kept attached for TTS prosody). A single sentence with no clause punctuation longer than the limit is kept intact as one oversized chunk. """ if not text.strip(): return [] sentences = re.split(r"(?<=[.!?])\s+", text) chunks = [] current_chunk = "" current_words = 0 for sentence in sentences: sentence_words = len(sentence.split()) if sentence_words > max_words: if current_chunk: chunks.append(current_chunk.strip()) current_chunk = "" current_words = 0 # Split long sentences at clause boundaries, keeping punctuation. parts = re.split(r"(?<=[,;:])\s*", sentence) for part in parts: part_words = len(part.split()) if current_words + part_words <= max_words: current_chunk += part + " " current_words += part_words else: if current_chunk: chunks.append(current_chunk.strip()) current_chunk = part + " " current_words = part_words else: if current_words + sentence_words <= max_words: current_chunk += sentence + " " current_words += sentence_words else: if current_chunk: chunks.append(current_chunk.strip()) current_chunk = sentence + " " current_words = sentence_words if current_chunk.strip(): chunks.append(current_chunk.strip()) return [chunk for chunk in chunks if chunk.strip()]