class RichText::Document::Entry

The Entry class extends the basic Node class and adds methods that make handling text a little nicer. Essentially the :text attribute is given special status by allowing it to a) be set during initialization, b) only visible in leaf nodes and c) copied over when adding children to leaf nodes.

Some attributes are also supported explicitly by the inclusion of special accesser methods. The attributes are are bold, italic, underline, color and font.

Attributes

attributes[R]

Public Class Methods

new(text = nil, **attributes) click to toggle source

Extend the default Node initializer by also accepting a string. It will, if given, be stored as a text attribute.

Calls superclass method
# File lib/richtext/document/entry.rb, line 25
def initialize(text = nil, **attributes)
  @attributes = attributes
  super text
end

Public Instance Methods

<<(child_text = nil, **attributes)
Alias for: append_child
[](key) click to toggle source

Accessor for single attributes.

key - the attribute key

Returns the attribute value if it is set and nil otherwise.

# File lib/richtext/document/entry.rb, line 45
def [](key)
  attributes[key]
end
[]=(key, v) click to toggle source

Write a single attribute.

key - the attribute key v - the new value

# File lib/richtext/document/entry.rb, line 54
def []=(key, v)
  attributes[key] = v
end
append_child(child_text = nil, **attributes) click to toggle source

Create and append a new child, initialized with the given text and attributes.

child_text - the text of the child or an Entry object. attributes - a hash of attributes to apply to the child if child_text is

not an Entry object.

Returns self to allow chaining.

Calls superclass method
# File lib/richtext/document/entry.rb, line 83
def append_child(child_text = nil, **attributes)
  if leaf? && !text.empty?
    super self.class.new(value)
  end

  if child_text.is_a? self.class
    super child_text
  else
    super self.class.new(child_text, attributes)
  end
end
Also aliased as: <<
freeze() click to toggle source

Freeze the attributes hash, as well as the node structure.

Returns self.

Calls superclass method
# File lib/richtext/document/entry.rb, line 34
def freeze
  @attributes.freeze
  super
end
inspect(*args, &block) click to toggle source

Represents the Entry structure as a hierarchy, showing the attributes of each node as well as the text entries in the leafs.

If a block is given, it will be called once for each entry, and the returned string will be used to represent the object in the output graph.

Returns a string. Note that it will contain newline characters if the node has children.

Calls superclass method
# File lib/richtext/document/entry.rb, line 168
def inspect *args, &block
  unless block_given?
    block = proc do |entry|
      base_name = entry.leaf? ? %Q{"#{entry.text}"} : '◯'
      base_name + entry.attributes.reduce('') do |a, (k, v)|
        a + " #{k}=#{v.inspect}"
      end
    end
  end

  super(*args, &block)
end
optimize(&block) click to toggle source

Optimize a copy of the node tree based on the rules outlined for optimize!.

Returns the root of the new optimized node structure.

# File lib/richtext/document/entry.rb, line 133
def optimize(&block)
  dup.optimize!(&block)
end
optimize!(&block) click to toggle source

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.

Returns self.

# File lib/richtext/document/entry.rb, line 103
def optimize!(&block)
  # If the node is a leaf it cannot be optimized further
  return self if leaf?

  block = proc { |e| e.leaf? && e.text.empty? } unless block_given?

  children.each do |child|
    child.delete if block.call child.optimize!(&block)
  end

  # 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 degree == 1
    # Move the attributes over
    attributes.merge! child.attributes
    self.value = child.text
    # Get the children of the child and add them to self
    first_child.delete.each { |child| append_child child }
  end

  self
end
text() click to toggle source

Read the text of the node.

Returns the string stored in the node, if it is a leaf. Otherwise nil.

# File lib/richtext/document/entry.rb, line 62
def text
  value || '' if leaf?
end
text=(new_text) click to toggle source

Write the text of the node. The method will raise a RuntimeException if the node is not a leaf.

# File lib/richtext/document/entry.rb, line 69
def text=(new_text)
  raise 'Only leafs can have a text entry' unless leaf?
  self.value = new_text
end
to_s() { |self, string| ... } click to toggle source

Combine the text from all the leaf nodes in the tree, from left to right. If a block is given the node, along with its text will be passed as arguments. The block will be called recursivly, starting at the leaf nodes and propagating up until the entire tree has been “rendered” in this way.

block - a block that will be used to generate strings for each node.

Returns a string representation of the node structure.

# File lib/richtext/document/entry.rb, line 147
def to_s(&block)
  string =
    if leaf?
      text
    else
      children.reduce('') { |a, e| a + e.to_s(&block) }
    end

  block_given? ? yield(self, string) : string
end