
    O&iU                         d Z ddlZddlZddlmZmZ ddlmZmZ d Z	d Z
 G d de          Z G d	 d
          Z G d d          ZddZ ej        d          Zd ZddZ	 	 	 ddZd ZdS )z
    babel.messages.pofile
    ~~~~~~~~~~~~~~~~~~~~~

    Reading and writing of files in the ``gettext`` PO (portable object)
    format.

    :copyright: (c) 2013-2022 by the Babel Team.
    :license: BSD, see LICENSE for more details.
    N)CatalogMessage)wraptext_cmpc                 h    d }t          j        d                              || dd                   S )zReverse `escape` the given string.

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

    :param string: the string to unescape
    c                 `    |                      d          }|dk    rdS |dk    rdS |dk    rdS |S )N   n
t	r)group)matchms     b/home/geonatureadmin/si_en_reseau/tutos/venv/lib/python3.11/site-packages/babel/messages/pofile.pyreplace_escapesz!unescape.<locals>.replace_escapes   s@    KKNN884#XX4#XX4    z\\([\\trn"])r	   )recompilesub)stringr   s     r   unescaper      s;    	 	 	 :o&&**?F1R4LIIIr   c                     d| v r]|                                  }|                     d          r
|dd         }t          t          |          }d                    |          S t          |           S )a  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
    r   ""r	   N )
splitlines
startswithmapr   join)r   escaped_linesliness      r   denormalizer%   *   so    * v~~))++T"" 	.)!""-MHm,,wwu~~r   c                   "     e Zd ZdZ fdZ xZS )PoFileErrorzDException thrown by PoParser when an invalid po file is encountered.c                 ~    t                                          | d|            || _        || _        || _        d S )Nz on )super__init__cataloglinelineno)selfmessager+   r,   r-   	__class__s        r   r*   zPoFileError.__init__K   sB    G1111222	r   )__name__
__module____qualname____doc__r*   __classcell__)r0   s   @r   r'   r'   I   s>        NN        r   r'   c                   V    e Zd Zd Zd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd ZdS )_NormalizedStringc                 H    g | _         |D ]}|                     |           d S N)_strsappend)r.   argsargs      r   r*   z_NormalizedString.__init__T   s7    
 	 	CKK	 	r   c                 ^    | j                             |                                           d S r9   )r:   r;   strip)r.   ss     r   r;   z_NormalizedString.appendY   s&    
!''))$$$$$r   c                 \    d                     t          t          | j                            S )Nr   )r"   r!   r   r:   r.   s    r   r%   z_NormalizedString.denormalize\   s     wws8TZ00111r   c                 *    t          | j                  S r9   )boolr:   rB   s    r   __bool__z_NormalizedString.__bool___   s    DJr   c                 J    t           j                            | j                  S r9   )oslinesepr"   r:   rB   s    r   __repr__z_NormalizedString.__repr__b   s    ztz***r   c                 ^    |sdS t          t          |           t          |                    S )Nr	   )r   strr.   others     r   __cmp__z_NormalizedString.__cmp__e   s+     	1CIIs5zz***r   c                 4    |                      |          dk    S Nr   rN   rL   s     r   __gt__z_NormalizedString.__gt__k       ||E""Q&&r   c                 4    |                      |          dk     S rP   rQ   rL   s     r   __lt__z_NormalizedString.__lt__n   rS   r   c                 4    |                      |          dk    S rP   rQ   rL   s     r   __ge__z_NormalizedString.__ge__q       ||E""a''r   c                 4    |                      |          dk    S rP   rQ   rL   s     r   __le__z_NormalizedString.__le__t   rX   r   c                 4    |                      |          dk    S rP   rQ   rL   s     r   __eq__z_NormalizedString.__eq__w   rX   r   c                 4    |                      |          dk    S rP   rQ   rL   s     r   __ne__z_NormalizedString.__ne__z   rX   r   N)r1   r2   r3   r*   r;   r%   rE   rI   rN   rR   rU   rW   rZ   r\   r^    r   r   r7   r7   R   s          
% % %2 2 2     + + ++ + +' ' '' ' '( ( (( ( (( ( (( ( ( ( (r   r7   c                   \    e Zd ZdZg dZddZd Zd Zd ZddZ	dd	Z
d
 Zd Zd Zd ZdS )PoFileParserzSupport class to  read messages from a ``gettext`` PO (portable object) file
    and add them to a `Catalog`

    See `read_po` for simple cases.
    )msgidmsgstrmsgctxtmsgid_pluralFc                 t    || _         || _        d| _        d| _        || _        |                                  d S rP   )r+   ignore_obsoletecounteroffsetabort_invalid_reset_message_state)r.   r+   rg   rj   s       r   r*   zPoFileParser.__init__   s?    .*!!#####r   c                     g | _         g | _        g | _        g | _        g | _        g | _        d | _        d| _        d| _        d| _	        d| _
        d S )NF)messagestranslations	locationsflagsuser_commentsauto_commentscontextobsoletein_msgid	in_msgstr
in_msgctxtrB   s    r   rk   z!PoFileParser._reset_message_state   sV    
r   c           
         | j                                          t          | j                  dk    rt	          d | j        D                       }n| j        d                                         }t          |t          t          f          rd t          | j	        j
                  D             }| j         D ]I\  }}|| j	        j
        k    r|                     d| j        d           2|                                ||<   Jt	          |          }n%| j         d         d                                         }| j        r| j                                        }nd}t          ||t          | j                  t!          | j                  | j        | j        | j        dz   |          }| j        r| j        s|| j	        j        |<   n
|| j	        |<   | xj        dz  c_        |                                  dS )	z
        Add a message to the catalog based on the current parser state and
        clear the state ready to process the next message.
        r	   c              3   >   K   | ]}|                                 V  d S r9   )r%   ).0r   s     r   	<genexpr>z,PoFileParser._add_message.<locals>.<genexpr>   s*      AAa!--//AAAAAAr   r   c                     g | ]}d S r   r_   )rz   _s     r   
<listcomp>z-PoFileParser._add_message.<locals>.<listcomp>   s    BBBQbBBBr   r   z5msg has more translations than num_plurals of catalogN)r-   rs   )rn   sortlenrm   tupler%   
isinstancelistranger+   num_plurals_invalid_pofileri   rs   r   ro   setrp   rr   rq   rt   rg   rh   rk   )r.   rb   r   idxtranslationrd   r/   s          r   _add_messagezPoFileParser._add_message   s   
 	   t}!!AA4=AAAAAEEM!$0022EedE]++ 		;BB%(@"A"ABBBF$($5 8 8 [$,222((dk;rsss)5577s6]]FF&q)!,88::F< 	l..00GGG%dn)=)=s4:,d.@WX")+ + + = 	*' 7/6%e,")DL!!#####r   c                 @    | j         r|                                  d S d S r9   )rm   r   rB   s    r   _finish_current_messagez$PoFileParser._finish_current_message   s.    = 	 	  	 r   c                     |                     d          r|                     ||           d S |                     |||           d S )N")r    !_process_string_continuation_line_process_keyword_line)r.   r-   r,   rt   s       r   _process_message_linez"PoFileParser._process_message_line   sP    ??3 	?224@@@@@&&vtX>>>>>r   c                    | j         D ]o}	 |                    |          r0|t          |                   dv r|t          |          d          } nAI# t          $ r |                     ||d           Y lw xY w|                     ||d           d S |dv r|                                  || _        |dk    r|| _        |dv r7d| _        d| _	        | j
                            t          |                     d S |d	k    rd| _	        d| _        |                    d
          rY|dd                              dd          \  }}| j                            t!          |          t          |          g           d S | j                            dt          |          g           d S |dk    rd| _        t          |          | _        d S d S )N) [z$Keyword must be followed by a stringz0Start of line didn't match any expected keyword.)rb   rd   rb   )rb   re   FTrc   r   r	   ]r   rd   )	_keywordsr    r   
IndexErrorr   r   rt   ri   rw   ru   rm   r;   r7   rv   splitrn   intrs   )r.   r-   r,   rt   keywordr=   r   msgs           r   r   z"PoFileParser._process_keyword_line   s   ~ 		 		G[??7++ S\\0Bj0P0Ps7||}}-CE [ [ [$$T63YZZZZZ[   v/abbbF***((***  g DK///#DO DMM  !23!7!788888  !DM!DN~~c"" Fqrr7==a00S!((#c((4Ec4J4J)KLLLLL!((!->s-C-C)DEEEEE	!!"DO,S11DLLL "!s   AA!A54A5c                     | j         r| j        d         }nC| j        r| j        d         d         }n(| j        r| j        }n|                     ||d           d S |                    |           d S )Nr   r	   z<Got line starting with " but not in msgid, msgstr or msgctxt)ru   rm   rv   rn   rw   rs   r   r;   )r.   r,   r-   r@   s       r   r   z.PoFileParser._process_string_continuation_line   s|    = 	b!AA^ 	!"%a(AA_ 	AA  v/noooF	r   c                    |                                   |dd                              d          r|dd                                                                          D ]}|                    d          }|dk    rQ	 t          ||dz   d                    }n# t          $ r Y Ew xY w| j                            |d |         |f           n| j                            |d f           d S |dd                              d          r`|dd                                                              d          D ].}| j	                            |
                                           /d S |dd                              d          r<|dd          
                                }|r| j                            |           d S d S | j                            |dd          
                                           d S )Nr	   :   r   ,.)r   r    lstripr   rfindr   
