Markdown is a popular markup language used to format text. It's great for documentation, blog posts, and other types of written content. Frontmatter is a feature of Markdown that allows you to store metadata such as the title, author, date, tags, and other information in a YAML block at the top of the file. YAML itself is yet another markup language -- literally what the acronym stands for -- and a superset of JSON that supports comments, multi-line strings, arrays, and other features.
.NET has two popular and well-supported libraries to help parse frontmatter:
- Markdig to parse Markdown into structured blocks.
- YamlDotNet to deserialize YAML content into a dictionary or object.
With the following sample markdown content:
---
title: How to Parse Markdown Frontmatter
desc: Article describing how to parse YAML frontmatter from a Markdown file.
posted: 2020-01-01
tags: [software, dotnet]
---
# Document Title
With some text
This is a code sample to parse and extract frontmatter:
using System;
using System.Linq;
using System.Collections.Generic;
using Markdig;
using Markdig.Extensions.Yaml;
using Markdig.Syntax;
using YamlDotNet.Serialization;
var markdown = "...";
// create a markdown parsing pipeline (with YAML frontmatter support)
// and parse the markdown text into blocks
var pipeline = new MarkdownPipelineBuilder().UseYamlFrontMatter().Build();
var document = Markdown.Parse(markdown, pipeline);
// extract the first YAML frontmatter block
// and assemble it into a string
var yamlBlock = document.Descendants<YamlFrontMatterBlock>().FirstOrDefault();
var yaml = yamlBlock?.Lines.ToString() ?? "";
// create a YAML deserializer
// and deserialize YAML into a dictionary (or object)
var deserializer = new DeserializerBuilder().Build();
var frontmatter = deserializer.Deserialize<Dictionary<string, object>>(yaml);
Console.WriteLine(frontmatter["title"]);
YamlDotNet can also deserialize into a strongly typed object:
public class PostFrontMatter
{
[YamlMember(Alias = "title")]
public string? Title { get; set; }
[YamlMember(Alias = "desc")]
public string? Description { get; set; }
[YamlMember(Alias = "posted")]
public DateTime Posted { get; set; }
[YamlMember(Alias = "tags")]
public List<string> Tags { get; set; } = new();
}
var frontmatter = deserializer.Deserialize<PostFrontMatter>(yaml);
Console.WriteLine(frontmatter.Title);
Working example on .NET Fiddle: https://dotnetfiddle.net/aV9TZL