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