ValueErrorro   r;   rp   r?   rr   rq   )r.   r,   locationposr-   flagcomments          r   _process_commentzPoFileParser._process_comment  s   $$&&&8s## 	8 HOO--3355 	< 	<nnS))!88!!$XcAghh%7!8!8% ! ! ! !N))8DSD>6*BCCCCN))8T*:;;;;	< 	< !""X  %% 
	8QRR))//44 0 0
!!$**,,////0 0!""X  %% 	8122hnn&&G 3"))'222223 3 %%d122hnn&6&677777s   >B
B&%B&c                    t          |          D ]\  }}|                                }t          |t                    s|                    | j        j                  }|sP|                    d          rf|dd                             d          r3|                     ||dd         	                                d           | 
                    |           |                     ||           |                                  | j        s{| j        s| j        s| j        rh| j                            t%          d                     | j                            d	t%          d          g           |                                  dS dS dS )
z
        Reads from the file-like object `fileobj` and adds any po file
        units found in it to the `Catalog` supplied to the constructor.
        #r	   N~r   T)rt   r   r   )	enumerater?   r   rK   decoder+   charsetr    r   r   r   r   rh   rp   rq   rr   rm   r;   r7   rn   r   )r.   fileobjr-   r,   s       r   parsezPoFileParser.parse  s    &g.. 	9 	9LFD::<<DdC(( 9{{4<#788 s## 98&&s++ 0..vtABBx7H7HSW.XXXX))$////**648888$$&&& | 	  	 t/A 	 TEW 	 M  !25!9!9:::$$a):5)A)A%BCCC	  	  	  	 r   c                     t          |t                    sJ | j        rt          || j        ||          t          d|           t          d                    |dz   t          |                               d S )NzWARNING:z!WARNING: Problem on line {0}: {1}r	   )r   rK   rj   r'   r+   printformatrepr)r.   r,   r-   r   s       r   r   zPoFileParser._invalid_pofile<  sz    $$$$$$ 	?c4<v>>>j# 	299&1*d4jjQQRRRRRr   N)FF)F)r1   r2   r3   r4   r   r*   rk   r   r   r   r   r   r   r   r   r_   r   r   ra   ra      s           I$ $ $ $     !$ !$ !$F     ? ? ? ?'2 '2 '2 '2R
 
 
