o
    S`YX                     @   s  d Z ddlmZ ddgZdZdZdZdZdd	lZdd	l	Z	z
dd	l
Z
d
d ZW n" eyH   z
dd	lZdd ZW n eyE   ejd  w Y nw z
dd	lZdd ZW n ey`   dd ZY nw ddlmZ ejdkrqeZeZneZeZdd Zdd ZG dd deZG dd deZG dd dZe dkre Z!e!"g d e!#g d e!$g dg dg d g d!g e%e!&  e%  e Z!e!'ej( e!)g d" e!"g d# e!$g d$g d%g d&g d'g d(g e%e!&  d	S d	S ))a  module for creating simple ASCII tables


Example:

    table = Texttable()
    table.set_cols_align(["l", "r", "c"])
    table.set_cols_valign(["t", "m", "b"])
    table.add_rows([["Name", "Age", "Nickname"],
                    ["Mr\nXavier\nHuon", 32, "Xav'"],
                    ["Mr\nBaptiste\nClement", 1, "Baby"],
                    ["Mme\nLouise\nBourgeau", 28, "Lou\n\nLoue"]])
    print(table.draw())
    print()

    table = Texttable()
    table.set_deco(Texttable.HEADER)
    table.set_cols_dtype(['t',  # text
                          'f',  # float (decimal)
                          'e',  # float (exponent)
                          'i',  # integer
                          'a']) # automatic
    table.set_cols_align(["l", "r", "r", "r", "l"])
    table.add_rows([["text",    "float", "exp", "int", "auto"],
                    ["abcd",    "67",    654,   89,    128.001],
                    ["efghijk", 67.5434, .654,  89.6,  12800000000000000000000.00023],
                    ["lmn",     5e-78,   5e-78, 89.4,  .000000000000128],
                    ["opqrstu", .023,    5e+78, 92.,   12800000000000000000000]])
    print(table.draw())

Result:

    +----------+-----+----------+
    |   Name   | Age | Nickname |
    +==========+=====+==========+
    | Mr       |     |          |
    | Xavier   |  32 |          |
    | Huon     |     |   Xav'   |
    +----------+-----+----------+
    | Mr       |     |          |
    | Baptiste |   1 |          |
    | Clement  |     |   Baby   |
    +----------+-----+----------+
    | Mme      |     |   Lou    |
    | Louise   |  28 |          |
    | Bourgeau |     |   Loue   |
    +----------+-----+----------+

    text   float       exp      int     auto
    ===========================================
    abcd   67.000   6.540e+02   89    128.001
    efgh   67.543   6.540e-01   90    1.280e+22
    ijkl   0.000    5.000e-78   89    0.000
    mnop   0.023    5.000e+78   92    1.280e+22
    )division	TexttableArraySizeErrorz%Gerome Fournier <jef(at)foutaise.org>MITz1.6.4a  Jeff Kowalczyk:
    - textwrap improved import
    - comment concerning header output

Anonymous:
    - add_rows method, for adding rows in one go

Sergey Simonenko:
    - redefined len() function to deal with non-ASCII characters

Roger Lew:
    - columns datatype specifications

Brian Peterson:
    - better handling of unicode errors

Frank Sachsenheim:
    - add Python 2/3-compatibility

Maximilian Hils:
    - fix minor bug for Python 3 compatibility

frinkelpi:
    - preserve empty lines
Nc                 C      t | |S N)cjkwrapwraptxtwidth r   +/usr/lib/python3/dist-packages/texttable.pytextwrapperg      r   c                 C   r   r   )textwrapr	   r
   r   r   r   r   l   r   zCan't import textwrap module!
c                 C   s   t dt| S ):Return the rendering width of a unicode character
        r   )maxwcwidthcr   r   r   uchar_widthw   s   r   c                 C   s$   t | dv r	dS t | rdS dS )r   WF   r      )unicodedataeast_asian_width	combiningr   r   r   r   r   |   s
   
)reduce)   r   c              
   C   sr   t | tr| S t | tr5zt| dW S  ty4 } ztjd| |f  t| ddW  Y d}~S d}~ww t| S )z7Return a unicode representation of a python object
    zutf-8z1UnicodeDecodeError exception for string '%s': %s
