36 lines
1.2 KiB
TypeScript
36 lines
1.2 KiB
TypeScript
|
|
function unquote(v: string): string {
|
||
|
|
const m = /^(["'])(.*)\1$/.exec(v);
|
||
|
|
return m ? (m[2] ?? "") : v;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Lit un en-tête YAML simple (--- … ---) : paires `clé: valeur`, valeurs entre guillemets,
|
||
|
|
* et blocs `>` / `|` (lignes indentées jointes par des espaces). Pas de YAML imbriqué.
|
||
|
|
*/
|
||
|
|
export function parseFrontmatter(raw: string): { data: Record<string, string>; body: string } {
|
||
|
|
const text = raw.replace(/\r\n/g, "\n");
|
||
|
|
if (!text.startsWith("---\n")) return { data: {}, body: text };
|
||
|
|
const end = text.indexOf("\n---", 4);
|
||
|
|
if (end === -1) return { data: {}, body: text };
|
||
|
|
|
||
|
|
const lines = text.slice(4, end).split("\n");
|
||
|
|
const body = text.slice(end + 4).replace(/^[ \t]*\n?/, "");
|
||
|
|
|
||
|
|
const data: Record<string, string> = {};
|
||
|
|
for (let i = 0; i < lines.length; i++) {
|
||
|
|
const m = /^([A-Za-z0-9_-]+):\s*(.*)$/.exec(lines[i] ?? "");
|
||
|
|
if (!m) continue;
|
||
|
|
let value = (m[2] ?? "").trim();
|
||
|
|
if (value === "" || /^[>|][+-]?$/.test(value)) {
|
||
|
|
const parts: string[] = [];
|
||
|
|
while (i + 1 < lines.length && /^\s+\S/.test(lines[i + 1] ?? "")) {
|
||
|
|
i++;
|
||
|
|
parts.push((lines[i] ?? "").trim());
|
||
|
|
}
|
||
|
|
value = parts.join(" ");
|
||
|
|
}
|
||
|
|
data[m[1]!] = unquote(value);
|
||
|
|
}
|
||
|
|
return { data, body };
|
||
|
|
}
|