U
    Z+d
3                     @  sT  d Z ddlmZ ddlZddlZddlmZ ddlmZm	Z	m
Z
mZmZmZ ddlmZ ddlmZmZmZmZmZ dd	lmZ d
dddgZdd e D ZdddddZedddddddddd	ZdddddZdddddZedZ G dd deZ!e!j"Z#G dd
 d
eZ$edZ%d dd!d"d#Z&d$d%d&d'dZ'G d(d% d%eZ(dS ))z-
Tool for creating styles from a dictionary.
    )annotationsN)Enum)DictHashableListSetTupleTypeVar)SimpleCache   )ANSI_COLOR_NAMESANSI_COLOR_NAMES_ALIASESDEFAULT_ATTRSAttrs	BaseStyle)NAMED_COLORSStyleparse_colorPrioritymerge_stylesc                 C  s    i | ]\}}|  |d qS )#)lowerlstrip).0kv r   ?/tmp/pip-unpacked-wheel-blk8czbf/prompt_toolkit/styles/style.py
<dictcomp>   s      r   str)textreturnc                 C  s   | t kr| S | tkrt|  S zt|   W S  tk
r>   Y nX | dd dkr| dd }|t krh|S |tkrxt| S t|dkr|S t|dkr|d d |d d  |d d  S n| dkr| S td	|  dS )
z
    Parse/validate color format.

    Like in Pygments, but also support the ANSI color names.
    (These will map to the colors of the 16 color palette.)
    r   r   r   N         ) defaultzWrong color format %r)r   r   _named_colors_lowercaser   KeyErrorlen
ValueError)r    colr   r   r   r       s*    &	colorbgcolorbold	underlinestrikeitalicblinkreversehiddenz	list[str])	classnamer!   c                 C  sF   g }|  d}tdt|d D ] }|d|d|   q |S )z
    Split a single class name at the `.` operator, and build a list of classes.

    E.g. 'a.b.c' becomes ['a', 'a.b', 'a.b.c']
    .r   N)splitranger)   appendjoinr   )r6   resultpartsir   r   r   _expand_classname]   s
    
r?   r   )	style_strr!   c                 C  s   d| krt }nt}|  D ]}|dkr*q|dkr@|jdd}q|dkrV|jdd}q|dkrl|jdd}q|d	kr|jdd}q|d
kr|jdd}q|dkr|jdd}q|dkr|jdd}q|dkr|jdd}q|dk r|jdd}q|dkr
|jdd}q|dkr"|jdd}q|dkr:|jdd}q|dkrR|jdd}q|dkrj|jdd}q|dkrvq|drq|dr|drq|dr|jt|dd d }q|d!r|jt|dd d"}q|jt|d"}q|S )#zd
    Take a style string, e.g.  'bg:red #88ff00 class:title'
    and return a `Attrs` instance.
    Z	noinheritr/   Tr/   ZnoboldFr2   r2   Znoitalicr0   r0   Znounderliner1   r1   Znostriker3   r3   Znoblinkr4   r4   Z	noreverser5   r5   Znohidden)ZromanZsansZmonozborder:[]zbg:r#   Nr.   zfg:r-   )r   _EMPTY_ATTRSr8   _replace
startswithendswithr   )r@   attrspartr   r   r   _parse_style_strl   s\    






rR   z^[a-z0-9.\s_-]*$c                   @  s   e Zd ZdZdZdZdS )r   a  
    The priority of the rules, when a style is created from a dictionary.

    In a `Style`, rules that are defined later will always override previous
    defined rules, however in a dictionary, the key order was arbitrary before
    Python 3.6. This means that the style could change at random between rules.

    We have two options:

    - `DICT_KEY_ORDER`: This means, iterate through the dictionary, and take
       the key/value pairs in order as they come. This is a good option if you
       have Python >3.6. Rules at the end will override rules at the beginning.
    - `MOST_PRECISE`: keys that are defined with most precision will get higher
      priority. (More precise means: more elements.)
    Z	KEY_ORDERMOST_PRECISEN)__name__
__module____qualname____doc__DICT_KEY_ORDERrS   r   r   r   r   r      s   c                   @  sp   e Zd ZdZdddddZedddd	Zeefd
dd dddZ	e
fddddddZddddZdS )r   a  
    Create a ``Style`` instance from a list of style rules.

    The `style_rules` is supposed to be a list of ('classnames', 'style') tuples.
    The classnames are a whitespace separated string of class names and the
    style string is just like a Pygments style definition, but with a few
    additions: it supports 'reverse' and 'blink'.

    Later rules always override previous rules.

    Usage::

        Style([
            ('title', '#ff0000 bold underline'),
            ('something-else', 'reverse'),
            ('class1 class2', 'reverse'),
        ])

    The ``from_dict`` classmethod is similar, but takes a dictionary as input.
    list[tuple[str, str]]None)style_rulesr!   c                 C  s^   g }|D ]D\}}t |s&tt|t|  }t|}|||f q|| _	|| _