8 8 86     :S S S S Sr   ra   Fc                 x    t          |||          }t          |||          }|                    |            |S )a  Read messages from a ``gettext`` PO (portable object) file from the given
    file-like object and return a `Catalog`.

    >>> from datetime import datetime
    >>> from io 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, 4, 1)

    >>> for message in catalog:
    ...     if message.id:
    ...         print((message.id, message.string))
    ...         print(' ', (message.locations, sorted(list(message.flags))))
    ...         print(' ', (message.user_comments, message.auto_comments))
    (u'foo %(name)s', u'quux %(name)s')
      ([(u'main.py', 1)], [u'fuzzy', u'python-format'])
      ([], [])
    ((u'bar', u'baz'), (u'bar', u'baaz'))
      ([(u'main.py', 3)], [])
      ([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.
    :param abort_invalid: abort read if po file is invalid
    )localedomainr   )rj   )r   ra   r   )r   r   r   rg   r   rj   r+   parsers           r   read_por   G  sD    ^ VFGDDDG'?-PPPF
LLNr   zL(\s+|[^\s\w]*\w+[a-zA-Z]-(?=\w+[a-zA-Z])|(?<=[\w\!\"\'\&\.\,\?])-{2,}(?=\w))c                     d|                      dd                               dd                               dd                               dd	                               d
d          z  S )zEscape 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
    z"%s"\z\\r   z\tr   z\rr   z\nr   z\")replace)r   s    r   escaper     s]     FNN400"74//"74//"74//"74//	0 0r   r   L   c                    |rW|dk    rPt                    }g }|                     d          D ]'}t          t          |                    |z   |k    rt                              |          }|                                 |rg }d}|rt          t          |d                             dz
  |z   }	||	z   |k     r-|                    |                                           ||	z  }n*|s'|                    |                                           n||                    d                    |                     ||                    |           )n|                     d          }t          |          dk    rt          |           S |r|d         s|d= |dxx         dz  cc<   dd                    fd	|D                       z   S )
a  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
    r   Tr   r   r   r	   r   z""
c                 4    g | ]}t          |          z   S r_   )r   )rz   r,   prefixs     r   r   znormalize.<locals>.<listcomp>  s$     K K KT&6$<<"7 K K Kr   )	r   r   r   WORD_SEPr   reverser;   popr"   )
r   r   width	prefixlenr$   r,   chunksbufsizels
    `        r   	normalizer     s   0  (KK	%%d++ 	# 	#D6$<<  9,u44!--    0CD  
"vbz 2 233a7)C!8e++JJvzz||444 AIDD#& 9 !$

6::<< 8 8 8! ! 
" LL#///  0  T"""")	#, !!$''
5zzQf~~  U2Y "Ib			T			UZZ K K K KU K K KLLLLr   Tc
           
      j    dfd	 fddfd	}
dfd	}d}|rd}n|rd}t          |	          D ]}|j        sc|rj        }rId
k    rCg }|                                D ]}|t	          |d          z  }d                    |          } |dz              |j        D ]} |
|           |j        D ]} |
|d           |sg }	 t          |j	        d           }n# t          $ r
 |j	        }Y nw xY w|D ]k\  }}|r(|	r&d|                    t          j        d          |fz  }n#d|                    t          j        d          z  }||vr|                    |           l |
d                    |          d           |j        r7 dd                    dgt          |j                  z             z             |j        rb|r` |
d |j        d
                   z  d           t#          |j                  dk    r$ |
d |j        d                   z  d            ||            d           |sXt          j                                        |	          D ]1}|j        D ]} |
|            ||d            d           0dS dS )a  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',))
    <Message...>
    >>> catalog.add((u'bar', u'baz'), locations=[('main.py', 3)])
    <Message...>
    >>> from io import BytesIO
    >>> buf = BytesIO()
    >>> write_po(buf, catalog, omit_header=True)
    >>> print(buf.getvalue().decode("utf8"))
    #: 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
    :param include_lineno: include line number in the location comment
    r   c                 (    t          | |          S )N)r   r   )r   )keyr   r   s     r   
_normalizezwrite_po.<locals>._normalize   s    V59999r   c                     t          | t                    r|                     j        d          }                     |            d S )Nbackslashreplace)r   rK   encoder   write)textr+   r   s    r   _writezwrite_po.<locals>._write  sD    dC   	D;;w0BCCDdr   c                     r	dk    r}nd}t          | |          D ]&} d|d|                                d           'd S )Nr   r   r   r   r   )r   r?   )r   r   _widthr,   r   r   s       r   _write_commentz write_po.<locals>._write_comment  sn      	UQYYFFFWf-- 	8 	8DFF67777	8 	8r   c           
         t          | j        t          t          f          r| j        r  |d | j        |          d            |d | j        d         |          d            |d | j        d         |          d           t          j                  D ]>}	 | j        |         }n# t          $ r d}Y nw xY w d|| ||          fz             ?d S | j        r  |d | j        |          d            |d | j        |          d            |d	 | j        pd|          d           d S )
Nzmsgctxt r   zmsgid r   zmsgid_plural r	   r   z%smsgstr[%d] %s
zmsgstr )	r   idr   r   rs   r   r   r   r   )r/   r   r   r   r   r   r+   s       r   _write_messagez write_po.<locals>._write_message  s   gj4-00 	 Q666+5:gov+N+N+N+NP Q Q QFVVVZZ
1v-N-N-N-NOPPPF

7:a=&9999    W011   $^C0FF!      FFF *CFF!;!;.        Q666+5:gov+N+N+N+NP Q Q QFVVVZZ
F-K-K-K-KLMMMF

7>#7R@@@@     s   -B;;C
	C
Nr/   r   )sort_byr   z# )r   subsequent_indentr   r   )r   c                 \    | d         t          | d         t                    r| d         pdfS )Nr   r	   r   )r   r   )xs    r   <lambda>zwrite_po.<locals>.<lambda>N  s/    !A$
1Q48M8M8VRSTURV8\Z\1] r   r   z%s:%d/z%sr   r   z#%s
z, zmsgid %s|r	   zmsgid_plural %sz#~ r}   )_sort_messagesr   header_commentr   r   r"   rq   rr   sortedro   	TypeErrorr   rG   sepr;   rp   previous_idr   rt   values)r   r+   r   no_locationomit_headersort_outputsort_by_filerg   include_previousinclude_linenor   r   r   r/   comment_headerr$   r,   r   locsro   filenamer-   r   r   r   s   ```                    @@r   write_por     sG   \: : : : : :     
8 8 8 8 8 8 8       6 G 	 !'7;;; 3 3z 
	+ $3N 3*5577 > >DXd%8<> > > >EE!&E!2!2F>E)***, 	$ 	$GN7####, 	0 	0GN73///// 	7D."7#4']']_ _ _		 . . .#-			. %. * * & En E'8+;+;BFC+H+H&*QQHH$x'7'7'D'DDH4''KK)))N388D>>#6666= 	FF7TYYtfW].C.C'CDDDEEE 	#3 	N:

73Fq3I(J(JJ"%' ' ' '7&''!++0::'*4 4      	wt %##%%
 
 
 	 	G #0 ( (w''''N751111F4LLLL 	 	s   C33DDc                     t          |           } |dk    r|                                  n|dk    r|                     d            | S )z
    Sort the given message iterable by the given criteria.

    Always returns a list.

    :param messages: An iterable of Messages.
    :param sort_by: Sort by which criteria? Options are `message` and `location`.
    :return: list[Message]
    r/   r   c                     | j         S r9   )ro   )r   s    r   r   z _sort_messages.<locals>.<lambda>  s    AK r   r   )r   r   )rm   r   s     r   r   r   s  sQ     H~~H)	J		//000Or   )NNFNF)r   r   )r   FFFFFFT)r4   rG   r   babel.messages.catalogr   r   
babel.utilr   r   r   r%   	Exceptionr'   r7   ra   r   r   r   r   r   r   r   r_   r   r   <module>r      s  	 	 
			 				 3 3 3 3 3 3 3 3 % % % % % % % %J J J.     >    )   )( )( )( )( )( )( )( )(ZES ES ES ES ES ES ES ESP2 2 2 2j 2:   0 0 0$:M :M :M :Mz INDI48^ ^ ^ ^B    r   