redhat-developer / vscode-yaml

YAML support for VS Code with built-in kubernetes syntax support
MIT License
665 stars 222 forks source link

Support YAML front matter in Markdown files #207

Open quintent opened 5 years ago

quintent commented 5 years ago

Summary

vscode-yaml should apply schema validation to YAML front matter in markdown files.

Description

YAML is often prepended to markdown files to provide structured metadata. This "front matter" pattern is commonly implemented by static site generators, including Hugo, Gatsby, Jekyll and Nikola. YAML Front Matter precedes all Markdown content. The file may or may not start with ---.

VScode recognizes YAML front matter in markdown files and formats it appropriately as long as there is not an initial --- (implemented here).vscode-yaml does not recognize YAML front matter, even when extension references are configured correctly.

vscode-yaml does support multiple YAML files delimited by ---, see #43. This works with or without an initial ---.

Reproduction

(1) Configure settings.json to use the same schema for YAML and Markdown files:

{
    "editor.minimap.enabled": false,
    "yaml.format.enable": true,
    "yaml.format.proseWrap": "always",
    "yaml.schemas": {
        "./my_schema.json": "*.yml",
        "./my_schema.json": "*.md"
    },
    "git.autofetch": true
}

(2) Create a YAML file as test.yml:

title: "A Blog Post"
date: 2019-07-07
draft: true

(3) Confirm that the vscode-yaml applies the schema to test.yml.

(4a) Create a Markdown file test.md with the same YAML contents in as front matter:

title: "A Blog Post"
date: 2019-07-07
draft: true
---
This is content of my blog post, which will be processed as Markdown.

(4b) Add an initial --- and save as test_initial_delimiter.md:

---
title: "A Blog Post"
date: 2019-07-07
draft: true
---
This is content of my blog post, which will be processed as Markdown.

(5) Confirm that vscode-yaml does not validate the schema of the YAML in either markdown file.

panoply commented 5 years ago

@JPinkney Don't know how far you are along with this and I haven't looked over this projects source but one way this can be achieved with a basic LS.

  1. Parse text document contents via onDidChangeContent() for frontmatter. A simple expression to grab inner content would be something like: /(?<=^---)[\s\S]+?(?=---)/ or you could just parse via index position.

  2. Create a new Yaml text document from parsed capture range, eg:TextDocument.create(document.uri, 'yaml', document.version, document.getText(/* parsed range */ ))

  3. Run validation / diagnostics on the newly created text document via while in the onDidChangeContent() function.

  4. Execute completions via the onCompletion() based on the range position of the documents frontmatter (so schemas and intellisense are applied accordingly).

Given that frontmatter can only be applied at the start of documents you won't need to recalculate offset positioning or even put much effort into the parsing side of things.

JPinkney commented 5 years ago

I haven't been able to implement this yet (and probably won't have the time for quite a while). That sounds like a good plan though :+1:

panoply commented 5 years ago

I might take a stab at it. I require YAML Intellisense in an LS I'm developing for Jekyll and can probably port it over to this project once stable.

gorkem commented 4 years ago

I think this should be implemented on the markdown extension to request forward front-matter language requests to vscode-yaml.

JulianCataldo commented 2 years ago

Hello, any update on this particular topic ?

I've resorted on work-arounds for now, as I can't live without YAML Schemas and Markdown editing: https://github.com/JulianCataldo/content-components

Thanks a lot !

julrichkieffer commented 2 years ago

To all:

It's not correct to assume all fenced blocks (---) contain YAML, nor that only 1 fenced block exists in a markdown file. The Markdown specification allows for many languages and multiple instances of fenced blocks to occur. So this thread is incompatiable with the specification.

@JulianCataldo:

I've resorted on work-arounds for now, as I can't live without YAML Schemas and Markdown editing: https://github.com/JulianCataldo/content-components

While unfamiliar with the use cases driving your statement above, your frustration may be misplaced by waiting on a feature not yet supported. Conversely, have you considered Dendron? With a dynamic taxonomy, driven by folders and file naming, each "class" of markdown file can have a YAML (JSON) schema enforced by configuration of this VSCode extension. Although there's Youtube content, I recommend you start your review here.

JulianCataldo commented 2 years ago

Thank you @julrichkieffer , I didn't know about the specs thing, as I it never occurred to me to have anything other than YAML before fences in an MD file. Also, I'll have a look on Dendron, thanks for pointing this out to me!

[EDIT] Dendron looks pretty cool, with some solid concepts, but it doesn't support JSON Schema :p It uses its own vocabulary, so no porting on regular frontend + further AJV validation is possible https://docs.dendron.so/notes/93418a5e-36d5-4251-9ff2-7380c99c9ab9/

JulianCataldo commented 2 years ago

For those who are familiar with unified and especially remark-lint, I've made this lint rule plugin which takes care of validating YAML embedded in markdown front matter against a JSON schema, with suggestions, etc.

https://github.com/JulianCataldo/remark-lint-frontmatter-schema

It's far less powerful than yaml-language-server + vscode-yaml, but at least, you will now have something to put your hands on ✌️. I use both for my all my YAML (vscode-yaml) and MDs (unifiedjs.vscode-remark) now.

WillsterJohnson commented 2 years ago

@julrichkieffer would it be possible to support explicit schemas in markdown fences?

For example it may be incorrect to outright target any fenced block, however if the block matches;

<!-- no content above -->
---
# yaml-language-server: $schema=pathHere
someYaml: here
---
<!-- rest of md file -->

Then a) it's definitely frontmatter, and b) the author of the file wants to validate this yaml with the given schema.

I'm not at all familiar with this projects inner magic, but it's probably possible to do the following when a markdown file is loaded;

Wouldn't this would be compatible with markdown's specification?

feritarou commented 12 months ago

@julrichkieffer would it be possible to support explicit schemas in markdown fences? ...

<!-- no content above -->
---
# yaml-language-server: $schema=pathHere
someYaml: here
---
<!-- rest of md file -->

Any news on this issue and especially on WillsterJohnson's suggestion quoted above? We're using YAML front-matter extensively for a complex content management system, where Markdown files can have different (large) sets of metadata, and this would be a huge improvement to our workflow.

vguhesan commented 10 months ago

+1