module CSL::Treelike

Attributes

children[R]
nodename[W]
parent[RW]

Public Class Methods

included(base) click to toggle source
# File lib/csl/treelike.rb, line 11
def self.included(base)
  base.extend(ClassMethods)
end

Public Instance Methods

<<(node) click to toggle source
# File lib/csl/treelike.rb, line 83
def <<(node)
  add_child node
  self
end
>(name, conditions = {})
Alias for: find_child
>>(name, conditions = {})
Alias for: find_children
add_child(node) click to toggle source
# File lib/csl/treelike.rb, line 68
def add_child(node)
  node.unlink

  node.parent = self
  children << node

  added_child node
  node.added_to self

  node
rescue => e
  # TODO rollback
  raise e
end
add_children(*nodes) click to toggle source
# File lib/csl/treelike.rb, line 61
def add_children(*nodes)
  nodes.each do |node|
    add_child node
  end
  self
end
ancestors() click to toggle source

@returns this node's ancestors as an array

# File lib/csl/treelike.rb, line 205
def ancestors
  @ancestors = each_ancestor.to_a
end
closest(name, conditions = {}) click to toggle source
# File lib/csl/treelike.rb, line 117
def closest(name, conditions = {})
  case
  when root?
    nil
  when parent.match?(name, conditions)
    parent
  else
    parent.closest(name, conditions)
  end
end
delete(*nodes)
Alias for: delete_children
delete_child(child) { || ... } click to toggle source

Deletes child nodes that are equal to the passed-in node. Returns all deleted children. If no children were deleted, returns nil. If the optional block is given, returns the result block if no children were deleted.

# File lib/csl/treelike.rb, line 40
def delete_child(child)
  deleted = children.delete child

  case
  when deleted.nil? && block_given?
    yield
  when deleted.nil?
    nil
  else
    deleted.parent = nil

    deleted_child deleted
    deleted.deleted_from self

    deleted
  end
rescue => e
  # TODO rollback
  raise e
end
delete_children(*nodes) click to toggle source
# File lib/csl/treelike.rb, line 29
def delete_children(*nodes)
  nodes.flatten.each do |node|
    delete_child node
  end
end
Also aliased as: delete
depth() click to toggle source

@return [Fixnum] the node's current depth in the tree

# File lib/csl/treelike.rb, line 210
def depth
  @depth = ancestors.length
end
descendants() click to toggle source

Returns all descendants of the node. See {#descendants!} for a memoized version.

# File lib/csl/treelike.rb, line 185
def descendants
  @descendants = each_descendant.to_a
end
each_ancestor() { |p| ... } click to toggle source
# File lib/csl/treelike.rb, line 189
def each_ancestor
  if block_given?
    p = parent

    until p.nil?
      yield p
      p = p.parent
    end

    self
  else
    enum_for :each_ancestor
  end
end
each_child(&block) click to toggle source
# File lib/csl/treelike.rb, line 20
def each_child(&block)
  if block_given?
    children.each(&block)
    self
  else
    enum_for :each_child
  end
end
each_descendant() { |child| ... } click to toggle source

Traverses the node's sub-tree in depth-first order.

# File lib/csl/treelike.rb, line 170
def each_descendant(&block)
  if block_given?
    each_child do |child|
      yield child
      child.each_descendant(&block)
    end

    self
  else
    enum_for :each_descendant
  end
end
each_sibling() { |node| ... } click to toggle source
# File lib/csl/treelike.rb, line 151
def each_sibling
  if block_given?
    unless root?
      parent.children.each do |node|
        yield node unless node.equal?(self)
      end
    end

    self
  else
    enum_for :each_sibling
  end
end
empty?() click to toggle source

@return [Boolean] true if this node has no child nodes; false otherwise.

# File lib/csl/treelike.rb, line 134
def empty?
  children.empty?
end
find_child(name, conditions = {}) click to toggle source

Returns the first immediate child node whose nodename matches the passed-in name/pattern and attribute conditions.

@param name [String,Regexp] the node name to match @param conditions [Hash] the attributes to match

@return [Node,nil] the first matching child node

# File lib/csl/treelike.rb, line 95
def find_child(name, conditions = {})
  children.detect do |child|
    child.match?(name, conditions)
  end
end
Also aliased as: >
find_children(name, conditions = {}) click to toggle source

Returns all immediate child nodes whose nodename matches the passed-in name/pattern and attribute conditions; returns an empty array if there is no match.

@param name [String,Regexp] the node name to match @param conditions [Hash] the attributes to match

@return [Array<Node>] all matching child nodes

# File lib/csl/treelike.rb, line 110
def find_children(name, conditions = {})
  children.select do |child|
    child.match?(name, conditions)
  end
end
Also aliased as: >>
has_children?() click to toggle source

@return [Boolean] true if this node has child nodes; false otherwise.

# File lib/csl/treelike.rb, line 129
def has_children?
  !empty?
end
nodename() click to toggle source

@return [String] the node's name.

# File lib/csl/treelike.rb, line 16
def nodename
  @nodename ||= self.class.name.split(/::/)[-1].gsub(/([[:lower:]])([[:upper:]])/, '\1-\2').downcase
end
root() click to toggle source

@return [Node] the root node

# File lib/csl/treelike.rb, line 215
def root
  @root = root? ? self : parent.root!
end
root?() click to toggle source

@returns [Boolean] whether or not the node is the tree's root node

# File lib/csl/treelike.rb, line 220
def root?
  parent.nil?
end
siblings() click to toggle source
# File lib/csl/treelike.rb, line 165
def siblings
  @siblings = each_sibling.to_a
end

Protected Instance Methods

added_to(node) click to toggle source

@abstract Called after the node was added to another node.

# File lib/csl/treelike.rb, line 245
def added_to(node)
end
deleted_from(node) click to toggle source

@abstract Called when the node was deleted from an other node.

# File lib/csl/treelike.rb, line 250
def deleted_from(node)
end

Private Instance Methods

added_child(node) click to toggle source

@abstract Called when the passed-in node was added to this node as a child.

# File lib/csl/treelike.rb, line 257
def added_child(node)
end
deleted_child(node) click to toggle source

@abstract Called when the passed-in node was deleted from this node's child nodes.

# File lib/csl/treelike.rb, line 262
def deleted_child(node)
end