/** * @copyright nhcarrigan * @license Naomi's Public License * @author Naomi Carrigan */ /* eslint-disable max-lines-per-function -- Multi-level split logic requires many lines. */ /* eslint-disable max-statements -- Multi-level split logic requires many statements. */ /* eslint-disable complexity -- Multi-level split logic has inherent branching complexity. */ /** * Splits content into chunks that do not exceed the given character limit. * Splits preferably at paragraph boundaries, then line boundaries, * then hard-cuts at the limit as a last resort. * @param content - The content to chunk. * @param limit - The maximum character count per chunk. * @returns An array of content chunks. */ export const chunkContent = (content: string, limit: number): Array => { if (content.length <= limit) { return [ content ]; } const chunks: Array = []; const paragraphs = content.split("\n\n"); let current = ""; for (const paragraph of paragraphs) { const separator = current.length > 0 ? "\n\n" : ""; const combined = `${current}${separator}${paragraph}`; if (combined.length <= limit) { current = combined; continue; } if (current.length > 0) { chunks.push(current); current = ""; } if (paragraph.length <= limit) { current = paragraph; continue; } // Paragraph itself exceeds the limit — split by lines const lines = paragraph.split("\n"); for (const line of lines) { const lineSeparator = current.length > 0 ? "\n" : ""; const combinedLine = `${current}${lineSeparator}${line}`; if (combinedLine.length <= limit) { current = combinedLine; continue; } if (current.length > 0) { chunks.push(current); current = ""; } if (line.length <= limit) { current = line; continue; } // Single line exceeds limit — hard-cut for (let index = 0; index < line.length; index = index + limit) { chunks.push(line.slice(index, index + limit)); } } } if (current.length > 0) { chunks.push(current); } return chunks; };