ó
™‚Mc           @   sõ   d  Z  d d l m Z m Z d d l Z d d l Z d d l m Z d d l m	 Z	 m
 Z
 d d l m Z m Z m Z d d g Z d	 Z d
 „  Z d „  Z d d e d „ Z e j d ƒ Z d „  Z d d d „ Z d e e e e e e d „ Z d S(   s¸   Reading and writing of files in the ``gettext`` PO (portable object)
format.

:see: `The Format of PO Files
       <http://www.gnu.org/software/gettext/manual/gettext.html#PO-Files>`_
iÿÿÿÿ(   t   datet   datetimeN(   t   __version__(   t   Catalogt   Message(   t   sett   wraptextt   LOCALTZt   read_pot   write_pos   restructuredtext enc         C   sG   |  d d !j  d d ƒ j  d d ƒ j  d d ƒ j  d	 d
 ƒ j  d d ƒ S(   sÿ   Reverse `escape` the given string.

    >>> print unescape('"Say:\\n  \\"hello, world!\\"\\n"')
    Say:
      "hello, world!"
    <BLANKLINE>

    :param string: the string to unescape
    :return: the unescaped string
    :rtype: `str` or `unicode`
    i   iÿÿÿÿs   \\s   \s   \ts   	s   \rs   s   \ns   
s   \"s   "(   t   replace(   t   string(    (    s9   /usr/lib/python2.7/site-packages/babel/messages/pofile.pyt   unescape    s
    c         C   s^   |  j  d ƒ rP g  } x+ |  j ƒ  d D] } | j t | ƒ ƒ q& Wd j | ƒ St |  ƒ Sd S(   s.  Reverse the normalization done by the `normalize` function.

    >>> print denormalize(r'''""
    ... "Say:\n"
    ... "  \"hello, world!\"\n"''')
    Say:
      "hello, world!"
    <BLANKLINE>

    >>> print denormalize(r'''""
    ... "Say:\n"
    ... "  \"Lorem ipsum dolor sit "
    ... "amet, consectetur adipisicing"
    ... " elit, \"\n"''')
    Say:
      "Lorem ipsum dolor sit amet, consectetur adipisicing elit, "
    <BLANKLINE>

    :param string: the string to denormalize
    :return: the denormalized string
    :rtype: `unicode` or `str`
    s   ""i   t    N(   t
   startswitht
   splitlinest   appendR   t   join(   R   t   linest   line(    (    s9   /usr/lib/python2.7/site-packages/babel/messages/pofile.pyt   denormalize2   s    c            s  t  d | d | ƒ ‰ d g ‰ d g ‰ g  ‰	 g  ‰ g  ‰ g  ‰ g  ‰ g  ‰ t g ‰
 t g ‰ t g ‰ ‡ ‡ ‡ ‡ ‡ ‡ ‡	 ‡
 ‡ ‡ ‡ f d †  ‰  ‡  ‡ ‡ ‡	 ‡ ‡ f d †  } x	t |  j ƒ  ƒ D]õ\ } } | j ƒ  } t | t ƒ s | j ˆ j ƒ } n  | j	 d ƒ r¬t ˆ d <ˆ d <ˆ	 r7ˆ r7ˆ  ƒ  n  | d j	 d ƒ rÒx\| d	 j
 ƒ  j ƒ  D]j } | j d ƒ } | d k ray t | | d ƒ } Wn t k
 r°qan Xˆ j | |  | f ƒ qaqaWq¹| d j	 d
 ƒ rxÁ | d	 j
 ƒ  j d
 ƒ D] }	 ˆ j |	 j ƒ  ƒ qÿWq¹| d j	 d ƒ rVt ˆ
 d <| | | d	 j
 ƒ  ƒ q¹| d j	 d ƒ r’| d	 j ƒ  }
 |
 r©ˆ j |
 ƒ q©q¹ˆ j | d j ƒ  ƒ qÄ | | | ƒ qÄ Wˆ	 rÍˆ  ƒ  nG ˆ d rˆ sêˆ sêˆ rˆ	 j d ƒ ˆ j d d g ƒ ˆ  ƒ  n  ˆ S(   s×  Read 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``
    t   localet   domaini    c       
      s  ˆ	 j  ƒ  t ˆ ƒ d k rD t g  ˆ D] }  t |  ƒ ^ q& ƒ } n t ˆ d ƒ } t | t t f ƒ rñ g  } xS t ˆ j ƒ D]B } y | j ˆ	 | ƒ Wq t	 k
 rÀ | j | d f ƒ q Xq Wt g  | D] } t | d ƒ ^ qÏ ƒ } n t ˆ	 d d ƒ } t
 | | t ˆ ƒ t ˆ ƒ ˆ  ˆ
 d ˆ d d ƒ} ˆ d r]ˆ sg| ˆ j | <qgn
 | ˆ | <ˆ 2ˆ	 2ˆ 2ˆ 2ˆ  2ˆ
 2t ˆ d <ˆ d c d 7<d  S(   Ni   i    R   t   lineno(   t   sortt   lent   tupleR   t
   isinstancet   listt   ranget   num_pluralsR   t
   IndexErrorR   R   t   obsoletet   False(   t   mt   msgidR   t   idxt   tt   message(   t   auto_commentst   catalogt   countert   flagst   ignore_obsoletet	   locationst   messagesR    t   offsett   translationst   user_comments(    s9   /usr/lib/python2.7/site-packages/babel/messages/pofile.pyt   _add_messageŠ   s6    
(,

    
c            sŠ  | j  d ƒ r9 t ˆ d <| d j ƒ  } ˆ j | ƒ nM| j  d ƒ rŒ t ˆ d <|  ˆ d <| d j ƒ  } ˆ r| ˆ  ƒ  n  ˆ j | ƒ nú | j  d ƒ r"t ˆ d <t ˆ d <| d j ƒ  } | j  d ƒ r| d	 j d
 d	 ƒ \ } } ˆ j t | ƒ | j ƒ  g ƒ q†ˆ j d | g ƒ nd | j  d ƒ r†ˆ d rXˆ d c d | j ƒ  7<q†ˆ d r†ˆ d d	 c d | j ƒ  7<q†n  d  S(   Nt   msgid_plurali    i   R#   i   t   msgstri   t   [i   t   ]t   "iÿÿÿÿu   
(   R   t   Truet   lstripR   R!   t   splitt   intt   rstrip(   R   R   t   msgt   txtR$   (   R1   t   in_msgidt	   in_msgstrR-   R.   R/   (    s9   /usr/lib/python2.7/site-packages/babel/messages/pofile.pyt   _process_message_line¦   s0    





"

t   #i   t   :i   t   ,t   ~t   .u    (   R   R!   t	   enumeratet	   readlinest   stripR   t   unicodet   decodet   charsetR   R8   R9   t   rfindR:   t
   ValueErrorR   R7   (   t   fileobjR   R   R+   R@   R   R   t   locationt   post   flagt   comment(    (   R1   R'   R(   R)   R*   R+   R>   R?   R,   R-   R    R.   R/   R0   s9   /usr/lib/python2.7/site-packages/babel/messages/pofile.pyR   Q   sd    +					-
! 


sL   (\s+|[^\s\w]*\w+[a-zA-Z]-(?=\w+[a-zA-Z])|(?<=[\w\!\"\'\&\.\,\?])-{2,}(?=\w))c         C   sD   d |  j  d d ƒ j  d d ƒ j  d d ƒ j  d d	 ƒ j  d
 d ƒ S(   s4  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
    :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.pyt   escapeõ   s
    R   iL   c      	   C   s½  | r9| d k r9t  | ƒ } g  } x!t |  j t ƒ ƒ D]ø \ } } t  t | ƒ ƒ | | k r%t j | ƒ } | j ƒ  x´ | r!g  } d }	 xu | rt  t | d ƒ ƒ d | }
 |	 |
 | k  rç | j | j	 ƒ  ƒ |	 |
 7}	 q“ | s| j | j	 ƒ  ƒ n  Pq“ W| j d j
 | ƒ ƒ q~ Wq: | j | ƒ q: Wn |  j t ƒ } t  | ƒ d k rdt |  ƒ S| r| d r| d =| d c d 7<n  d d j
 g  | D] }
 | t |
 ƒ ^ qŸƒ S(	   sà  Convert a string into a format that is appropriate for .po files.

    >>> 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`
    i    i   iÿÿÿÿu    i   s   
u   ""
u   
(   R   RF   R   R7   RS   t   WORD_SEPR9   t   reverseR   t   popR   (   R   t   prefixt   widtht	   prefixlenR   R$   R   t   chunkst   buft   sizet   l(    (    s9   /usr/lib/python2.7/site-packages/babel/messages/pofile.pyt	   normalize  s6    "
		
c	      
      sÚ  d ‡ ‡ f d † ‰  ‡ ‡ f d †  ‰ d ‡ ‡ f d † }	 d ‡  ‡ ‡ f d † }
 t  ˆ ƒ } | rs | j ƒ  n | rŒ | j d „  ƒ n  xì| D]ä} | j s%| r® q“ n  ˆ j } ˆ rˆ d k rg  } x0 | j ƒ  D]" } | t | d ˆ d	 d
 ƒ7} qÜ Wd j | ƒ d } n  ˆ | ƒ n  x | j D] } |	 | ƒ q/Wx! | j D] } |	 | d d ƒqMW| sÄd j g  | j	 D]+ \ } } d | j
 t j d ƒ | f ^ q}ƒ } |	 | d d ƒn  | j r÷ˆ d d j d g t  | j ƒ ƒ ƒ n  | j rc| rc|	 d ˆ  | j d ƒ d d ƒt | j ƒ d k rc|	 d ˆ  | j d ƒ d d ƒqcn  |
 | ƒ ˆ d ƒ q“ W| sÖxR ˆ j j ƒ  D]> } x | j D] } |	 | ƒ q¡W|
 | d d ƒˆ d ƒ q‘Wn  d S(   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 ""
    <BLANKLINE>
    #: main.py:3
    msgid "bar"
    msgid_plural "baz"
    msgstr[0] ""
    msgstr[1] ""
    <BLANKLINE>
    <BLANKLINE>

    :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   c            s%   t  |  d | d ˆ ƒj ˆ  j d ƒ S(   NRW   RX   t   backslashreplace(   R^   t   encodeRK   (   t   keyRW   (   R(   RX   (    s9   /usr/lib/python2.7/site-packages/babel/messages/pofile.pyt
   _normalizeq  s    c            s5   t  |  t ƒ r$ |  j ˆ  j ƒ }  n  ˆ j |  ƒ d  S(   N(   R   RI   R`   RK   t   write(   t   text(   R(   RN   (    s9   /usr/lib/python2.7/site-packages/babel/messages/pofile.pyt   _writeu  s    c            sY   ˆ r ˆ d k r ˆ } n d } x1 t  |  | ƒ D]  } ˆ  d | | j ƒ  f ƒ q1 Wd  S(   Ni    iL   s   #%s %s
(   R   RH   (   RR   RW   t   _widthR   (   Re   RX   (    s9   /usr/lib/python2.7/site-packages/babel/messages/pofile.pyt   _write_commentz  s
    	c            s  t  |  j t t f ƒ rÈ ˆ d | ˆ  |  j d | ƒ f ƒ ˆ d | ˆ  |  j d | ƒ f ƒ x« t ˆ j ƒ D]Q } y |  j | } Wn t k
 r  d } n Xˆ d | | ˆ  | | ƒ f ƒ qp WnF ˆ d | ˆ  |  j | ƒ f ƒ ˆ d | ˆ  |  j p d | ƒ f ƒ d  S(   Ns   %smsgid %s
i    s   %smsgid_plural %s
i   R   s   %smsgstr[%d] %s
s   %smsgstr %s
(   R   t   idR   R   R   R   R   R   (   R&   RW   R$   R   (   Rb   Re   R(   (    s9   /usr/lib/python2.7/site-packages/babel/messages/pofile.pyt   _write_message„  s    $
! c         S   s   t  |  j | j ƒ S(   N(   t   cmpR,   (   t   xt   y(    (    s9   /usr/lib/python2.7/site-packages/babel/messages/pofile.pyt   <lambda>  s    i    RX   t   subsequent_indents   # u   
RW   RE   u    u   %s:%dt   /RB   s   #%s
s   , s   msgid %st   |i   s   msgid_plural %ss   
s   #~ N(   R   R   Rh   t   header_commentR   R   R   R0   R'   R,   R
   t   ost   sepR*   t   previous_idR   R    t   values(   RN   R(   RX   t   no_locationt   omit_headert   sort_outputt   sort_by_fileR+   t   include_previousRg   Ri   R-   R&   t   comment_headerR   R   RR   t   filenameR   t   locs(    (   Rb   Re   R(   RN   RX   s9   /usr/lib/python2.7/site-packages/babel/messages/pofile.pyR	   F  s\    +
			;	*	
(   t   __doc__R   R    Rr   t   ret   babelR   t   VERSIONt   babel.messages.catalogR   R   t
   babel.utilR   R   R   t   __all__t   __docformat__R   R   t   NoneR!   R   t   compileRT   RS   R^   R	   (    (    (    s9   /usr/lib/python2.7/site-packages/babel/messages/pofile.pyt   <module>   s"   		ž	>		