def textDiff(a, b):
 out = []
 (a, b) = (html2list(a), html2list(b))
 s = difflib.SequenceMatcher(None, a, b)
 for e in s.get_opcodes():
  if (e[0] == 'replace'):
   out.append((((('<del>' + ''.join(a[e[1]:e[2]])) + '</del><ins>') + ''.join(b[e[3]:e[4]])) + '</ins>'))
  elif (e[0] == 'delete'):
   out.append((('<del >' + ''.join(a[e[1]:e[2]])) + '</del>'))
  elif (e[0] == 'insert'):
   out.append((('<ins >' + ''.join(b[e[3]:e[4]])) + '</ins>'))
  elif (e[0] == 'equal'):
   out.append(''.join(b[e[3]:e[4]]))
  else:
   raise (("Um, something's broken. I didn't expect a '" + `e[0]`) + "'.")
 return ''.join(out)

def textDiff ( a , b ) : out = [ ] ( a , b ) = ( html2list ( a ) , html2list ( b ) ) s = difflib . SequenceMatcher ( None , a , b ) for e in s . get_opcodes ( ) : if ( e [ 0 ] == 'replace' ) : out . append ( ( ( ( ( '<del>' + '' . join ( a [ e [ 1 ] : e [ 2 ] ] ) ) + '</del><ins>' ) + '' . join ( b [ e [ 3 ] : e [ 4 ] ] ) ) + '</ins>' ) ) elif ( e [ 0 ] == 'delete' ) : out . append ( ( ( '<del >' + '' . join ( a [ e [ 1 ] : e [ 2 ] ] ) ) + '</del>' ) ) elif ( e [ 0 ] == 'insert' ) : out . append ( ( ( '<ins >' + '' . join ( b [ e [ 3 ] : e [ 4 ] ] ) ) + '</ins>' ) ) elif ( e [ 0 ] == 'equal' ) : out . append ( '' . join ( b [ e [ 3 ] : e [ 4 ] ] ) ) else : raise ( ( "Um, something's broken. I didn't expect a '" + ` e [ 0 ] ` ) + "'." ) return '' . join ( out )
takes in strings a and b and returns a human-readable html diff .