module Diffy
class HtmlFormatter
def initialize(diff, options = {})
@diff = diff
@options = options
end
def to_s
if @options[:highlight_words]
wrap_lines(highlighted_words)
else
wrap_lines(@diff.map{|line| wrap_line(ERB::Util.h(line))})
end
end
private
def wrap_line(line)
cleaned = line.gsub(/^./, '').chomp
case line
when /^\+/
'
' + cleaned + ''
when /^-/
' ' + cleaned + ''
when /^ /
' ' + cleaned + ''
end
end
def wrap_lines(lines)
%'\n'
end
def highlighted_words
chunks = @diff.each_chunk.to_a
processed = []
lines = chunks.each_with_index.map do |chunk1, index|
next if processed.include? index
processed << index
chunk1 = chunk1
chunk2 = chunks[index + 1]
if not chunk2
next chunk1
end
chunk1 = ERB::Util.h(chunk1)
chunk2 = ERB::Util.h(chunk2)
dir1 = chunk1.each_char.first
dir2 = chunk2.each_char.first
case [dir1, dir2]
when ['-', '+']
line_diff = Diffy::Diff.new(
split_characters(chunk1),
split_characters(chunk2)
)
hi1 = reconstruct_characters(line_diff, '-')
hi2 = reconstruct_characters(line_diff, '+')
processed << (index + 1)
[hi1, hi2]
else
chunk1
end
end.flatten
lines.map{|line| line.each_line.map(&:chomp).to_a if line }.flatten.compact.
map{|line|wrap_line(line) }.compact
end
def split_characters(chunk)
chunk.gsub(/^./, '').each_line.map do |line|
line.chomp.split('') + ['\n']
end.flatten.join("\n")
end
def reconstruct_characters(line_diff, type)
line_diff.each_chunk.map do |l|
re = /(^|\\n)#{Regexp.escape(type)}/
case l
when re
"" + l.gsub(re, '').gsub("\n", '').
gsub('\n', "\n") + ""
when /^ /
l.gsub(/^./, '').gsub("\n", '').
gsub('\r', "\r").gsub('\n', "\n")
end
end.join('').split("\n").map do |l|
type + l
end
end
end
end