replaceN)
isinstanceunicode_type
bytes_typeUnicodeDecodeErrorsysstderrwrite)objstrerrorr   r   r   obj2unicode   s   

r*   c                 C   s2   t | ts
t | trtdd t| D S |  S )zMRedefining len here so it will be able to work with non-ASCII characters
    c                 S      g | ]}t |qS r   )r   ).0r   r   r   r   
<listcomp>       zlen.<locals>.<listcomp>)r!   r#   r"   sumr*   __len__)iterabler   r   r   len   s   r2   c                   @   s    e Zd ZdZdd Zdd ZdS )r   zEException raised when specified rows don't fit the required size
    c                 C   s   || _ t| |d d S )N )msg	Exception__init__)selfr4   r   r   r   r6      s   zArraySizeError.__init__c                 C   s   | j S r   )r4   r7   r   r   r   __str__   s   zArraySizeError.__str__N)__name__
__module____qualname____doc__r6   r9   r   r   r   r   r      s    c                   @   s   e Zd ZdZdS )FallbackToTextz#Used for failed conversion to floatN)r:   r;   r<   r=   r   r   r   r   r>      s    r>   c                   @   sT  e Zd ZdZdZdZdZdOddZdd	 Zd
d Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd ZdPd!d"Zd#d$ Zed%d& Zed'd( Zed)d* Zed+d, Zed-d. Zed/d0 Zd1d2 Zd3d4 Zd5d6 Zd7d8 Z d9d: Z!d;d< Z"d=d> Z#d?d@ Z$dQdBdCZ%dDdE Z&dFdG Z'dHdI Z(dQdJdKZ)dLdM Z*dNS )Rr   r   r         P   c                 C   sD   |  | d| _tjtjB tjB tjB | _| g d | 	  dS )zConstructor

        - max_width is an integer, specifying the maximum width of the table
        - if set to 0, size is unlimited, therefore cells won't be wrapped
        r   )-|+=N)
set_max_width
_precisionr   VLINESHLINESBORDERHEADER_deco	set_charsresetr7   	max_widthr   r   r   r6      s   
zTexttable.__init__c                 C   s   d| _ d| _g | _g | _| S )z<Reset the instance

        - reset rows and header
        N)_hline_string	_row_size_header_rowsr8   r   r   r   rN      s
   zTexttable.resetc                 C   s   |dkr	|| _ | S d| _ | S )zSet the maximum width of the table

        - max_width is an integer, specifying the maximum width of the table
        - if set to 0, size is unlimited, therefore cells won't be wrapped
        r   F)
_max_widthrO   r   r   r   rF      s   zTexttable.set_max_widthc                 C   sD   t |dkr
tddd dd |D D }|\| _| _| _| _| S )zSet the characters used to draw lines between rows and columns

        - the array should contain 4 fields:

            [horizontal, vertical, corner, header]

        - default is set to:

            ['-', '|', '+', '=']
        r?   z!array should contain 4 charactersc                 S   s   g | ]}|d d qS )Nr   r   r,   xr   r   r   r-      s    z'Texttable.set_chars.<locals>.<listcomp>c                 S   r+   r   )str)r,   sr   r   r   r-      r.   )r2   r   _char_horiz
_char_vert_char_corner_char_headerr7   arrayr   r   r   rM      s   
zTexttable.set_charsc                 C   s   || _ d| _| S )a  Set the table decoration

        - 'deco' can be a combination of:

            Texttable.BORDER: Border around the table
            Texttable.HEADER: Horizontal line below the header
            Texttable.HLINES: Horizontal lines between rows
            Texttable.VLINES: Vertical lines between columns

           All of them are enabled by default

        - example:

            Texttable.BORDER | Texttable.HEADER
        N)rL   rQ   )r7   decor   r   r   set_deco   s   zTexttable.set_decoc                 C      |  | || _| S )zSet the desired header alignment

        - the elements of the array should be either "l", "c" or "r":

            * "l": column flushed left
            * "c": column centered
            * "r": column flushed right
        )_check_row_size_header_alignr^   r   r   r   set_header_align     

