Skip to content
Kward Search API index

Module: Kward::Frontmatter

Defined in:
lib/kward/frontmatter.rb

Overview

Markdown frontmatter parsing shared by prompt templates and skills.

Class Method Summary collapse

Class Method Details

.lenient_frontmatter(yaml_text) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/kward/frontmatter.rb', line 30

def lenient_frontmatter(yaml_text)
  yaml_text.each_line.each_with_object({}) do |line, result|
    match = line.chomp.match(/\A([A-Za-z0-9_-]+):\s*(.*)\z/)
    next unless match

    key = match[1]
    value = match[2].strip
    next if value.empty?

    result[key] = value.delete_prefix('"').delete_suffix('"')
  end
end

.load_frontmatter(yaml_text, lenient: false) ⇒ Object



22
23
24
25
26
27
28
# File 'lib/kward/frontmatter.rb', line 22

def load_frontmatter(yaml_text, lenient: false)
  YAML.safe_load(yaml_text, permitted_classes: [], aliases: false)
rescue Psych::SyntaxError
  raise unless lenient

  lenient_frontmatter(yaml_text)
end

.markdown_parts(path, lenient: false) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/kward/frontmatter.rb', line 9

def markdown_parts(path, lenient: false)
  content = File.read(path)
  return [{}, content] unless content.start_with?("---\n", "---\r\n")

  _opening, rest = content.split(/\A---\r?\n/, 2)
  yaml_text, body = rest.to_s.split(/\r?\n---\r?\n/, 2)
  raise "missing frontmatter closing delimiter" if body.nil?

  data = yaml_text.to_s.empty? ? {} : load_frontmatter(yaml_text, lenient: lenient)
  frontmatter = data.is_a?(Hash) ? data.transform_keys(&:to_s) : {}
  [frontmatter, body]
end