Class: RichText::Document

Inherits:
Object
  • Object
show all
Defined in:
lib/richtext/document.rb,
lib/richtext/document/entry.rb

Overview

Document

Defined Under Namespace

Classes: Entry

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(arg = '') ⇒ Document

Create a new RichText Document, either from a string or from an existing document. That feature is particularly useful when converting between formats.

When given a string or a RichText Document of the same class no parsing is performed. Only when given a document of a different subclass will the parser need to be run parsed. Note that the document(s) may already be in parsed form, in which case no further parsing is performed. See #root for more details.



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/richtext/document.rb', line 20

def initialize(arg = '')
  @root, @raw =
    if arg.instance_of? self.class
      arg.parsed? ? [arg.root, nil] : [nil, arg.raw]
    elsif arg.is_a? Document
      # For any other RichText object we take the root node
      [arg.root, nil]
    elsif arg.is_a? Entry
      # Also accept an Entry which will be used as the
      # document root
      [arg.root, nil]
    else
      [nil, arg.to_s]
    end
end

Class Method Details

.from(doc) ⇒ Object

Convenience method for instansiating one RichText object from another. The methods only purpose is to make that intent more clear, and to make the creation from another RichText object explicit.



165
166
167
168
169
170
171
172
# File 'lib/richtext/document.rb', line 165

def self.from(doc)
  unless doc.is_a? Document
    raise TypeError,
          "Can only create a #{name} from other RichText Documents"
  end

  new doc
end

.parse(root, string) ⇒ Object

Document type specific method for parsing a string and turning it into a tree of entry nodes. This method is intended to be overridden when the Document is subclassed. The default implementation just creates a top level Entry containing the given string.



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

def self.parse(root, string)
  root.text = string
end

.render(root) ⇒ Object

Document type specific method for rendering a tree of entry nodes. This method is intended to be overridden when the Document is subclassed. The default implementation just concatenates the text entries into.



157
158
159
# File 'lib/richtext/document.rb', line 157

def self.render(root)
  root.to_s
end

Instance Method Details

#+(other) ⇒ Object

Add another Document to this one. If the two are of (exactly) the same class and neither one has been parsed, the two raw strings will be concatenated. If the other is a Document the two root nodes will be merged and the new root added to a new Document.

Lastly, if other is a string it will first be wraped in a new Document and then added to this one.



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/richtext/document.rb', line 73

def +(other)
  # If the other object is of the same class, and neither
  # one of the texts have been parsed, we can concatenate
  # the raw inputs together
  if other.class == self.class && !parsed? && !other.parsed?
    return self.class.new(@raw + other.raw)
  end

  # Same root class
  return self.class.new(root + other.root) if other.is_a? Document

  unless other.respond_to? :to_s
    raise TypeError,
          "Cannot add #{other.class.name} to #{self.class.name}"
  end

  # Assume that the input is a raw string of the same
  # class as the current RichText object and wrap it
  # before adding it
  self + self.class.new(other)
end

#append(string, **attributes) ⇒ Object

Append a string to the document. The string will not be parsed but inserted into a new entry, directly under the document root.

string - the string that will be wrapped in an Entry object. attributes - a hash of attributes that will be applied to the Entry.

Returns the newly created child.



103
104
105
106
# File 'lib/richtext/document.rb', line 103

def append(string, **attributes)
  root.append_child string, **attributes
  root.child(-1)
end

#each_node(&block) ⇒ Object Also known as: each_entry

Iterate over all Entry nodes in the document tree.



138
139
140
# File 'lib/richtext/document.rb', line 138

def each_node(&block)
  root.each(&block)
end

#parsed?Boolean

Returns true if the raw input has been parsed and the internal representation is now a tree of nodes.

Returns:

  • (Boolean)


128
129
130
# File 'lib/richtext/document.rb', line 128

def parsed?
  @raw.nil?
end

#rootObject Also known as: base

Getter for the root node. If the raw input has not yet been parsed that will happen first, before the root node is returned.

Returns the root Entry.



113
114
115
116
117
118
119
120
121
# File 'lib/richtext/document.rb', line 113

def root
  unless @root
    @root = Entry.new
    self.class.parse @root, @raw
    @raw = nil
  end

  @root
end

#to_plainObject

Uses Entry#to_s to reduce the node structure down to a string.

Returns the strings from all of the leaf nodes without any formatting applied.



61
62
63
# File 'lib/richtext/document.rb', line 61

def to_plain
  root.to_s
end

#to_s(&block) ⇒ Object

Uses the static implementation of .render to convert the document back into a string. If the document was never parsed (and is unchanged) the origninal string is just returned.

If a block is given it will be used in place of .render to format the node tree.

Returns a string formatted according to the rules outlined by the Document format.



46
47
48
49
50
51
52
53
54
# File 'lib/richtext/document.rb', line 46

def to_s(&block)
  if block_given?
    root.to_s(&block)
  elsif parsed? || should_parse?
    self.class.render root
  else
    @raw
  end
end