More diff fixes. This time for "<br/>" tags.
This commit is contained in:
parent
94fdd08cf4
commit
570e0ade77
4
NEWS
4
NEWS
|
@ -1,3 +1,7 @@
|
|||
1.3.11: May 2, 2008
|
||||
* Fixed another bug that prevented diffs from working. This time, those with
|
||||
<br/> tags didn't parse correctly.
|
||||
|
||||
1.3.10: May 2, 2008
|
||||
* Fixed a bug that prevented diffs from working for notes with links.
|
||||
|
||||
|
|
|
@ -82,8 +82,9 @@ class Html_differ( HTMLParser ):
|
|||
( a, b ) = self.prepare_lists( a, b )
|
||||
return self.diff_lists( a, b )
|
||||
|
||||
START_TAG_PATTERN = re.compile( "<(\w+)(\s+[^>]*)*>" )
|
||||
END_TAG_PATTERN = re.compile( "</(\w+)>" )
|
||||
SINGLE_TAG_PATTERN = re.compile( "<(\w+)(\s+[^>]*)*\s*/>" ) # e.g. '<br/>' or '<br />' or '<img src="foo" />'
|
||||
START_TAG_PATTERN = re.compile( "<(\w+)(\s+[^>]*)*>" ) # e.g. '<i>' or '<a href="foo">'
|
||||
END_TAG_PATTERN = re.compile( "</(\w+)>" ) # e.g. '</i>' or '</a>'
|
||||
|
||||
@staticmethod
|
||||
def track_open_tags( item, open_tags ):
|
||||
|
@ -96,6 +97,9 @@ class Html_differ( HTMLParser ):
|
|||
@type open_tags: [ unicode, ... ]
|
||||
@param open_tags: list of open tags
|
||||
"""
|
||||
match = Html_differ.SINGLE_TAG_PATTERN.search( item )
|
||||
if match: return
|
||||
|
||||
match = Html_differ.START_TAG_PATTERN.search( item )
|
||||
if match:
|
||||
open_tags.append( match.group( 1 ) )
|
||||
|
@ -148,11 +152,14 @@ class Html_differ( HTMLParser ):
|
|||
continue
|
||||
|
||||
# go through the altered items looking for start and end tags
|
||||
orig_len_open_tags = len( open_tags )
|
||||
for i in range( i1, i2 ):
|
||||
Html_differ.track_open_tags( a[ i ], open_tags )
|
||||
for j in range( j1, j2 ):
|
||||
Html_differ.track_open_tags( b[ j ], open_tags )
|
||||
|
||||
all_tags_got_closed = ( orig_len_open_tags > 0 and len( open_tags ) == 0 )
|
||||
|
||||
if change_type == "replace":
|
||||
open_del_items.extend( a[ i1:i2 ] )
|
||||
open_ins_items.extend( b[ j1:j2 ] )
|
||||
|
@ -161,13 +168,19 @@ class Html_differ( HTMLParser ):
|
|||
elif change_type == "insert":
|
||||
open_ins_items.extend( b[ j1:j2 ] )
|
||||
|
||||
if len( open_tags ) == 0:
|
||||
if all_tags_got_closed:
|
||||
# if all tags were just closed, then merge the items that were in those tags
|
||||
if len( open_del_items ) > 0:
|
||||
result_a.append( ''.join( open_del_items ) )
|
||||
if len( open_ins_items ) > 0:
|
||||
result_b.append( ''.join( open_ins_items ) )
|
||||
open_del_items = []
|
||||
open_ins_items = []
|
||||
elif len( open_tags ) == 0:
|
||||
result_a.extend( open_del_items )
|
||||
result_b.extend( open_ins_items )
|
||||
open_del_items = []
|
||||
open_ins_items = []
|
||||
|
||||
return ( result_a, result_b )
|
||||
|
||||
|
|
|
@ -83,11 +83,22 @@ class Test_html_differ( object ):
|
|||
|
||||
assert result == 'foo bar <del class="diff modified">baz </del><ins class="diff modified"><a href="whee">baz</a> </ins>quux'
|
||||
|
||||
def test_diff_with_br( self ):
|
||||
a = 'foo bar baz quux'
|
||||
b = 'foo bar <br/><br />baz quux'
|
||||
|
||||
result = self.differ.diff( a, b )
|
||||
|
||||
print result
|
||||
assert result == 'foo bar <ins class="diff"><br /><br /></ins>baz quux'
|
||||
|
||||
def test_track_open_tags( self ):
|
||||
open_tags = []
|
||||
|
||||
self.differ.track_open_tags( u"foo ", open_tags )
|
||||
assert open_tags == []
|
||||
self.differ.track_open_tags( u"<br/>", open_tags )
|
||||
assert open_tags == []
|
||||
self.differ.track_open_tags( u"<i>", open_tags )
|
||||
assert open_tags == [ u"i" ]
|
||||
self.differ.track_open_tags( u"bar ", open_tags )
|
||||
|
@ -96,6 +107,8 @@ class Test_html_differ( object ):
|
|||
assert open_tags == [ u"i", u"a" ]
|
||||
self.differ.track_open_tags( u"baz", open_tags )
|
||||
assert open_tags == [ u"i", u"a" ]
|
||||
self.differ.track_open_tags( u"<br />", open_tags )
|
||||
assert open_tags == [ u"i", u"a" ]
|
||||
self.differ.track_open_tags( u"</a>", open_tags )
|
||||
assert open_tags == [ u"i" ]
|
||||
self.differ.track_open_tags( u"</i>", open_tags )
|
||||
|
@ -181,6 +194,19 @@ class Test_html_differ( object ):
|
|||
assert new_a == [ 'foo ', 'bar baz ', 'quux' ]
|
||||
assert new_b == [ 'foo ', '<a href="whee">bar baz</a> ', 'quux' ]
|
||||
|
||||
def test_prepare_lists_with_br( self ):
|
||||
a = [ 'foo ', 'bar ', 'baz ', 'quux' ]
|
||||
b = [ 'foo ', 'bar ', '<br/>', '<br />', 'baz ', 'quux' ]
|
||||
|
||||
result = self.differ.prepare_lists( a, b )
|
||||
|
||||
assert len( result ) == 2
|
||||
( new_a, new_b ) = result
|
||||
|
||||
# there should be no change
|
||||
assert new_a == a
|
||||
assert new_b == b
|
||||
|
||||
def test_diff_lists_with_insert( self ):
|
||||
a = [ 'foo ', 'bar ', 'baz ', 'quux' ]
|
||||
b = [ 'foo ', 'bar ', 'whee ', 'baz ', 'quux' ]
|
||||
|
@ -229,3 +255,11 @@ class Test_html_differ( object ):
|
|||
|
||||
assert result == 'foo <del class="diff modified">bar baz </del><ins class="diff modified"><a href="whee">bar baz</a> </ins>quux'
|
||||
|
||||
def test_diff_lists_with_br( self ):
|
||||
a = [ 'foo ', 'bar ', 'baz ', 'quux' ]
|
||||
b = [ 'foo ', 'bar ', '<br/>', '<br />', 'baz ', 'quux' ]
|
||||
|
||||
result = self.differ.diff_lists( a, b )
|
||||
|
||||
print result
|
||||
assert result == 'foo bar <ins class="diff"><br/><br /></ins>baz quux'
|
||||
|
|
Reference in New Issue