zTexttable.set_header_alignc                 C   rb   )zSet the desired columns alignment

        - the elements of the array should be either "l", "c" or "r":

            * "l": column flushed left
            * "c": column centered
            * "r": column flushed right
        )rc   _alignr^   r   r   r   set_cols_align  rf   zTexttable.set_cols_alignc                 C   rb   )a,  Set the desired columns vertical alignment

        - the elements of the array should be either "t", "m" or "b":

            * "t": column aligned on the top of the cell
            * "m": column aligned on the middle of the cell
            * "b": column aligned on the bottom of the cell
        )rc   _valignr^   r   r   r   set_cols_valign(  rf   zTexttable.set_cols_valignc                 C   rb   )a.  Set the desired columns datatype for the cols.

        - the elements of the array should be either a callable or any of
          "a", "t", "f", "e" or "i":

            * "a": automatic (try to use the most appropriate datatype)
            * "t": treat as text
            * "f": treat as float in decimal format
            * "e": treat as float in exponential format
            * "i": treat as int
            * a callable: should return formatted string for any value given

        - by default, automatic datatyping is used for each column
        )rc   _dtyper^   r   r   r   set_cols_dtype6  s   
zTexttable.set_cols_dtypec                 C   sV   |  | zttt|}tt|dkrtW n ty%   tj	d  w || _
| S )zSet the desired columns width

        - the elements of the array should be integers, specifying the
          width of each column. For example:

                [10, 20, 5]
        r   z-Wrong argument in column width specification
)rc   listmapintr   min
ValueErrorr%   r&   r'   _widthr^   r   r   r   set_cols_widthJ  s   
	zTexttable.set_cols_widthc                 C   s&   t |tus
|dk rtd|| _| S )zSet the desired precision for float/exponential formats

        - width must be an integer >= 0

        - default value is set to 3
        r   z'width must be an integer greater then 0)typero   rq   rG   )r7   r   r   r   r   set_precision^  s   zTexttable.set_precisionc                 C   s   |  | ttt|| _| S )z(Specify the header of the table
        )rc   rm   rn   r*   rS   r^   r   r   r   headerk  s   
zTexttable.headerc                 C   sZ   |  | t| dsdg| j | _g }t|D ]\}}|| || q| j| | S )zSAdd a row in the rows stack

        - cells can contain newlines and tabs
        rk   a)rc   hasattrrR   rk   	enumerateappend_strrT   )r7   r_   cellsirW   r   r   r   add_rows  s   

zTexttable.add_rowTc                 C   sZ   |r!t |drt |dr| |  n| |d  |dd }|D ]}| | q#| S )zAdd several rows in the rows stack

        - The 'rows' argument can be either an iterator returning arrays,
          or a by-dimensional array
        - 'header' specifies if the first row should be used as the header
          of the table
        __iter__nextr   r   N)rx   rv   r   r~   )r7   rowsrv   rowr   r   r   add_rows  s   zTexttable.add_rowsc                 C   s   | j s| jsdS |   |   d}|  r||  7 }| j r3|| j| j dd7 }|  r3||  7 }d}| jD ]}|d7 }|| |7 }| 	 rV|t
| jk rV||  7 }q8|  ra||  7 }|dd S )zJDraw the table

        - the table is returned as a whole string
        Nr3   T)isheaderr   r   )rS   rT   _compute_cols_width_check_align_has_border_hline
