diff --git a/.agents/skills/impeccable/reference/editorial.md b/.agents/skills/impeccable/reference/editorial.md index 50bc0ec3b..11dc39602 100644 --- a/.agents/skills/impeccable/reference/editorial.md +++ b/.agents/skills/impeccable/reference/editorial.md @@ -51,6 +51,16 @@ Editorial has permission for Committed, Full palette, and Drenched strategies. U - Don't center everything. Left-aligned in asymmetric compositions feels more designed. - When cards ARE the right affordance, use `grid-template-columns: repeat(auto-fit, minmax(280px, 1fr))` — breakpoint-free responsiveness. +## Imagery + +Editorial register leans on imagery. A restaurant, hotel, magazine, or product landing page without any imagery reads as incomplete, not as restrained. A solid-color rectangle where a hero image should go is worse than a representative stock photo. + +- **For greenfield work without local assets, reach for stock imagery** from Unsplash (`https://images.unsplash.com/photo-{id}?w=…&q=80`), Pexels, or similar. A well-chosen Unsplash photo is a valid deliverable — colored placeholder blocks are not. +- **Search for the brand's physical object**, not the generic category: "handmade pasta on a scratched wooden table" beats "Italian food"; "cypress trees above a limestone hotel facade at dusk" beats "luxury hotel". +- **One decisive photo beats five mediocre ones.** Hero imagery should commit to a mood; padding with more stock doesn't rescue an indecisive one. +- **Don't stop at zero** when the brief implies imagery. A moto forum without motorcycle photos, a restaurant without food, a hotel without a view — these read as stubs, not as editorial restraint. +- **Alt text is part of the voice.** "Coastal fettuccine, hand-cut, served on the terrace" beats "pasta dish". + ## Motion - One well-orchestrated page-load with staggered reveals beats scattered micro-interactions. diff --git a/.agents/skills/impeccable/scripts/live-accept.mjs b/.agents/skills/impeccable/scripts/live-accept.mjs index b93b60f6b..af22180aa 100644 --- a/.agents/skills/impeccable/scripts/live-accept.mjs +++ b/.agents/skills/impeccable/scripts/live-accept.mjs @@ -192,91 +192,117 @@ function findMarkerBlock(id, lines) { } /** - * Extract the original element content from within the variant wrapper. - * Returns an array of lines (still indented as stored in the wrapper). - * - * CSS inside a ` to close on) + * - Same-line `` blocks + * - Multi-line `` blocks */ -function extractOriginal(lines, block) { - let inOriginal = false; +function stripStyleAndJoin(lines, block) { + const out = []; let inStyle = false; - let depth = 0; - const content = []; - for (let i = block.start; i <= block.end; i++) { - const line = lines[i]; + let line = lines[i]; - if (!inStyle && /]/.test(line)) { inStyle = true; continue; } - if (inStyle) { - if (line.trimStart().startsWith('')) inStyle = false; - continue; - } + if (!inStyle) { + // Strip any complete . + const closeIdx = line.search(/<\/style\s*>/); + if (closeIdx !== -1) { + inStyle = false; + out.push(line.slice(closeIdx).replace(/<\/style\s*>/, '')); + } + // else: skip line entirely } } + return out.join('\n'); +} - return content; +/** + * Find the inner content of `` inside `text`, + * handling nested same-tag elements via depth counting. `attrMatch` is a + * regex source fragment that must appear inside the opener tag. + * Returns the inner string (may be empty), or null if not found. + */ +function extractInnerByAttr(text, attrMatch) { + const openerRe = new RegExp('<([A-Za-z][A-Za-z0-9]*)\\b[^>]*' + attrMatch + '[^>]*>'); + const openMatch = text.match(openerRe); + if (!openMatch) return null; + + const tagName = openMatch[1]; + const innerStart = openMatch.index + openMatch[0].length; + + // Match any opener or closer of this tag name after innerStart. + // (Does not match self-closing , which doesn't contribute to depth.) + const tagRe = new RegExp('<(?:/)?' + tagName + '\\b[^>]*>', 'g'); + tagRe.lastIndex = innerStart; + + let depth = 1; + let m; + while ((m = tagRe.exec(text))) { + const isClose = m[0].startsWith('$/.test(m[0]); + if (isClose) { + depth--; + if (depth === 0) return text.slice(innerStart, m.index); + } else if (!isSelfClose) { + depth++; + } + } + return null; +} + +/** + * Extract the original element content from within the variant wrapper. + * Returns an array of lines. + */ +function extractOriginal(lines, block) { + const text = stripStyleAndJoin(lines, block); + const inner = extractInnerByAttr(text, 'data-impeccable-variant="original"'); + if (inner === null) return []; + return inner.split('\n'); } /** * Extract a specific variant's inner content (stripping the wrapper div). * Returns an array of lines, or null if not found. - * - * Skip ')) inStyle = false; - continue; - } - - if (!inVariant && line.includes('data-impeccable-variant="' + variantNum + '"')) { - inVariant = true; - depth = 1; - continue; // skip the opening
- } - - if (inVariant) { - const opens = (line.match(/]/g) || []).length; - const closes = (line.match(/<\/div\s*>/g) || []).length; - depth += opens - closes; - - if (depth <= 0) break; // closing
of the variant wrapper - content.push(line); - } - } - - return content.length > 0 ? content : null; + const text = stripStyleAndJoin(lines, block); + const inner = extractInnerByAttr(text, 'data-impeccable-variant="' + variantNum + '"'); + if (inner === null) return null; + const result = inner.split('\n'); + // Collapse a lone empty leading/trailing line (common after string splice). + while (result.length > 1 && result[0].trim() === '') result.shift(); + while (result.length > 1 && result[result.length - 1].trim() === '') result.pop(); + return result.length > 0 ? result : null; } /** * Extract the colocated ` — return the inner content. + * 3. Multi-line: `` on a later line — return + * the lines between them. */ function extractCss(lines, block, id) { const styleAttr = 'data-impeccable-css="' + id + '"'; @@ -287,6 +313,14 @@ function extractCss(lines, block, id) { const line = lines[i]; if (!inStyle && line.includes(styleAttr)) { + // Self-closing: nothing to carbonize. + if (/]*\/\s*>/.test(line)) return null; + // Same-line open + close: extract inner text. + const sameLine = line.match(/]*>([\s\S]*?)<\/style\s*>/); + if (sameLine) { + const inner = sameLine[1]; + return inner.length > 0 ? inner.split('\n') : null; + } inStyle = true; continue; // skip the ` to close on) + * - Same-line `` blocks + * - Multi-line `` blocks */ -function extractOriginal(lines, block) { - let inOriginal = false; +function stripStyleAndJoin(lines, block) { + const out = []; let inStyle = false; - let depth = 0; - const content = []; - for (let i = block.start; i <= block.end; i++) { - const line = lines[i]; + let line = lines[i]; - if (!inStyle && /]/.test(line)) { inStyle = true; continue; } - if (inStyle) { - if (line.trimStart().startsWith('')) inStyle = false; - continue; - } + if (!inStyle) { + // Strip any complete . + const closeIdx = line.search(/<\/style\s*>/); + if (closeIdx !== -1) { + inStyle = false; + out.push(line.slice(closeIdx).replace(/<\/style\s*>/, '')); + } + // else: skip line entirely } } + return out.join('\n'); +} - return content; +/** + * Find the inner content of `` inside `text`, + * handling nested same-tag elements via depth counting. `attrMatch` is a + * regex source fragment that must appear inside the opener tag. + * Returns the inner string (may be empty), or null if not found. + */ +function extractInnerByAttr(text, attrMatch) { + const openerRe = new RegExp('<([A-Za-z][A-Za-z0-9]*)\\b[^>]*' + attrMatch + '[^>]*>'); + const openMatch = text.match(openerRe); + if (!openMatch) return null; + + const tagName = openMatch[1]; + const innerStart = openMatch.index + openMatch[0].length; + + // Match any opener or closer of this tag name after innerStart. + // (Does not match self-closing , which doesn't contribute to depth.) + const tagRe = new RegExp('<(?:/)?' + tagName + '\\b[^>]*>', 'g'); + tagRe.lastIndex = innerStart; + + let depth = 1; + let m; + while ((m = tagRe.exec(text))) { + const isClose = m[0].startsWith('$/.test(m[0]); + if (isClose) { + depth--; + if (depth === 0) return text.slice(innerStart, m.index); + } else if (!isSelfClose) { + depth++; + } + } + return null; +} + +/** + * Extract the original element content from within the variant wrapper. + * Returns an array of lines. + */ +function extractOriginal(lines, block) { + const text = stripStyleAndJoin(lines, block); + const inner = extractInnerByAttr(text, 'data-impeccable-variant="original"'); + if (inner === null) return []; + return inner.split('\n'); } /** * Extract a specific variant's inner content (stripping the wrapper div). * Returns an array of lines, or null if not found. - * - * Skip ')) inStyle = false; - continue; - } - - if (!inVariant && line.includes('data-impeccable-variant="' + variantNum + '"')) { - inVariant = true; - depth = 1; - continue; // skip the opening
- } - - if (inVariant) { - const opens = (line.match(/]/g) || []).length; - const closes = (line.match(/<\/div\s*>/g) || []).length; - depth += opens - closes; - - if (depth <= 0) break; // closing
of the variant wrapper - content.push(line); - } - } - - return content.length > 0 ? content : null; + const text = stripStyleAndJoin(lines, block); + const inner = extractInnerByAttr(text, 'data-impeccable-variant="' + variantNum + '"'); + if (inner === null) return null; + const result = inner.split('\n'); + // Collapse a lone empty leading/trailing line (common after string splice). + while (result.length > 1 && result[0].trim() === '') result.shift(); + while (result.length > 1 && result[result.length - 1].trim() === '') result.pop(); + return result.length > 0 ? result : null; } /** * Extract the colocated ` — return the inner content. + * 3. Multi-line: `` on a later line — return + * the lines between them. */ function extractCss(lines, block, id) { const styleAttr = 'data-impeccable-css="' + id + '"'; @@ -287,6 +313,14 @@ function extractCss(lines, block, id) { const line = lines[i]; if (!inStyle && line.includes(styleAttr)) { + // Self-closing: nothing to carbonize. + if (/]*\/\s*>/.test(line)) return null; + // Same-line open + close: extract inner text. + const sameLine = line.match(/]*>([\s\S]*?)<\/style\s*>/); + if (sameLine) { + const inner = sameLine[1]; + return inner.length > 0 ? inner.split('\n') : null; + } inStyle = true; continue; // skip the ` to close on) + * - Same-line `` blocks + * - Multi-line `` blocks */ -function extractOriginal(lines, block) { - let inOriginal = false; +function stripStyleAndJoin(lines, block) { + const out = []; let inStyle = false; - let depth = 0; - const content = []; - for (let i = block.start; i <= block.end; i++) { - const line = lines[i]; + let line = lines[i]; - if (!inStyle && /]/.test(line)) { inStyle = true; continue; } - if (inStyle) { - if (line.trimStart().startsWith('')) inStyle = false; - continue; - } + if (!inStyle) { + // Strip any complete . + const closeIdx = line.search(/<\/style\s*>/); + if (closeIdx !== -1) { + inStyle = false; + out.push(line.slice(closeIdx).replace(/<\/style\s*>/, '')); + } + // else: skip line entirely } } + return out.join('\n'); +} - return content; +/** + * Find the inner content of `` inside `text`, + * handling nested same-tag elements via depth counting. `attrMatch` is a + * regex source fragment that must appear inside the opener tag. + * Returns the inner string (may be empty), or null if not found. + */ +function extractInnerByAttr(text, attrMatch) { + const openerRe = new RegExp('<([A-Za-z][A-Za-z0-9]*)\\b[^>]*' + attrMatch + '[^>]*>'); + const openMatch = text.match(openerRe); + if (!openMatch) return null; + + const tagName = openMatch[1]; + const innerStart = openMatch.index + openMatch[0].length; + + // Match any opener or closer of this tag name after innerStart. + // (Does not match self-closing , which doesn't contribute to depth.) + const tagRe = new RegExp('<(?:/)?' + tagName + '\\b[^>]*>', 'g'); + tagRe.lastIndex = innerStart; + + let depth = 1; + let m; + while ((m = tagRe.exec(text))) { + const isClose = m[0].startsWith('$/.test(m[0]); + if (isClose) { + depth--; + if (depth === 0) return text.slice(innerStart, m.index); + } else if (!isSelfClose) { + depth++; + } + } + return null; +} + +/** + * Extract the original element content from within the variant wrapper. + * Returns an array of lines. + */ +function extractOriginal(lines, block) { + const text = stripStyleAndJoin(lines, block); + const inner = extractInnerByAttr(text, 'data-impeccable-variant="original"'); + if (inner === null) return []; + return inner.split('\n'); } /** * Extract a specific variant's inner content (stripping the wrapper div). * Returns an array of lines, or null if not found. - * - * Skip ')) inStyle = false; - continue; - } - - if (!inVariant && line.includes('data-impeccable-variant="' + variantNum + '"')) { - inVariant = true; - depth = 1; - continue; // skip the opening
- } - - if (inVariant) { - const opens = (line.match(/]/g) || []).length; - const closes = (line.match(/<\/div\s*>/g) || []).length; - depth += opens - closes; - - if (depth <= 0) break; // closing
of the variant wrapper - content.push(line); - } - } - - return content.length > 0 ? content : null; + const text = stripStyleAndJoin(lines, block); + const inner = extractInnerByAttr(text, 'data-impeccable-variant="' + variantNum + '"'); + if (inner === null) return null; + const result = inner.split('\n'); + // Collapse a lone empty leading/trailing line (common after string splice). + while (result.length > 1 && result[0].trim() === '') result.shift(); + while (result.length > 1 && result[result.length - 1].trim() === '') result.pop(); + return result.length > 0 ? result : null; } /** * Extract the colocated ` — return the inner content. + * 3. Multi-line: `` on a later line — return + * the lines between them. */ function extractCss(lines, block, id) { const styleAttr = 'data-impeccable-css="' + id + '"'; @@ -287,6 +313,14 @@ function extractCss(lines, block, id) { const line = lines[i]; if (!inStyle && line.includes(styleAttr)) { + // Self-closing: nothing to carbonize. + if (/]*\/\s*>/.test(line)) return null; + // Same-line open + close: extract inner text. + const sameLine = line.match(/]*>([\s\S]*?)<\/style\s*>/); + if (sameLine) { + const inner = sameLine[1]; + return inner.length > 0 ? inner.split('\n') : null; + } inStyle = true; continue; // skip the ` to close on) + * - Same-line `` blocks + * - Multi-line `` blocks */ -function extractOriginal(lines, block) { - let inOriginal = false; +function stripStyleAndJoin(lines, block) { + const out = []; let inStyle = false; - let depth = 0; - const content = []; - for (let i = block.start; i <= block.end; i++) { - const line = lines[i]; + let line = lines[i]; - if (!inStyle && /]/.test(line)) { inStyle = true; continue; } - if (inStyle) { - if (line.trimStart().startsWith('')) inStyle = false; - continue; - } + if (!inStyle) { + // Strip any complete . + const closeIdx = line.search(/<\/style\s*>/); + if (closeIdx !== -1) { + inStyle = false; + out.push(line.slice(closeIdx).replace(/<\/style\s*>/, '')); + } + // else: skip line entirely } } + return out.join('\n'); +} - return content; +/** + * Find the inner content of `` inside `text`, + * handling nested same-tag elements via depth counting. `attrMatch` is a + * regex source fragment that must appear inside the opener tag. + * Returns the inner string (may be empty), or null if not found. + */ +function extractInnerByAttr(text, attrMatch) { + const openerRe = new RegExp('<([A-Za-z][A-Za-z0-9]*)\\b[^>]*' + attrMatch + '[^>]*>'); + const openMatch = text.match(openerRe); + if (!openMatch) return null; + + const tagName = openMatch[1]; + const innerStart = openMatch.index + openMatch[0].length; + + // Match any opener or closer of this tag name after innerStart. + // (Does not match self-closing , which doesn't contribute to depth.) + const tagRe = new RegExp('<(?:/)?' + tagName + '\\b[^>]*>', 'g'); + tagRe.lastIndex = innerStart; + + let depth = 1; + let m; + while ((m = tagRe.exec(text))) { + const isClose = m[0].startsWith('$/.test(m[0]); + if (isClose) { + depth--; + if (depth === 0) return text.slice(innerStart, m.index); + } else if (!isSelfClose) { + depth++; + } + } + return null; +} + +/** + * Extract the original element content from within the variant wrapper. + * Returns an array of lines. + */ +function extractOriginal(lines, block) { + const text = stripStyleAndJoin(lines, block); + const inner = extractInnerByAttr(text, 'data-impeccable-variant="original"'); + if (inner === null) return []; + return inner.split('\n'); } /** * Extract a specific variant's inner content (stripping the wrapper div). * Returns an array of lines, or null if not found. - * - * Skip ')) inStyle = false; - continue; - } - - if (!inVariant && line.includes('data-impeccable-variant="' + variantNum + '"')) { - inVariant = true; - depth = 1; - continue; // skip the opening
- } - - if (inVariant) { - const opens = (line.match(/]/g) || []).length; - const closes = (line.match(/<\/div\s*>/g) || []).length; - depth += opens - closes; - - if (depth <= 0) break; // closing
of the variant wrapper - content.push(line); - } - } - - return content.length > 0 ? content : null; + const text = stripStyleAndJoin(lines, block); + const inner = extractInnerByAttr(text, 'data-impeccable-variant="' + variantNum + '"'); + if (inner === null) return null; + const result = inner.split('\n'); + // Collapse a lone empty leading/trailing line (common after string splice). + while (result.length > 1 && result[0].trim() === '') result.shift(); + while (result.length > 1 && result[result.length - 1].trim() === '') result.pop(); + return result.length > 0 ? result : null; } /** * Extract the colocated ` — return the inner content. + * 3. Multi-line: `` on a later line — return + * the lines between them. */ function extractCss(lines, block, id) { const styleAttr = 'data-impeccable-css="' + id + '"'; @@ -287,6 +313,14 @@ function extractCss(lines, block, id) { const line = lines[i]; if (!inStyle && line.includes(styleAttr)) { + // Self-closing: nothing to carbonize. + if (/]*\/\s*>/.test(line)) return null; + // Same-line open + close: extract inner text. + const sameLine = line.match(/]*>([\s\S]*?)<\/style\s*>/); + if (sameLine) { + const inner = sameLine[1]; + return inner.length > 0 ? inner.split('\n') : null; + } inStyle = true; continue; // skip the ` to close on) + * - Same-line `` blocks + * - Multi-line `` blocks */ -function extractOriginal(lines, block) { - let inOriginal = false; +function stripStyleAndJoin(lines, block) { + const out = []; let inStyle = false; - let depth = 0; - const content = []; - for (let i = block.start; i <= block.end; i++) { - const line = lines[i]; + let line = lines[i]; - if (!inStyle && /]/.test(line)) { inStyle = true; continue; } - if (inStyle) { - if (line.trimStart().startsWith('')) inStyle = false; - continue; - } + if (!inStyle) { + // Strip any complete . + const closeIdx = line.search(/<\/style\s*>/); + if (closeIdx !== -1) { + inStyle = false; + out.push(line.slice(closeIdx).replace(/<\/style\s*>/, '')); + } + // else: skip line entirely } } + return out.join('\n'); +} - return content; +/** + * Find the inner content of `` inside `text`, + * handling nested same-tag elements via depth counting. `attrMatch` is a + * regex source fragment that must appear inside the opener tag. + * Returns the inner string (may be empty), or null if not found. + */ +function extractInnerByAttr(text, attrMatch) { + const openerRe = new RegExp('<([A-Za-z][A-Za-z0-9]*)\\b[^>]*' + attrMatch + '[^>]*>'); + const openMatch = text.match(openerRe); + if (!openMatch) return null; + + const tagName = openMatch[1]; + const innerStart = openMatch.index + openMatch[0].length; + + // Match any opener or closer of this tag name after innerStart. + // (Does not match self-closing , which doesn't contribute to depth.) + const tagRe = new RegExp('<(?:/)?' + tagName + '\\b[^>]*>', 'g'); + tagRe.lastIndex = innerStart; + + let depth = 1; + let m; + while ((m = tagRe.exec(text))) { + const isClose = m[0].startsWith('$/.test(m[0]); + if (isClose) { + depth--; + if (depth === 0) return text.slice(innerStart, m.index); + } else if (!isSelfClose) { + depth++; + } + } + return null; +} + +/** + * Extract the original element content from within the variant wrapper. + * Returns an array of lines. + */ +function extractOriginal(lines, block) { + const text = stripStyleAndJoin(lines, block); + const inner = extractInnerByAttr(text, 'data-impeccable-variant="original"'); + if (inner === null) return []; + return inner.split('\n'); } /** * Extract a specific variant's inner content (stripping the wrapper div). * Returns an array of lines, or null if not found. - * - * Skip ')) inStyle = false; - continue; - } - - if (!inVariant && line.includes('data-impeccable-variant="' + variantNum + '"')) { - inVariant = true; - depth = 1; - continue; // skip the opening
- } - - if (inVariant) { - const opens = (line.match(/]/g) || []).length; - const closes = (line.match(/<\/div\s*>/g) || []).length; - depth += opens - closes; - - if (depth <= 0) break; // closing
of the variant wrapper - content.push(line); - } - } - - return content.length > 0 ? content : null; + const text = stripStyleAndJoin(lines, block); + const inner = extractInnerByAttr(text, 'data-impeccable-variant="' + variantNum + '"'); + if (inner === null) return null; + const result = inner.split('\n'); + // Collapse a lone empty leading/trailing line (common after string splice). + while (result.length > 1 && result[0].trim() === '') result.shift(); + while (result.length > 1 && result[result.length - 1].trim() === '') result.pop(); + return result.length > 0 ? result : null; } /** * Extract the colocated ` — return the inner content. + * 3. Multi-line: `` on a later line — return + * the lines between them. */ function extractCss(lines, block, id) { const styleAttr = 'data-impeccable-css="' + id + '"'; @@ -287,6 +313,14 @@ function extractCss(lines, block, id) { const line = lines[i]; if (!inStyle && line.includes(styleAttr)) { + // Self-closing: nothing to carbonize. + if (/]*\/\s*>/.test(line)) return null; + // Same-line open + close: extract inner text. + const sameLine = line.match(/]*>([\s\S]*?)<\/style\s*>/); + if (sameLine) { + const inner = sameLine[1]; + return inner.length > 0 ? inner.split('\n') : null; + } inStyle = true; continue; // skip the ` to close on) + * - Same-line `` blocks + * - Multi-line `` blocks */ -function extractOriginal(lines, block) { - let inOriginal = false; +function stripStyleAndJoin(lines, block) { + const out = []; let inStyle = false; - let depth = 0; - const content = []; - for (let i = block.start; i <= block.end; i++) { - const line = lines[i]; + let line = lines[i]; - if (!inStyle && /]/.test(line)) { inStyle = true; continue; } - if (inStyle) { - if (line.trimStart().startsWith('')) inStyle = false; - continue; - } + if (!inStyle) { + // Strip any complete . + const closeIdx = line.search(/<\/style\s*>/); + if (closeIdx !== -1) { + inStyle = false; + out.push(line.slice(closeIdx).replace(/<\/style\s*>/, '')); + } + // else: skip line entirely } } + return out.join('\n'); +} - return content; +/** + * Find the inner content of `` inside `text`, + * handling nested same-tag elements via depth counting. `attrMatch` is a + * regex source fragment that must appear inside the opener tag. + * Returns the inner string (may be empty), or null if not found. + */ +function extractInnerByAttr(text, attrMatch) { + const openerRe = new RegExp('<([A-Za-z][A-Za-z0-9]*)\\b[^>]*' + attrMatch + '[^>]*>'); + const openMatch = text.match(openerRe); + if (!openMatch) return null; + + const tagName = openMatch[1]; + const innerStart = openMatch.index + openMatch[0].length; + + // Match any opener or closer of this tag name after innerStart. + // (Does not match self-closing , which doesn't contribute to depth.) + const tagRe = new RegExp('<(?:/)?' + tagName + '\\b[^>]*>', 'g'); + tagRe.lastIndex = innerStart; + + let depth = 1; + let m; + while ((m = tagRe.exec(text))) { + const isClose = m[0].startsWith('$/.test(m[0]); + if (isClose) { + depth--; + if (depth === 0) return text.slice(innerStart, m.index); + } else if (!isSelfClose) { + depth++; + } + } + return null; +} + +/** + * Extract the original element content from within the variant wrapper. + * Returns an array of lines. + */ +function extractOriginal(lines, block) { + const text = stripStyleAndJoin(lines, block); + const inner = extractInnerByAttr(text, 'data-impeccable-variant="original"'); + if (inner === null) return []; + return inner.split('\n'); } /** * Extract a specific variant's inner content (stripping the wrapper div). * Returns an array of lines, or null if not found. - * - * Skip ')) inStyle = false; - continue; - } - - if (!inVariant && line.includes('data-impeccable-variant="' + variantNum + '"')) { - inVariant = true; - depth = 1; - continue; // skip the opening
- } - - if (inVariant) { - const opens = (line.match(/]/g) || []).length; - const closes = (line.match(/<\/div\s*>/g) || []).length; - depth += opens - closes; - - if (depth <= 0) break; // closing
of the variant wrapper - content.push(line); - } - } - - return content.length > 0 ? content : null; + const text = stripStyleAndJoin(lines, block); + const inner = extractInnerByAttr(text, 'data-impeccable-variant="' + variantNum + '"'); + if (inner === null) return null; + const result = inner.split('\n'); + // Collapse a lone empty leading/trailing line (common after string splice). + while (result.length > 1 && result[0].trim() === '') result.shift(); + while (result.length > 1 && result[result.length - 1].trim() === '') result.pop(); + return result.length > 0 ? result : null; } /** * Extract the colocated ` — return the inner content. + * 3. Multi-line: `` on a later line — return + * the lines between them. */ function extractCss(lines, block, id) { const styleAttr = 'data-impeccable-css="' + id + '"'; @@ -287,6 +313,14 @@ function extractCss(lines, block, id) { const line = lines[i]; if (!inStyle && line.includes(styleAttr)) { + // Self-closing: nothing to carbonize. + if (/]*\/\s*>/.test(line)) return null; + // Same-line open + close: extract inner text. + const sameLine = line.match(/]*>([\s\S]*?)<\/style\s*>/); + if (sameLine) { + const inner = sameLine[1]; + return inner.length > 0 ? inner.split('\n') : null; + } inStyle = true; continue; // skip the ` to close on) + * - Same-line `` blocks + * - Multi-line `` blocks */ -function extractOriginal(lines, block) { - let inOriginal = false; +function stripStyleAndJoin(lines, block) { + const out = []; let inStyle = false; - let depth = 0; - const content = []; - for (let i = block.start; i <= block.end; i++) { - const line = lines[i]; + let line = lines[i]; - if (!inStyle && /]/.test(line)) { inStyle = true; continue; } - if (inStyle) { - if (line.trimStart().startsWith('')) inStyle = false; - continue; - } + if (!inStyle) { + // Strip any complete . + const closeIdx = line.search(/<\/style\s*>/); + if (closeIdx !== -1) { + inStyle = false; + out.push(line.slice(closeIdx).replace(/<\/style\s*>/, '')); + } + // else: skip line entirely } } + return out.join('\n'); +} - return content; +/** + * Find the inner content of `` inside `text`, + * handling nested same-tag elements via depth counting. `attrMatch` is a + * regex source fragment that must appear inside the opener tag. + * Returns the inner string (may be empty), or null if not found. + */ +function extractInnerByAttr(text, attrMatch) { + const openerRe = new RegExp('<([A-Za-z][A-Za-z0-9]*)\\b[^>]*' + attrMatch + '[^>]*>'); + const openMatch = text.match(openerRe); + if (!openMatch) return null; + + const tagName = openMatch[1]; + const innerStart = openMatch.index + openMatch[0].length; + + // Match any opener or closer of this tag name after innerStart. + // (Does not match self-closing , which doesn't contribute to depth.) + const tagRe = new RegExp('<(?:/)?' + tagName + '\\b[^>]*>', 'g'); + tagRe.lastIndex = innerStart; + + let depth = 1; + let m; + while ((m = tagRe.exec(text))) { + const isClose = m[0].startsWith('$/.test(m[0]); + if (isClose) { + depth--; + if (depth === 0) return text.slice(innerStart, m.index); + } else if (!isSelfClose) { + depth++; + } + } + return null; +} + +/** + * Extract the original element content from within the variant wrapper. + * Returns an array of lines. + */ +function extractOriginal(lines, block) { + const text = stripStyleAndJoin(lines, block); + const inner = extractInnerByAttr(text, 'data-impeccable-variant="original"'); + if (inner === null) return []; + return inner.split('\n'); } /** * Extract a specific variant's inner content (stripping the wrapper div). * Returns an array of lines, or null if not found. - * - * Skip ')) inStyle = false; - continue; - } - - if (!inVariant && line.includes('data-impeccable-variant="' + variantNum + '"')) { - inVariant = true; - depth = 1; - continue; // skip the opening
- } - - if (inVariant) { - const opens = (line.match(/]/g) || []).length; - const closes = (line.match(/<\/div\s*>/g) || []).length; - depth += opens - closes; - - if (depth <= 0) break; // closing
of the variant wrapper - content.push(line); - } - } - - return content.length > 0 ? content : null; + const text = stripStyleAndJoin(lines, block); + const inner = extractInnerByAttr(text, 'data-impeccable-variant="' + variantNum + '"'); + if (inner === null) return null; + const result = inner.split('\n'); + // Collapse a lone empty leading/trailing line (common after string splice). + while (result.length > 1 && result[0].trim() === '') result.shift(); + while (result.length > 1 && result[result.length - 1].trim() === '') result.pop(); + return result.length > 0 ? result : null; } /** * Extract the colocated ` — return the inner content. + * 3. Multi-line: `` on a later line — return + * the lines between them. */ function extractCss(lines, block, id) { const styleAttr = 'data-impeccable-css="' + id + '"'; @@ -287,6 +313,14 @@ function extractCss(lines, block, id) { const line = lines[i]; if (!inStyle && line.includes(styleAttr)) { + // Self-closing: nothing to carbonize. + if (/]*\/\s*>/.test(line)) return null; + // Same-line open + close: extract inner text. + const sameLine = line.match(/]*>([\s\S]*?)<\/style\s*>/); + if (sameLine) { + const inner = sameLine[1]; + return inner.length > 0 ? inner.split('\n') : null; + } inStyle = true; continue; // skip the ` to close on) + * - Same-line `` blocks + * - Multi-line `` blocks */ -function extractOriginal(lines, block) { - let inOriginal = false; +function stripStyleAndJoin(lines, block) { + const out = []; let inStyle = false; - let depth = 0; - const content = []; - for (let i = block.start; i <= block.end; i++) { - const line = lines[i]; + let line = lines[i]; - if (!inStyle && /]/.test(line)) { inStyle = true; continue; } - if (inStyle) { - if (line.trimStart().startsWith('')) inStyle = false; - continue; - } + if (!inStyle) { + // Strip any complete . + const closeIdx = line.search(/<\/style\s*>/); + if (closeIdx !== -1) { + inStyle = false; + out.push(line.slice(closeIdx).replace(/<\/style\s*>/, '')); + } + // else: skip line entirely } } + return out.join('\n'); +} - return content; +/** + * Find the inner content of `` inside `text`, + * handling nested same-tag elements via depth counting. `attrMatch` is a + * regex source fragment that must appear inside the opener tag. + * Returns the inner string (may be empty), or null if not found. + */ +function extractInnerByAttr(text, attrMatch) { + const openerRe = new RegExp('<([A-Za-z][A-Za-z0-9]*)\\b[^>]*' + attrMatch + '[^>]*>'); + const openMatch = text.match(openerRe); + if (!openMatch) return null; + + const tagName = openMatch[1]; + const innerStart = openMatch.index + openMatch[0].length; + + // Match any opener or closer of this tag name after innerStart. + // (Does not match self-closing , which doesn't contribute to depth.) + const tagRe = new RegExp('<(?:/)?' + tagName + '\\b[^>]*>', 'g'); + tagRe.lastIndex = innerStart; + + let depth = 1; + let m; + while ((m = tagRe.exec(text))) { + const isClose = m[0].startsWith('$/.test(m[0]); + if (isClose) { + depth--; + if (depth === 0) return text.slice(innerStart, m.index); + } else if (!isSelfClose) { + depth++; + } + } + return null; +} + +/** + * Extract the original element content from within the variant wrapper. + * Returns an array of lines. + */ +function extractOriginal(lines, block) { + const text = stripStyleAndJoin(lines, block); + const inner = extractInnerByAttr(text, 'data-impeccable-variant="original"'); + if (inner === null) return []; + return inner.split('\n'); } /** * Extract a specific variant's inner content (stripping the wrapper div). * Returns an array of lines, or null if not found. - * - * Skip ')) inStyle = false; - continue; - } - - if (!inVariant && line.includes('data-impeccable-variant="' + variantNum + '"')) { - inVariant = true; - depth = 1; - continue; // skip the opening
- } - - if (inVariant) { - const opens = (line.match(/]/g) || []).length; - const closes = (line.match(/<\/div\s*>/g) || []).length; - depth += opens - closes; - - if (depth <= 0) break; // closing
of the variant wrapper - content.push(line); - } - } - - return content.length > 0 ? content : null; + const text = stripStyleAndJoin(lines, block); + const inner = extractInnerByAttr(text, 'data-impeccable-variant="' + variantNum + '"'); + if (inner === null) return null; + const result = inner.split('\n'); + // Collapse a lone empty leading/trailing line (common after string splice). + while (result.length > 1 && result[0].trim() === '') result.shift(); + while (result.length > 1 && result[result.length - 1].trim() === '') result.pop(); + return result.length > 0 ? result : null; } /** * Extract the colocated ` — return the inner content. + * 3. Multi-line: `` on a later line — return + * the lines between them. */ function extractCss(lines, block, id) { const styleAttr = 'data-impeccable-css="' + id + '"'; @@ -287,6 +313,14 @@ function extractCss(lines, block, id) { const line = lines[i]; if (!inStyle && line.includes(styleAttr)) { + // Self-closing: nothing to carbonize. + if (/]*\/\s*>/.test(line)) return null; + // Same-line open + close: extract inner text. + const sameLine = line.match(/]*>([\s\S]*?)<\/style\s*>/); + if (sameLine) { + const inner = sameLine[1]; + return inner.length > 0 ? inner.split('\n') : null; + } inStyle = true; continue; // skip the ` to close on) + * - Same-line `` blocks + * - Multi-line `` blocks */ -function extractOriginal(lines, block) { - let inOriginal = false; +function stripStyleAndJoin(lines, block) { + const out = []; let inStyle = false; - let depth = 0; - const content = []; - for (let i = block.start; i <= block.end; i++) { - const line = lines[i]; + let line = lines[i]; - if (!inStyle && /]/.test(line)) { inStyle = true; continue; } - if (inStyle) { - if (line.trimStart().startsWith('')) inStyle = false; - continue; - } + if (!inStyle) { + // Strip any complete . + const closeIdx = line.search(/<\/style\s*>/); + if (closeIdx !== -1) { + inStyle = false; + out.push(line.slice(closeIdx).replace(/<\/style\s*>/, '')); + } + // else: skip line entirely } } + return out.join('\n'); +} - return content; +/** + * Find the inner content of `` inside `text`, + * handling nested same-tag elements via depth counting. `attrMatch` is a + * regex source fragment that must appear inside the opener tag. + * Returns the inner string (may be empty), or null if not found. + */ +function extractInnerByAttr(text, attrMatch) { + const openerRe = new RegExp('<([A-Za-z][A-Za-z0-9]*)\\b[^>]*' + attrMatch + '[^>]*>'); + const openMatch = text.match(openerRe); + if (!openMatch) return null; + + const tagName = openMatch[1]; + const innerStart = openMatch.index + openMatch[0].length; + + // Match any opener or closer of this tag name after innerStart. + // (Does not match self-closing , which doesn't contribute to depth.) + const tagRe = new RegExp('<(?:/)?' + tagName + '\\b[^>]*>', 'g'); + tagRe.lastIndex = innerStart; + + let depth = 1; + let m; + while ((m = tagRe.exec(text))) { + const isClose = m[0].startsWith('$/.test(m[0]); + if (isClose) { + depth--; + if (depth === 0) return text.slice(innerStart, m.index); + } else if (!isSelfClose) { + depth++; + } + } + return null; +} + +/** + * Extract the original element content from within the variant wrapper. + * Returns an array of lines. + */ +function extractOriginal(lines, block) { + const text = stripStyleAndJoin(lines, block); + const inner = extractInnerByAttr(text, 'data-impeccable-variant="original"'); + if (inner === null) return []; + return inner.split('\n'); } /** * Extract a specific variant's inner content (stripping the wrapper div). * Returns an array of lines, or null if not found. - * - * Skip ')) inStyle = false; - continue; - } - - if (!inVariant && line.includes('data-impeccable-variant="' + variantNum + '"')) { - inVariant = true; - depth = 1; - continue; // skip the opening
- } - - if (inVariant) { - const opens = (line.match(/]/g) || []).length; - const closes = (line.match(/<\/div\s*>/g) || []).length; - depth += opens - closes; - - if (depth <= 0) break; // closing
of the variant wrapper - content.push(line); - } - } - - return content.length > 0 ? content : null; + const text = stripStyleAndJoin(lines, block); + const inner = extractInnerByAttr(text, 'data-impeccable-variant="' + variantNum + '"'); + if (inner === null) return null; + const result = inner.split('\n'); + // Collapse a lone empty leading/trailing line (common after string splice). + while (result.length > 1 && result[0].trim() === '') result.shift(); + while (result.length > 1 && result[result.length - 1].trim() === '') result.pop(); + return result.length > 0 ? result : null; } /** * Extract the colocated ` — return the inner content. + * 3. Multi-line: `` on a later line — return + * the lines between them. */ function extractCss(lines, block, id) { const styleAttr = 'data-impeccable-css="' + id + '"'; @@ -287,6 +313,14 @@ function extractCss(lines, block, id) { const line = lines[i]; if (!inStyle && line.includes(styleAttr)) { + // Self-closing: nothing to carbonize. + if (/]*\/\s*>/.test(line)) return null; + // Same-line open + close: extract inner text. + const sameLine = line.match(/]*>([\s\S]*?)<\/style\s*>/); + if (sameLine) { + const inner = sameLine[1]; + return inner.length > 0 ? inner.split('\n') : null; + } inStyle = true; continue; // skip the ` to close on) + * - Same-line `` blocks + * - Multi-line `` blocks */ -function extractOriginal(lines, block) { - let inOriginal = false; +function stripStyleAndJoin(lines, block) { + const out = []; let inStyle = false; - let depth = 0; - const content = []; - for (let i = block.start; i <= block.end; i++) { - const line = lines[i]; + let line = lines[i]; - if (!inStyle && /]/.test(line)) { inStyle = true; continue; } - if (inStyle) { - if (line.trimStart().startsWith('')) inStyle = false; - continue; - } + if (!inStyle) { + // Strip any complete . + const closeIdx = line.search(/<\/style\s*>/); + if (closeIdx !== -1) { + inStyle = false; + out.push(line.slice(closeIdx).replace(/<\/style\s*>/, '')); + } + // else: skip line entirely } } + return out.join('\n'); +} - return content; +/** + * Find the inner content of `` inside `text`, + * handling nested same-tag elements via depth counting. `attrMatch` is a + * regex source fragment that must appear inside the opener tag. + * Returns the inner string (may be empty), or null if not found. + */ +function extractInnerByAttr(text, attrMatch) { + const openerRe = new RegExp('<([A-Za-z][A-Za-z0-9]*)\\b[^>]*' + attrMatch + '[^>]*>'); + const openMatch = text.match(openerRe); + if (!openMatch) return null; + + const tagName = openMatch[1]; + const innerStart = openMatch.index + openMatch[0].length; + + // Match any opener or closer of this tag name after innerStart. + // (Does not match self-closing , which doesn't contribute to depth.) + const tagRe = new RegExp('<(?:/)?' + tagName + '\\b[^>]*>', 'g'); + tagRe.lastIndex = innerStart; + + let depth = 1; + let m; + while ((m = tagRe.exec(text))) { + const isClose = m[0].startsWith('$/.test(m[0]); + if (isClose) { + depth--; + if (depth === 0) return text.slice(innerStart, m.index); + } else if (!isSelfClose) { + depth++; + } + } + return null; +} + +/** + * Extract the original element content from within the variant wrapper. + * Returns an array of lines. + */ +function extractOriginal(lines, block) { + const text = stripStyleAndJoin(lines, block); + const inner = extractInnerByAttr(text, 'data-impeccable-variant="original"'); + if (inner === null) return []; + return inner.split('\n'); } /** * Extract a specific variant's inner content (stripping the wrapper div). * Returns an array of lines, or null if not found. - * - * Skip ')) inStyle = false; - continue; - } - - if (!inVariant && line.includes('data-impeccable-variant="' + variantNum + '"')) { - inVariant = true; - depth = 1; - continue; // skip the opening
- } - - if (inVariant) { - const opens = (line.match(/]/g) || []).length; - const closes = (line.match(/<\/div\s*>/g) || []).length; - depth += opens - closes; - - if (depth <= 0) break; // closing
of the variant wrapper - content.push(line); - } - } - - return content.length > 0 ? content : null; + const text = stripStyleAndJoin(lines, block); + const inner = extractInnerByAttr(text, 'data-impeccable-variant="' + variantNum + '"'); + if (inner === null) return null; + const result = inner.split('\n'); + // Collapse a lone empty leading/trailing line (common after string splice). + while (result.length > 1 && result[0].trim() === '') result.shift(); + while (result.length > 1 && result[result.length - 1].trim() === '') result.pop(); + return result.length > 0 ? result : null; } /** * Extract the colocated ` — return the inner content. + * 3. Multi-line: `` on a later line — return + * the lines between them. */ function extractCss(lines, block, id) { const styleAttr = 'data-impeccable-css="' + id + '"'; @@ -287,6 +313,14 @@ function extractCss(lines, block, id) { const line = lines[i]; if (!inStyle && line.includes(styleAttr)) { + // Self-closing: nothing to carbonize. + if (/]*\/\s*>/.test(line)) return null; + // Same-line open + close: extract inner text. + const sameLine = line.match(/]*>([\s\S]*?)<\/style\s*>/); + if (sameLine) { + const inner = sameLine[1]; + return inner.length > 0 ? inner.split('\n') : null; + } inStyle = true; continue; // skip the ` to close on) + * - Same-line `` blocks + * - Multi-line `` blocks */ -function extractOriginal(lines, block) { - let inOriginal = false; +function stripStyleAndJoin(lines, block) { + const out = []; let inStyle = false; - let depth = 0; - const content = []; - for (let i = block.start; i <= block.end; i++) { - const line = lines[i]; + let line = lines[i]; - if (!inStyle && /]/.test(line)) { inStyle = true; continue; } - if (inStyle) { - if (line.trimStart().startsWith('')) inStyle = false; - continue; - } + if (!inStyle) { + // Strip any complete . + const closeIdx = line.search(/<\/style\s*>/); + if (closeIdx !== -1) { + inStyle = false; + out.push(line.slice(closeIdx).replace(/<\/style\s*>/, '')); + } + // else: skip line entirely } } + return out.join('\n'); +} - return content; +/** + * Find the inner content of `` inside `text`, + * handling nested same-tag elements via depth counting. `attrMatch` is a + * regex source fragment that must appear inside the opener tag. + * Returns the inner string (may be empty), or null if not found. + */ +function extractInnerByAttr(text, attrMatch) { + const openerRe = new RegExp('<([A-Za-z][A-Za-z0-9]*)\\b[^>]*' + attrMatch + '[^>]*>'); + const openMatch = text.match(openerRe); + if (!openMatch) return null; + + const tagName = openMatch[1]; + const innerStart = openMatch.index + openMatch[0].length; + + // Match any opener or closer of this tag name after innerStart. + // (Does not match self-closing , which doesn't contribute to depth.) + const tagRe = new RegExp('<(?:/)?' + tagName + '\\b[^>]*>', 'g'); + tagRe.lastIndex = innerStart; + + let depth = 1; + let m; + while ((m = tagRe.exec(text))) { + const isClose = m[0].startsWith('$/.test(m[0]); + if (isClose) { + depth--; + if (depth === 0) return text.slice(innerStart, m.index); + } else if (!isSelfClose) { + depth++; + } + } + return null; +} + +/** + * Extract the original element content from within the variant wrapper. + * Returns an array of lines. + */ +function extractOriginal(lines, block) { + const text = stripStyleAndJoin(lines, block); + const inner = extractInnerByAttr(text, 'data-impeccable-variant="original"'); + if (inner === null) return []; + return inner.split('\n'); } /** * Extract a specific variant's inner content (stripping the wrapper div). * Returns an array of lines, or null if not found. - * - * Skip ')) inStyle = false; - continue; - } - - if (!inVariant && line.includes('data-impeccable-variant="' + variantNum + '"')) { - inVariant = true; - depth = 1; - continue; // skip the opening
- } - - if (inVariant) { - const opens = (line.match(/]/g) || []).length; - const closes = (line.match(/<\/div\s*>/g) || []).length; - depth += opens - closes; - - if (depth <= 0) break; // closing
of the variant wrapper - content.push(line); - } - } - - return content.length > 0 ? content : null; + const text = stripStyleAndJoin(lines, block); + const inner = extractInnerByAttr(text, 'data-impeccable-variant="' + variantNum + '"'); + if (inner === null) return null; + const result = inner.split('\n'); + // Collapse a lone empty leading/trailing line (common after string splice). + while (result.length > 1 && result[0].trim() === '') result.shift(); + while (result.length > 1 && result[result.length - 1].trim() === '') result.pop(); + return result.length > 0 ? result : null; } /** * Extract the colocated ` — return the inner content. + * 3. Multi-line: `` on a later line — return + * the lines between them. */ function extractCss(lines, block, id) { const styleAttr = 'data-impeccable-css="' + id + '"'; @@ -287,6 +313,14 @@ function extractCss(lines, block, id) { const line = lines[i]; if (!inStyle && line.includes(styleAttr)) { + // Self-closing: nothing to carbonize. + if (/]*\/\s*>/.test(line)) return null; + // Same-line open + close: extract inner text. + const sameLine = line.match(/]*>([\s\S]*?)<\/style\s*>/); + if (sameLine) { + const inner = sameLine[1]; + return inner.length > 0 ? inner.split('\n') : null; + } inStyle = true; continue; // skip the ` to close on) + * - Same-line `` blocks + * - Multi-line `` blocks */ -function extractOriginal(lines, block) { - let inOriginal = false; +function stripStyleAndJoin(lines, block) { + const out = []; let inStyle = false; - let depth = 0; - const content = []; - for (let i = block.start; i <= block.end; i++) { - const line = lines[i]; + let line = lines[i]; - if (!inStyle && /]/.test(line)) { inStyle = true; continue; } - if (inStyle) { - if (line.trimStart().startsWith('')) inStyle = false; - continue; - } + if (!inStyle) { + // Strip any complete . + const closeIdx = line.search(/<\/style\s*>/); + if (closeIdx !== -1) { + inStyle = false; + out.push(line.slice(closeIdx).replace(/<\/style\s*>/, '')); + } + // else: skip line entirely } } + return out.join('\n'); +} - return content; +/** + * Find the inner content of `` inside `text`, + * handling nested same-tag elements via depth counting. `attrMatch` is a + * regex source fragment that must appear inside the opener tag. + * Returns the inner string (may be empty), or null if not found. + */ +function extractInnerByAttr(text, attrMatch) { + const openerRe = new RegExp('<([A-Za-z][A-Za-z0-9]*)\\b[^>]*' + attrMatch + '[^>]*>'); + const openMatch = text.match(openerRe); + if (!openMatch) return null; + + const tagName = openMatch[1]; + const innerStart = openMatch.index + openMatch[0].length; + + // Match any opener or closer of this tag name after innerStart. + // (Does not match self-closing , which doesn't contribute to depth.) + const tagRe = new RegExp('<(?:/)?' + tagName + '\\b[^>]*>', 'g'); + tagRe.lastIndex = innerStart; + + let depth = 1; + let m; + while ((m = tagRe.exec(text))) { + const isClose = m[0].startsWith('$/.test(m[0]); + if (isClose) { + depth--; + if (depth === 0) return text.slice(innerStart, m.index); + } else if (!isSelfClose) { + depth++; + } + } + return null; +} + +/** + * Extract the original element content from within the variant wrapper. + * Returns an array of lines. + */ +function extractOriginal(lines, block) { + const text = stripStyleAndJoin(lines, block); + const inner = extractInnerByAttr(text, 'data-impeccable-variant="original"'); + if (inner === null) return []; + return inner.split('\n'); } /** * Extract a specific variant's inner content (stripping the wrapper div). * Returns an array of lines, or null if not found. - * - * Skip ')) inStyle = false; - continue; - } - - if (!inVariant && line.includes('data-impeccable-variant="' + variantNum + '"')) { - inVariant = true; - depth = 1; - continue; // skip the opening
- } - - if (inVariant) { - const opens = (line.match(/]/g) || []).length; - const closes = (line.match(/<\/div\s*>/g) || []).length; - depth += opens - closes; - - if (depth <= 0) break; // closing
of the variant wrapper - content.push(line); - } - } - - return content.length > 0 ? content : null; + const text = stripStyleAndJoin(lines, block); + const inner = extractInnerByAttr(text, 'data-impeccable-variant="' + variantNum + '"'); + if (inner === null) return null; + const result = inner.split('\n'); + // Collapse a lone empty leading/trailing line (common after string splice). + while (result.length > 1 && result[0].trim() === '') result.shift(); + while (result.length > 1 && result[result.length - 1].trim() === '') result.pop(); + return result.length > 0 ? result : null; } /** * Extract the colocated ` — return the inner content. + * 3. Multi-line: `` on a later line — return + * the lines between them. */ function extractCss(lines, block, id) { const styleAttr = 'data-impeccable-css="' + id + '"'; @@ -287,6 +313,14 @@ function extractCss(lines, block, id) { const line = lines[i]; if (!inStyle && line.includes(styleAttr)) { + // Self-closing: nothing to carbonize. + if (/]*\/\s*>/.test(line)) return null; + // Same-line open + close: extract inner text. + const sameLine = line.match(/]*>([\s\S]*?)<\/style\s*>/); + if (sameLine) { + const inner = sameLine[1]; + return inner.length > 0 ? inner.split('\n') : null; + } inStyle = true; continue; // skip the line-by-line. JSX self-closing block should also be treated as a + // single skipped unit; the line has both open and close tags. + it('finds the accepted variant after a single-line block', () => { + const html = ` + +
+

