Page Builder parser: tolerate label variants (missing colon, markdown emphasis) — first live build failed because the model wrote STORY without a colon
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+22
-10
@@ -46,19 +46,31 @@ function buildPrompt(input) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Locate each label wherever it appears and slice between them. Deliberately
|
||||||
|
// forgiving: the colon is optional (models drop it — "STORY" alone broke the
|
||||||
|
// first build), markdown emphasis is tolerated, order is taken from the text.
|
||||||
function parseSections(raw) {
|
function parseSections(raw) {
|
||||||
const out = { headline: '', subhead: '', story: [], bullets: [], closing: '' };
|
const out = { headline: '', subhead: '', story: [], bullets: [], closing: '' };
|
||||||
const text = String(raw || '').replace(/\r/g, '');
|
const text = String(raw || '').replace(/\r/g, '');
|
||||||
const grab = function (label, next) {
|
const LABELS = ['HEADLINE', 'SUBHEAD', 'STORY', 'BULLETS', 'CLOSING'];
|
||||||
const re = new RegExp(label + ':\\s*([\\s\\S]*?)(?=\\n(?:' + next + '):|$)', 'i');
|
const found = [];
|
||||||
const m = text.match(re);
|
LABELS.forEach(function (L) {
|
||||||
return m ? m[1].trim() : '';
|
const m = text.match(new RegExp('(?:^|\\n)[ \\t]*[*#>\\s]*' + L + '[ \\t]*[*#]*[ \\t]*:?[ \\t]*[*#]*[ \\t]*', 'i'));
|
||||||
};
|
if (m) found.push({ label: L, at: m.index, from: m.index + m[0].length });
|
||||||
out.headline = grab('HEADLINE', 'SUBHEAD|STORY|BULLETS|CLOSING').split('\n')[0].trim().slice(0, 90);
|
});
|
||||||
out.subhead = grab('SUBHEAD', 'STORY|BULLETS|CLOSING').split('\n')[0].trim().slice(0, 200);
|
if (!found.length) return out;
|
||||||
out.story = grab('STORY', 'BULLETS|CLOSING').split(/\n{2,}/).map(function (p) { return p.replace(/\s+/g, ' ').trim(); }).filter(Boolean).slice(0, 4);
|
found.sort(function (a, b) { return a.at - b.at; });
|
||||||
out.bullets = grab('BULLETS', 'CLOSING').split('\n').map(function (b) { return b.replace(/^[-•*]\s*/, '').trim(); }).filter(Boolean).slice(0, 4);
|
const seg = {};
|
||||||
out.closing = grab('CLOSING', 'ZZZZ').replace(/\s+/g, ' ').trim().slice(0, 400);
|
found.forEach(function (f, i) {
|
||||||
|
const end = i + 1 < found.length ? found[i + 1].at : text.length;
|
||||||
|
// strip any leftover markdown emphasis the label pattern didn't absorb
|
||||||
|
seg[f.label] = text.slice(f.from, end).replace(/^[*#\s]+/, '').replace(/[*#\s]+$/, '').trim();
|
||||||
|
});
|
||||||
|
out.headline = (seg.HEADLINE || '').split('\n')[0].replace(/^["“]|["”]$/g, '').trim().slice(0, 90);
|
||||||
|
out.subhead = (seg.SUBHEAD || '').split('\n')[0].trim().slice(0, 200);
|
||||||
|
out.story = (seg.STORY || '').split(/\n{2,}/).map(function (p) { return p.replace(/\s+/g, ' ').trim(); }).filter(Boolean).slice(0, 4);
|
||||||
|
out.bullets = (seg.BULLETS || '').split('\n').map(function (b) { return b.replace(/^[-•*]\s*/, '').trim(); }).filter(Boolean).slice(0, 4);
|
||||||
|
out.closing = (seg.CLOSING || '').replace(/\s+/g, ' ').trim().slice(0, 400);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user