Module: CSL::Treelike

Included in:
Node
Defined in:
lib/csl/treelike.rb

Defined Under Namespace

Modules: ClassMethods

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#childrenObject (readonly)

Returns the value of attribute children.



6
7
8
# File 'lib/csl/treelike.rb', line 6

def children
  @children
end

#nodenameString

Returns the node’s name.

Returns:

  • (String)

    the node’s name.



16
17
18
# File 'lib/csl/treelike.rb', line 16

def nodename
  @nodename ||= self.class.name.split(/::/)[-1].gsub(/([[:lower:]])([[:upper:]])/, '\1-\2').downcase
end

#parentObject

Returns the value of attribute parent.



5
6
7
# File 'lib/csl/treelike.rb', line 5

def parent
  @parent
end

Instance Method Details

#<<(node) ⇒ Object



83
84
85
86
# File 'lib/csl/treelike.rb', line 83

def <<(node)
  add_child node
  self
end

#add_child(node) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
81
# 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) ⇒ Object



61
62
63
64
65
66
# File 'lib/csl/treelike.rb', line 61

def add_children(*nodes)
  nodes.each do |node|
    add_child node
  end
  self
end

#ancestorsObject



194
195
196
# File 'lib/csl/treelike.rb', line 194

def ancestors
  @ancestors = each_ancestor.to_a
end

#delete_child(child) ⇒ Object

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.



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# 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) ⇒ Object Also known as: delete



29
30
31
32
33
# File 'lib/csl/treelike.rb', line 29

def delete_children(*nodes)
  nodes.each do |node|
    delete_child node
  end
end

#depthFixnum

Returns the node’s current depth in the tree.

Returns:

  • (Fixnum)

    the node’s current depth in the tree



199
200
201
# File 'lib/csl/treelike.rb', line 199

def depth
  @depth = ancestors.length
end

#descendantsObject

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



174
175
176
# File 'lib/csl/treelike.rb', line 174

def descendants
  @descendants = each_descendant.to_a
end

#each_ancestorObject



178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/csl/treelike.rb', line 178

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_childObject



20
21
22
23
24
25
26
27
# File 'lib/csl/treelike.rb', line 20

def each_child
  if block_given?
    children.each(&Proc.new)
    self
  else
    enum_for :each_child
  end
end

#each_descendantObject

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



159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/csl/treelike.rb', line 159

def each_descendant
  if block_given?
    each_child do |child|
      yield child
      child.each_descendant(&Proc.new)
    end

    self
  else
    enum_for :each_descendant
  end
end

#each_siblingObject



140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/csl/treelike.rb', line 140

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?Boolean

Returns true if this node has no child nodes; false otherwise.

Returns:

  • (Boolean)

    true if this node has no child nodes; false otherwise.



123
124
125
# File 'lib/csl/treelike.rb', line 123

def empty?
  children.empty?
end

#find_child(name, conditions = {}) ⇒ Node? Also known as: >

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

Parameters:

  • name (String, Regexp)

    the node name to match

  • conditions (Hash) (defaults to: {})

    the attributes to match

Returns:

  • (Node, nil)

    the first matching child node



95
96
97
98
99
# File 'lib/csl/treelike.rb', line 95

def find_child(name, conditions = {})
  children.detect do |child|
    child.match?(name, conditions)
  end
end

#find_children(name, conditions = {}) ⇒ Array<Node> Also known as: >>

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.

Parameters:

  • name (String, Regexp)

    the node name to match

  • conditions (Hash) (defaults to: {})

    the attributes to match

Returns:

  • (Array<Node>)

    all matching child nodes



110
111
112
113
114
# File 'lib/csl/treelike.rb', line 110

def find_children(name, conditions = {})
  children.select do |child|
    child.match?(name, conditions)
  end
end

#has_children?Boolean

Returns true if this node has child nodes; false otherwise.

Returns:

  • (Boolean)

    true if this node has child nodes; false otherwise.



118
119
120
# File 'lib/csl/treelike.rb', line 118

def has_children?
  !empty?
end

#rootNode

Returns the root node.

Returns:

  • (Node)

    the root node



204
205
206
# File 'lib/csl/treelike.rb', line 204

def root
  @root = root? ? self : parent.root!
end

#root?Boolean

Returns:

  • (Boolean)


209
210
211
# File 'lib/csl/treelike.rb', line 209

def root?
  parent.nil?
end

#siblingsObject



154
155
156
# File 'lib/csl/treelike.rb', line 154

def siblings
  @siblings = each_sibling.to_a
end

Unlinks the node and all its children from its parent node. Returns the old parent node or nil.



129
130
131
132
133
134
135
136
137
138
# File 'lib/csl/treelike.rb', line 129

def unlink
  return nil if root?

  other = parent
  other.delete_child self

  self.parent = nil

  other
end