58 lines
1.7 KiB
Ruby
58 lines
1.7 KiB
Ruby
class DiffBuilder
|
|
attr_reader :this_text, :that_text, :pattern
|
|
|
|
def initialize(this_text, that_text, pattern)
|
|
@this_text = this_text
|
|
@that_text = that_text
|
|
@pattern = pattern
|
|
end
|
|
|
|
def build
|
|
thisarr = this_text.scan(pattern)
|
|
otharr = that_text.scan(pattern)
|
|
|
|
cbo = Diff::LCS::ContextDiffCallbacks.new
|
|
diffs = otharr.diff(thisarr, cbo)
|
|
|
|
escape_html = ->(str) {str.gsub(/&/, '&').gsub(/</, '<').gsub(/>/, '>')}
|
|
|
|
output = otharr
|
|
output.each { |q| q.replace(escape_html[q]) }
|
|
|
|
diffs.reverse_each do |hunk|
|
|
newchange = hunk.max {|a, b| a.old_position <=> b.old_position}
|
|
newstart = newchange.old_position
|
|
oldstart = hunk.min {|a, b| a.old_position <=> b.old_position}.old_position
|
|
|
|
if newchange.action == '+'
|
|
output.insert(newstart, '</ins>')
|
|
end
|
|
|
|
hunk.reverse_each do |chg|
|
|
case chg.action
|
|
when '-'
|
|
oldstart = chg.old_position
|
|
output[chg.old_position] = '<span class="paragraph-mark">¶</span><br>' if chg.old_element.match(/^\r?\n$/)
|
|
when '+'
|
|
if chg.new_element.match(/^\r?\n$/)
|
|
output.insert(chg.old_position, '<span class="paragraph-mark">¶</span><br>')
|
|
else
|
|
output.insert(chg.old_position, (escape_html[chg.new_element]).to_s)
|
|
end
|
|
end
|
|
end
|
|
|
|
if newchange.action == '+'
|
|
output.insert(newstart, '<ins>')
|
|
end
|
|
|
|
if hunk[0].action == '-'
|
|
output.insert((newstart == oldstart || newchange.action != '+') ? newstart + 1 : newstart, '</del>')
|
|
output.insert(oldstart, '<del>')
|
|
end
|
|
end
|
|
|
|
output.join.gsub(/\r?\n/, '<span class="paragraph-mark">¶</span><br>').html_safe
|
|
end
|
|
end
|