Module: WritersRoom::FrontMatter

Defined in:
lib/writers_room/front_matter.rb

Overview

Parses and renders Markdown files with YAML front matter.

Front matter is delimited by --- at the start of the file:

---
title: My Document
tags: [a, b]
---

Body content here.

Class Method Summary collapse

Class Method Details

.deep_symbolize_keys(obj) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



73
74
75
76
77
78
79
80
81
82
# File 'lib/writers_room/front_matter.rb', line 73

def deep_symbolize_keys(obj)
  case obj
  when Hash
    obj.each_with_object({}) { |(k, v), h| h[k.to_sym] = deep_symbolize_keys(v) }
  when Array
    obj.map { |v| deep_symbolize_keys(v) }
  else
    obj
  end
end

.dump(metadata, body = "") ⇒ String

Render metadata + body back to a front matter string.

Parameters:

  • metadata (Hash)

    YAML metadata

  • body (String) (defaults to: "")

    markdown body

Returns:

  • (String)

    rendered content



64
65
66
67
68
69
70
# File 'lib/writers_room/front_matter.rb', line 64

def dump(, body = "")
  body = body.to_s
  meta_str = .empty? ? "" : stringify_keys().to_yaml.sub(/^---\n/, "")
  result = "---\n#{meta_str}---\n"
  result += "\n#{body}\n" unless body.empty?
  result
end

.load_file(path, symbolize_keys: true) ⇒ Hash

Load and parse a file with front matter.

Parameters:

  • path (String)

    file path

  • symbolize_keys (Boolean) (defaults to: true)

    convert metadata keys to symbols (default: true)

Returns:

  • (Hash)

    { metadata: Hash, body: String }



54
55
56
57
# File 'lib/writers_room/front_matter.rb', line 54

def load_file(path, symbolize_keys: true)
  content = File.read(path)
  parse(content, symbolize_keys: symbolize_keys)
end

.parse(content, symbolize_keys: true) ⇒ Hash

Parse a string containing front matter + body.

Parameters:

  • content (String)

    raw file content

  • symbolize_keys (Boolean) (defaults to: true)

    convert metadata keys to symbols (default: true)

Returns:

  • (Hash)

    { metadata: Hash, body: String }



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/writers_room/front_matter.rb', line 25

def parse(content, symbolize_keys: true)
  content = content.to_s

  unless content.start_with?("---")
    return { metadata: {}, body: content.strip }
  end

  # Split on the closing `---` delimiter (second occurrence)
  parts = content.split(/^---\s*$/, 3)

  # parts[0] is empty (before first ---), parts[1] is YAML, parts[2] is body
  if parts.length >= 3
    raw_meta = YAML.safe_load(parts[1], permitted_classes: [Date, Time, Symbol]) || {}
    body = parts[2].to_s.strip
  else
    raw_meta = {}
    body = content.strip
  end

   = symbolize_keys ? deep_symbolize_keys(raw_meta) : raw_meta

  { metadata: , body: body }
end

.stringify_keys(obj) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



85
86
87
88
89
90
91
92
93
94
# File 'lib/writers_room/front_matter.rb', line 85

def stringify_keys(obj)
  case obj
  when Hash
    obj.each_with_object({}) { |(k, v), h| h[k.to_s] = stringify_keys(v) }
  when Array
    obj.map { |v| stringify_keys(v) }
  else
    obj
  end
end