// frontmatter.mjs // Delt frontmatter-parse/skrive for okr-pluginen. Zero npm dependencies. // // Konsoliderer den dupliserte flate `get()`-parseren fra inject-okr-context.mjs // (:59-66) og coaching-hook.mjs (:20-27) til EN modul, med to korreksjoner mot // den gamle atferden: // 1. Linjeanker (`^\s*key:`, multiline) — key matcher kun ved linjestart // (modulo innrykk), aldri som substring midt i en annen key/verdi. Bevarer // first-match og nestet (innrykket) oppslag (load-bearing: inject:69). // 2. Trailing " #kommentar" strippes KUN fra USITERTE verdier. Siterte verdier // beholder en intern '#' ("A #B" -> A #B). Retter comment-leak-bugen der // `okr_frikoblet_fra_loenn: true # ...` lakk kommentaren inn i verdien. // // Tolererer fler-linje OKF-list-verdier (f.eks. `tags:`) uten krasj: get() paa // en list-key returnerer null (rest-av-linja er tom); list-elementer paa // foelgende linjer konsumeres aldri (ingen konsument leser tre-filenes `tags`). const FM_RE = /^---\n([\s\S]*?)\n---/; export function parseFrontmatter(content) { const match = String(content).match(FM_RE); const raw = match ? match[1] : null; const get = (key) => { if (raw === null) return null; const m = raw.match(new RegExp(`^\\s*${key}:\\s*(.*)$`, 'm')); if (!m) return null; let v = m[1].trim(); if (v === '') return null; const q = v[0]; if (q === '"' || q === "'") { const end = v.indexOf(q, 1); if (end !== -1) return v.slice(1, end); // intern '#' bevart v = v.slice(1); // uavsluttet quote: fall tilbake til resten } else { v = v.replace(/\s+#.*$/, '').trim(); // usitert: strip trailing kommentar } return v === '' ? null : v; }; return { raw, get }; } export function writeFrontmatter(fields) { const lines = ['---']; for (const [key, value] of Object.entries(fields)) { const s = String(value); // Siter naar verdien inneholder '#'/':' eller har kant-whitespace, slik at // round-trip via parseFrontmatter bevarer den eksakt (jf. siter-#-regelen). const needsQuote = /[#:]/.test(s) || /^\s|\s$/.test(s) || /^["']/.test(s); lines.push(`${key}: ${needsQuote ? JSON.stringify(s) : s}`); } lines.push('---'); return lines.join('\n') + '\n'; }