(function (root, factory) { const normalize = factory(); if (typeof module === 'object' && module.exports) module.exports = normalize; if (root) root.ccNormalizeMarkdownText = normalize; })(typeof globalThis !== 'undefined' ? globalThis : this, function () { const CODE_LIKE_PATTERN = /(?:=>|[{};]|^\s*(?:const|let|var|function|class|return|import|export|def|print|console\.)\b|<\/?[a-z][^>]*>)/im; const FENCE_PATTERN = /^ {0,3}(`{3,}|~{3,})/; function indentationWidth(line) { let width = 0; for (const character of line.match(/^[ \t]*/)?.[0] || '') { width = character === '\t' ? width + (4 - (width % 4)) : width + 1; } return width; } function removeIndent(line, width) { let column = 0; let index = 0; while (index < line.length && column < width) { const character = line[index]; if (character !== ' ' && character !== '\t') break; const nextColumn = character === '\t' ? column + (4 - (column % 4)) : column + 1; index += 1; if (nextColumn > width) return `${' '.repeat(nextColumn - width)}${line.slice(index)}`; column = nextColumn; } return line.slice(index); } function isNaturalLanguage(lines) { const text = lines.map((line) => line.trim()).join(' ').trim(); if (!text || CODE_LIKE_PATTERN.test(text)) return false; const cjkCount = (text.match(/[\u3400-\u9fff]/g) || []).length; if (cjkCount >= 4) return /[。!?;:]/.test(text); const wordCount = (text.match(/[a-z][a-z'-]*/gi) || []).length; return wordCount >= 8 && /[.!?]/.test(text); } function normalizeParagraph(lines) { const contentLines = lines.filter((line) => line.trim()); if (contentLines.length === 0) return lines; const commonIndent = Math.min(...contentLines.map(indentationWidth)); if (commonIndent < 4 || !isNaturalLanguage(contentLines)) return lines; return lines.map((line) => (line.trim() ? removeIndent(line, commonIndent) : line)); } return function normalizeMarkdownText(value) { const lines = String(value ?? '').split('\n'); const output = []; let paragraph = []; let fence = null; function flushParagraph() { if (paragraph.length > 0) output.push(...normalizeParagraph(paragraph)); paragraph = []; } for (const line of lines) { const fenceMatch = line.match(FENCE_PATTERN); if (fence) { output.push(line); if (fenceMatch && fenceMatch[1][0] === fence.character && fenceMatch[1].length >= fence.length) { fence = null; } continue; } if (fenceMatch) { flushParagraph(); fence = { character: fenceMatch[1][0], length: fenceMatch[1].length }; output.push(line); } else if (!line.trim() || /^\s{0,3}<\/?[a-z][^>]*>/i.test(line)) { flushParagraph(); output.push(line); } else { paragraph.push(line); } } flushParagraph(); return output.join('\n'); }; });