<s> """<STR_LIT>""" <EOL> from __future__ import print_function <EOL> import os <EOL> import re <EOL> from babel . messages . catalog import Catalog , Message <EOL> from babel . util import wraptext <EOL> from babel . _compat import text_type <EOL> def unescape ( string ) : <EOL> r"""<STR_LIT>""" <EOL> def replace_escapes ( match ) : <EOL> m = match . group ( <NUM_LIT:1> ) <EOL> if m == '<STR_LIT:n>' : <EOL> return '<STR_LIT:\n>' <EOL> elif m == '<STR_LIT:t>' : <EOL> return '<STR_LIT:\t>' <EOL> elif m == '<STR_LIT:r>' : <EOL> return '<STR_LIT:\r>' <EOL> return m <EOL> return re . compile ( r'<STR_LIT>' ) . sub ( replace_escapes , string [ <NUM_LIT:1> : - <NUM_LIT:1> ] ) <EOL> def denormalize ( string ) : <EOL> r"""<STR_LIT>""" <EOL> if '<STR_LIT:\n>' in string : <EOL> escaped_lines = string . splitlines ( ) <EOL> if string . startswith ( '<STR_LIT>' ) : <EOL> escaped_lines = escaped_lines [ <NUM_LIT:1> : ] <EOL> lines = map ( unescape , escaped_lines ) <EOL> return '<STR_LIT>' . join ( lines ) <EOL> else : <EOL> return unescape ( string ) <EOL> def read_po ( fileobj , locale = None , domain = None , ignore_obsolete = False , charset = None ) : <EOL> """<STR_LIT>""" <EOL> catalog = Catalog ( locale = locale , domain = domain , charset = charset ) <EOL> counter = [ <NUM_LIT:0> ] <EOL> offset = [ <NUM_LIT:0> ] <EOL> messages = [ ] <EOL> translations = [ ] <EOL> locations = [ ] <EOL> flags = [ ] <EOL> user_comments = [ ] <EOL> auto_comments = [ ] <EOL> obsolete = [ False ] <EOL> context = [ ] <EOL> in_msgid = [ False ] <EOL> in_msgstr = [ False ] <EOL> in_msgctxt = [ False ] <EOL> def _add_message ( ) : <EOL> translations . sort ( ) <EOL> if len ( messages ) > <NUM_LIT:1> : <EOL> msgid = tuple ( [ denormalize ( m ) for m in messages ] ) <EOL> else : <EOL> msgid = denormalize ( messages [ <NUM_LIT:0> ] ) <EOL> if isinstance ( msgid , ( list , tuple ) ) : <EOL> string = [ ] <EOL> for idx in range ( catalog . num_plurals ) : <EOL> try : <EOL> string . append ( translations [ idx ] ) <EOL> except IndexError : <EOL> string . append ( ( idx , '<STR_LIT>' ) ) <EOL> string = tuple ( [ denormalize ( t [ <NUM_LIT:1> ] ) for t in string ] ) <EOL> else : <EOL> string = denormalize ( translations [ <NUM_LIT:0> ] [ <NUM_LIT:1> ] ) <EOL> if context : <EOL> msgctxt = denormalize ( '<STR_LIT:\n>' . join ( context ) ) <EOL> else : <EOL> msgctxt = None <EOL> message = Message ( msgid , string , list ( locations ) , set ( flags ) , <EOL> auto_comments , user_comments , lineno = offset [ <NUM_LIT:0> ] + <NUM_LIT:1> , <EOL> context = msgctxt ) <EOL> if obsolete [ <NUM_LIT:0> ] : <EOL> if not ignore_obsolete : <EOL> catalog . obsolete [ msgid ] = message <EOL> else : <EOL> catalog [ msgid ] = message <EOL> del messages [ : ] <EOL> del translations [ : ] <EOL> del context [ : ] <EOL> del locations [ : ] <EOL> del flags [ : ] <EOL> del auto_comments [ : ] <EOL> del user_comments [ : ] <EOL> obsolete [ <NUM_LIT:0> ] = False <EOL> counter [ <NUM_LIT:0> ] += <NUM_LIT:1> <EOL> def _process_message_line ( lineno , line ) : <EOL> if line . startswith ( '<STR_LIT>' ) : <EOL> in_msgid [ <NUM_LIT:0> ] = True <EOL> msg = line [ <NUM_LIT:12> : ] . lstrip ( ) <EOL> messages . append ( msg ) <EOL> elif line . startswith ( '<STR_LIT>' ) : <EOL> in_msgid [ <NUM_LIT:0> ] = True <EOL> offset [ <NUM_LIT:0> ] = lineno <EOL> txt = line [ <NUM_LIT:5> : ] . lstrip ( ) <EOL> if messages : <EOL> _add_message ( ) <EOL> messages . append ( txt ) <EOL> elif line . startswith ( '<STR_LIT>' ) : <EOL> in_msgid [ <NUM_LIT:0> ] = False <EOL> in_msgstr [ <NUM_LIT:0> ] = True <EOL> msg = line [ <NUM_LIT:6> : ] . lstrip ( ) <EOL> if msg . startswith ( '<STR_LIT:[>' ) : <EOL> idx , msg = msg [ <NUM_LIT:1> : ] . split ( '<STR_LIT:]>' , <NUM_LIT:1> ) <EOL> translations . append ( [ int ( idx ) , msg . lstrip ( ) ] ) <EOL> else : <EOL> translations . append ( [ <NUM_LIT:0> , msg ] ) <EOL> elif line . startswith ( '<STR_LIT>' ) : <EOL> if messages : <EOL> _add_message ( ) <EOL> in_msgid [ <NUM_LIT:0> ] = in_msgstr [ <NUM_LIT:0> ] = False <EOL> context . append ( line [ <NUM_LIT:7> : ] . lstrip ( ) ) <EOL> elif line . startswith ( '<STR_LIT:">' ) : <EOL> if in_msgid [ <NUM_LIT:0> ] : <EOL> messages [ - <NUM_LIT:1> ] += u'<STR_LIT:\n>' + line . rstrip ( ) <EOL> elif in_msgstr [ <NUM_LIT:0> ] : <EOL> translations [ - <NUM_LIT:1> ] [ <NUM_LIT:1> ] += u'<STR_LIT:\n>' + line . rstrip ( ) <EOL> elif in_msgctxt [ <NUM_LIT:0> ] : <EOL> context . append ( line . rstrip ( ) ) <EOL> for lineno , line in enumerate ( fileobj . readlines ( ) ) : <EOL> line = line . strip ( ) <EOL> if not isinstance ( line , text_type ) : <EOL> line = line . decode ( catalog . charset ) <EOL> if line . startswith ( '<STR_LIT:#>' ) : <EOL> in_msgid [ <NUM_LIT:0> ] = in_msgstr [ <NUM_LIT:0> ] = False <EOL> if messages and translations : <EOL> _add_message ( ) <EOL> if line [ <NUM_LIT:1> : ] . startswith ( '<STR_LIT::>' ) : <EOL> for location in line [ <NUM_LIT:2> : ] . lstrip ( ) . split ( ) : <EOL> pos = location . rfind ( '<STR_LIT::>' ) <EOL> if pos >= <NUM_LIT:0> : <EOL> try : <EOL> lineno = int ( location [ pos + <NUM_LIT:1> : ] ) <EOL> except ValueError : <EOL> continue <EOL> locations . append ( ( location [ : pos ] , lineno ) ) <EOL> else : <EOL> locations . append ( ( location , None ) ) <EOL> elif line [ <NUM_LIT:1> : ] . startswith ( '<STR_LIT:U+002C>' ) : <EOL> for flag in line [ <NUM_LIT:2> : ] . lstrip ( ) . split ( '<STR_LIT:U+002C>' ) : <EOL> flags . append ( flag . strip ( ) ) <EOL> elif line [ <NUM_LIT:1> : ] . startswith ( '<STR_LIT>' ) : <EOL> obsolete [ <NUM_LIT:0> ] = True <EOL> _process_message_line ( lineno , line [ <NUM_LIT:2> : ] . lstrip ( ) ) <EOL> elif line [ <NUM_LIT:1> : ] . startswith ( '<STR_LIT:.>' ) : <EOL> comment = line [ <NUM_LIT:2> : ] . strip ( ) <EOL> if comment : <EOL> auto_comments . append ( comment ) <EOL> else : <EOL> user_comments . append ( line [ <NUM_LIT:1> : ] . strip ( ) ) <EOL> else : <EOL> _process_message_line ( lineno , line ) <EOL> if messages : <EOL> _add_message ( ) <EOL> elif not counter [ <NUM_LIT:0> ] and ( flags or user_comments or auto_comments ) : <EOL> messages . append ( u'<STR_LIT>' ) <EOL> translations . append ( [ <NUM_LIT:0> , u'<STR_LIT>' ] ) <EOL> _add_message ( ) <EOL> return catalog <EOL> WORD_SEP = re . compile ( '<STR_LIT:(>' <EOL> r'<STR_LIT>' <EOL> r'<STR_LIT>' <EOL> r'<STR_LIT>' <EOL> '<STR_LIT:)>' ) <EOL> def escape ( string ) : <EOL> r"""<STR_LIT>""" <EOL> return '<STR_LIT>' % string . replace ( '<STR_LIT:\\>' , '<STR_LIT>' ) . replace ( '<STR_LIT:\t>' , '<STR_LIT>' ) . replace ( '<STR_LIT:\r>' , '<STR_LIT>' ) . replace ( '<STR_LIT:\n>' , '<STR_LIT>' ) . replace ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> def normalize ( string , prefix = '<STR_LIT>' , width = <NUM_LIT> ) : <EOL> r"""<STR_LIT>""" <EOL> if width and width > <NUM_LIT:0> : <EOL> prefixlen = len ( prefix ) <EOL> lines = [ ] <EOL> for line in string . splitlines ( True ) : <EOL> if len ( escape ( line ) ) + prefixlen > width : <EOL> chunks = WORD_SEP . split ( line ) <EOL> chunks . reverse ( ) <EOL> while chunks : <EOL> buf = [ ] <EOL> size = <NUM_LIT:2> <EOL> while chunks : <EOL> l = len ( escape ( chunks [ - <NUM_LIT:1> ] ) ) - <NUM_LIT:2> + prefixlen <EOL> if size + l < width : <EOL> buf . append ( chunks . pop ( ) ) <EOL> size += l <EOL> else : <EOL> if not buf : <EOL> buf . append ( chunks . pop ( ) ) <EOL> break <EOL> lines . append ( u'<STR_LIT>' . join ( buf ) ) <EOL> else : <EOL> lines . append ( line ) <EOL> else : <EOL> lines = string . splitlines ( True ) <EOL> if len ( lines ) <= <NUM_LIT:1> : <EOL> return escape ( string ) <EOL> if lines and not lines [ - <NUM_LIT:1> ] : <EOL> del lines [ - <NUM_LIT:1> ] <EOL> lines [ - <NUM_LIT:1> ] += '<STR_LIT:\n>' <EOL> return u'<STR_LIT>' + u'<STR_LIT:\n>' . join ( [ ( prefix + escape ( line ) ) for line in lines ] ) <EOL> def write_po ( fileobj , catalog , width = <NUM_LIT> , no_location = False , omit_header = False , <EOL> sort_output = False , sort_by_file = False , ignore_obsolete = False , <EOL> include_previous = False ) : <EOL> r"""<STR_LIT>""" <EOL> def _normalize ( key , prefix = '<STR_LIT>' ) : <EOL> return normalize ( key , prefix = prefix , width = width ) <EOL> def _write ( text ) : <EOL> if isinstance ( text , text_type ) : <EOL> text = text . encode ( catalog . charset , '<STR_LIT>' ) <EOL> fileobj . write ( text ) <EOL> def _write_comment ( comment , prefix = '<STR_LIT>' ) : <EOL> if width and width > <NUM_LIT:0> : <EOL> _width = width <EOL> else : <EOL> _width = <NUM_LIT> <EOL> for line in wraptext ( comment , _width ) : <EOL> _write ( '<STR_LIT>' % ( prefix , line . strip ( ) ) ) <EOL> def _write_message ( message , prefix = '<STR_LIT>' ) : <EOL> if isinstance ( message . id , ( list , tuple ) ) : <EOL> if message . context : <EOL> _write ( '<STR_LIT>' % ( prefix , <EOL> _normalize ( message . context , prefix ) ) ) <EOL> _write ( '<STR_LIT>' % ( prefix , _normalize ( message . id [ <NUM_LIT:0> ] , prefix ) ) ) <EOL> _write ( '<STR_LIT>' % ( <EOL> prefix , _normalize ( message . id [ <NUM_LIT:1> ] , prefix ) <EOL> ) ) <EOL> for idx in range ( catalog . num_plurals ) : <EOL> try : <EOL> string = message . string [ idx ] <EOL> except IndexError : <EOL> string = '<STR_LIT>' <EOL> _write ( '<STR_LIT>' % ( <EOL> prefix , idx , _normalize ( string , prefix ) <EOL> ) ) <EOL> else : <EOL> if message . context : <EOL> _write ( '<STR_LIT>' % ( prefix , <EOL> _normalize ( message . context , prefix ) ) ) <EOL> _write ( '<STR_LIT>' % ( prefix , _normalize ( message . id , prefix ) ) ) <EOL> _write ( '<STR_LIT>' % ( <EOL> prefix , _normalize ( message . string or '<STR_LIT>' , prefix ) <EOL> ) ) <EOL> sort_by = None <EOL> if sort_output : <EOL> sort_by = "<STR_LIT:message>" <EOL> elif sort_by_file : <EOL> sort_by = "<STR_LIT:location>" <EOL> for message in _sort_messages ( catalog , sort_by = sort_by ) : <EOL> if not message . id : <EOL> if omit_header : <EOL> continue <EOL> comment_header = catalog . header_comment <EOL> if width and width > <NUM_LIT:0> : <EOL> lines = [ ] <EOL> for line in comment_header . splitlines ( ) : <EOL> lines += wraptext ( line , width = width , <EOL> subsequent_indent = '<STR_LIT>' ) <EOL> comment_header = u'<STR_LIT:\n>' . join ( lines ) <EOL> _write ( comment_header + u'<STR_LIT:\n>' ) <EOL> for comment in message . user_comments : <EOL> _write_comment ( comment ) <EOL> for comment in message . auto_comments : <EOL> _write_comment ( comment , prefix = '<STR_LIT:.>' ) <EOL> if not no_location : <EOL> locs = [ ] <EOL> for filename , lineno in sorted ( message . locations ) : <EOL> if lineno : <EOL> locs . append ( u'<STR_LIT>' % ( filename . replace ( os . sep , '<STR_LIT:/>' ) , lineno ) ) <EOL> else : <EOL> locs . append ( u'<STR_LIT:%s>' % filename . replace ( os . sep , '<STR_LIT:/>' ) ) <EOL> _write_comment ( '<STR_LIT:U+0020>' . join ( locs ) , prefix = '<STR_LIT::>' ) <EOL> if message . flags : <EOL> _write ( '<STR_LIT>' % '<STR_LIT:U+002CU+0020>' . join ( [ '<STR_LIT>' ] + sorted ( message . flags ) ) ) <EOL> if message . previous_id and include_previous : <EOL> _write_comment ( '<STR_LIT>' % _normalize ( message . previous_id [ <NUM_LIT:0> ] ) , <EOL> prefix = '<STR_LIT:|>' ) <EOL> if len ( message . previous_id ) > <NUM_LIT:1> : <EOL> _write_comment ( '<STR_LIT>' % _normalize ( <EOL> message . previous_id [ <NUM_LIT:1> ] <EOL> ) , prefix = '<STR_LIT:|>' ) <EOL> _write_message ( message ) <EOL> _write ( '<STR_LIT:\n>' ) <EOL> if not ignore_obsolete : <EOL> for message in _sort_messages ( <EOL> catalog . obsolete . values ( ) , <EOL> sort_by = sort_by <EOL> ) : <EOL> for comment in message . user_comments : <EOL> _write_comment ( comment ) <EOL> _write_message ( message , prefix = '<STR_LIT>' ) <EOL> _write ( '<STR_LIT:\n>' ) <EOL> def _sort_messages ( messages , sort_by ) : <EOL> """<STR_LIT>""" <EOL> messages = list ( messages ) <EOL> if sort_by == "<STR_LIT:message>" : <EOL> messages . sort ( ) <EOL> elif sort_by == "<STR_LIT:location>" : <EOL> messages . sort ( key = lambda m : m . locations ) <EOL> return messages </s>
