diff --git a/scripts/apply-ticket.mjs b/scripts/apply-ticket.mjs index af3abc3..8892e19 100755 --- a/scripts/apply-ticket.mjs +++ b/scripts/apply-ticket.mjs @@ -185,6 +185,20 @@ function unquoteBlock(s) { .trim(); } +function extractAnchorIdAnywhere(text) { + const s = String(text || ""); + // accepte "#p-3-abcdef12" ou "p-3-abcdef12" + const m = s.match(/#?(p-\d+-[0-9a-f]{8})/i); + return m ? m[1] : ""; +} + +function extractCheminFromAnyUrl(body) { + const s = String(body || ""); + // Cherche un chemin du type "/archicratie/prologue/#p-..." + const m = s.match(/(\/[a-z0-9\-]+\/[a-z0-9\-\/]+\/)#p-\d+-[0-9a-f]{8}/i); + return m ? m[1] : ""; +} + async function readHtmlParagraphText(htmlPath, anchorId) { const html = await fs.readFile(htmlPath, "utf-8"); const re = new RegExp(`]*\\bid=["']${escapeRegExp(anchorId)}["'][^>]*>([\\s\\S]*?)<\\/p>`, "i"); @@ -423,12 +437,24 @@ async function main() { const body = String(issue.body || "").replace(/\r\n/g, "\n"); - let chemin = pickLine(body, "Chemin") || pickHeadingValue(body, "Chemin"); - let ancre = pickLine(body, "Ancre") || pickHeadingValue(body, "Ancre paragraphe") || pickHeadingValue(body, "Ancre"); - chemin = normalizeChemin(chemin); + const title = String(issue.title || ""); + + let chemin = + pickLine(body, "Chemin") || + pickHeadingValue(body, "Chemin") || + extractCheminFromAnyUrl(body); + + let ancre = + pickLine(body, "Ancre") || + pickHeadingValue(body, "Ancre paragraphe") || + pickHeadingValue(body, "Ancre"); + ancre = (ancre || "").trim(); if (ancre.startsWith("#")) ancre = ancre.slice(1); + // ✅ fallback si le ticket est mal formé + if (!ancre) ancre = extractAnchorIdAnywhere(title) || extractAnchorIdAnywhere(body); + const currentFull = pickSection(body, ["Texte actuel (copie exacte du paragraphe)", "## Texte actuel (copie exacte du paragraphe)"]); const currentEx = pickSection(body, ["Texte actuel (extrait)", "## Assertion / passage à vérifier", "Assertion / passage à vérifier"]); const texteActuel = unquoteBlock(currentFull || currentEx);