_draw_line_has_header_hline_header_has_hlinesr2   )r7   outlengthr   r   r   r   draw  s*   
zTexttable.drawc              	   C   s2   |d u rt  zt|W S  ttfy   t  w r   )r>   float	TypeErrorrq   )clsrW   r   r   r   	_to_float  s   
zTexttable._to_floatc                 K   s*   t |tkr
t|S ttt| |S )z)Integer formatting class-method.
        )rt   ro   rX   roundr   r   rW   kwr   r   r   _fmt_int  s   zTexttable._fmt_intc                 K      | d}d|| |f S )zFloat formatting class-method.

        - x parameter is ignored. Instead kw-argument f being x float-converted
          will be used.

        - precision will be taken from `n` kw-argument.
        nz%.*fgetr   r   rW   r   r   r   r   r   
_fmt_float     
	zTexttable._fmt_floatc                 K   r   )zExponential formatting class-method.

        - x parameter is ignored. Instead kw-argument f being x float-converted
          will be used.

        - precision will be taken from `n` kw-argument.
        r   z%.*er   r   r   r   r   _fmt_exp  r   zTexttable._fmt_expc                 K   s   t |S )zString formatting class-method.)r*   r   r   r   r   	_fmt_text  s   zTexttable._fmt_textc                 K   s\   |  |}t|dkr| j}n||kr| j}n|t| dkr#| j}n| j}||fi |S )zauto formatting class-method.g    חAr   )r   absr   r   r   r   r   )r   rW   r   ffnr   r   r   	_fmt_auto  s   
zTexttable._fmt_autoc                 C   sl   | j | j| j| j| jd}| j}| j| }zt|r||W S || ||dW S  ty5   | | Y S w )zHandles string formatting of cell data

            i - index of the cell datatype in self._dtype
            x - cell data to format
        )rw   r}   r   et)r   )	r   r   r   r   r   rG   rk   callabler>   )r7   r}   rW   FMTr   dtyper   r   r   r{     s   

zTexttable._strc                 C   s4   | j s
t|| _ dS | j t|krtd| j  dS )zCCheck that the specified array fits the previous rows size
        z array should contain %d elementsN)rR   r2   r   r^   r   r   r   rc   	  s   zTexttable._check_row_sizec                 C      | j tj@ dkS )z8Return a boolean, if vlines are required or not
        r   )rL   r   rH   r8   r   r   r   _has_vlines     zTexttable._has_vlinesc                 C   r   )z8Return a boolean, if hlines are required or not
        r   )rL   r   rI   r8   r   r   r   r     r   zTexttable._has_hlinesc                 C   r   )z7Return a boolean, if border is required or not
        r   )rL   r   rJ   r8   r   r   r   r     r   zTexttable._has_borderc                 C   r   )z<Return a boolean, if header line is required or not
        r   )rL   r   rK   r8   r   r   r   r   %  r   zTexttable._has_headerc                 C   s
   |  dS )z'Print header's horizontal line
        T)_build_hliner8   r   r   r   r   +  s   
zTexttable._hline_headerc                 C   s   | j s|  | _ | j S )z!Print an horizontal line
        )rQ   r   r8   r   r   r   r   1  s   
zTexttable._hlineFc                    st   | j  |r| j d  | jg|    f }| fdd| jD }|  r4d| j | | jf }|S |d7 }|S )zTReturn a string used to separated rows or separate header from
        rows
        z%s%s%sc                    s   g | ]} | qS r   r   )r,   r   horizr   r   r-   D  r.   z*Texttable._build_hline.<locals>.<listcomp>z%s%s%s%s%s

)rZ   r]   r\   r   joinrr   r   )r7   	is_headerrY   lr   r   r   r   9  s   zTexttable._build_hlinec           	      C   s   | d}d}|D ]5}d}| d}t|ttdt|d D ]\}}|t| }|t|k r8|d d d }q t||}q	|S )zReturn the width of the cell

        Special characters are taken into account to return the width of the
        cell, such like newlines and tabs
        r   r   	r   r@   )splitziprm   ranger2   r   )	r7   cell
cell_linesmaxiliner   partspartr}   r   r   r   	_len_cellM  s   

