Class: Deltoid
- Inherits:
-
Object
- Object
- Deltoid
- Defined in:
- lib/deltoid.rb
Class Method Summary collapse
-
.all_children_are_text?(node) ⇒ Boolean
(Internal API).
- .attributes(node) ⇒ Object
-
.attributes_match?(nodes) ⇒ Boolean
Do the attributes of the
nodes
match?. -
.content_match?(nodes) ⇒ Boolean
Does the content of the
nodes
match? (Note: only applies to nodes whose children are all text nodes.). -
.delta_children_nodes(nodes) ⇒ Object
Returns an array of nodes that are different between
nodes
. -
.delta_documents(documents) ⇒ Object
Returns an array of nodes that are different between
documents
. -
.delta_nodes(nodes) ⇒ Object
Returns an array of nodes that are different between
nodes
. - .delta_nodes_group(nodes_group) ⇒ Object
-
.find_deltas(nodes_group, matches_group) ⇒ Object
Figure out the deltas (differences) based on:
nodes_group
(an array of array of nodes)matches_group
(an array of array of nodes). -
.find_match(the_node, nodes) ⇒ Object
If
the_node
matches a node innode_group
, return the latter node. -
.find_matches_group(all_nodes_group) ⇒ Object
Parameters:
all_nodes_group
is an array of an array of nodes, with the same length as the number of documents being diffed. -
.find_matches_in(node, remaining_nodes_group) ⇒ Object
If
node
can be found in each ofremaining_nodes_group
, return an array of each matching node. - .friendly_deltas(deltas, root_nodes) ⇒ Object
-
.match?(nodes) ⇒ Boolean
Do the
nodes
match?. -
.parse(item) ⇒ Object
(Internal API).
Instance Method Summary collapse
-
#delta ⇒ Object
Find the differences between the documents.
-
#initialize(strings) ⇒ Deltoid
constructor
A new instance of Deltoid.
Constructor Details
#initialize(strings) ⇒ Deltoid
Returns a new instance of Deltoid.
7 8 9 10 |
# File 'lib/deltoid.rb', line 7 def initialize(strings) @strings = strings @parsed = @strings.map { |s| self.class.parse(s) } end |
Class Method Details
.all_children_are_text?(node) ⇒ Boolean
(Internal API)
145 146 147 |
# File 'lib/deltoid.rb', line 145 def self.all_children_are_text?(node) node.children.all? { |x| x.text? } end |
.attributes(node) ⇒ Object
135 136 137 138 139 140 141 142 |
# File 'lib/deltoid.rb', line 135 def self.attributes(node) map = {} node.attributes.values.each do |attribute| name, value = attribute.name, attribute.value map[name] = value end map end |
.attributes_match?(nodes) ⇒ Boolean
Do the attributes of the nodes
match?
122 123 124 125 |
# File 'lib/deltoid.rb', line 122 def self.attributes_match?(nodes) attributes = nodes.map { |node| attributes(node) }.uniq attributes.length == 1 end |
.content_match?(nodes) ⇒ Boolean
Does the content of the nodes
match? (Note: only applies to nodes whose children are all text nodes.)
129 130 131 132 133 |
# File 'lib/deltoid.rb', line 129 def self.content_match?(nodes) return true if nodes.any? { |node| !all_children_are_text?(node) } content = nodes.map { |node| node.content }.uniq content.length == 1 end |
.delta_children_nodes(nodes) ⇒ Object
Returns an array of nodes that are different between nodes
.
45 46 47 48 |
# File 'lib/deltoid.rb', line 45 def self.delta_children_nodes(nodes) children = nodes.map { |node| node.children.select { |k| k.element? } } delta_nodes_group(children) end |
.delta_documents(documents) ⇒ Object
Returns an array of nodes that are different between documents
.
30 31 32 33 |
# File 'lib/deltoid.rb', line 30 def self.delta_documents(documents) roots = documents.map { |document| document.root } delta_nodes(roots) end |
.delta_nodes(nodes) ⇒ Object
Returns an array of nodes that are different between nodes
.
Idea: could this be rewritten as a special case of delta_nodes_group?
38 39 40 41 42 |
# File 'lib/deltoid.rb', line 38 def self.delta_nodes(nodes) deltas = [] deltas.concat(nodes) unless match?(nodes) deltas.concat(delta_children_nodes(nodes)) end |
.delta_nodes_group(nodes_group) ⇒ Object
50 51 52 53 54 55 56 57 |
# File 'lib/deltoid.rb', line 50 def self.delta_nodes_group(nodes_group) matches_group = find_matches_group(nodes_group) deltas = find_deltas(nodes_group, matches_group) matches_group.each do |matches| deltas.concat(delta_children_nodes(matches)) end deltas end |
.find_deltas(nodes_group, matches_group) ⇒ Object
Figure out the deltas (differences) based on:
+nodes_group+ (an array of array of nodes)
+matches_group+ (an array of array of nodes)
111 112 113 |
# File 'lib/deltoid.rb', line 111 def self.find_deltas(nodes_group, matches_group) nodes_group.flatten - matches_group.flatten end |
.find_match(the_node, nodes) ⇒ Object
If the_node
matches a node in node_group
, return the latter node. Otherwise, return nil.
Note: stops after finding the first match.
101 102 103 104 105 106 |
# File 'lib/deltoid.rb', line 101 def self.find_match(the_node, nodes) nodes.each do |node| return node if match?([the_node, node]) end nil end |
.find_matches_group(all_nodes_group) ⇒ Object
Parameters:
+all_nodes_group+ is an array of an array of nodes, with the same
length as the number of documents being diffed.
Returns:
an array of array of nodes that match each other
64 65 66 67 68 69 70 71 72 73 |
# File 'lib/deltoid.rb', line 64 def self.find_matches_group(all_nodes_group) first_nodes = all_nodes_group.first remaining_nodes_group = all_nodes_group.drop(1) matches_group = [] first_nodes.each do |node| matches = find_matches_in(node, remaining_nodes_group) matches_group << matches unless matches.empty? end matches_group end |
.find_matches_in(node, remaining_nodes_group) ⇒ Object
If node
can be found in each of remaining_nodes_group
, return an array of each matching node. Otherwise, return [].
Parameters:
+nodes_group+ is an array of an array of nodes, with the same length
as the number of documents being diffed.
Returns:
An array containing each matched node; otherwise [].
83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/deltoid.rb', line 83 def self.find_matches_in(node, remaining_nodes_group) matches = [node] remaining_nodes_group.each do |nodes_group| match = find_match(node, nodes_group) if match matches << match else matches = [] break end end matches end |
.friendly_deltas(deltas, root_nodes) ⇒ Object
18 19 20 21 22 23 24 25 26 27 |
# File 'lib/deltoid.rb', line 18 def self.friendly_deltas(deltas, root_nodes) deltas.map do |delta| root = delta.ancestors.last { :index => root_nodes.find_index(root), :content => delta.content, :xpath => delta.path, } end end |
.match?(nodes) ⇒ Boolean
Do the nodes
match?
116 117 118 119 |
# File 'lib/deltoid.rb', line 116 def self.match?(nodes) names = nodes.map { |node| node.name }.uniq names.length == 1 && attributes_match?(nodes) && content_match?(nodes) end |
.parse(item) ⇒ Object
(Internal API)
150 151 152 |
# File 'lib/deltoid.rb', line 150 def self.parse(item) Nokogiri::HTML::Document.parse(item) end |
Instance Method Details
#delta ⇒ Object
Find the differences between the documents.
13 14 15 16 |
# File 'lib/deltoid.rb', line 13 def delta deltas = self.class.delta_documents(@parsed) self.class.friendly_deltas(deltas, @parsed) end |