ó ƒòQc@sÄdZddlZddlZddlmZmZddlmZddlm Z d„Z d„Z dde dd„Zejd ƒZd „Zd d d „Zd e e e e e e d„ZdS(sé babel.messages.pofile ~~~~~~~~~~~~~~~~~~~~~ Reading and writing of files in the ``gettext`` PO (portable object) format. :copyright: (c) 2013 by the Babel Team. :license: BSD, see LICENSE for more details. iÿÿÿÿN(tCatalogtMessage(twraptext(t text_typecCs)d„}tjdƒj||dd!ƒS(s¾Reverse `escape` the given string. >>> print unescape('"Say:\\n \\"hello, world!\\"\\n"') Say: "hello, world!" :param string: the string to unescape cSsC|jdƒ}|dkrdS|dkr/dS|dkr?dS|S(Nitns tts trs (tgroup(tmatchtm((s?/usr/local/lib/python2.7/site-packages/babel/messages/pofile.pytreplace_escapess   s \\([\\trn"])iiÿÿÿÿ(tretcompiletsub(tstringR ((s?/usr/local/lib/python2.7/site-packages/babel/messages/pofile.pytunescapes cCs^d|krP|jƒ}|jdƒr4|d}ntt|ƒ}dj|ƒ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 s s""itN(t splitlinest startswithtmapRtjoin(Rt escaped_linestlines((s?/usr/local/lib/python2.7/site-packages/babel/messages/pofile.pyt denormalize,s    c s6td|d|d|ƒ‰dg‰dg‰ g‰ g‰g‰ g‰g‰g‰tg‰ g‰tg‰tg‰ tg‰‡‡‡‡‡‡‡ ‡ ‡ ‡ ‡‡f d†‰‡‡‡‡‡ ‡ ‡ ‡fd†}x t|jƒƒD]õ\}}|jƒ}t|tƒs|jˆjƒ}n|j dƒrÊtˆd<ˆ d<ˆ rUˆrUˆƒn|dj d ƒrðx\|d j ƒj ƒD]j}|j d ƒ} | dkryt || dƒ}Wntk rÎqnXˆ j|| |fƒqqWq×|dj d ƒr=xÁ|d j ƒj d ƒD]} ˆj| jƒƒqWq×|dj d ƒrttˆ d<|||d j ƒƒq×|dj d ƒr°|d jƒ} | rLjj| ƒqÇq׈j|djƒƒqâ|||ƒqâWˆ r눃nGˆd r2ˆsˆsˆr2ˆ jdƒˆjddgƒˆƒnˆS(sJRead messages from a ``gettext`` PO (portable object) file from the given file-like object and return a `Catalog`. >>> from datetime import datetime >>> from StringIO import StringIO >>> buf = StringIO(''' ... #: main.py:1 ... #, fuzzy, python-format ... msgid "foo %(name)s" ... msgstr "quux %(name)s" ... ... # A user comment ... #. An auto comment ... #: main.py:3 ... msgid "bar" ... msgid_plural "baz" ... msgstr[0] "bar" ... msgstr[1] "baaz" ... ''') >>> 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'quux %(name)s') ([(u'main.py', 1)], set([u'fuzzy', u'python-format'])) ([], []) ((u'bar', u'baz'), (u'bar', u'baaz')) ([(u'main.py', 3)], set([])) ([u'A user comment'], [u'An auto comment']) .. versionadded:: 1.0 Added support for explicit charset argument. :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 :param charset: the character set of the catalog. tlocaletdomaintcharsetic sˈ jƒtˆƒdkrDtgˆD]}t|ƒ^q&ƒ}ntˆdƒ}t|ttfƒrñg}xStˆjƒD]B}y|jˆ |ƒWqt k rÀ|j|dfƒqXqWtg|D]}t|dƒ^qσ}ntˆ ddƒ}ˆr#tdj ˆƒƒ}nd}t ||tˆƒt ˆƒˆˆ dˆ ddd|ƒ}ˆdr‡ˆs‘|ˆj|      "   ! t#it:it,t~t.u(RR)t enumeratet readlineststripR RtdecodeRRR?R@trfindRAt ValueErrorR$R>( tfileobjRRR2RRIRRCtlocationtpostflagtcomment((R8R.R/RR0R1R2RFRGRHR3R4R(R5R6R7s?/usr/local/lib/python2.7/site-packages/babel/messages/pofile.pytread_poKsh.      0!$"     !     sL(\s+|[^\s\w]*\w+[a-zA-Z]-(?=\w+[a-zA-Z])|(?<=[\w\!\"\'\&\.\,\?])-{2,}(?=\w))cCsDd|jddƒjddƒjddƒjdd ƒjd d ƒS( sõEscape 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 s"%s"s\s\\s s\ts s\rs s\ns"s\"(treplace(R((s?/usr/local/lib/python2.7/site-packages/babel/messages/pofile.pytescapes    RiLc Cs±|r-|dkr-t|ƒ}g}x|jtƒD]ò}tt|ƒƒ||krtj|ƒ}|jƒx´|rg}d}xu|rûtt|dƒƒd|} || |krÛ|j|jƒƒ|| 7}q‡|s÷|j|jƒƒnPq‡W|jdj |ƒƒqrWq4|j|ƒq4Wn|jtƒ}t|ƒdkrXt|ƒ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 iiiÿÿÿÿuis u"" u ( RRR>R\tWORD_SEPR@treverseR$tpopR( Rtprefixtwidtht prefixlenRRCtchunkstbuftsizetl((s?/usr/local/lib/python2.7/site-packages/babel/messages/pofile.pyt normalizes6      c  s×d‡fd†‰‡‡fd†‰d‡‡fd†} d‡‡‡fd†} tˆƒ} |rp| jƒn|r‰| jd„ƒnxì| D]ä} | js"|r«qnˆj} ˆrˆdkrg}x0| jƒD]"}|t|dˆd d ƒ7}qÙWd j|ƒ} nˆ| d ƒnx| jD]}| |ƒq,Wx!| jD]}| |d d ƒqJW|sÁdjg| j D]+\}}d|j t j dƒ|f^qzƒ}| |d dƒn| j rôˆddjdgt| j ƒƒƒn| jr`|r`| dˆ| jdƒd dƒt| jƒdkr`| dˆ| jdƒd dƒq`n| | ƒˆdƒqW|sÓxRˆjjƒD]>} x| jD]}| |ƒqžW| | d dƒˆdƒqŽWndS(svWrite 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 io import BytesIO >>> buf = BytesIO() >>> 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 Rcst|d|dˆƒS(NR`Ra(Rg(tkeyR`(Ra(s?/usr/local/lib/python2.7/site-packages/babel/messages/pofile.pyt _normalize~scs8t|tƒr'|jˆjdƒ}nˆj|ƒdS(Ntbackslashreplace(R RtencodeRtwrite(ttext(R/RU(s?/usr/local/lib/python2.7/site-packages/babel/messages/pofile.pyt_writescsYˆrˆdkrˆ}nd}x1t||ƒD] }ˆd||jƒfƒq1WdS(NiiLs#%s %s (RRQ(RYR`t_widthRC(RnRa(s?/usr/local/lib/python2.7/site-packages/babel/messages/pofile.pyt_write_comment†s  csjt|jttfƒrô|jrDˆd|ˆ|j|ƒfƒnˆd|ˆ|jd|ƒfƒˆd|ˆ|jd|ƒfƒx×tˆjƒD]Q}y|j|}Wntk rÌd}nXˆd||ˆ||ƒfƒqœWnr|jr ˆd|ˆ|j|ƒfƒnˆd|ˆ|j|ƒfƒˆd|ˆ|jpXd|ƒfƒdS( Ns %smsgctxt %s s %smsgid %s is%smsgid_plural %s iRs%smsgstr[%d] %s s %smsgstr %s ( R tidR!RRR"R#RR%(R-R`R+R(RiRnR/(s?/usr/local/lib/python2.7/site-packages/babel/messages/pofile.pyt_write_messages(  $  !   cSst|j|jƒS(N(tcmpR3(txty((s?/usr/local/lib/python2.7/site-packages/babel/messages/pofile.pyt¯siRatsubsequent_indents# u R`RNu u%s:%dt/RKs#%s s, smsgid %st|ismsgid_plural %ss s#~ N(R!RRqtheader_commentRRRR7R.R3R[tostsepR1tsortedt previous_idRR(tvalues(RUR/Rat no_locationt omit_headert sort_outputt sort_by_fileR2tinclude_previousRpRrR4R-tcomment_headerRRCRYtfilenameRtlocs((RiRnR/RURas?/usr/local/lib/python2.7/site-packages/babel/messages/pofile.pytwrite_poQs\-       ; *   (t__doc__R{R tbabel.messages.catalogRRt babel.utilRt babel._compatRRRR&R)RZR R]R\RgRˆ(((s?/usr/local/lib/python2.7/site-packages/babel/messages/pofile.pyt s    ° =