Skip to content

Instantly share code, notes, and snippets.

@robhurring
Created March 26, 2010 20:20
Show Gist options
  • Save robhurring/345342 to your computer and use it in GitHub Desktop.
Save robhurring/345342 to your computer and use it in GitHub Desktop.
Ruby Diff -- Ghetto style!
require 'tempfile'
# TODO: do some pre-comparison on a and b so we can skip creating temp files and all that jazz.
# NOTE: this is so ghetto ;)
module Diffable
def diff(b, options = {})
Diff.new(self, b, options).diff
end
end
class Diff
attr_reader :output, :changed
alias_method :changed?, :changed
alias_method :to_s, :output
def initialize(a, b, options = {})
@a = a.to_str
@b = b.to_str
@options = options
@changed = false
@output = ''
end
def diff
file_a = string_to_file('a', @a).path
file_b = string_to_file('b', @b).path
@output = format_output(`diff --unified=-1 #{file_a} #{file_b}`)
@changed = !@output.strip.empty?
self
end
def to_html(options = {})
diff.output.each_line.inject("") do |output, line|
output + \
case line[0]
when '@'
"<div class='#{options[:meta_class] || 'diff_meta'}'>#{line}</div>"
when '-'
"<div class='#{options[:sub_class] || 'diff_sub'}'>#{line}</div>"
when '+'
"<div class='#{options[:add_class] || 'diff_add'}'>#{line}</div>"
else
line
end
end
end
def to_s
output
end
private
def string_to_file(key, data)
Tempfile.open("#{key}.tmp_diff") do |file|
file << data.to_str
end
end
def format_output(output)
output.gsub! /\-{3}.+/, "--- #{@options[:mine]}" if @options[:mine]
output.gsub! /\+{3}.+/, "+++ #{@options[:theirs]}" if @options[:theirs]
output
end
end
class String
include Diffable
end
require 'diff'
require 'pp'
original = "
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Donec convallis urna nec magna ornare sit amet molestie leo dapibus.
Maecenas augue tortor, eleifend sed consectetur consectetur, aliquet et risus.
Suspendisse eu tellus ac quam adipiscing placerat.
In a erat quis dui euismod interdum.
In sapien lacus, suscipit sit amet faucibus sit amet, malesuada vehicula purus.
Etiam in odio ut urna viverra rhoncus.
Etiam ultricies tellus a metus adipiscing rutrum.
"
modified = "
Donec convallis urna nec magna ornare sit amet molestie leo dapibus.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Etiam in odio ut urna viverra rhoncus.
Etiam ultricies tellus a metus adipiscing rutrum.
Suspendisse eu tellus ac quam adipiscing placerat.
In sapien lacus, suscipit sit amet faucibus sit amet, malesuada vehicula purus.
In a erat quis dui euismod interdum.
Maecenas augue tortor, eleifend sed consectetur consectetur, aliquet et risus.
"
puts original.diff(modified, :mine => 'original', :theirs => 'modified')
__END__
--- original
+++ modified
@@ -1,9 +1,9 @@
-Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Donec convallis urna nec magna ornare sit amet molestie leo dapibus.
-Maecenas augue tortor, eleifend sed consectetur consectetur, aliquet et risus.
-Suspendisse eu tellus ac quam adipiscing placerat.
-In a erat quis dui euismod interdum.
-In sapien lacus, suscipit sit amet faucibus sit amet, malesuada vehicula purus.
+Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Etiam in odio ut urna viverra rhoncus.
Etiam ultricies tellus a metus adipiscing rutrum.
+Suspendisse eu tellus ac quam adipiscing placerat.
+In sapien lacus, suscipit sit amet faucibus sit amet, malesuada vehicula purus.
+In a erat quis dui euismod interdum.
+Maecenas augue tortor, eleifend sed consectetur consectetur, aliquet et risus.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment