class SvgDrawer::Base
Attributes
Public Class Methods
The default_values is a hash of param values that will be used as a last-resort fallback
With and height are applicable to all elements, so they are always included here to avoid “No such param” errors (see ParamMerger#param for details)
# File lib/svg_drawer/base.rb, line 43 def defaults(hash) default_params.update(hash) end
All elements can are initialized with a params hash only. This hash contains stuff regular keys like :width, :height, etc. If this hash does not contain any of the keys found in self.class.required_params, an error is risen. It may contain an :inherited. Its value is a hash which will serve as a fall-back to any keys not found in the top-level hash. For example: { width: 100, inherited: { width: 200, height: 500 } }
Calling param
(:width) on the element will return 100 Calling param
(:height) on the element will return 500 Calling param
(:foo) will not be found in any of the hashes, so it will be looked up in self.class.default_params:
- if found, will be returned - if not found, an error will be risen (see ParameterMerger#param)
A special @child_params hash is automatically constructed every time update_params!
is called (incl. initialize) It is a hash that will be passed on as the value of the :inherited key to any child elements constructed. Note that it will not contain any keys found in self.class.special_params
Inheritance example:
Table.new(font: 'A') do |table| table.row do |row| row.cell do |cell| cell.content = TextBox.new('foo') # text 1 end table.row(font: 'B') do |row| row.cell do |cell| cell.content = TextBox.new('foo') # text 2 end row.cell(font: 'C') do |cell| cell.content = TextBox.new('foo') # text 3 end row.cell(font: 'C') do |cell| cell.content(TextBox.new('foo', font: 'D')) # text 4 end end end
The texts 1, 2, 3 and 4 will have font 'A', 'B', 'C' and 'D'.
# File lib/svg_drawer/base.rb, line 122 def initialize(params = {}) @params = {} @inherited_params = {} @child_params = {} @pmerger = Utils::ParameterMerger.new(@params, @inherited_params, self.class.default_params) update_params!(params) end
The required_params
contain param keys vital to the element. For example, a table can't be initialized without a :columns param. Their values can be provided via inherited_params.
# File lib/svg_drawer/base.rb, line 17 def requires(*names) required_params.concat(names) end
The special_params
contain param keys special to the element. They will not be stored in @child_params See note in initialize
# File lib/svg_drawer/base.rb, line 26 def special(*names) # Ensure special param are also a valid param (see ParameterMerger#param) names_hash = names.map { |n| [n, nil] }.to_h # this just Hash#reverse_merge! as implemented in activesupport-4.2 default_params.merge!(names_hash) { |_key, left, _right| left } special_params.concat(names) end
Public Instance Methods
# File lib/svg_drawer/base.rb, line 155 def draw(*args, debug: false) ensure_complete! @debug = debug _draw(*args) end
# File lib/svg_drawer/base.rb, line 161 def ensure_complete! pending_element = incomplete raise ElementIncomplete, pending_element if pending_element end
# File lib/svg_drawer/base.rb, line 174 def height raise NotImplementedError end
# File lib/svg_drawer/base.rb, line 178 def incomplete raise NotImplementedError end
# File lib/svg_drawer/base.rb, line 147 def param(name, default = nil) @pmerger.param(name) || default end
# File lib/svg_drawer/base.rb, line 151 def param!(name) param(name) or raise "No default value for: #{name}" end
The way to update an element's params
# File lib/svg_drawer/base.rb, line 134 def update_params!(params) @params.update(_deep_dup(params)) @inherited_params.update(@params.delete(:inherited) || {}) # Note: self.class.default_params is NOT to be merged in @child_params @child_params = @inherited_params.merge(@params) self.class.special_params.each { |name| @child_params.delete(name) } self.class.required_params.each do |rp| raise "Required param is missing: #{rp}" unless @pmerger.param?(rp) end end
To be defined in subclasses
# File lib/svg_drawer/base.rb, line 170 def width raise NotImplementedError end
Private Instance Methods
# File lib/svg_drawer/base.rb, line 188 def _complete? raise NotImplementedError end
# File lib/svg_drawer/base.rb, line 206 def _deep_dup(value) case value when Array then value.map { |v| _deep_dup(v) } when Hash then value.map { |k, v| [_deep_dup(k), _deep_dup(v)] }.to_h when Integer, Float, Symbol, TrueClass, FalseClass then value else value.dup end end
# File lib/svg_drawer/base.rb, line 184 def _draw(*) raise NotImplementedError end
# File lib/svg_drawer/base.rb, line 192 def draw_border(svg, width_override: width, height_override: height) borders = param(:borders) borders ||= %i[left right top bottom] if param(:border) Border.draw( svg, width_override, height_override, borders, param(:border_style), param(:class), @debug ) end