Mc@sdZddlmZmZddlZddlZddlmZddlm Z m Z ddl m Z m Z mZddgZd Zd Zd Zdded Zejd ZdZdddZdeeeeeedZdS(sReading and writing of files in the ``gettext`` PO (portable object) format. :see: `The Format of PO Files `_ i(tdatetdatetimeN(t __version__(tCatalogtMessage(tsettwraptexttLOCALTZtread_potwrite_posrestructuredtext encCsG|dd!jddjddjddjd d jd d S( sReverse `escape` the given string. >>> print unescape('"Say:\\n \\"hello, world!\\"\\n"') Say: "hello, world!" :param string: the string to unescape :return: the unescaped string :rtype: `str` or `unicode` iis\\s\s\ts s\rs s\ns s\"s"(treplace(tstring((s9/usr/lib/python2.7/site-packages/babel/messages/pofile.pytunescape s    cCs^|jdrPg}x+|jdD]}|jt|q&Wdj|St|SdS(s.Reverse the normalization done by the `normalize` function. >>> print denormalize(r'''"" ... "Say:\n" ... " \"hello, world!\"\n"''') Say: "hello, world!" >>> print denormalize(r'''"" ... "Say:\n" ... " \"Lorem ipsum dolor sit " ... "amet, consectetur adipisicing" ... " elit, \"\n"''') Say: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, " :param string: the string to denormalize :return: the denormalized string :rtype: `unicode` or `str` s""itN(t startswitht splitlinestappendR tjoin(R tlinestline((s9/usr/lib/python2.7/site-packages/babel/messages/pofile.pyt denormalize2s  c std|d|dgdg g g ggg gtg tgtg f d fd}x t|jD]\}}|j}t|ts|jj}n|j drtd<d< r7 r7n|dj drx\|d j j D]j}|j d}|dkrayt ||d}Wntk rqanXj|| |fqaqaWq|dj d rx|d j j d D]} j| jqWq|dj d rVt d<|||d j q|dj d r|d j} | rj| qq j|djq|||qW rnGd rs sr jd  jdd gnS(sRead messages from a ``gettext`` PO (portable object) file from the given file-like object and return a `Catalog`. >>> from StringIO import StringIO >>> buf = StringIO(''' ... #: main.py:1 ... #, fuzzy, python-format ... msgid "foo %(name)s" ... msgstr "" ... ... # A user comment ... #. An auto comment ... #: main.py:3 ... msgid "bar" ... msgid_plural "baz" ... msgstr[0] "" ... msgstr[1] "" ... ''') >>> catalog = read_po(buf) >>> catalog.revision_date = datetime(2007, 04, 01) >>> for message in catalog: ... if message.id: ... print (message.id, message.string) ... print ' ', (message.locations, message.flags) ... print ' ', (message.user_comments, message.auto_comments) (u'foo %(name)s', '') ([(u'main.py', 1)], set([u'fuzzy', u'python-format'])) ([], []) ((u'bar', u'baz'), ('', '')) ([(u'main.py', 3)], set([])) ([u'A user comment'], [u'An auto comment']) :param fileobj: the file-like object to read the PO file from :param locale: the locale identifier or `Locale` object, or `None` if the catalog is not bound to a locale (which basically means it's a template) :param domain: the message domain :param ignore_obsolete: whether to ignore obsolete messages in the input :return: an iterator over ``(message, translation, location)`` tuples :rtype: ``iterator`` tlocaletdomainic s jtdkrDtgD]}t|^q&}ntd}t|ttfrg}xStjD]B}y|j |Wqt k r|j|dfqXqWtg|D]}t|d^q}nt dd}t ||tt  ddd}dr]sg|j |R?R,R-R R.R/R0s9/usr/lib/python2.7/site-packages/babel/messages/pofile.pyRQsd+     -     !     sL(\s+|[^\s\w]*\w+[a-zA-Z]-(?=\w+[a-zA-Z])|(?<=[\w\!\"\'\&\.\,\?])-{2,}(?=\w))cCsDd|jddjddjddjdd jd d S( s4Escape the given string so that it can be included in double-quoted strings in ``PO`` files. >>> escape('''Say: ... "hello, world!" ... ''') '"Say:\\n \\"hello, world!\\"\\n"' :param string: the string to escape :return: the escaped string :rtype: `str` or `unicode` s"%s"s\s\\s s\ts s\rs s\ns"s\"(R (R ((s9/usr/lib/python2.7/site-packages/babel/messages/pofile.pytescapes    R iLc Cs|r9|dkr9t|}g}x!t|jtD]\}}tt|||kr%tj|}|jx|r!g}d} xu|rtt|dd|} | | |kr|j|j | | 7} q|s|j|j nPqW|jdj |q~Wq:|j|q:Wn|jt}t|dkrdt|S|r|d r|d=|dcd7>> print normalize('''Say: ... "hello, world!" ... ''', width=None) "" "Say:\n" " \"hello, world!\"\n" >>> print normalize('''Say: ... "Lorem ipsum dolor sit amet, consectetur adipisicing elit, " ... ''', width=32) "" "Say:\n" " \"Lorem ipsum dolor sit " "amet, consectetur adipisicing" " elit, \"\n" :param string: the string to normalize :param prefix: a string that should be prepended to every line :param width: the maximum line width; use `None`, 0, or a negative number to completely disable line wrapping :return: the normalized string :rtype: `unicode` iiiuis u"" u ( RRFRR7RStWORD_SEPR9treverseRtpopR( R tprefixtwidtht prefixlenRR$Rtchunkstbuftsizetl((s9/usr/lib/python2.7/site-packages/babel/messages/pofile.pyt normalizes6 "     c  sdfdfddfd} dfd} t} |rs| jn|r| jdnx| D]} | js%|rqnj} rdkrg}x0| jD]"}|t|dd d 7}qWd j|d } n| nx| jD]}| |q/Wx!| jD]}| |d d qMW|sdjg| j D]+\}}d|j t j d|f^q}}| |d dn| j rddjdgt| j n| jrc|rc| d| jdd dt| jdkrc| d| jdd dqcn| | dqW|sxRjjD]>} x| jD]}| |qW| | d ddqWndS(s\Write a ``gettext`` PO (portable object) template file for a given message catalog to the provided file-like object. >>> catalog = Catalog() >>> catalog.add(u'foo %(name)s', locations=[('main.py', 1)], ... flags=('fuzzy',)) >>> catalog.add((u'bar', u'baz'), locations=[('main.py', 3)]) >>> from StringIO import StringIO >>> buf = StringIO() >>> write_po(buf, catalog, omit_header=True) >>> print buf.getvalue() #: main.py:1 #, fuzzy, python-format msgid "foo %(name)s" msgstr "" #: main.py:3 msgid "bar" msgid_plural "baz" msgstr[0] "" msgstr[1] "" :param fileobj: the file-like object to write to :param catalog: the `Catalog` instance :param width: the maximum line width for the generated output; use `None`, 0, or a negative number to completely disable line wrapping :param no_location: do not emit a location comment for every message :param omit_header: do not include the ``msgid ""`` entry at the top of the output :param sort_output: whether to sort the messages in the output by msgid :param sort_by_file: whether to sort the messages in the output by their locations :param ignore_obsolete: whether to ignore obsolete messages and not include them in the output; by default they are included as comments :param include_previous: include the old msgid as a comment when updating the catalog R cs%t|d|djjdS(NRWRXtbackslashreplace(R^tencodeRK(tkeyRW(R(RX(s9/usr/lib/python2.7/site-packages/babel/messages/pofile.pyt _normalizeqscs5t|tr$|jj}nj|dS(N(RRIR`RKtwrite(ttext(R(RN(s9/usr/lib/python2.7/site-packages/babel/messages/pofile.pyt_writeuscsYrdkr}nd}x1t||D] }d||jfq1WdS(NiiLs#%s %s (RRH(RRRWt_widthR(ReRX(s9/usr/lib/python2.7/site-packages/babel/messages/pofile.pyt_write_commentzs  cst|jttfrd||jd|fd||jd|fxtjD]Q}y|j|}Wntk rd}nXd||||fqpWnFd||j|fd||jpd|fdS(Ns %smsgid %s is%smsgid_plural %s iR s%smsgstr[%d] %s s %smsgstr %s (RtidRRRRR R(R&RWR$R (RbReR((s9/usr/lib/python2.7/site-packages/babel/messages/pofile.pyt_write_messages$  ! cSst|j|jS(N(tcmpR,(txty((s9/usr/lib/python2.7/site-packages/babel/messages/pofile.pytsiRXtsubsequent_indents# u RWREu u%s:%dt/RBs#%s s, smsgid %st|ismsgid_plural %ss s#~ N(RRRhtheader_commentRRRR0R'R,R tostsepR*t previous_idRR tvalues(RNR(RXt no_locationt omit_headert sort_outputt sort_by_fileR+tinclude_previousRgRiR-R&tcomment_headerRRRRtfilenameRtlocs((RbReR(RNRXs9/usr/lib/python2.7/site-packages/babel/messages/pofile.pyR Fs\+        ; *   (t__doc__RRRrtretbabelRtVERSIONtbabel.messages.catalogRRt babel.utilRRRt__all__t __docformat__R RtNoneR!RtcompileRTRSR^R (((s9/usr/lib/python2.7/site-packages/babel/messages/pofile.pyts"      >