Draw diff-lcs for human reading

I use the diff-lcs gem to output the difference between the two bodies of html content. Here is the contents of the sample.

Version One:

<p>Paragraph one. Sentence one.</p> <p>Paragraph two. Another sentence.</p> <p>Paragraph three. I dare you to change me!</p> 

Second version:

 <p>Paragraph one. Sentence two.</p> <p>Paragraph two. Another sentence.</p> <p>Paragraph three. I dare you to update me!</p> 

Using this:

 seq1 = @versionOne.body seq2 = @versionTwo.body seq = Diff::LCS.diff(seq1, seq2) 

You get this monster:

 seq => [[#<Diff::LCS::Change:0x0000000be539f8 @action="-", @position=27, @element="t">, #<Diff::LCS::Change:0x0000000be538b8 @action="-", @position=28, @element="w">], [#<Diff::LCS::Change:0x0000000be53520 @action="+", @position=28, @element="n">, #<Diff::LCS::Change:0x0000000be53408 @action="+", @position=29, @element="e">], [#<Diff::LCS::Change:0x0000000be3aa70 @action="-", @position=110, @element="u">, #<Diff::LCS::Change:0x0000000be3a840 @action="-", @position=111, @element="p">, #<Diff::LCS::Change:0x0000000be34ee0 @action="-", @position=112, @element="d">, #<Diff::LCS::Change:0x0000000be349e0 @action="+", @position=110, @element="c">, #<Diff::LCS::Change:0x0000000be348a0 @action="+", @position=111, @element="h">], [#<Diff::LCS::Change:0x0000000be34580 @action="-", @position=114, @element="t">, #<Diff::LCS::Change:0x0000000be34210 @action="+", @position=113, @element="n">, #<Diff::LCS::Change:0x0000000be33f40 @action="+", @position=114, @element="g">], [#<Diff::LCS::Change:0x0000000be331d0 @action="-", @position=124, @element="">]] 

The sdiff outputs and other methods found in the documentation are also horrific. I understand the structure of the array (s), but there should be an easy way to show the differences in a human-readable and capable way.

PS - If someone wants to create a diff-lcs , this will be appreciated.

+2
source share
1 answer

What I fed diff-lcs was an ordinary string - an array of characters. If I wanted to compare with the characters, I got what I wanted, but wanted something more readable - a comparison of words, lines or sentences. I have chosen offers.

 seq1 = @versionOne.body.split('.') seq2 = @versionTwo.body.split('.') compareDiff = Diff::LCS.sdiff(seq1, seq2) 

This created much more readable and parsable content. Really, I also want to divide by ! and ? . However, the structure is not an ordinary array of arrays or hashes. The output in the browser threw me away, but it is an array of objects, and you can parse it, like everything else. This is the result of the YAML formatting that I got in the rails console (I don’t know why this did not appear in the browser):

 --- - !ruby/object:Diff::LCS::ContextChange action: "=" new_element: <p>Paragraph one new_position: 0 old_element: <p>Paragraph one old_position: 0 - !ruby/object:Diff::LCS::ContextChange action: "!" new_element: " Sentence two" new_position: 1 old_element: " Sentence one" old_position: 1 - !ruby/object:Diff::LCS::ContextChange action: "=" new_element: |- </p> <p>Paragraph two new_position: 2 old_element: |- </p> <p>Paragraph two old_position: 2 - !ruby/object:Diff::LCS::ContextChange action: "=" new_element: " Another sentence" new_position: 3 old_element: " Another sentence" old_position: 3 - !ruby/object:Diff::LCS::ContextChange action: "=" new_element: |- </p> <p>Paragraph three new_position: 4 old_element: |- </p> <p>Paragraph three old_position: 4 - !ruby/object:Diff::LCS::ContextChange action: "!" new_element: " I dare you to update me!</p>" new_position: 5 old_element: " I dare you to change me!</p>" old_position: 5 => nil 

Super helpful! This will output a wiki-like diff:

 sdiff = Diff::LCS.sdiff(seq2, seq1) diffHTML = '' sdiff.each do |diff| case diff.action when '=' diffHTML << diff.new_element + "." when '!' # strip_tags only needed on old_element. removes pre-mature end tags. diffHTML << "<del>#{diff.old_element.strip_tags}</del> <add>#{diff.new_element}</add>. " end end @compareBody = diffHTML.html ...[format do block] 

Then just put <del> and <add> you want. If you're looking for something simpler, diffy might be, but it is very flexible as soon as you find out.

+1
source

All Articles