$zTexttable._len_cellc           
         s\  t  drdS g } jr fdd jD } jD ]3}t|ttt|D ]%\}}zt||  |||< W q& t	t
fyK   | | Y q&w qt|}t|}d|d  ddg    } jr||  jkr	  j|| k rytd	 j| }dg| }	d}|dkr|	| || k r|	|  d7  < |d8 }|d | }|dks|	}| _dS )
a  Return an array with the width of each column

        If a specific width has been specified, exit. If the total of the
        columns width exceed the table desired width, another width will be
        computed to fit, and cells will be wrapped.
        rr   Nc                    s   g | ]}  |qS r   )r   rV   r8   r   r   r-   l  s    z1Texttable._compute_cols_width.<locals>.<listcomp>r   r   r   r?   z max_width too low to render data)rx   rS   rT   r   rm   r   r2   r   r   r   
IndexErrorrz   r/   r   rU   rq   rr   )
r7   r   r   r   r}   ncolscontent_width
deco_widthavailable_widthnewmaxir   r8   r   r   `  s>   




zTexttable._compute_cols_widthc                 C   sP   t | dsdg| j | _t | dsdg| j | _t | ds&dg| j | _dS dS )zFCheck if alignment has been specified, set default one if not
        rd   r   rg   r   ri   r   N)rx   rR   rd   rg   ri   r8   r   r   r   r     s   


zTexttable._check_alignc                 C   s:  |  ||}d}d}tt|d D ]}|  r|d| j 7 }d}t|| j| jD ]a\}}}	|d7 }|| }
|t|
 }|rE| j|d  }	|	dkrR||| |
 7 }n%|	dkro|t	|d | |
 t	|d |d  |  7 }n||
||  7 }|t|k r|d	|| jg| 
   7 }q)|d
d|| j g|    7 }q|S )zPDraw a line

        Loop over a single cell length, over all the cells
         r3   r   z%s r   rr   r   z %s z%s
)_splititr   r2   r   r[   r   rr   rg   rd   ro   r   )r7   r   r   spacer   r}   r   r   r   align	cell_linefillr   r   r   r     s2    zTexttable._draw_linec                 C   s"  g }t || jD ]'\}}g }|dD ]}| dkr!|d q|t|| q|| qttt	t
t|}t || jD ]N\}}	|rHd}	|	dkrp|t| }
dgt|
d  |dd< |dgt|
d |
d    q@|	dkrdg|t|  |dd< q@|dg|t|   q@|S )	zSplit each element of line to fit the column width

        Each element is turned into a list, result of the wrapping of the
        string to the desired width
        r   r3   r   mr   Nr   b)r   rr   r   striprz   extendr   r   r   rm   rn   r2   ri   ro   )r7   r   r   line_wrappedr   r   r_   r   max_cell_linesvalignmissingr   r   r   r     s(   "zTexttable._splititN)rA   )T)F)+r:   r;   r<   rJ   rK   rI   rH   r6   rN   rF   rM   ra   re   rh   rj   rl   rs   ru   rv   r~   r   r   classmethodr   r   r   r   r   r   r{   rc   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r      s\    
	








(
__main__)r   r   r   )r   r   r   )NameAgeNickname)zMr
Xavier
Huon    zXav')zMr
Baptiste
Clementr   Baby)zMme
Louise
Bourgeau   z
Lou
 
Loue)r   r   r   r}   rw   )r   r   r   r   r   )textr   expro   auto)abcd67i  Y   gy&1 `@)efghijkg_)P@g!rh?gffffffV@g@xD)lmnܐ؆/r   gYV@gV瞯B=)opqrstugZd;O?g/'%EPg      W@l      Zx^+)*r=   
__future__r   __all__
__author____license____version____credits__r%   r   r   r   ImportErrorr   r&   r'   r   r   	functoolsr   version_inforX   r"   bytesr#   unicoder*   r2   r5   r   r>   r   r:   tablerh   rj   r   printr   ra   rK   rl   r   r   r   r   <module>   s   8
	    

