You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

57 lines
1.6 KiB

/** 匹配以 --- 开头/结尾的 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()
}