diff --git a/lib/obsidian/parser.rb b/lib/obsidian/parser.rb index 09233c9..21977b0 100644 --- a/lib/obsidian/parser.rb +++ b/lib/obsidian/parser.rb @@ -6,6 +6,7 @@ require_relative "parser/page" require_relative "parser/html_renderer" require_relative "parser/content_type" +require_relative "parser/frontmatter_parser" require "forwardable" diff --git a/lib/obsidian/parser/frontmatter_parser.rb b/lib/obsidian/parser/frontmatter_parser.rb new file mode 100644 index 0000000..57b37aa --- /dev/null +++ b/lib/obsidian/parser/frontmatter_parser.rb @@ -0,0 +1,27 @@ +require 'yaml' + +class Obsidian::MarkdownParser::FrontMatterParser + # Look for frontmatter delimited by '---' lines + # and try to interpret it as yaml. + # If it is valid YAML, then denotes properties. + # https://help.obsidian.md/Editing+and+formatting/Properties#Property+format + def parse(content) + enumerator = content.each_line + first_line = enumerator.next + + if first_line.chomp != "---" + return {} + end + + lines = [] + while true + line = enumerator.next + break if line.chomp == "---" + lines << line + end + + YAML.safe_load(lines.join) + rescue YAML::SyntaxError, StopIteration => ex + {} + end +end diff --git a/spec/obsidian/parser/frontmatter_parser.rb b/spec/obsidian/parser/frontmatter_parser.rb new file mode 100644 index 0000000..8c4b3d5 --- /dev/null +++ b/spec/obsidian/parser/frontmatter_parser.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +RSpec.describe(Obsidian::MarkdownParser::FrontMatterParser) do + subject(:parser) { described_class.new } + it "parses valid yaml" do + content = %(--- +foo: 1 +bar: banana +--- +some text + ) + expect(parser.parse(content)).to eq({"foo" => 1, "bar" => "banana"}) + end + + it "returns empty hash for invalid yaml" do + content = %(--- +{ +--- +some text + ) + expect(parser.parse(content)).to eq({}) + end + + it "returns empty hash if the frontmatter is not terminated" do + content = %(--- +some text + ) + expect(parser.parse(content)).to eq({}) + end + + + it "returns empty hash if no frontmatter" do + content = "hello world" + expect(parser.parse(content)).to eq({}) + end +end