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



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

def ancestors
  @ancestors = each_ancestor.to_a
end

#closest(name, conditions = {}) ⇒ Object



117
118
119
120
121
122
123
124
125
126
# 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_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.flatten.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



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

def depth
  @depth = ancestors.length
end

#descendantsObject

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



185
186
187
# File 'lib/csl/treelike.rb', line 185

def descendants
  @descendants = each_descendant.to_a
end

#each_ancestorObject



189
190
191
192
193
194
195
196
197
198
199
200
201
202
# 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) ⇒ Object



20
21
22
23
24
25
26
27
# 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(&block) ⇒ Object

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



170
171
172
173
174
175
176
177
178
179
180
181
# 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_siblingObject



151
152
153
154
155
156
157
158
159
160
161
162
163
# 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?Boolean

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

Returns:

  • (Boolean)

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



134
135
136
# File 'lib/csl/treelike.rb', line 134

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.



129
130
131
# File 'lib/csl/treelike.rb', line 129

def has_children?
  !empty?
end

#rootNode

Returns the root node.

Returns:

  • (Node)

    the root node



215
216
217
# File 'lib/csl/treelike.rb', line 215

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

#root?Boolean

Returns:

  • (Boolean)


220
221
222
# File 'lib/csl/treelike.rb', line 220

def root?
  parent.nil?
end

#siblingsObject



165
166
167
# File 'lib/csl/treelike.rb', line 165

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.



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

def unlink
  return nil if root?

  other = parent
  other.delete_child self

  self.parent = nil

  other
end