<s> """<STR_LIT>""" <EOL> import re <EOL> from django . utils . html import escape <EOL> def prepare_udiff ( udiff ) : <EOL> return DiffRenderer ( udiff ) . prepare ( ) <EOL> class DiffRenderer ( object ) : <EOL> _chunk_re = re . compile ( r'<STR_LIT>' ) <EOL> def __init__ ( self , udiff ) : <EOL> self . lines = [ escape ( line ) for line in udiff . splitlines ( ) ] <EOL> def prepare ( self ) : <EOL> return self . _parse_udiff ( ) <EOL> def _parse_udiff ( self ) : <EOL> info = self . _parse_info ( ) <EOL> in_header = True <EOL> header = [ ] <EOL> lineiter = iter ( self . lines ) <EOL> files = [ ] <EOL> try : <EOL> line = lineiter . next ( ) <EOL> while True : <EOL> if not line . startswith ( '<STR_LIT>' ) : <EOL> if in_header : <EOL> header . append ( line ) <EOL> line = lineiter . next ( ) <EOL> continue <EOL> if header and all ( o . strip ( ) for o in header ) : <EOL> files . append ( { '<STR_LIT>' : True , '<STR_LIT>' : header } ) <EOL> header = [ ] <EOL> in_header = [ ] <EOL> chunks = [ ] <EOL> old , new = self . _extract_rev ( line , lineiter . next ( ) ) <EOL> files . append ( { <EOL> '<STR_LIT>' : False , <EOL> '<STR_LIT>' : old [ <NUM_LIT:0> ] , <EOL> '<STR_LIT>' : old [ <NUM_LIT:1> ] , <EOL> '<STR_LIT>' : new [ <NUM_LIT:0> ] , <EOL> '<STR_LIT>' : new [ <NUM_LIT:1> ] , <EOL> '<STR_LIT>' : chunks , <EOL> } ) <EOL> line = lineiter . next ( ) <EOL> while line : <EOL> match = self . _chunk_re . match ( line ) <EOL> if not match : <EOL> in_header = False <EOL> break <EOL> lines = [ ] <EOL> chunks . append ( lines ) <EOL> old_line , old_end , new_line , new_end = [ int ( o or <NUM_LIT:1> ) for o in match . groups ( ) ] <EOL> old_line -= <NUM_LIT:1> <EOL> new_line -= <NUM_LIT:1> <EOL> old_end += old_line <EOL> new_end += new_line <EOL> line = lineiter . next ( ) <EOL> while old_line < old_end or new_line < new_end : <EOL> if line : <EOL> command , line = line [ <NUM_LIT:0> ] , line [ <NUM_LIT:1> : ] <EOL> else : <EOL> command = '<STR_LIT:U+0020>' <EOL> affects_old = affects_new = False <EOL> if command == '<STR_LIT:+>' : <EOL> affects_new = True <EOL> action = '<STR_LIT>' <EOL> elif command == '<STR_LIT:->' : <EOL> affects_old = True <EOL> action = '<STR_LIT>' <EOL> else : <EOL> affects_old = affects_new = True <EOL> action = '<STR_LIT>' <EOL> old_line += affects_old <EOL> new_line += affects_new <EOL> lines . append ( { <EOL> '<STR_LIT>' : affects_old and old_line or u'<STR_LIT>' , <EOL> '<STR_LIT>' : affects_new and new_line or u'<STR_LIT>' , <EOL> '<STR_LIT:action>' : action , <EOL> '<STR_LIT>' : line , <EOL> } ) <EOL> line = lineiter . next ( ) <EOL> except StopIteration : <EOL> pass <EOL> for file in files : <EOL> if file [ '<STR_LIT>' ] : <EOL> continue <EOL> for chunk in file [ '<STR_LIT>' ] : <EOL> lineiter = iter ( chunk ) <EOL> first = True <EOL> try : <EOL> while True : <EOL> line = lineiter . next ( ) <EOL> if line [ '<STR_LIT:action>' ] != '<STR_LIT>' : <EOL> nextline = lineiter . next ( ) <EOL> if nextline [ '<STR_LIT:action>' ] == '<STR_LIT>' or nextline [ '<STR_LIT:action>' ] == line [ '<STR_LIT:action>' ] : <EOL> continue <EOL> self . _highlight_line ( line , nextline ) <EOL> except StopIteration : <EOL> pass <EOL> return files , info <EOL> def _parse_info ( self ) : <EOL> nlines = len ( self . lines ) <EOL> if not nlines : <EOL> return <EOL> firstline = self . lines [ <NUM_LIT:0> ] <EOL> info = [ ] <EOL> return info <EOL> def _extract_rev ( self , line1 , line2 ) : <EOL> def _extract ( line ) : <EOL> parts = line . split ( None , <NUM_LIT:1> ) <EOL> return parts [ <NUM_LIT:0> ] , ( len ( parts ) == <NUM_LIT:2> and parts [ <NUM_LIT:1> ] or None ) <EOL> try : <EOL> if line1 . startswith ( '<STR_LIT>' ) and line2 . startswith ( '<STR_LIT>' ) : <EOL> return _extract ( line1 [ <NUM_LIT:4> : ] ) , _extract ( line2 [ <NUM_LIT:4> : ] ) <EOL> except ( ValueError , IndexError ) : <EOL> pass <EOL> return ( None , None ) , ( None , None ) <EOL> def _highlight_line ( self , line , next ) : <EOL> start = <NUM_LIT:0> <EOL> limit = min ( len ( line [ '<STR_LIT>' ] ) , len ( next [ '<STR_LIT>' ] ) ) <EOL> while start < limit and line [ '<STR_LIT>' ] [ start ] == next [ '<STR_LIT>' ] [ start ] : <EOL> start += <NUM_LIT:1> <EOL> end = - <NUM_LIT:1> <EOL> limit -= start <EOL> while - end <= limit and line [ '<STR_LIT>' ] [ end ] == next [ '<STR_LIT>' ] [ end ] : <EOL> end -= <NUM_LIT:1> <EOL> end += <NUM_LIT:1> <EOL> if start or end : <EOL> def do ( l ) : <EOL> last = end + len ( l [ '<STR_LIT>' ] ) <EOL> if l [ '<STR_LIT:action>' ] == '<STR_LIT>' : <EOL> tag = '<STR_LIT>' <EOL> else : <EOL> tag = '<STR_LIT>' <EOL> l [ '<STR_LIT>' ] = u'<STR_LIT>' % ( <EOL> l [ '<STR_LIT>' ] [ : start ] , <EOL> tag , <EOL> l [ '<STR_LIT>' ] [ start : last ] , <EOL> tag , <EOL> l [ '<STR_LIT>' ] [ last : ] , <EOL> ) <EOL> do ( line ) <EOL> do ( next ) </s>