d S N)CLASS_NAMES_REmatchAssertionErrorrepr	frozensetr   r8   rR   r:   _style_rulesclass_names_and_attrs)selfr[   rc   class_namesr@   Zclass_names_setrP   r   r   r   __init__   s    zStyle.__init__r!   c                 C  s   | j S r\   )rb   rd   r   r   r   r[      s    zStyle.style_ruleszdict[str, str]r   )
style_dictpriorityr!   c                 C  sB   |t jkr.ddddd}| t| |dS | t| S dS )za
        :param style_dict: Style dictionary.
        :param priority: `Priority` value.
        ztuple[str, str]int)itemr!   c                 S  s   t dd | d  D S )Nc                 s  s   | ]}t |d V  qdS )r7   N)r)   r8   )r   r>   r   r   r   	<genexpr>  s     z/Style.from_dict.<locals>.key.<locals>.<genexpr>r   )sumr8   )rl   r   r   r   key  s    zStyle.from_dict.<locals>.key)ro   N)r   rS   sorteditemslist)clsri   rj   ro   r   r   r   	from_dict   s    
zStyle.from_dictr   r   r@   r&   r!   c              	   C  s  |g}t  }| jD ]\}}|s|| q| D ]}|drg }|dd  dD ]}	|t|	 qZ|D ]}
t  }|t	|
g t
dt|d D ]*}t||D ]}|t	||
f  qq| jD ]\}}||kr|| q||
 qrq2t|}|| q2t|S )z9
        Get `Attrs` for the given style string.
        zclass:r"   N,r   )setrc   r:   r8   rN   r   extendr?   addra   r9   r)   	itertoolscombinationsrR   _merge_attrs)rd   r@   r&   list_of_attrsre   namesattrrQ   Znew_class_namespnew_nameZcomboscountc2Zinline_attrsr   r   r   get_attrs_for_style_str  s.    
zStyle.get_attrs_for_style_strr   c                 C  s
   t | jS r\   )idrc   rh   r   r   r   invalidation_hash<  s    zStyle.invalidation_hashN)rT   rU   rV   rW   rf   propertyr[   classmethoddefault_priorityrt   r   r   r   r   r   r   r   r      s   1_Tzlist[Attrs])r}   r!   c                 C  s   ddddd}t |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  |ddd | D  d	S )z
    Take a list of :class:`.Attrs` instances and merge them into one.
    Every `Attr` in the list can override the styling of the previous one. So,
    the last one has highest priority.
    r   )valuesr!   c                  W  s,   | ddd D ]}|dk	r|  S qt dS )z/Take first not-None value, starting at the end.N)r*   )r   r   r   r   r   _orJ  s    
z_merge_attrs.<locals>._orr%   c                 S  s   g | ]
}|j qS r   rK   r   ar   r   r   
<listcomp>R  s     z _merge_attrs.<locals>.<listcomp>c                 S  s   g | ]
}|j qS r   rJ   r   r   r   r   r   S  s     Fc                 S  s   g | ]
}|j qS r   rA   r   r   r   r   r   T  s     c                 S  s   g | ]
}|j qS r   rC   r   r   r   r   r   U  s     c                 S  s   g | ]
}|j qS r   rD   r   r   r   r   r   V  s     c                 S  s   g | ]
}|j qS r   rB   r   r   r   r   r   W  s     c                 S  s   g | ]
}|j qS r   rE   r   r   r   r   r   X  s     c                 S  s   g | ]
}|j qS r   rF   r   r   r   r   r   Y  s     c                 S  s   g | ]
}|j qS r   rG   r   r   r   r   r   Z  s     r,   )r%   )r%   )F)F)F)F)F)F)F)r   )r}   r   r   r   r   r|   C  s    r|   list[BaseStyle]_MergedStylestylesr!   c                 C  s   dd | D } t | S )z)
    Merge multiple `Style` objects.
    c                 S  s   g | ]}|d k	r|qS r\   r   r   sr   r   r   r   b  s      z merge_styles.<locals>.<listcomp>)r   )r   r   r   r   r   ^  s    c                   @  sh   e Zd ZdZdddddZeddd	d
ZeddddZefddddddZ	ddddZ
dS )r   z
    Merge multiple `Style` objects into one.
    This is supposed to ensure consistency: if any of the given styles changes,
    then this style will be updated.
    r   rZ   r   c                 C  s   || _ tdd| _d S )Nr   )maxsize)r   r
   _style)rd   r   r   r   r   rf   v  s    z_MergedStyle.__init__r   rg   c                   s$   dd fdd} j   |S )z=The `Style` object that has the other styles merged together.r   rg   c                     s
   t  jS r\   )r   r[   r   rh   r   r   get~  s    z'_MergedStyle._merged_style.<locals>.get)r   r   r   )rd   r   r   rh   r   _merged_stylez  s    z_MergedStyle._merged_stylerY   c                 C  s    g }| j D ]}||j q
|S r\   )r   rx   r[   )rd   r[   r   r   r   r   r[     s    
z_MergedStyle.style_rulesr   r   ru   c                 C  s   | j ||S r\   )r   r   )rd   r@   r&   r   r   r   r     s    z$_MergedStyle.get_attrs_for_style_strr   c                 C  s   t dd | jD S )Nc                 s  s   | ]}|  V  qd S r\   )r   r   r   r   r   rm     s     z1_MergedStyle.invalidation_hash.<locals>.<genexpr>)tupler   rh   r   r   r   r     s    z_MergedStyle.invalidation_hashN)rT   rU   rV   rW   rf   r   r   r[   r   r   r   r   r   r   r   r   f  s   ))rW   
__future__r   rz   reenumr   typingr   r   r   r   r   r	   Zprompt_toolkit.cacher
   baser   r   r   r   r   Znamed_colorsr   __all__rq   r'   r   rL   r?   rR   compiler]   r   rX   r   r   r   r|   r   r   r   r   r   r   <module>   sH    0D
s