original

+ +

variant one

+

variant two

+

variant three

+
+ +`; + writeFileSync(join(tmp, 'page.html'), html); + + const result = runAccept(tmp, ['--id', 'ONELINE', '--variant', '3']); + assert.equal(result.handled, true, `accept should succeed: ${JSON.stringify(result)}`); + + const after = readFileSync(join(tmp, 'page.html'), 'utf-8'); + assert.ok(after.includes('data-impeccable-variant="3"'), 'accepted wrapper for variant 3 present'); + assert.ok(after.includes('variant three'), 'variant 3 content kept'); + assert.ok(!after.includes('variant two'), 'other variant content dropped'); + }); + + // Baseline: the standard multi-line case must keep working. + it('finds the accepted variant after a multi-line block (regression baseline)', () => { + const html = ` + +
+

original

+ +

variant one

+

variant two

+
+ +`; + writeFileSync(join(tmp, 'page.html'), html); + + const result = runAccept(tmp, ['--id', 'MULTI', '--variant', '1']); + assert.equal(result.handled, true, `accept should succeed: ${JSON.stringify(result)}`); + + const after = readFileSync(join(tmp, 'page.html'), 'utf-8'); + assert.ok(after.includes('data-impeccable-variant="1"'), 'accepted wrapper for variant 1 present'); + assert.ok(after.includes('variant one'), 'variant 1 content kept'); + }); + + // Discard must restore the original element after a self-closing