U
    .R”i7  ã                   @   s   d Z ddlmZ ddlmZmZ ddlmZmZ ddl	Z	ddl
mZ e	 d¡Zd	Zd
ZdZe	 de d e	j¡ZdZe	 d ee¡e	j¡Zdd„ Zdd„ Zdd„ Zdgeeƒ Zedd�dd„ ƒZdd„ eedƒD ƒZdZedd�dd„ ƒZdd „ Z d!d"„ Z!d#d$„ Z"d%d&„ Z#d'd(„ Z$d)d*„ Z%dS )+zT
Collection of utilities used within the package and also available for client code
é    )Ú	lru_cache)ÚchainÚproduct)Úascii_uppercaseÚdigitsNé   )ÚCellCoordinatesExceptionz^[$]?([A-Za-z]{1,3})[$]?(\d+)$z[A-Z]{1,3}:[A-Z]{1,3}:z\d+:\d+:zq
[$]?(?P<min_col>[A-Za-z]{1,3})?
[$]?(?P<min_row>\d+)?
(:[$]?(?P<max_col>[A-Za-z]{1,3})?
[$]?(?P<max_row>\d+)?)?
ú^ú$z7
(('(?P<quoted>([^']|'')*)')|(?P<notquoted>[^'^ ^!]*))!z{0}(?P<cells>{1})(?=,?)c                 C   s<   t | tƒrt| ƒ} t |tƒr$t|ƒ}dd„ t| |d ƒD ƒS )z¤
    Given the start and end columns, return all the columns in the series.

    The start and end columns can be either column letters or 1-based
    indexes.
    c                 S   s   g | ]}t |ƒ‘qS © ©Úget_column_letter)Ú.0Úxr   r   ú7/tmp/pip-unpacked-wheel-r0v169r1/openpyxl/utils/cell.pyÚ
<listcomp>)   s     z'get_column_interval.<locals>.<listcomp>r   )Ú
isinstanceÚstrÚcolumn_index_from_stringÚrange)ÚstartÚendr   r   r   Úget_column_interval   s
    

r   c                 C   sV   t  | ¡}|s"d| › d�}t|ƒ‚| ¡ \}}t|ƒ}|sNd| › d�}t|ƒ‚||fS )z;Convert a coordinate string like 'B12' to a tuple ('B', 12)zInvalid cell coordinates (ú)zThere is no row 0 ()ÚCOORD_REÚmatchr   ÚgroupsÚint)Úcoord_stringr   ÚmsgÚcolumnÚrowr   r   r   Úcoordinate_from_string,   s    
r"   c                 C   sp   t  | ¡}|st| › d�ƒ‚| d¡}| ¡ D ]\}}|r.d|› �||< q.|d sZ|d r`d}nd}|jf |ŽS )zDConvert a coordinate to an absolute coordinate string (B12 -> $B$12)z  is not a valid coordinate rangeÚ r
   Úmax_colÚmax_rowz%{min_col}{min_row}:{max_col}{max_row}z{min_col}{min_row})ÚABSOLUTE_REr   Ú
ValueErrorÚ	groupdictÚitemsÚformat)r   ÚmÚdÚkÚvÚfmtr   r   r   Úabsolute_coordinate:   s    

r0   r#   )Úmaxsizec                 C   s~   d|   krdks$n t d | ¡ƒ‚g }| dk r8t|  S | rtt| dƒ\} }| dt| ¡ |s8| d8 } | dd¡ q8d |¡S )aÎ  
    Convert decimal column position to its ASCII (base 26) form.

    Because column indices are 1-based, strides are actually pow(26, n) + 26
    Hence, a correction is applied between pow(26, n) and pow(26, 2) + 26 to
    prevent and additional column letter being prepended

    "A" == 1 == pow(26, 0)
    "Z" == 26 == pow(26, 0) + 26 // decimal equivalent 10
    "AA" == 27 == pow(26, 1) + 1
    "ZZ" == 702 == pow(26, 2) + 26 // decimal equivalent 100
    r   ifG  zInvalid column index {0}é   r   ÚZr#   )r'   r*   Ú__decimal_to_alphaÚdivmodÚinsertÚjoin)Zcol_idxÚresultÚ	remainderr   r   r   r   N   s    r   c                 C   s   i | ]\}}||“qS r   r   )r   ÚposÚletterr   r   r   Ú
