#!/usr/bin/ruby -w require 'algorithm/diff' module Diff class Hunk attr_reader :type, :content def initialize(type, content) @type = type @content = content end end def Diff.word_diff(s1, s2) words = [s1, s2].collect { |str| str.split(/\b(?=\w)/xm) } differences = diff(words[0], words[1]) # Same string return [ Hunk.new(:both, s1) ] if differences.length == 0 hunks = [] # Adding lengths that are the same involves a similar operation # three times. Using a proc allows knowledge of private # data without having to make this a class push_identical = proc { |beginning, ending| return unless ending - beginning > 1 hunks.push(Hunk.new(:both, words[0][beginning..ending-1].join)) } # Leading identical stuff push_identical.call(0, differences[0][1]) differences.each_with_index { |d, i| hunks.push(Hunk.new(d[0] == :+ ? :right : :left, d[2].join)) push_identical.call(differences[i][1], differences[i + 1][1]) unless differences[i + 1].nil? } # Trailing identical stuff push_identical.call(differences[-1][1] + 1, words[0].length) return hunks end end