
    cVH                        d Z d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 ddlmZ ddlmZmZmZmZmZmZmZ 	 dd	lmZ ddlmZ i ddddddddddddddddddddd d!d"d#d$dd%d&d'd(d)d*Z	 d~d+e d,ee   d-ee    d.e fd/Z!d0e d.e fd1Z" ej                  d2      Z# ej                  d3      Z$dd4e d5e%d6e d7e&d.e f
d8Z'dd4e d5e%d6e d.e fd9Z(dd4e d5e%d6e d.e fd:Z)d4e d5e%d.ee e f   fd;Z*dd0e d<e d.ee    fd=Z+  ed>      e+      Z,d? Z-d@ Z.dAZ/ ej                  e/      Z0dBZ1dCZ2 ej                  dDe1dEe2dF      Z3 ej                  dGe1dHe2dIe1dJ      Z4dKdLdMdNdOdPZ5dQdKdRdSdTdUZ6de7e0e3fd0e dVee e%f   dWeede
f   dXe
dYedZed.ee7e%f   fd[Z8 ej                  d\      Z9dd]ed0e d^e d.e fd_Z:d`Z;daZ<dbZ=dcdddedfdgdhdidjZ>dcdkdldmdndodpdqdrds	Z?d~dtee    duee    d.e fdvZ@d~dwe dtee    duee    d.e fdxZAdydzd{d|ZBej                  eBfd}ZDy# e	$ rW  e
ej                  j                  dd            Z e
ej                  j                  dd      j                  d            ZY Lw xY w# e	$ r d
ZY 5w xY w)a  Some text manipulation utility functions.


:group text formatting: normalize_text, normalize_paragraph, pretty_match,unquote, colorize_ansi
:group text manipulation: searchall, splitstrip
:sort: text formatting, text manipulation

:type ANSI_STYLES: dict(str)
:var ANSI_STYLES: dictionary mapping style identifier to ANSI terminal code

:type ANSI_COLORS: dict(str)
:var ANSI_COLORS: dictionary mapping color identifier to ANSI terminal code

:type ANSI_PREFIX: str
:var ANSI_PREFIX:
  ANSI terminal code notifying the start of an ANSI escape sequence

:type ANSI_END: str
:var ANSI_END:
  ANSI terminal code notifying the end of an ANSI escape sequence

:type ANSI_RESET: str
:var ANSI_RESET:
  ANSI terminal code resetting format defined by a previous ANSI escape sequence
zrestructuredtext en    N)PatternMatch )warn)	normalize)AnyOptionalTupleListCallableDictUnion)linesep
)callable_deprecated   ¡!u   łlu   ⁄/   ÆAE   ©z(c)   «"   æae   ®z(r)u   œoeu   ŒOE   ØO   øo   »   ßssu   –-u   ’'ustringignorenonascii
substitutereturnc                    |t        dt        d       |rd}g }| dd D ]  }	 t        |   }|j                  |        dj                  |      S # t        $ r/ t	        d|      d   }t        |      dk\  r|t        d	      |}Y [w xY w)
aV  replace diacritical characters with their corresponding ascii characters

    Convert the unicode string to its long normalized form (unicode character
    will be transform into several characters) and keep the first one only.
    The normal form KD (NFKD) will apply the compatibility decomposition, i.e.
    replace all compatibility characters with their equivalents.

    :type substitute: str
    :param substitute: replacement character to use if decomposition fails

    :see: Another project about ASCII transliterations of Unicode text
          http://pypi.python.org/pypi/Unidecode
    NzDignorenonascii is deprecated, use substitute named parameter instead   )
stacklevelr   NFKDr      z*can't deal with non-ascii based characters)	r   DeprecationWarningMANUAL_UNICODE_MAPKeyError_uninormalizeord
ValueErrorappendjoin)r)   r*   r+   resletterreplacements         :/usr/lib/python3/dist-packages/logilab/common/textutils.py
unormalizer>   \   s    " !R	

 J
C!* 	 	),V4K 	

;	  773<  	)'7:K;4'%$%QRR(	)s   	A5B	B	stringc                 >    | s| S | d   dv r| dd } | d   dv r| dd } | S )zremove optional quotes (simple or double) from the string

    :type string: str or unicode
    :param string: an optionally quoted string

    :rtype: str or unicode
    :return: the unquoted string (or the input string if it wasn't quoted)
    r   z"'   N )r?   s    r=   unquoterD      s?     ayEbzUM    z?
?
z\s+textline_lenindentrestc                     |rt         }nt        }g }t        j                  |       D ]  } |j	                   || ||              t
        |t
        j                  |      S )a  normalize a text to display it with a maximum line size and
    optionally arbitrary indentation. Line jumps are normalized but blank
    lines are kept. The indentation string may be used to insert a
    comment (#) or a quoting (>) mark  for instance.

    :type text: str or unicode
    :param text: the input text to normalize

    :type line_len: int
    :param line_len: expected maximum line's length, default to 80

    :type indent: str or unicode
    :param indent: optional string to use as indentation

    :rtype: str or unicode
    :return:
      the input text normalized to fit on lines with a maximized size
      inferior to `line_len`, and optionally prefixed by an
      indentation string
    )normalize_rest_paragraphnormalize_paragraph_BLANKLINES_RGXsplitr8   r   r9   )rF   rG   rH   rI   normpresults         r=   normalize_textrQ      s]    * (#F%%d+ 5eD(F345177??rE   c                     t         j                  d|       } |t        |      z
  }g }| r4t        | j	                         |      \  }} |j                  ||z          | r4t        j                  |      S )a  normalize a text to display it with a maximum line size and
    optionally arbitrary indentation. Line jumps are normalized. The
    indentation string may be used top insert a comment mark for
    instance.

    :type text: str or unicode
    :param text: the input text to normalize

    :type line_len: int
    :param line_len: expected maximum line's length, default to 80

    :type indent: str or unicode
    :param indent: optional string to use as indentation

    :rtype: str or unicode
    :return:
      the input text normalized to fit on lines with a maximized size
      inferior to `line_len`, and optionally prefixed by an
      indentation string
     )_NORM_SPACES_RGXsublen	splittextstripr8   r   r9   )rF   rG   rH   linesalines        r=   rL   rL      sh    * T*D#f+%HE


h7tVe^$  <<rE   c                    d}g }|t        |      z
  }| j                         D ]  }|t        j                  d|j	                               z   }d}t        |      |kD  r>t        ||      \  }}|j                  ||z          |r|dz   }d}nd}t        |      |kD  r>|s{|j                  ||j	                         z           t        j                  |      S )a  normalize a ReST text to display it with a maximum line size and
    optionally arbitrary indentation. Line jumps are normalized. The
    indentation string may be used top insert a comment mark for
    instance.

    :type text: str or unicode
    :param text: the input text to normalize

    :type line_len: int
    :param line_len: expected maximum line's length, default to 80

    :type indent: str or unicode
    :param indent: optional string to use as indentation

    :rtype: str or unicode
    :return:
      the input text normalized to fit on lines with a maximized size
      inferior to `line_len`, and optionally prefixed by an
      indentation string
    r   rS   )	rV   
splitlinesrT   rU   rX   rW   r8   r   r9   )rF   rG   rH   toreportrY   lines         r=   rK   rK      s    * HE#f+%H! 0*..sDJJLAA$i("&tX6ND(LL$'#~ $i(" LL$**,./0 <<rE   c                 d   t        |       |k  r| dfS t        t        |       dz
  |      }|dkD  r| |   dk7  r|dz  }|dkD  r	| |   dk7  r|dk(  rGt        t        |       |      }t        |       |kD  r$| |   dk7  r|dz  }t        |       |kD  r	| |   dk7  r| d| | |dz   d j                         fS )zsplit the given text on space according to the given max line size

    return a 2-uple:
    * a line <= line_len if possible
    * the rest of the text which has to be reported on another line
    r   rA   r   rS   N)rV   minrX   )rF   rG   poss      r=   rW   rW      s     4yHRx
c$i!mX
&C
'd3i3&q 'd3i3&
ax#d)X&$i#o$s)s"21HC $i#o$s)s"2:tC!GI,,...rE   sepc                     | j                  |      D cg c]#  }|j                         s|j                         % c}S c c}w )a  return a list of stripped string by splitting the string given as
    argument on `sep` (',' by default). Empty string are discarded.

    >>> splitstrip('a, b, c   ,  4,,')
    ['a', 'b', 'c', '4']
    >>> splitstrip('a')
    ['a']
    >>>

    :type string: str or unicode
    :param string: a csv line

    :type sep: str or unicode
    :param sep: field separator, default to the comma (',')

    :rtype: str or unicode
    :return: the unquoted string (or the input string if it wasn't quoted)
    )rN   rX   )r?   rb   words      r=   
splitstripre     s/    & &,\\#%6GT$**,DJJLGGGs   ??z%get_csv is deprecated, use splitstripc                     d| v r!| j                  d      j                  dd      S t        j                  | j                  t        j                              S )zreturn the latest component of a string containing either an url of the
    form <scheme>://<path> or a local file system path
    z://r   rA   )rstriprsplitosprN   rb   )url_or_paths    r=   split_url_or_pathrk   +  sH     !!#&--c15599[''011rE   c                 b   i }| s|S | j                         D ]w  }|j                         }|s|j                  d      r(|j                  dd      D cg c]  }|j                          c}\  }}||v r	 ||   j	                  |       s|||<   y |S c c}w # t
        $ r ||   |g||<   Y w xY w)am  parse multilines text containing simple 'key=value' lines and return a
    dict of {'key': 'value'}. When the same key is encountered multiple time,
    value is turned into a list containing all values.

    >>> d = text_to_dict('''multiple=1
    ... multiple= 2
    ... single =3
    ... ''')
    >>> d['single']
    '3'
    >>> d['multiple']
    ['1', '2']

    #=rA   )r\   rX   
startswithrN   r8   AttributeError)rF   r:   r^   wkeyvalues         r=   text_to_dictrt   4  s     C
! 
!zz|,-1ZZQ-?@!'')@JCcz1HOOE* !C
! J A & 1 #C%0CH1s   B5BB.-B.z(\s|,)+z#-?(([0-9]+\.[0-9]*)|((0x?)?[0-9]+))z	[a-zA-Z]+z
(?P<value>z
)(?P<unit>z)?z^((z)(z))*(z)?$rA   i   i   i   @l        )bkbmbgbtbg-C6?<   i  iQ )mssr`   hdunitsinterfinal	blank_reg	value_regc                    ||}t         j                  d|       }|rt        j                  |      st	        d| z        g }|j                  |      D ]Z  }|j                         }	|	d   |	j                  d      }}
 ||
      }|	 |||j                            z  }|j                  |       \  |t        |            S # t        $ r) t	        d|dt        |j                                     w xY w)am  Parse the string applying the units defined in units
    (e.g.: "1.5m",{'m',60} -> 80).

    :type string: str or unicode
    :param string: the string to parse

    :type units: dict (or any object with __getitem__ using basestring key)
    :param units: a dict mapping a unit string repr to its value

    :type inter: type
    :param inter: used to parse every intermediate value (need __sum__)

    :type blank_reg: regexp
    :param blank_reg: should match every blank char to ignore.

    :type value_reg: regexp with "value" and optional "unit" group
    :param value_reg: match a value and it's unit into the
    r   zInvalid unit string: %r.rs   unitzinvalid unit z. valid units are )	_BLANK_RErU   _VALIDATION_REmatchr7   finditer	groupdictgetlowerr4   listkeysr8   sum)r?   r   r   r   r   r   fstringvaluesr   diclitr   rs   s                r=   apply_unitsr   l  s    4 }mmB'G,,W53f<==F##G, 	ooL#''&/Tc
