ruby 44 lines · 8 steps

Parsing YAML front matter in Ruby

A small class that splits a document's leading YAML block from its body and exposes the metadata as symbol keys.

Explained by highlit
1require "yaml"
2 
3class FrontMatter
4 DELIMITER = /\A---\s*\n(.*?)\n---\s*\n?(.*)\z/m
5 
6 attr_reader :metadata, :body
7 
8 def self.parse(source)
9 new(source).tap(&:parse)
10 end
11 
12 def initialize(source)
13 @source = source.to_s
14 @metadata = {}
15 @body = @source
16 end
17 
18 def parse
19 match = @source.match(DELIMITER)
20 return self unless match
21 
22 raw_yaml, @body = match.captures
23 @metadata = symbolize(YAML.safe_load(raw_yaml, permitted_classes: [Date, Time]) || {})
24 self
25 rescue Psych::SyntaxError => e
26 raise ArgumentError, "Invalid front matter: #{e.message}"
27 end
28 
29 def [](key)
30 @metadata[key.to_sym]
31 end
32 
33 def to_h
34 { metadata: @metadata, body: @body }
35 end
36 
37 private
38 
39 def symbolize(hash)
40 hash.each_with_object({}) do |(key, value), acc|
41 acc[key.to_sym] = value.is_a?(Hash) ? symbolize(value) : value
42 end
43 end
44end
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1A single multiline regex with captures can cleanly separate a structured header from free-form content.
  2. 2Wrapping a class-level factory around instance setup keeps callers to one tidy entry point.
  3. 3Recursing into nested hashes lets you normalize keys all the way down, not just at the top level.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Parsing YAML front matter in Ruby — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code