Skip to content

Commit

Permalink
Add yamlFrontmatter language
Browse files Browse the repository at this point in the history
FEATURE: `yamlFrontmatter` can now be used to wrap a language with a YAML frontmatter.

See https://discuss.codemirror.net/t/how-to-integrate-yaml-front-matter-in-codemirror-6-with-markdown/8092
  • Loading branch information
marijnh committed Apr 7, 2024
1 parent 8f9d75e commit 9701f4d
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 3 deletions.
9 changes: 8 additions & 1 deletion README.md
Expand Up @@ -36,4 +36,11 @@ The initial implementation of this package was funded by [Braintrust Data](https
parser</a>, extended with
highlighting and indentation information.</p>
</dd>
</dl>
<dt id="user-content-yamlfrontmatter">
<code><strong><a href="#user-content-yamlfrontmatter">yamlFrontmatter</a></strong>(<a id="user-content-yamlfrontmatter^config" href="#user-content-yamlfrontmatter^config">config</a>: {content: <a href="https://codemirror.net/docs/ref#language.Language">Language</a> | <a href="https://codemirror.net/docs/ref#language.LanguageSupport">LanguageSupport</a>}) → <a href="https://codemirror.net/docs/ref#language.LanguageSupport">LanguageSupport</a></code></dt>

<dd><p>Returns language support for a document parsed as <code>config.content</code>
with an optional YAML &quot;frontmatter&quot; delimited by lines that
contain three dashes.</p>
</dd>
</dl>
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -30,6 +30,7 @@
"@codemirror/language": "^6.0.0",
"@codemirror/state": "^6.0.0",
"@lezer/common": "^1.2.0",
"@lezer/highlight": "^1.2.0",
"@lezer/yaml": "^1.0.0"
},
"devDependencies": {
Expand Down
2 changes: 2 additions & 0 deletions src/README.md
Expand Up @@ -26,3 +26,5 @@ The initial implementation of this package was funded by [Braintrust Data](https
@yaml

@yamlLanguage

@yamlFrontmatter
14 changes: 14 additions & 0 deletions src/frontmatter.grammar
@@ -0,0 +1,14 @@
@precedence { frontmatter }

@top Document { Frontmatter? Body }

Frontmatter { DashLine FrontmatterContent { line* } DashLine }
DashLine { !frontmatter dashLine }
Body { (line | dashLine)* }

@tokens {
lineEnd { "\r" | "\n" }
dashLine { "---" (lineEnd | @eof) }
line { ![\n\r]* lineEnd | ![\n\r]+ @eof }
@precedence { dashLine line }
}
2 changes: 2 additions & 0 deletions src/frontmatter.grammar.d.ts
@@ -0,0 +1,2 @@
import {LRParser} from "@lezer/lr"
export declare const parser: LRParser
28 changes: 26 additions & 2 deletions src/yaml.ts
@@ -1,7 +1,9 @@
import {parser} from "@lezer/yaml"
import {LRLanguage, delimitedIndent, indentNodeProp,
foldNodeProp, foldInside, LanguageSupport} from "@codemirror/language"
import {SyntaxNode} from "@lezer/common"
foldNodeProp, foldInside, Language, LanguageSupport} from "@codemirror/language"
import {SyntaxNode, parseMixed} from "@lezer/common"
import {tags, styleTags} from "@lezer/highlight"
import {parser as frontmatterParser} from "./frontmatter.grammar"

/// A language provider based on the [Lezer YAML
/// parser](https://github.com/lezer-parser/yaml), extended with
Expand Down Expand Up @@ -50,3 +52,25 @@ export const yamlLanguage = LRLanguage.define({
export function yaml() {
return new LanguageSupport(yamlLanguage)
}

const frontmatterLanguage = LRLanguage.define({
name: "yaml-frontmatter",
parser: frontmatterParser.configure({
props: [styleTags({DashLine: tags.meta})]
})
})

/// Returns language support for a document parsed as `config.content`
/// with an optional YAML "frontmatter" delimited by lines that
/// contain three dashes.
export function yamlFrontmatter(config: {content: Language | LanguageSupport}) {
let {language, support} = config.content instanceof LanguageSupport ? config.content
: {language: config.content, support: []}
return new LanguageSupport(frontmatterLanguage.configure({
wrap: parseMixed(node => {
return node.name == "FrontmatterContent" ? {parser: yamlLanguage.parser}
: node.name == "Body" ? {parser: language.parser}
: null
})
}), support)
}

0 comments on commit 9701f4d

Please sign in to comment.