lib/csl/node.rb in csl-1.0.0.pre1 vs lib/csl/node.rb in csl-1.0.0.pre2

- old
+ new

@@ -27,26 +27,31 @@ def default_attributes @default_attributes ||= {} end def constantize(name) - types.detect do |t| - t.name.split(/::/)[-1].gsub(/([[:lower:]])([[:upper:]])/, '\1-\2').downcase == name + klass = types.detect { |t| t.matches?(name) } + + if klass || !superclass.respond_to?(:constantize) + klass + else + superclass.constantize(name) end end + + # @return [Boolean] whether or not the node's name matches the passed-in name + def matches?(nodename) + name.split(/::/)[-1].gsub(/([[:lower:]])([[:upper:]])/, '\1-\2').downcase == nodename + end # Returns a new node with the passed in name and attributes. def create(name, attributes = {}, &block) klass = constantize(name) - unless klass.nil? - klass.new(attributes, &block) - else - node = new(attributes, &block) - node.nodename = name - node - end + node = (klass || Node).new(attributes, &block) + node.nodename = name + node end def create_attributes(attributes) if const?(:Attributes) const_get(:Attributes).new(default_attributes.merge(attributes)) @@ -70,23 +75,23 @@ def attr_struct(*attributes) const_set(:Attributes, Struct.new(*attributes) { # 1.8 Compatibility @keys = attributes.map(&:to_sym).freeze - + class << self attr_reader :keys end - + def initialize(attrs = {}) super(*attrs.symbolize_keys.values_at(*keys)) end # @return [<Symbol>] a list of symbols representing the names/keys # of the attribute variables. def keys - self.class.keys + __class__.keys end def values super.compact end @@ -100,11 +105,11 @@ def empty? values.compact.empty? end def fetch(key, default = nil) - value = keys.include?(key.to_sym) && send(key) + value = keys.include?(key.to_sym) && send(:'[]', key) if block_given? value || yield(key) else value || default @@ -118,12 +123,12 @@ def merge(other) raise ArgumentError, "failed to merge #{other.class} into Attributes" unless other.respond_to?(:each_pair) other.each_pair do |part, value| - writer = "#{part}=" - send(writer, value) if !value.nil? && respond_to?(writer) + part = part.to_sym + send(:'[]=', part, value) if !value.nil? && keys.include?(part) end self end @@ -185,10 +190,18 @@ def textnode? false end alias has_text? textnode? + def save_to(path, options = {}) + File.open(path, 'w:UTF-8') do |f| + f << (options[:compact] ? to_xml : pretty_print) + end + + self + end + def <=>(other) [nodename, attributes, children] <=> [other.nodename, other.attributes, other.children] rescue nil end @@ -198,13 +211,13 @@ def tags if has_children? tags = [] tags << "<#{[nodename, *attribute_assignments].join(' ')}>" - tags << children.map do |node| + tags << children.map { |node| node.respond_to?(:tags) ? node.tags : [node.to_s] - end + }.flatten(1) tags << "</#{nodename}>" tags else ["<#{[nodename, *attribute_assignments].join(' ')}/>"] @@ -233,12 +246,21 @@ has_no_children class << self undef_method :attr_children + + # @override + def create(name, attributes = {}, &block) + klass = constantize(name) + + node = (klass || TextNode).new(attributes, &block) + node.nodename = name + node + end end - + attr_accessor :text alias to_s text # TextNodes quack like a string. # def_delegators :to_s, *String.instance_methods(false).reject do |m| @@ -267,14 +289,10 @@ def textnode? true end def tags - tags = [] - tags << "<#{attribute_assignments.unshift(nodename).join(' ')}>" - tags << text - tags << "</#{nodename}>" - tags + ["<#{attribute_assignments.unshift(nodename).join(' ')}>#{text}</#{nodename}>"] end def inspect "#<#{[self.class.name, text.inspect, *attribute_assignments].join(' ')}>" end \ No newline at end of file