Class: RichText::Node

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/richtext/node.rb

Direct Known Subclasses

Document::Entry

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(**attributes) ⇒ Node



30
31
32
33
34
# File 'lib/richtext/node.rb', line 30

def initialize **attributes
  @children   = []
  @attributes = attributes
  #@attributes[:text] = text if text
end

Instance Attribute Details

#attributesObject (readonly)

Returns the value of attribute attributes.



28
29
30
# File 'lib/richtext/node.rb', line 28

def attributes
  @attributes
end

Instance Method Details

#+(other) ⇒ Object

Add (+)

Combines two nodes by creating a new root and adding the two as children.



82
83
84
# File 'lib/richtext/node.rb', line 82

def + other
  self.class.new.tap {|root| root.add self, other }
end

#==(other) ⇒ Object

Deep equality (include children)

Returns true if the other node has the same attributes and its children are also identical.



213
214
215
216
217
218
219
220
221
222
223
# File 'lib/richtext/node.rb', line 213

def == other
  # First make sure the nodes child count matches
  return false unless count == other.count
  
  # The nodes are not equal if their attributes do not
  # match
  return false unless self === other
  
  # Lastly make sure all of the children are equal
  each_child.zip(other.each_child).all? {|c| c[0] == c[1] }
end

#===(other) ⇒ Object

Shallow equality (exclude children)

Returns true if the other node has the exact same attributes.



203
204
205
# File 'lib/richtext/node.rb', line 203

def === other
  @attributes == other.attributes
end

#[](attribute) ⇒ Object

Attribute accessor

Read and write an attribute of the node. Attributes are simply key-value pairs stored internally in a hash.



136
137
138
# File 'lib/richtext/node.rb', line 136

def [] attribute
  @attributes[attribute]
end

#[]=(attribute, value) ⇒ Object



140
141
142
# File 'lib/richtext/node.rb', line 140

def []= attribute, value
  @attributes[attribute] = value
end

#add(*new_children) ⇒ Object Also known as: <<

Add child

A child is either another node or any object that respond to #to_s.



67
68
69
70
71
72
73
# File 'lib/richtext/node.rb', line 67

def add *new_children
  new_children.each do |c|
    @children << ((Node === c) ? c : self.class.new(c))
  end

  @children
end

#countObject

Count

Returns the child count of this node.



149
150
151
# File 'lib/richtext/node.rb', line 149

def count
  @children.size
end

#each {|_self| ... } ⇒ Object

Each

Iterate over each node in the tree, including self.

Yields:

  • (_self)

Yield Parameters:



91
92
93
94
95
96
97
98
99
100
# File 'lib/richtext/node.rb', line 91

def each &block
  return to_enum(__callee__) unless block_given?
  
  yield self
        
  @children.each do |child|
    yield child
    child.each(&block) unless child.leaf?
  end
end

#each_child(&block) ⇒ Object

Each child

Iterate over the children of this node.



126
127
128
# File 'lib/richtext/node.rb', line 126

def each_child &block
  @children.each(&block)
end

#each_leaf(&block) ⇒ Object

Each Leaf

Iterate over each leaf in the tree. This method will yield the leaf nodes of the tree from left to right.



108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/richtext/node.rb', line 108

def each_leaf &block
  return to_enum(__callee__) unless block_given?
  return yield self if leaf?
  
  @children.each do |child|
    if child.leaf?
      yield child
    else
      child.each_leaf(&block)
    end
  end
end

#initialize_copy(original) ⇒ Object



37
38
39
40
# File 'lib/richtext/node.rb', line 37

def initialize_copy original
  @children   = original.children.map(&:dup)
  @attributes = original.attributes.dup
end

#inspectObject



226
227
228
229
230
231
232
# File 'lib/richtext/node.rb', line 226

def inspect
  children = @children.reduce(''){|s, c| 
      s + "\n" + c.inspect.gsub(/(^)/) { $1 + '  ' }}
      
  "#<%{name} %<a>p:%<id>#x>%{children}" % {
      name: self.class.name, id: self.object_id, a: @attributes, children: children}
end

#leaf?Boolean

Leaf?

Returns true if this node a leaf (childless) node.



47
48
49
# File 'lib/richtext/node.rb', line 47

def leaf?
  @children.empty?
end

#minimal?Boolean

Minimal?

Test if the tree under this node is minimal or not. A non minimal tree contains children which themselvs only have one child.



168
169
170
# File 'lib/richtext/node.rb', line 168

def minimal?
  all? {|node| node.count != 1 }
end

#optimize!Object

Optimize!

Go through each child and merge any node that a) is not a lead node and b) only has one child, with its child. The attributes of the child will override those of the parent.



179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/richtext/node.rb', line 179

def optimize!
  # If the node is a leaf it cannot be optimized further
  return if leaf?
  
  # First optimize each of the children
  @children.map(&:optimize!)
  
  # If we only have one child it is superfluous and
  # should be merged. That means this node will inherrit
  # the children of the single child as well as its
  # attributes
  if count == 1
    child = @children[0]
    # Move the children over
    @children = child.children
    @attributes.merge! child.attributes
  end
end

#sizeObject

Size

Returns the size of the tree where this node is the root.



158
159
160
# File 'lib/richtext/node.rb', line 158

def size
  @children.reduce(1) {|total, child| total + child.size }
end