etzz|,, 	e	 V  e $PTUZU_U_UaPb!cddes   C2C3z
|+|
r   underline_charc                 t   | j                         }| j                         }t        j                  t        |      }|j                  t        d|      }|dk(  rd}g }n|d| g}|t        t              z  }||z
  }d|z  |||z
  z  z   }|j                  t        |      }	|	dk(  r(||d }|j                  |       |j                  |       nM||	t        t              z   d }|||	 }|j                  |       |j                  |       |j                  |       t	        j                  |      j                         S )a  return a string with the match location underlined:

    >>> import re
    >>> print(pretty_match(re.search('mange', 'il mange du bacon'), 'il mange du bacon'))
    il mange du bacon
       ^^^^^
    >>>

    :type match: _sre.SRE_match
    :param match: object returned by re.match, re.search or re.finditer

    :type string: str or unicode
    :param string:
      the string on which the regular expression has been applied to
      obtain the `match` object

    :type underline_char: str or unicode
    :param underline_char:
      character to use to underline the matched section, default to the
      carret '^'

    :rtype: str or unicode
    :return:
      the original string with an inserted line to underline the match
      location
    r   rB   NrS   )startend	_LINE_RGXrU   r   rfindrV   findr8   r9   rg   )
r   r?   r   r   r   start_line_posrP   offset	underlineend_line_poss
             r=   pretty_matchr     s(   6 KKME
))+C]]7F+F\\'1e4N.)*#g,&^#Ff~u==I;;w,Lr(fi 
 \CL023|4fi c<<&&((rE   z[mz[0m0134579)resetbolditalicr   blinkinversestrike3031323334353637)	r   blackredgreenyellowbluemagentacyanwhitecolorstylec                 @   g }|r*t        |      }|D ]  }|j                  t        |           | rM| j                         r%|j	                  ddg       |j                  |        n|j                  t
        |           |rt        dj                  |      z   t        z   S y)a  return ansi escape code corresponding to color and style

    :type color: str or None
    :param color:
      the color name (see `ANSI_COLORS` for available values)
      or the color number when 256 colors are available

    :type style: str or None
    :param style:
      style string (see `ANSI_COLORS` for available values). To get
      several style effects at the same time, use a coma as separator.

    :raise KeyError: if an unexistent color or style identifier is given

    :rtype: str
    :return: the built escape code
    38r   ;r   )	re   r8   ANSI_STYLESisdigitextendANSI_COLORSANSI_PREFIXr9   ANSI_END)r   r   	ansi_codestyle_attrseffects        r=   _get_ansi_coder     s    $ I '! 	2F[01	2==?dC[)U#[/0SXXi008;;rE   msgc                 F    ||| S t        ||      }|r|| t        S | S )aC  colorize message by wrapping it with ansi escape codes

    :type msg: str or unicode
    :param msg: the message string to colorize

    :type color: str or None
    :param color:
      the color identifier (see `ANSI_COLORS` for available values)

    :type style: str or None
    :param style:
      style string (see `ANSI_COLORS` for available values). To get
      several style effects at the same time, use a coma as separator.

    :raise KeyError: if an unexistent color or style identifier is given

    :rtype: str or unicode
    :return: the ansi escaped string
    )r   