<dictcomp>o   s      r<   )r   r2   i¤  c              	   C   sœ   d| › d�}t | ƒdkr t|ƒ‚d}t|  ¡ ƒ} t| tƒD ]>\}}zt| }W n tk
rj   t|ƒ‚Y nX ||| 7 }q:d|  k rŽdk s˜n t|ƒ‚|S )zÊ
    Convert ASCII column name (base 26) to decimal with 1-based index

    Characters represent descending multiples of powers of 26

    "AFZ" == 26 * pow(26, 0) + 6 * pow(26, 1) + 1 * pow(26, 2)
    ú'z<' is not a valid column name. Column names are from A to ZZZé   r   igG  )Úlenr'   ÚreversedÚupperÚzipÚ__powersÚ__alpha_to_decimalÚKeyError)ÚcolÚ	error_msgÚidxr;   Úpowerr:   r   r   r   r   r   s    	r   c           
      C   sÒ   d  | ¡}t | ¡}|s t|ƒ‚| ¡ \}}}}}|rz||f}||f}	t||	 ƒszt|ƒrbt|	ƒrzt|	ƒrrt|ƒrzt|ƒ‚|dk	rŠt|ƒ}|dk	ršt|ƒ}|dk	r¬t|ƒ}n|}|dk	rÂt|ƒ}n|}||||fS )z³
    Convert a range string into a tuple of boundaries:
    (min_col, min_row, max_col, max_row)
    Cell coordinates will be converted into a range with the cell at both end
    z&{0} is not a valid coordinate or rangeN)	r*   r&   r   r'   r   ÚallÚanyr   r   )
Úrange_stringr   r+   Úmin_colÚmin_rowÚsepr$   r%   ÚcolsÚrowsr   r   r   Úrange_boundaries‹   s<    


ÿþþýý

rR   c                 #   s\   t | ƒ\}}}}t||d ƒ}dd„ t||d ƒD ƒ}|D ]‰ t‡ fdd„|D ƒƒV  q:dS )ú[
    Get individual addresses for every cell in a range.
    Yields one row at a time.
    r   c                 S   s   g | ]}t |ƒ‘qS r   r   ©r   rF   r   r   r   r   ½   s     z#rows_from_range.<locals>.<listcomp>c                 3   s   | ]}d   |ˆ ¡V  qdS ©z{0}{1}N©r*   rT   ©r!   r   r   Ú	<genexpr>¿   s     z"rows_from_range.<locals>.<genexpr>N©rR   r   Útuple©rL   rM   rN   r$   r%   rQ   rP   r   rW   r   Úrows_from_range¶   s
    r\   c                 #   s\   t | ƒ\}}}}t||d ƒ}dd„ t||d ƒD ƒ}|D ]‰ t‡ fdd„|D ƒƒV  q:dS )rS   r   c                 s   s   | ]}t |ƒV  qd S )Nr   rT   r   r   r   rX   É   s     z"cols_from_range.<locals>.<genexpr>c                 3   s   | ]}d   ˆ |¡V  qdS rU   rV   )r   r!   ©rF   r   r   rX   Ë   s     NrY   r[   r   r]   r   Úcols_from_rangeÂ   s
    r^   c                 C   sF   t | ƒD ]\}}|tkr qq| d|… }| |d… }t|ƒt|ƒfS )zB
    Convert an Excel style coordinate to (row, column) tuple
    N)Ú	enumerater   r   r   )Z
coordinaterH   ÚcrF   r!   r   r   r   Úcoordinate_to_tupleÎ   s    ra   c                 C   sH   t  | ¡}|dkrtdƒ‚| d¡p,| d¡}| d¡}t|ƒ}||fS )zc
    Convert a worksheet range to the sheetname and maximum and minimum
    coordinate indices
    Nz)Value must be of the form sheetname!A1:E4ÚquotedZ	notquotedÚcells)ÚSHEETRANGE_REr   r'   ÚgrouprR   )rL   r+   Ú	sheetnamerc   Z
boundariesr   r   r   Úrange_to_tupleÚ   s    

rg   c                 C   s"   d| kr|   dd¡} d | ¡} | S )z>
    Add quotes around sheetnames if they contain spaces.
    r=   z''z'{0}')Úreplacer*   )rf   r   r   r   Úquote_sheetnameè   s    
ri   )&Ú__doc__Ú	functoolsr   Ú	itertoolsr   r   Ústringr   r   ÚreÚ
exceptionsr   Úcompiler   Z	COL_RANGEZ	ROW_RANGEZ
RANGE_EXPRÚVERBOSEr&   ZSHEET_TITLEr*   rd   r   r"   r0   Úlistr4   r   r_   rD   rC   r   rR   r\   r^   ra   rg   ri   r   r   r   r   Ú<module>   sB   
 ÿÿ
 
+