cleanup
parent
02bf443abf
commit
750cb40267
|
|
@ -2,125 +2,122 @@ require_relative '../constants'
|
||||||
require_relative '../conf'
|
require_relative '../conf'
|
||||||
require 'ostruct'
|
require 'ostruct'
|
||||||
|
|
||||||
module Squib
|
# Intended to be used a a mix-in,
|
||||||
# @api private
|
# For example use see Box as an example
|
||||||
module Args
|
module Squib::Args::ArgLoader
|
||||||
|
|
||||||
# Intended to be used a a mix-in,
|
# wrapper for compatibility
|
||||||
# For example use see Box as an example
|
def extract!(args, deck)
|
||||||
module ArgLoader
|
load!(args, expand_by: deck.size, layout: deck.layout, dpi: deck.dpi)
|
||||||
|
|
||||||
# Main class invoked by the client (i.e. api/ methods)
|
|
||||||
def load!(args, expand_by: 1, layout: {}, dpi: 300)
|
|
||||||
Squib.logger.debug { "ARG LOADER: load! for #{self.class}, args: #{args}" }
|
|
||||||
@dpi = dpi
|
|
||||||
args[:layout] = prep_layout_args(args[:layout], expand_by: expand_by)
|
|
||||||
expand_and_set_and_defaultify(args: args, by: expand_by, layout: layout)
|
|
||||||
validate
|
|
||||||
convert_units dpi: dpi
|
|
||||||
self
|
|
||||||
end
|
|
||||||
|
|
||||||
def expand_and_set_and_defaultify(args: {}, by: 1, layout: {})
|
|
||||||
attributes = self.class.parameters.keys
|
|
||||||
attributes.each do |p|
|
|
||||||
args[p] = defaultify(p, args, layout)
|
|
||||||
val = if expandable_singleton?(p, args[p])
|
|
||||||
[args[p]] * by
|
|
||||||
else
|
|
||||||
args[p] # not an expanding parameter
|
|
||||||
end
|
|
||||||
instance_variable_set "@#{p}", val
|
|
||||||
end
|
|
||||||
self.class.class_eval { attr_reader *(attributes) }
|
|
||||||
end
|
|
||||||
|
|
||||||
# Must be:
|
|
||||||
# (a) an expanding parameter, and
|
|
||||||
# (b) a singleton already (i.e. doesn't respond to :each)
|
|
||||||
def expandable_singleton?(p, arg)
|
|
||||||
self.class.expanding_parameters.include?(p) && !arg.respond_to?(:each)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Incorporate defaults and layouts
|
|
||||||
# (1) Use whatever is specified if it is
|
|
||||||
# (2) Go over all layout specifications (if any) and look them up
|
|
||||||
# - Use layout when it's specified for that card
|
|
||||||
# - Use "default" if no layout was specified, or the layout itself did not specify
|
|
||||||
# Defaut can be overriden for a given dsl method (@dsl_method_defaults)
|
|
||||||
# (e.g stroke width is 0.0 for text, non-zero everywhere else)
|
|
||||||
#
|
|
||||||
def defaultify(p, args, layout)
|
|
||||||
return args[p] if args.key? p # arg was specified, no defaults used
|
|
||||||
defaults = self.class.parameters.merge(@dsl_method_defaults || {})
|
|
||||||
args[:layout].map do |layout_arg|
|
|
||||||
return defaults[p] if layout_arg.nil? # no layout specified, use default
|
|
||||||
unless layout.key? layout_arg.to_s # specified a layout, but it doesn't exist in layout. Oops!
|
|
||||||
Squib.logger.warn("Layout \"#{layout_arg.to_s}\" does not exist in layout file - using default instead")
|
|
||||||
return defaults[p]
|
|
||||||
end
|
|
||||||
if layout[layout_arg.to_s].key?(p.to_s)
|
|
||||||
layout[layout_arg.to_s][p.to_s] # param specified in layout
|
|
||||||
else
|
|
||||||
defaults[p] # layout specified, but not this param
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Do singleton expansion on the layout argument as well
|
|
||||||
# Treated differently since layout is not always specified
|
|
||||||
def prep_layout_args(layout_args, expand_by: 1)
|
|
||||||
unless layout_args.respond_to?(:each)
|
|
||||||
layout_args = [layout_args] * expand_by
|
|
||||||
end
|
|
||||||
layout_args || []
|
|
||||||
end
|
|
||||||
|
|
||||||
# For each parameter/attribute foo we try to invoke a validate_foo
|
|
||||||
def validate
|
|
||||||
self.class.parameters.each do |param, default|
|
|
||||||
method = "validate_#{param}"
|
|
||||||
if self.respond_to? method
|
|
||||||
attribute = "@#{param}"
|
|
||||||
val = instance_variable_get(attribute)
|
|
||||||
if val.respond_to? :each
|
|
||||||
new_val = val.map.with_index{ |v, i| send(method, v, i) }
|
|
||||||
instance_variable_set(attribute, new_val)
|
|
||||||
else
|
|
||||||
instance_variable_set(attribute, send(method, val))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Access an individual arg for a given card
|
|
||||||
# @return an OpenStruct that looks just like the mixed-in class
|
|
||||||
# @api private
|
|
||||||
def [](i)
|
|
||||||
card_arg = OpenStruct.new
|
|
||||||
self.class.expanding_parameters.each do |p|
|
|
||||||
p_val = instance_variable_get("@#{p}")
|
|
||||||
card_arg[p] = p_val[i]
|
|
||||||
end
|
|
||||||
card_arg
|
|
||||||
end
|
|
||||||
|
|
||||||
# Convert units
|
|
||||||
def convert_units(dpi: 300)
|
|
||||||
self.class.params_with_units.each do |p|
|
|
||||||
p_str = "@#{p}"
|
|
||||||
p_val = instance_variable_get(p_str)
|
|
||||||
if p_val.respond_to? :each
|
|
||||||
arr = p_val.map { |x| UnitConversion.parse(x, dpi) }
|
|
||||||
instance_variable_set p_str, arr
|
|
||||||
else
|
|
||||||
instance_variable_set p_str, UnitConversion.parse(p_val, dpi)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
self
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Main class invoked by the client (i.e. api/ methods)
|
||||||
|
def load!(args, expand_by: 1, layout: {}, dpi: 300)
|
||||||
|
@dpi = dpi
|
||||||
|
args[:layout] = prep_layout_args(args[:layout], expand_by: expand_by)
|
||||||
|
expand_and_set_and_defaultify(args: args, by: expand_by, layout: layout)
|
||||||
|
validate
|
||||||
|
convert_units dpi: dpi
|
||||||
|
self
|
||||||
|
end
|
||||||
|
|
||||||
|
def expand_and_set_and_defaultify(args: {}, by: 1, layout: {})
|
||||||
|
attributes = self.class.parameters.keys
|
||||||
|
attributes.each do |p|
|
||||||
|
args[p] = defaultify(p, args, layout)
|
||||||
|
val = if expandable_singleton?(p, args[p])
|
||||||
|
[args[p]] * by
|
||||||
|
else
|
||||||
|
args[p] # not an expanding parameter
|
||||||
|
end
|
||||||
|
instance_variable_set "@#{p}", val
|
||||||
|
end
|
||||||
|
self.class.class_eval { attr_reader *(attributes) }
|
||||||
|
end
|
||||||
|
|
||||||
|
# Must be:
|
||||||
|
# (a) an expanding parameter, and
|
||||||
|
# (b) a singleton already (i.e. doesn't respond to :each)
|
||||||
|
def expandable_singleton?(p, arg)
|
||||||
|
self.class.expanding_parameters.include?(p) && !arg.respond_to?(:each)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Incorporate defaults and layouts
|
||||||
|
# (1) Use whatever is specified if it is
|
||||||
|
# (2) Go over all layout specifications (if any) and look them up
|
||||||
|
# - Use layout when it's specified for that card
|
||||||
|
# - Use "default" if no layout was specified, or the layout itself did not specify
|
||||||
|
# Defaut can be overriden for a given dsl method (@dsl_method_defaults)
|
||||||
|
# (e.g stroke width is 0.0 for text, non-zero everywhere else)
|
||||||
|
#
|
||||||
|
def defaultify(p, args, layout)
|
||||||
|
return args[p] if args.key? p # arg was specified, no defaults used
|
||||||
|
defaults = self.class.parameters.merge(@dsl_method_defaults || {})
|
||||||
|
args[:layout].map do |layout_arg|
|
||||||
|
return defaults[p] if layout_arg.nil? # no layout specified, use default
|
||||||
|
unless layout.key? layout_arg.to_s # specified a layout, but it doesn't exist in layout. Oops!
|
||||||
|
Squib.logger.warn("Layout \"#{layout_arg.to_s}\" does not exist in layout file - using default instead")
|
||||||
|
return defaults[p]
|
||||||
|
end
|
||||||
|
if layout[layout_arg.to_s].key?(p.to_s)
|
||||||
|
layout[layout_arg.to_s][p.to_s] # param specified in layout
|
||||||
|
else
|
||||||
|
defaults[p] # layout specified, but not this param
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Do singleton expansion on the layout argument as well
|
||||||
|
# Treated differently since layout is not always specified
|
||||||
|
def prep_layout_args(layout_args, expand_by: 1)
|
||||||
|
unless layout_args.respond_to?(:each)
|
||||||
|
layout_args = [layout_args] * expand_by
|
||||||
|
end
|
||||||
|
layout_args || []
|
||||||
|
end
|
||||||
|
|
||||||
|
# For each parameter/attribute foo we try to invoke a validate_foo
|
||||||
|
def validate
|
||||||
|
self.class.parameters.each do |param, default|
|
||||||
|
method = "validate_#{param}"
|
||||||
|
if self.respond_to? method
|
||||||
|
attribute = "@#{param}"
|
||||||
|
val = instance_variable_get(attribute)
|
||||||
|
if val.respond_to? :each
|
||||||
|
new_val = val.map.with_index{ |v, i| send(method, v, i) }
|
||||||
|
instance_variable_set(attribute, new_val)
|
||||||
|
else
|
||||||
|
instance_variable_set(attribute, send(method, val))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Access an individual arg for a given card
|
||||||
|
# @return an OpenStruct that looks just like the mixed-in class
|
||||||
|
# @api private
|
||||||
|
def [](i)
|
||||||
|
card_arg = OpenStruct.new
|
||||||
|
self.class.expanding_parameters.each do |p|
|
||||||
|
p_val = instance_variable_get("@#{p}")
|
||||||
|
card_arg[p] = p_val[i]
|
||||||
|
end
|
||||||
|
card_arg
|
||||||
|
end
|
||||||
|
|
||||||
|
# Convert units
|
||||||
|
def convert_units(dpi: 300)
|
||||||
|
self.class.params_with_units.each do |p|
|
||||||
|
p_str = "@#{p}"
|
||||||
|
p_val = instance_variable_get(p_str)
|
||||||
|
if p_val.respond_to? :each
|
||||||
|
arr = p_val.map { |x| Squib::Args::UnitConversion.parse(x, dpi) }
|
||||||
|
instance_variable_set p_str, arr
|
||||||
|
else
|
||||||
|
instance_variable_set p_str, Squib::Args::UnitConversion.parse(p_val, dpi)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -2,33 +2,34 @@ require_relative '../errors_warnings/warn_unexpected_params'
|
||||||
|
|
||||||
module Squib
|
module Squib
|
||||||
class Deck
|
class Deck
|
||||||
def background(opts = {}) # DSL method. See http://squib.readthedocs.io
|
def background(opts = {})
|
||||||
BackgroundDSLMethod.new(self, __callee__).run(opts)
|
DSL::Background.new(self, __callee__).run(opts)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class BackgroundDSLMethod
|
module DSL
|
||||||
include WarnUnexpectedParams
|
class Background
|
||||||
|
include WarnUnexpectedParams
|
||||||
|
attr_reader :dsl_method, :deck
|
||||||
|
|
||||||
attr_reader :dsl_method, :deck
|
def initialize(deck, dsl_method)
|
||||||
|
@deck = deck
|
||||||
|
@dsl_method = dsl_method
|
||||||
|
end
|
||||||
|
|
||||||
def initialize(deck, dsl_method)
|
def accepted_params
|
||||||
@deck = deck
|
%i{
|
||||||
@dsl_method = dsl_method
|
range
|
||||||
end
|
color
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
def accepted_params
|
def run(opts)
|
||||||
%i{
|
warn_if_unexpected opts
|
||||||
range
|
range = Args::CardRange.new(opts[:range], deck_size: deck.size)
|
||||||
color
|
draw = Args::Draw.new(@deck.custom_colors).extract!(opts, deck)
|
||||||
}
|
range.each { |i| @deck.cards[i].background(draw.color[i]) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def run(opts)
|
|
||||||
warn_if_unexpected opts
|
|
||||||
range = Args::CardRange.new(opts[:range], deck_size: @deck.size)
|
|
||||||
draw = Args::Draw.new(@deck.custom_colors).load!(opts, expand_by: @deck.size, layout: @deck.layout, dpi: @deck.dpi)
|
|
||||||
range.each { |i| @deck.cards[i].background(draw.color[i]) }
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ module Squib::WarnUnexpectedParams
|
||||||
def warn_if_unexpected(opts, uplevel: 5)
|
def warn_if_unexpected(opts, uplevel: 5)
|
||||||
unexpected = opts.keys - accepted_params
|
unexpected = opts.keys - accepted_params
|
||||||
unexpected.each do |key|
|
unexpected.each do |key|
|
||||||
warn "Unexpected parameter '#{key.to_s.yellow}:' to #{dsl_method.to_s.cyan}(), ignoring...",
|
warn "Unexpected parameter '#{key.to_s.yellow}:' to #{dsl_method.to_s.cyan}(). Accepted parameters: #{accepted_params}",
|
||||||
uplevel: uplevel
|
uplevel: uplevel
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,10 @@ def project_template(file)
|
||||||
"#{File.expand_path(File.dirname(__FILE__))}/../lib/squib/project_template/#{file}"
|
"#{File.expand_path(File.dirname(__FILE__))}/../lib/squib/project_template/#{file}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def doc(file)
|
||||||
|
"#{File.expand_path(File.dirname(__FILE__))}/../docs/#{file}"
|
||||||
|
end
|
||||||
|
|
||||||
def conf(file)
|
def conf(file)
|
||||||
"#{File.expand_path(File.dirname(__FILE__))}/data/conf/#{file}"
|
"#{File.expand_path(File.dirname(__FILE__))}/data/conf/#{file}"
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue