add parsing for YAML frontmatter

This doesn't parse the YAML, but recognizes the YAML markers in
markdown.
This commit is contained in:
Eric Rykwalder 2022-03-05 13:28:07 -05:00
parent 8a6998c413
commit d1dc4afca6
2 changed files with 124 additions and 0 deletions

View file

@ -21,6 +21,9 @@ const specParser = new SpecParser(parser, {
fM: "FootnoteMark",
fL: "FootnoteLabel",
FR: "FootnoteReference",
YF: "YAMLFrontMatter",
ym: "YAMLMarker",
yc: "YAMLContent",
});
function test(name: string, spec: string, p = parser, only = false) {
@ -162,4 +165,83 @@ Line 5}
{BL:{LI:{l:-} {P:Line 6}}}
`
);
test(
"Frontmatter",
`
{YF:{ym:---}
{yc:tags: blah}
{ym:---}}
{HR:---}
{P:some text}
{SH2:A header
{h:---}}
`
);
test(
"Frontmatter (trailing text)",
`
{YF:{ym:---}
{yc:tags: blah}
{ym:---}}{P:test}
{HR:---}
{P:some text}
{SH2:A header
{h:---}}
`
);
test(
"Not Frontmatter (no close)",
`
{HR:---}
{P:some text}
{SH1:A header
{h:===}}
`
);
test(
"Not Frontmatter (close indented)",
`
{HR:---}
{P:some text}
{HR:---}
`
);
test(
"Not Frontmatter (space after open)",
`
{HR:--- }
{P:some text}
{HR:---}
`
);
test(
"Not Frontmatter (data before open)",
`
{P:some text}
{HR:---}
{P:some text}
{HR:---}
`
);
});

View file

@ -1,3 +1,4 @@
import { Input, PartialParse, Tree } from "@lezer/common";
import {
BlockContext,
Element,
@ -11,6 +12,13 @@ import {
Table,
} from "@lezer/markdown";
declare module "@lezer/markdown" {
class BlockContext {
readonly input: Input;
checkedYaml: boolean | null;
}
}
/*
Copyright (C) 2020 by Marijn Haverbeke <marijnh@gmail.com> and others
https://github.com/lezer-parser/markdown/blob/f49eb8c8c82cfe45aa213ca1fe2cebc95305b88b/LICENSE
@ -279,8 +287,42 @@ export const Footnote: MarkdownConfig = {
],
};
export const YAMLFrontMatter: MarkdownConfig = {
defineNodes: ["YAMLFrontMatter", "YAMLMarker", "YAMLContent"],
parseBlock: [
{
name: "YAMLFrontMatter",
parse(cx, line) {
if (cx.checkedYaml) {
return false;
}
cx.checkedYaml = true;
const fmRegex = /(^|^\s*\n)(---\n.+?\n---)/s;
const match = fmRegex.exec(cx.input.chunk(0));
if (match) {
const start = match[1].length;
const end = start + match[2].length;
cx.addElement(
cx.elt("YAMLFrontMatter", start, end, [
cx.elt("YAMLMarker", start, start + 3),
cx.elt("YAMLContent", start + 4, end - 4),
cx.elt("YAMLMarker", end - 3, end),
])
);
while (cx.lineStart + line.text.length < end && cx.nextLine()) {}
line.pos = 3;
return true;
}
return false;
},
before: "LinkReference",
},
],
};
export const ObsidianMDExtensions = [
Footnote,
YAMLFrontMatter,
InternalLink,
Strikethrough,
Table,