class RubyXL::OOXMLObject
Public Class Methods
define_attribute(attr_name, attr_type, extra_params = {})
click to toggle source
# File lib/rubyXL/objects/ooxml_object.rb, line 24 def self.define_attribute(attr_name, attr_type, extra_params = {}) attrs = obtain_class_variable(:@@ooxml_attributes) accessor = extra_params[:accessor] || accessorize(attr_name) attrs[accessor] = { :attr_name => attr_name.to_s, :attr_type => attr_type, :optional => !extra_params[:required], :default => extra_params[:default], :validation => extra_params[:values] } self.send(:attr_accessor, accessor) end
define_child_node(klass, extra_params = {})
click to toggle source
# File lib/rubyXL/objects/ooxml_object.rb, line 40 def self.define_child_node(klass, extra_params = {}) child_nodes = obtain_class_variable(:@@ooxml_child_nodes) child_node_name = (extra_params[:node_name] || klass.class_variable_get(:@@ooxml_tag_name)).to_s accessor = (extra_params[:accessor] || accessorize(child_node_name)).to_sym child_nodes[child_node_name] = { :class => klass, :is_array => extra_params[:collection], :accessor => accessor } self.send(:attr_accessor, accessor) end
define_element_name(v)
click to toggle source
# File lib/rubyXL/objects/ooxml_object.rb, line 54 def self.define_element_name(v) self.class_variable_set(:@@ooxml_tag_name, v) end
new(params = {})
click to toggle source
# File lib/rubyXL/objects/ooxml_object.rb, line 80 def initialize(params = {}) obtain_class_variable(:@@ooxml_attributes).each_key { |k| instance_variable_set("@#{k}", params[k]) } obtain_class_variable(:@@ooxml_child_nodes).each_pair { |k, v| initial_value = if params.has_key?(v[:accessor]) then params[v[:accessor]] elsif v[:is_array] then [] else nil end instance_variable_set("@#{v[:accessor]}", initial_value) } instance_variable_set("@count", 0) if obtain_class_variable(:@@ooxml_countable, false) end
obtain_class_variable(var_name, default = {})
click to toggle source
Throughout this class, setting class variables through explicit method calls rather than by directly addressing the name of the variable because of context issues: addressing variable by name creates it in the context of defining class, while calling the setter/getter method addresses it in the context of descendant class, which is what we need.
# File lib/rubyXL/objects/ooxml_object.rb, line 11 def self.obtain_class_variable(var_name, default = {}) if class_variable_defined?(var_name) then self.class_variable_get(var_name) else self.class_variable_set(var_name, default) end end
parse(node)
click to toggle source
# File lib/rubyXL/objects/ooxml_object.rb, line 96 def self.parse(node) obj = self.new obtain_class_variable(:@@ooxml_attributes).each_pair { |k, v| raw_value = if v[:attr_name] == '_' then node.text else attr = node.attributes[v[:attr_name]] attr && attr.value end val = raw_value && case v[:attr_type] when :int then Integer(raw_value) when :float then Float(raw_value) when :string then raw_value when :sqref then RubyXL::Sqref.new(raw_value) when :ref then RubyXL::Reference.new(raw_value) when :bool then ['1', 'true'].include?(raw_value) end obj.send("#{k}=", val) } known_child_nodes = obtain_class_variable(:@@ooxml_child_nodes) unless known_child_nodes.empty? node.element_children.each { |child_node| child_node_name = child_node.name child_node_params = known_child_nodes[child_node_name] raise "Unknown child node: #{child_node_name}" if child_node_params.nil? parsed_object = child_node_params[:class].parse(child_node) if child_node_params[:is_array] then obj.send(child_node_params[:accessor]) << parsed_object else obj.send("#{child_node_params[:accessor]}=", parsed_object) end } end obj end
set_countable()
click to toggle source
# File lib/rubyXL/objects/ooxml_object.rb, line 58 def self.set_countable self.class_variable_set(:@@ooxml_countable, true) self.send(:attr_accessor, :count) end
Private Class Methods
accessorize(str)
click to toggle source
# File lib/rubyXL/objects/ooxml_object.rb, line 144 def self.accessorize(str) acc = str.to_s.dup acc.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2') acc.gsub!(/([a-z\d])([A-Z])/,'\1_\2') acc.gsub!(':','_') acc.downcase.to_sym end
Public Instance Methods
dup()
click to toggle source
Calls superclass method
# File lib/rubyXL/objects/ooxml_object.rb, line 137 def dup new_copy = super new_copy.count = 0 if obtain_class_variable(:@@ooxml_countable, false) new_copy end
write_xml(xml, node_name_override = nil)
click to toggle source
# File lib/rubyXL/objects/ooxml_object.rb, line 63 def write_xml(xml, node_name_override = nil) before_write_xml if self.respond_to?(:before_write_xml) attrs = prepare_attributes element_text = attrs.delete('_') elem = xml.create_element(node_name_override || obtain_class_variable(:@@ooxml_tag_name), attrs, element_text) child_nodes = obtain_class_variable(:@@ooxml_child_nodes) child_nodes.each_pair { |child_node_name, child_node_params| obj = self.send(child_node_params[:accessor]) unless obj.nil? if child_node_params[:is_array] then obj.each { |item| elem << item.write_xml(xml) } else elem << obj.write_xml(xml, child_node_name) end end } elem end
Private Instance Methods
obtain_class_variable(var_name, default = {})
click to toggle source
# File lib/rubyXL/objects/ooxml_object.rb, line 19 def obtain_class_variable(var_name, default = {}) self.class.obtain_class_variable(var_name, default) end
prepare_attributes()
click to toggle source
# File lib/rubyXL/objects/ooxml_object.rb, line 152 def prepare_attributes xml_attrs = {} obtain_class_variable(:@@ooxml_attributes).each_pair { |k, v| val = self.send(k) if val.nil? then next if v[:optional] val = v[:default] end val = val && case v[:attr_type] when :bool then val ? '1' : '0' when :float then val.to_s.gsub(/\.0*$/, '') # Trim trailing zeroes else val end xml_attrs[v[:attr_name]] = val } xml_attrs end