5 changed files with 93 additions and 6 deletions
@ -0,0 +1,57 @@ |
|||
/** 匹配以 --- 开头/结尾的 YAML front matter(全文开头) */ |
|||
const FRONT_MATTER_RE = /^---[\t ]*\r?\n([\s\S]*?)\r?\n---[\t ]*(?:\r?\n|$)([\s\S]*)$/ |
|||
|
|||
export function splitFrontMatter(markdown: string): { front: string | null; body: string } { |
|||
const s = markdown.replace(/^\uFEFF/, "") |
|||
const m = FRONT_MATTER_RE.exec(s) |
|||
if (!m) { |
|||
return { front: null, body: markdown } |
|||
} |
|||
return { front: m[1].trim(), body: m[2] } |
|||
} |
|||
|
|||
/** 正文渲染用:去掉 front matter,避免把元数据块排进 HTML */ |
|||
export function stripFrontMatter(markdown: string): string { |
|||
return splitFrontMatter(markdown).body |
|||
} |
|||
|
|||
function pickYamlScalar(block: string, key: string): string { |
|||
const lines = block.split(/\r?\n/) |
|||
const prefix = `${key}:` |
|||
for (const line of lines) { |
|||
const t = line.trim() |
|||
if (!t.startsWith(prefix)) { |
|||
continue |
|||
} |
|||
let v = t.slice(prefix.length).trim() |
|||
if (!v) { |
|||
return "" |
|||
} |
|||
if ( |
|||
(v.startsWith('"') && v.endsWith('"')) || |
|||
(v.startsWith("'") && v.endsWith("'")) |
|||
) { |
|||
return v.slice(1, -1) |
|||
} |
|||
return v |
|||
} |
|||
return "" |
|||
} |
|||
|
|||
/** 列表摘要:优先 `desc`,其次 `description`(简单标量行) */ |
|||
export function extractFrontMatterDesc(markdown: string): string { |
|||
const { front } = splitFrontMatter(markdown) |
|||
if (!front) { |
|||
return "" |
|||
} |
|||
const d = pickYamlScalar(front, "desc") || pickYamlScalar(front, "description") |
|||
return d.trim() |
|||
} |
|||
|
|||
export function listCardSummaryFromPostBody(bodyMarkdown: string, dbExcerpt: string): string { |
|||
const fromFm = extractFrontMatterDesc(bodyMarkdown) |
|||
if (fromFm) { |
|||
return fromFm |
|||
} |
|||
return (dbExcerpt ?? "").trim() |
|||
} |
|||
Loading…
Reference in new issue