Spaces:
Runtime error
Runtime error
| /** | |
| * Minimal YAML frontmatter reader/writer for idea files. | |
| * Supports: scalars (string/number/bool), nested object (one level), inline arrays [a, b]. | |
| * Not a general YAML lib — kept simple intentionally. | |
| */ | |
| const DELIM = "---"; | |
| function parseScalar(raw) { | |
| const s = raw.trim(); | |
| if (s === "true") return true; | |
| if (s === "false") return false; | |
| if (s === "null") return null; | |
| if (/^-?\d+(\.\d+)?$/.test(s)) return Number(s); | |
| if (s.startsWith("[") && s.endsWith("]")) { | |
| const inner = s.slice(1, -1).trim(); | |
| if (!inner) return []; | |
| return inner.split(",").map((x) => parseScalar(x.trim())); | |
| } | |
| if ((s.startsWith('"') && s.endsWith('"')) || (s.startsWith("'") && s.endsWith("'"))) { | |
| return s.slice(1, -1); | |
| } | |
| return s; | |
| } | |
| export function parseFrontmatter(text) { | |
| if (typeof text !== "string") return null; | |
| if (!text.startsWith(`${DELIM}\n`)) return null; | |
| const rest = text.slice(DELIM.length + 1); | |
| const closeIdx = rest.indexOf(`\n${DELIM}`); | |
| if (closeIdx < 0) return null; | |
| const body = rest.slice(0, closeIdx); | |
| const out = {}; | |
| let currentNested = null; | |
| for (const line of body.split("\n")) { | |
| if (!line.trim()) continue; | |
| if (line.startsWith(" ") && currentNested) { | |
| const m = line.match(/^\s{2}([\w_-]+):\s*(.*)$/); | |
| if (m) currentNested[m[1]] = parseScalar(m[2]); | |
| continue; | |
| } | |
| const m = line.match(/^([\w_-]+):\s*(.*)$/); | |
| if (!m) continue; | |
| const key = m[1]; | |
| const val = m[2]; | |
| if (val === "") { | |
| currentNested = {}; | |
| out[key] = currentNested; | |
| } else { | |
| currentNested = null; | |
| out[key] = parseScalar(val); | |
| } | |
| } | |
| return out; | |
| } | |
| function serializeScalar(v) { | |
| if (v === null) return "null"; | |
| if (typeof v === "boolean") return String(v); | |
| if (typeof v === "number") return String(v); | |
| if (Array.isArray(v)) return `[${v.map(serializeScalar).join(", ")}]`; | |
| return String(v); | |
| } | |
| export function serializeFrontmatter(meta, body) { | |
| const lines = [DELIM]; | |
| for (const [k, v] of Object.entries(meta)) { | |
| if (v && typeof v === "object" && !Array.isArray(v)) { | |
| lines.push(`${k}:`); | |
| for (const [nk, nv] of Object.entries(v)) { | |
| lines.push(` ${nk}: ${serializeScalar(nv)}`); | |
| } | |
| } else { | |
| lines.push(`${k}: ${serializeScalar(v)}`); | |
| } | |
| } | |
| lines.push(DELIM, "", body); | |
| return lines.join("\n"); | |
| } | |
| export function stripFrontmatter(text) { | |
| if (typeof text !== "string") return text; | |
| if (!text.startsWith(`${DELIM}\n`)) return text; | |
| const rest = text.slice(DELIM.length + 1); | |
| const closeIdx = rest.indexOf(`\n${DELIM}`); | |
| if (closeIdx < 0) return text; | |
| return rest.slice(closeIdx + DELIM.length + 1).replace(/^\n+/, ""); | |
| } | |