1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
x20 x20 x3 x9 x9 x9 x9 x3 x9 x6 x6 x3 x3 x3 x6 x3 x3 x3 x3 x3 x3 x3 x3 x3 x3 x3 x3 |
I I |
// Imports
import type { MarkdownIt } from "../types.ts"
import { parse } from "@std/yaml/parse"
/**
* Support for frontmatter.
*
* Passing `metadata: true` to the markdown rendering method is required to retrieve the frontmatter.
* The frontmatter is automatically parsed as YAML.
*
* ```md
* ---
* title: foo
* ---
* ```
* ```ts
* import { Renderer } from "../renderer.ts"
*
* const markdown = new Renderer({ frontmatter: true })
* const { metadata } = markdown.render("---\ntitle: foo\n---\nbar", { metadata: true })
* console.log(metadata.frontmatter) // { title: "foo" }
* ```
*/
export default function frontmatter(engine: MarkdownIt): void {
engine.block.ruler.before("table", "frontmatter", (state, startLine, endLine, silent) => {
if ((startLine !== 0) || (state.blkIndent !== 0) || (state.tShift[0] > 0))
return false
if (state.src.slice(state.bMarks[0], state.eMarks[0]).trimEnd() !== "---")
return false
let close = -1
for (let line = 1; line < endLine; line++) {
const text = state.src.slice(state.bMarks[line], state.eMarks[line]).trimEnd()
if ((text === "---") || (text === "...")) {
close = line
break
}
}
if (close < 0)
return false
let parsed
try {
parsed = parse(state.getLines(1, close, 0, false))
} catch {
return false
}
if (!silent) {
const env = state.env as { metadata?: Record<PropertyKey, unknown> }
env.metadata ??= {}
env.metadata.frontmatter = parsed
state.line = close + 1
}
return true
})
}
|