lib/csl/node.rb in csl-1.0.0.pre10 vs lib/csl/node.rb in csl-1.0.0.pre11
- old
+ new
@@ -64,34 +64,49 @@
else
default_attributes.merge(attributes)
end
end
+ def parse(data)
+ parse!(data)
+ rescue
+ nil
+ end
+
+ def parse!(data)
+ node = CSL.parse!(data, self)
+
+ raise ParseError, "root node not #{self.name}: #{node.inspect}" unless
+ node.class == self || Node.equal?(self)
+
+ node
+ end
+
private
- def has_language
- attr_accessor :language
-
- define_method :has_language? do
- !language.nil?
- end
-
- public :language, :language=, :has_language?
-
- alias_method :original_attribute_assignments, :attribute_assignments
-
- define_method :attribute_assignments do
- if has_language?
- original_attribute_assignments.unshift('xml:lang="%s"' % language)
- else
- original_attribute_assignments
- end
- end
-
- private :original_attribute_assignments, :attribute_assignments
- end
+ def has_language
+ attr_accessor :language
+ define_method :has_language? do
+ !language.nil?
+ end
+
+ public :language, :language=, :has_language?
+
+ alias_method :original_attribute_assignments, :attribute_assignments
+
+ define_method :attribute_assignments do
+ if has_language?
+ original_attribute_assignments.unshift('xml:lang="%s"' % language)
+ else
+ original_attribute_assignments
+ end
+ end
+
+ private :original_attribute_assignments, :attribute_assignments
+ end
+
def attr_defaults(attributes)
@default_attributes = attributes
end
# Creates a new Struct for the passed-in attributes. Node instances
@@ -118,17 +133,21 @@
# of the attribute variables.
def keys
__class__.keys
end
+ def symbolize_keys
+ self
+ end
+
def values
super.compact
end
- # def to_a
- # keys.zip(values_at(*keys)).reject { |k,v| v.nil? }
- # end
+ def to_hash
+ Hash[keys.zip(values_at(*keys)).reject { |_, v| v.nil? }]
+ end
# @return [Boolean] true if all the attribute values are nil;
# false otherwise.
def empty?
values.compact.empty?
@@ -190,10 +209,27 @@
@children = self.class.create_children
yield self if block_given?
end
+ def initialize_copy(other)
+ super
+ @attributes = self.class.create_attributes(other.attributes)
+ @children = self.class.create_children
+ @parent, @ancestors, @descendants, @siblings, @root, @depth = nil
+ end
+
+ def deep_copy
+ copy = dup
+
+ each_child do |child|
+ copy.add_child child.deep_copy
+ end
+
+ copy
+ end
+
# Iterates through the Node's attributes
def each
if block_given?
attributes.each_pair(&Proc.new)
self
@@ -213,13 +249,13 @@
# false otherwise.
def has_attributes?
!attributes.empty?
end
- def has_language?
- false
- end
+ def has_language?
+ false
+ end
def textnode?
false
end
alias has_text? textnode?
@@ -249,12 +285,17 @@
# no other attributes than specified by the conditions, {#exact_match?}
# should be used instead.
#
# @see #exact_match?
#
- # If the optional
- # @param name [String,Regexp] must match the nodename
+ # @example
+ # node.match?(name, conditions)
+ # node.match?(conditions)
+ # node.match?(other_node)
+ #
+ # @param name [String,Regexp,Node] must match the nodename; alternatively
+ # you can pass a node
# @param conditions [Hash] the conditions
#
# @return [Boolean] whether or not the query matches the node
def match?(name = nodename, conditions = {})
name, conditions = match_conditions_for(name, conditions)
@@ -284,11 +325,17 @@
# Note that all node attributes are used by this method – if you want
# to match only a subset of attributes {#match?} should be used instead.
#
# @see #match?
#
- # @param name [String,Regexp] must match the nodename
+ # @example
+ # node.exact_match?(name, conditions)
+ # node.exact_match?(conditions)
+ # node.exact_match?(other_node)
+ #
+ # @param name [String,Regexp,Node] must match the nodename; alternatively
+ # you can pass a node
# @param conditions [Hash] the conditions
#
# @return [Boolean] whether or not the query matches the node exactly
def exact_match?(name = nodename, conditions = {})
name, conditions = match_conditions_for(name, conditions)
@@ -301,24 +348,24 @@
condition === value
end
end
alias matches_exactly? exact_match?
- # @option filter [Array] a list of attribute names
- # @return [Hash] the node's attributes matching the filter
- def attributes_for(*filter)
- filter.flatten!
+ # @option filter [Array] a list of attribute names
+ # @return [Hash] the node's attributes matching the filter
+ def attributes_for(*filter)
+ filter.flatten!
- Hash[map { |name, value|
- !value.nil? && filter.include?(name) ? [name, value.to_s] : nil
- }.compact]
- end
+ Hash[map { |name, value|
+ !value.nil? && filter.include?(name) ? [name, value.to_s] : nil
+ }.compact]
+ end
- # @return [Hash] the node's formatting options
- def formatting_options
- attributes_for Schema.attr(:formatting)
- end
+ # @return [Hash] the node's formatting options
+ def formatting_options
+ attributes_for Schema.attr(:formatting)
+ end
def <=>(other)
[nodename, attributes, children] <=> [other.nodename, other.attributes, other.children]
rescue
nil
@@ -347,19 +394,26 @@
end
alias to_s pretty_print
+ protected
+
+ def match_conditions
+ end
+
private
def attribute_assignments
each_pair.map { |name, value|
value.nil? ? nil : [name, value.to_s.inspect].join('=')
}.compact
end
def match_conditions_for(name, conditions)
case name
+ when Node
+ [name.nodename, name.attributes.to_hash]
when Hash
conditions, name = name, nodename
when Symbol
name = name.to_s
end
\ No newline at end of file