Refactoring out LayoutParser

This commit is contained in:
Andy Meneely
2015-01-05 23:07:46 -05:00
parent 04783ef8de
commit 31e5d75f59
4 changed files with 263 additions and 238 deletions
+2 -64
View File
@@ -5,6 +5,7 @@ require 'squib/card'
require 'squib/progress'
require 'squib/input_helpers'
require 'squib/constants'
require 'squib/layout_parser'
# The project module
#
@@ -65,7 +66,7 @@ module Squib
cards.times{ @cards << Squib::Card.new(self, width, height) }
show_info(config, layout)
load_config(config)
load_layout(layout)
@layout = LayoutParser.load_layout(layout)
if block_given?
instance_eval(&block)
end
@@ -106,69 +107,6 @@ module Squib
end
end
# Load the layout configuration file, if exists
# @api private
def load_layout(files)
@layout = {}
Squib::logger.info { " using layout(s): #{files}" }
Array(files).each do |file|
thefile = file
thefile = "#{File.dirname(__FILE__)}/layouts/#{file}" unless File.exists?(file)
if File.exists? thefile
yml = @layout.merge(YAML.load_file(thefile) || {}) #load_file returns false on empty file
yml.each do |key, value|
@layout[key] = recurse_extends(yml, key, {})
end
else
puts "the file: #{thefile}"
Squib::logger.error { "Layout file not found: #{file}" }
end
end
end
# Process the extends recursively
# :nodoc:
# @api private
def recurse_extends(yml, key, visited )
assert_not_visited(key, visited)
return yml[key] unless has_extends?(yml, key)
visited[key] = key
parent_keys = [yml[key]['extends']].flatten
h = {}
parent_keys.each do |parent_key|
from_extends = yml[key].merge(recurse_extends(yml, parent_key, visited)) do |key, child_val, parent_val|
if child_val.to_s.strip.start_with?('+=')
parent_val + child_val.sub('+=','').strip.to_f
elsif child_val.to_s.strip.start_with?('-=')
parent_val - child_val.sub('-=','').strip.to_f
else
child_val #child overrides parent when merging, no +=
end
end
h = h.merge(from_extends) do |key, older_sibling, younger_sibling|
younger_sibling #when two siblings have the same entry, the "younger" (lower one) overrides
end
end
return h
end
# Does this layout entry have an extends field?
# i.e. is it a base-case or will it need recursion?
# :nodoc:
# @api private
def has_extends?(yml, key)
!!yml[key] && yml[key].key?('extends')
end
# Safeguard against malformed circular extends
# :nodoc:
# @api private
def assert_not_visited(key, visited)
if visited.key? key
raise "Invalid layout: circular extends with '#{key}'"
end
end
# Use Logger to show more detail on the run
# :nodoc:
# @api private
+75
View File
@@ -0,0 +1,75 @@
module Squib
# Internal class for handling layouts
#@api private
class LayoutParser
# Load the layout file(s), if exists
# @api private
def self.load_layout(files)
layout = {}
Squib::logger.info { " using layout(s): #{files}" }
Array(files).each do |file|
thefile = file
thefile = builtin(file) unless File.exists?(file)
if File.exists? thefile
yml = layout.merge(YAML.load_file(thefile) || {}) #load_file returns false on empty file
yml.each do |key, value|
layout[key] = recurse_extends(yml, key, {})
end
else
Squib::logger.error { "Layout file not found: #{file}. Skipping..." }
end
end
return layout
end
# Determine the file path of the built-in layout file
def self.builtin(file)
"#{File.dirname(__FILE__)}/layouts/#{file}"
end
# Process the extends recursively
# :nodoc:
# @api private
def self.recurse_extends(yml, key, visited )
assert_not_visited(key, visited)
return yml[key] unless has_extends?(yml, key)
visited[key] = key
parent_keys = [yml[key]['extends']].flatten
h = {}
parent_keys.each do |parent_key|
from_extends = yml[key].merge(recurse_extends(yml, parent_key, visited)) do |key, child_val, parent_val|
if child_val.to_s.strip.start_with?('+=')
parent_val + child_val.sub('+=','').strip.to_f
elsif child_val.to_s.strip.start_with?('-=')
parent_val - child_val.sub('-=','').strip.to_f
else
child_val #child overrides parent when merging, no +=
end
end
h = h.merge(from_extends) do |key, older_sibling, younger_sibling|
younger_sibling #when two siblings have the same entry, the "younger" (lower one) overrides
end
end
return h
end
# Does this layout entry have an extends field?
# i.e. is it a base-case or will it need recursion?
# :nodoc:
# @api private
def self.has_extends?(yml, key)
!!yml[key] && yml[key].key?('extends')
end
# Safeguard against malformed circular extends
# :nodoc:
# @api private
def self.assert_not_visited(key, visited)
if visited.key? key
raise "Invalid layout: circular extends with '#{key}'"
end
end
end
end