Sha256: 11745b55e523bb57b45d7e4619d7b4346dca8ffd2238219f959cc0d0e788eb72

Contents?: true

Size: 1.6 KB

Versions: 2

Compression:

Stored size: 1.6 KB

Contents

# frozen_string_literal: true
require 'strscan'
require 'yaml'

module Decant
  module Frontmatter
    # Parse a +String+ input (the contents of a file) into its frontmatter /
    # content constituents.
    #
    # For frontmatter to be valid/detected the +input+ must start with a line
    # consisting of three dashes +---+, then the YAML, then another line of
    # three dashes. The returned +Hash+ will have +Symbol+ keys.
    #
    # Technically frontmatter can be any valid YAML not just key/value pairs but
    # this would be very unusual and wouldn't be compatible with other
    # frontmatter-related expectations like {Content.frontmatter}.
    #
    # @example Input with valid frontmatter
    #   ---
    #   title: Frontmatter
    #   ---
    #   The rest of the content
    #
    # @example Result of loading the above input
    #   Decant::Frontmatter.load(string)
    #   # => [{:title=>"Frontmatter"}, "The rest of the content"]
    #
    # @param input [String]
    #
    # @return [Array([Hash<Symbol, anything>, nil], String)] a frontmatter /
    #   content tuple. If +input+ contains frontmatter then the YAML will be
    #   parsed into a +Hash+ with +Symbol+ keys, if it doesn't have frontmatter
    #   then it will be +nil+.
    def self.load(input)
      return [nil, input] unless input.start_with?("---\n")

      scanner = StringScanner.new(input)
      scanner.skip("---\n")
      scanner.skip_until(/^---$\n?/)
      yaml = scanner.pre_match

      return [nil, input] unless yaml

      [
        YAML.safe_load(yaml, symbolize_names: true) || {},
        scanner.post_match
      ]
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
decant-0.3.0 lib/decant/frontmatter.rb
decant-0.2.0 lib/decant/frontmatter.rb