ANSI_RESET)r   r   r   escape_codes       r=   colorize_ansir     s3    * }
 .K&Z88JrE   r   r   r   )	separatorremoveaddc                    | D ]  }|d d dv r|j                  t        ||d                )|d   dk(  r|j                  t        ||d                P|d   dk(  r|j                  t        ||d                w|d d d	k(  r|j                  t        ||d                |d d d
k(  r|j                  t        ||d                |j                  |        y )N   )--- +++ r   r   r'   r   +r   r   r   )writer   )rY   outr   r^   s       r=   diff_colorize_ansir   2  s     8''IImD%*<=>!W^IImD%/:;!W^IImD%,78"1XIImD%*<=>"1XIImD%*<=>IIdOrE   )NN)P   r   F)r   r   ),)^)E__doc____docformat__sysreos.pathpathri   r   r   ImportErrortypesre_compilecompiler   warningsr   unicodedatar   r5   typingr   r	   r
   r   r   r   r   osr   logilab.common.deprecationr   r3   strr>   rD   rM   rT   intboolrQ   rL   rK   rW   re   get_csvrk   rt   
_BLANK_UREr   __VALUE_URE__UNITS_URE	_VALUE_REr   
BYTE_UNITS
TIME_UNITSfloatr   r   r   r   r   r   r   r   r   r   
DIFF_STYLEstdoutr   rC   rE   r=   <module>r      s  $4 & 
 	 
:!  2 D D D ;
Cc c D	
 E C D E d d C C C D c  c! * UY$$"*3-$DLSM$$NC C $ "**\*2::f% @ @ @# @$ @[^ @>c S s C <&3 &# &C &QT &R/C /3 /5c? /&Hs H HtCy H, G
E
Fz
R2@ 
BJJz"	4BJJ[QR	[+{[\ 





 	
		
 *.""**S>* 4%&* 	*
 * * 5#:*Z BJJ}%	5) 5)s 5)C 5)# 5)t 
 
(3- x} PS Ds 8C=  Y\ < "U7C
 #&**J }  : 2>>))"a01G''A.44R89E:  Gs#   H I, AI)(I),I76I7