diff --git a/middleman-core/lib/middleman-core/util/data.rb b/middleman-core/lib/middleman-core/util/data.rb index c37c7bf4..c1d1e572 100644 --- a/middleman-core/lib/middleman-core/util/data.rb +++ b/middleman-core/lib/middleman-core/util/data.rb @@ -1,103 +1,82 @@ -# Core Pathname library used for traversal +require 'yaml' +require 'json' require 'pathname' - -# DbC +require 'middleman-core/util' require 'middleman-core/contracts' -# Shared util methods -require 'middleman-core/util' +module Middleman::Util::Data + include Contracts -# Parsing YAML data -require 'yaml' + module_function -# Parsing JSON data -require 'json' + # Get the frontmatter and plain content from a file + # @param [String] path + # @return [Array] + Contract Pathname, Maybe[Symbol] => [Hash, Maybe[String]] + def parse(full_path, known_type=nil) + return [{}, nil] if Middleman::Util.binary?(full_path) -module Middleman - module Util - module Data - include Contracts + # Avoid weird race condition when a file is renamed + begin + content = File.read(full_path) + rescue EOFError, IOError, Errno::ENOENT + return [{}, nil] + end - module_function + case known_type + when :yaml + return [parse_yaml(content, full_path), nil] + when :json + return [parse_json(content, full_path), nil] + end - # Get the frontmatter and plain content from a file - # @param [String] path - # @return [Array] - Contract Pathname, Maybe[Symbol] => [Hash, Maybe[String]] - def parse(full_path, known_type=nil) - return [{}, nil] if Middleman::Util.binary?(full_path) + / + (?^[-;]{3})[ ]*\r?\n + (?.*?)[ ]*\r?\n + (?^[-.;]{3})[ ]*\r?\n? + (?.*) + /mx =~ content - # Avoid weird race condition when a file is renamed - begin - content = File.read(full_path) - rescue EOFError, IOError, Errno::ENOENT - return [{}, nil] - end + case [start, stop] + when %w[--- ---], %w[--- ...] + [parse_yaml(frontmatter, full_path), additional_content] + when %w[;;; ;;;] + [parse_json(frontmatter, full_path), additional_content] + else + [{}, content] + end + end - case known_type - when :yaml - return [parse_yaml(content, full_path), nil] - when :json - return [parse_json(content, full_path), nil] - end + # Parse YAML frontmatter out of a string + # @param [String] content + # @return [Array] + Contract String, Pathname, Bool => Hash + def parse_yaml(content, full_path) + symbolize_recursive(YAML.load(content)) + rescue StandardError, Psych::SyntaxError => error + warn "YAML Exception parsing #{full_path}: #{error.message}" + {} + end - / - (?^[-;]{3})[ ]*\r?\n - (?.*?)[ ]*\r?\n - (?^[-.;]{3})[ ]*\r?\n? - (?.*) - /mx =~ content + # Parse JSON frontmatter out of a string + # @param [String] content + # @return [Array] + Contract String, Pathname => Hash + def parse_json(content, full_path) + symbolize_recursive(JSON.parse(content)) + rescue StandardError => error + warn "JSON Exception parsing #{full_path}: #{error.message}" + {} + end - return [{}, content] unless frontmatter - - case [start, stop] - when %w[--- ---], %w[--- ...] - [parse_yaml(frontmatter, full_path), additional_content] - when %w[;;; ;;;] - [parse_json(frontmatter, full_path), additional_content] - else - [{}, content] - end - end - - # Parse YAML frontmatter out of a string - # @param [String] content - # @return [Array] - Contract String, Pathname, Bool => Hash - def parse_yaml(content, full_path) - map_value(YAML.load(content)) - rescue StandardError, Psych::SyntaxError => error - warn "YAML Exception parsing #{full_path}: #{error.message}" - {} - end - - # Parse JSON frontmatter out of a string - # @param [String] content - # @return [Array] - Contract String, Pathname => Hash - def parse_json(content, full_path) - map_value(JSON.parse(content)) - rescue StandardError => error - warn "JSON Exception parsing #{full_path}: #{error.message}" - {} - end - - def symbolize_recursive(hash) - {}.tap do |h| - hash.each { |key, value| h[key.to_sym] = map_value(value) } - end - end - - def map_value(thing) - case thing - when Hash - symbolize_recursive(thing) - when Array - thing.map { |v| map_value(v) } - else - thing - end - end + def symbolize_recursive(value) + case value + when Hash + value.map { |k, v| [k.to_sym, symbolize_recursive(v)] }.to_h + when Array + value.map { |v| symbolize_recursive(v) } + else + value end end end