我正在使用diff-lcs gem来输出两个html内容体之间的差异。这是示例内容。
版本一:
<p>Paragraph one. Sentence one.</p>
<p>Paragraph two. Another sentence.</p>
<p>Paragraph three. I dare you to change me!</p>
版本二:
<p>Paragraph one. Sentence two.</p>
<p>Paragraph two. Another sentence.</p>
<p>Paragraph three. I dare you to update me!</p>
使用此:
seq1 = @versionOne.body
seq2 = @versionTwo.body
seq = Diff::LCS.diff(seq1, seq2)
你得到了这个怪物:
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="">]]
sdiff
中的diff-lcs
和其他方法的输出同样令人恐惧。我理解数组(数组)的结构,但必须有一种简单的方法来以人类可读和风格的方式显示差异。
PS - 如果有人想要创建{{1}}标签,我们将不胜感激。
答案 0 :(得分:1)
我正在为diff-lcs提供的是一个常规字符串 - 一个字符数组。如果我想要的是角色的比较,我得到了我想要的东西,但我想要更具可读性的东西 - 比较单词,行或句子。我选择了句子。
seq1 = @versionOne.body.split('.')
seq2 = @versionTwo.body.split('.')
compareDiff = Diff::LCS.sdiff(seq1, seq2)
这产生了更具可读性和可解析性的内容。实际上,我还希望按!
和?
进行拆分。然而,该结构不是正常的数组或散列数组。浏览器中的输出将我抛弃,但它是一个对象数组,您可以像其他任何东西一样解析它。这是我在rails控制台中获得的YAML格式化输出(不知道为什么它没有在浏览器中显示):
---
- !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
超级有帮助!这将输出类似wiki的差异:
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]
然后根据需要设置<del>
和<add>
样式。如果你正在寻找更容易的东西,diffy可能是它,但是一旦你弄明白,这就非常灵活。
答案 1 :(得分:0)
还有你可以使用的块版本,你可以结合数组解构:
seq1.sdiff(seq2) { |action, (old_pos, old_element), (new_pos, new_element)|
...
puts [action, old_pos, old_element, new_pos, new_element].inspect
...
}
seq1.diff(seq2) { |action, position, element|
puts [action, position, element].inspect
}