TDiff

Description

Calculates the differences between two tree-like structures. Similar to
Rubys built-in TSort
module.

Features

  • Provides the {TDiff} mixin.
  • Provides the {TDiff::Unordered} mixin for unordered diffing.
  • Allows custom node equality and traversal logic by overriding the {TDiff#tdiff_equal} and {TDiff#tdiff_each_child} methods.
  • Implements the Longest Common Subsequence (LCS) algorithm.

Examples

Diff two HTML documents:

require ‘nokogiri’
require ‘tdiff’

class Nokogiri::XML::Node

include TDiff

def tdiff_equal(node)
if (self.text? && node.text?)
self.text == node.text
elsif (self.respond_to?(:root) && node.respond_to?(:root))
self.root.tdiff_equal(node.root)
elsif (self.respond_to?(:name) && node.respond_to?(:name))
self.name == node.name
else
false
end
end

def tdiff_each_child(node,&block)
node.children.each(&block)
end

end

doc1 = Nokogiri::HTML(‘

one

three

’)
doc2 = Nokogiri::HTML(‘

one

two

three

’)

doc1.at(‘div’).tdiff(doc2.at(‘div’)) do |change,node|
puts “#{change} #{node.to_html}”.ljust(30) + node.parent.path
end

Output

+

one

/html/body/div
+ /html/body/div

one

/html/body/div
/html/body/div

three

/html/body/div
- one /html/body/div/p[1]
+ two /html/body/div/p[2]
three /html/body/div/p[2]

Requirements

Install

$ gem install tdiff

Copyright

See {file:LICENSE.txt} for details.