a
    &ñ»j4‚  ã                   @  sú   d Z ddlmZ ddlZddlmZ ddlmZmZm	Z	 ddl
mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ er”ddlmZ G dd	„ d	eeƒZG d
d„ dƒZ e !d¡j"Z#e !d¡j$Z%e !d¡j$Z&G dd„ dƒZ'G dd„ de'ƒZ(dS )zâ
cssselect.xpath
===============

Translation of parsed CSS selectors to XPath expressions.


:copyright: (c) 2007-2012 Ian Bicking and contributors.
See AUTHORS for more details.
:license: BSD, see LICENSE for more details.

é    )ÚannotationsN)ÚCallable)ÚTYPE_CHECKINGÚOptionalÚcast)ÚAttribÚClassÚCombinedSelectorÚElementÚFunctionÚHashÚMatchingÚNegationÚPseudoÚPseudoElementÚRelationÚSelectorÚSelectorErrorÚSpecificityAdjustmentÚTreeÚparseÚparse_series)ÚSelfc                   @  s   e Zd ZdZdS )ÚExpressionErrorz3Unknown or unsupported selector (eg. pseudo-class).N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__© r   r   ú5E:\soccer\ml_env\Lib\site-packages\cssselect/xpath.pyr   -   s   r   c                   @  sˆ   e Zd Zdddddddœdd	„Zdd
œdd„Zdd
œdd„Zdddddœdd„Zdd
œdd„Zdd
œdd„Zddd ddddœdd„Z	dS ) Ú	XPathExprÚ Ú*FÚstrÚboolÚNone)ÚpathÚelementÚ	conditionÚstar_prefixÚreturnc                 C  s   || _ || _|| _d S ©N)r&   r'   r(   )Úselfr&   r'   r(   r)   r   r   r   Ú__init__5   s    zXPathExpr.__init__)r*   c                 C  s0   t | jƒt | jƒ }| jr,|d| j› d�7 }|S ©Nú[ú]©r#   r&   r'   r(   )r,   r&   r   r   r   Ú__str__@   s    zXPathExpr.__str__c                 C  s   | j j› d| › d�S r.   )Ú	__class__r   ©r,   r   r   r   Ú__repr__F   s    zXPathExpr.__repr__Úandr   )r(   Ú
conjuctionr*   c                 C  s.   | j r$d| j › d|› d|› d�| _ n|| _ | S )Nú(z) z (ú))r(   )r,   r(   r7   r   r   r   Úadd_conditionI   s    zXPathExpr.add_conditionc                 C  s0   | j dkrd S |  dt | j ¡› �¡ d| _ d S )Nr"   z	name() = )r'   r:   ÚGenericTranslatorÚxpath_literalr4   r   r   r   Úadd_name_testP   s    
zXPathExpr.add_name_testc                 C  s   |  j d7  _ dS )ze
        Append '*/' to the path to keep the context constrained
        to a single parent.
        ú*/N)r&   r4   r   r   r   Úadd_star_prefixW   s    zXPathExpr.add_star_prefixNú
str | None)ÚcombinerÚotherÚclosing_combinerÚhas_inner_conditionr*   c                 C  s†   t | ƒ| }|jdkr ||j7 }|| _|sJ|r8|j| n|j| _|j| _n8|j| _|jrp|  jd|j d 7  _|r‚|  j|7  _| S )Nr>   r/   r0   r1   )r,   rA   rB   rC   rD   r&   r   r   r   Újoin^   s    

ÿ
zXPathExpr.join)r!   r"   r!   F)r6   )NF)
r   r   r   r-   r2   r5   r:   r=   r?   rE   r   r   r   r   r    4   s       û  ûr    z('+)z^[a-zA-Z_][a-zA-Z0-9_.-]*$z^[^ \t\r\n\f]+$c                	   @  sÂ  e Zd ZdZdddddœZddd	d
dddddœZdZdZdZdZ	dZ
eZd›ddddœdd„Zdœdddddœdd„Zddddœd d!„Zeddd"œd#d$„ƒZd%dd&œd'd(„Zd)dd*œd+d,„Zd-dd.œd/d0„Zd1dd2œd3d4„Zd5dd6œd7d8„Zd9dd6œd:d;„Zd<dd=œd>d?„Zd@ddAœdBdC„ZdDddEœdFdG„ZdHddIœdJdK„ZdLddMœdNdO„ZdPddEœdQdR„ZddddSœdTdU„ZddddSœdVdW„ZddddSœdXdY„Z ddddSœdZd[„Z!ddddSœd\d]„Z"ddddSœd^d_„Z#ddddSœd`da„Z$ddddSœdbdc„Z%d�dd<ddddeœdfdg„Z&dd<ddhœdidj„Z'dd<ddhœdkdl„Z(dd<ddhœdmdn„Z)dd<ddhœdodp„Z*dd<ddhœdqdr„Z+dddsœdtdu„Z,dddsœdvdw„Z-dddsœdxdy„Z.dddsœdzd{„Z/dddsœd|d}„Z0dddsœd~d„Z1dddsœd€d�„Z2dddsœd‚dƒ„Z3dddsœd„d…„Z4dddsœd†d‡„Z5e5Z6e5Z7e5Z8e5Z9e5Z:e5Z;e5Z<e5Z=e5Z>dddˆdd‰œdŠd‹„Z?dddˆdd‰œdŒd�„Z@dddˆdd‰œdŽd�„ZAdddˆdd‰œd�d‘„ZBdddˆdd‰œd’d“„ZCdddˆdd‰œd”d•„ZDdddˆdd‰œd–d—„ZEdddˆdd‰œd˜d™„ZFdšS )žr;   z¤
    Translator for "generic" XML documents.

    Everything is case-sensitive, no assumption is made on the meaning
    of element names and attribute names.

    Z
descendantÚchildZdirect_adjacentZindirect_adjacent)ú ú>ú+ú~ÚexistsÚequalsZincludesZ	dashmatchZprefixmatchZsuffixmatchZsubstringmatchZ	different)rK   ú=z~=z|=z^=z$=z*=z!=Úidzxml:langFúdescendant-or-self::r#   )ÚcssÚprefixr*   c                   s   d  ‡ ‡fdd„t|ƒD ƒ¡S )u®  Translate a *group of selectors* to XPath.

        Pseudo-elements are not supported here since XPath only knows
        about "real" elements.

        :param css:
            A *group of selectors* as a string.
        :param prefix:
            This string is prepended to the XPath expression for each selector.
            The default makes selectors scoped to the context nodeâ€™s subtree.
        :raises:
            :class:`~cssselect.SelectorSyntaxError` on invalid selectors,
            :class:`ExpressionError` on unknown/unsupported selectors,
            including pseudo-elements.
        :returns:
            The equivalent XPath 1.0 expression as a string.

        z | c                 3  s   | ]}ˆj |ˆ d d�V  qdS )T)Útranslate_pseudo_elementsN)Úselector_to_xpath©Ú.0Úselector©rQ   r,   r   r   Ú	<genexpr>Ý   s   ÿz1GenericTranslator.css_to_xpath.<locals>.<genexpr>)rE   r   )r,   rP   rQ   r   rW   r   Úcss_to_xpathÊ   s    þzGenericTranslator.css_to_xpathr   r$   )rV   rQ   rR   r*   c                 C  s`   t |ddƒ}|std|›�ƒ‚|  |¡}t|| jƒs8J ‚|rP|jrP|  ||j¡}|pVdt|ƒ S )u+  Translate a parsed selector to XPath.


        :param selector:
            A parsed :class:`Selector` object.
        :param prefix:
            This string is prepended to the resulting XPath expression.
            The default makes selectors scoped to the context nodeâ€™s subtree.
        :param translate_pseudo_elements:
            Unless this is set to ``True`` (as :meth:`css_to_xpath` does),
            the :attr:`~Selector.pseudo_element` attribute of the selector
            is ignored.
            It is the caller's responsibility to reject selectors
            with pseudo-elements, or to account for them somehow.
        :raises:
            :class:`ExpressionError` on unknown/unsupported selectors.
        :returns:
            The equivalent XPath 1.0 expression as a string.

        Úparsed_treeNz Expected a parsed selector, got r!   )ÚgetattrÚ	TypeErrorÚxpathÚ
isinstanceÚxpathexpr_clsÚpseudo_elementÚxpath_pseudo_elementr#   )r,   rV   rQ   rR   Útreer]   r   r   r   rS   â   s    

z#GenericTranslator.selector_to_xpathr    r   )r]   r`   r*   c                 C  s   t dƒ‚dS )z�Translate a pseudo-element.

        Defaults to not supporting pseudo-elements at all,
        but can be overridden by sub-classes.

        z"Pseudo-elements are not supported.N)r   )r,   r]   r`   r   r   r   ra     s    	z&GenericTranslator.xpath_pseudo_element)Úsr*   c                 C  sZ   t | ƒ} d| vrd| › d�} n8d| vr4d| › d�} n"dd„ t| ƒD ƒ}d d |¡¡} | S )Nú'ú"c                 S  s0   g | ](}|rd |v r d|› d�n
d |› d �‘qS )rd   re   r   )rU   Úpartr   r   r   Ú
<listcomp>  s   þz3GenericTranslator.xpath_literal.<locals>.<listcomp>z
concat({})ú,)r#   Úsplit_at_single_quotesÚformatrE   )rc   Zparts_quotedr   r   r   r<     s    þzGenericTranslator.xpath_literalr   )Úparsed_selectorr*   c                 C  sR   t |ƒj}ttttgtf  t| d| ¡ › �dƒƒ}|du rJt	|› d�ƒ‚||ƒS )z%Translate any parsed selector object.Úxpath_Nz is not supported.)
Útyper   r   r   r   r   r    r[   Úlowerr   )r,   rk   Ú	type_nameÚmethodr   r   r   r]      s    
þzGenericTranslator.xpathr	   )Úcombinedr*   c                 C  sJ   | j |j }ttttgtf t| d|› d�ƒƒ}||  |j¡|  |j¡ƒS )zTranslate a combined selector.rl   Ú_combinator)	Úcombinator_mappingÚ
combinatorr   r   r    r[   r]   rV   Úsubselector)r,   rq   rt   rp   r   r   r   Úxpath_combinedselector-  s    þz(GenericTranslator.xpath_combinedselectorr   )Únegationr*   c                 C  sD   |   |j¡}|   |j¡}| ¡  |jr:| d|j› d�¡S | d¡S )Núnot(r9   Ú0)r]   rV   ru   r=   r(   r:   )r,   rw   r]   Z	sub_xpathr   r   r   Úxpath_negation6  s    z GenericTranslator.xpath_negationr   )Úrelationr*   c              	   C  s`   |   |j¡}|j}|j}|   |j¡}ttttgtf t| d| j	tt
|jƒ › d�ƒƒ}|||ƒS )NZxpath_relation_rr   )r]   rV   rt   ru   rZ   r   r   r    r[   rs   r#   Úvalue)r,   r{   r]   rt   ru   Úrightrp   r   r   r   Úxpath_relation>  s    þþz GenericTranslator.xpath_relationr   )Úmatchingr*   c                   sJ   ˆ   |j¡}‡ fdd„|jD ƒ}|D ] }| ¡  |jr$| |jd¡ q$|S )Nc                   s   g | ]}ˆ   |¡‘qS r   ©r]   rT   r4   r   r   rg   N  ó    z4GenericTranslator.xpath_matching.<locals>.<listcomp>Úor©r]   rV   Zselector_listr=   r(   r:   ©r,   r   r]   ZexprsÚer   r4   r   Úxpath_matchingL  s    z GenericTranslator.xpath_matchingr   c                   sJ   ˆ   |j¡}‡ fdd„|jD ƒ}|D ] }| ¡  |jr$| |jd¡ q$|S )Nc                   s   g | ]}ˆ   |¡‘qS r   r€   rT   r4   r   r   rg   W  r�   zAGenericTranslator.xpath_specificityadjustment.<locals>.<listcomp>r‚   rƒ   r„   r   r4   r   Úxpath_specificityadjustmentU  s    z-GenericTranslator.xpath_specificityadjustmentr   )Úfunctionr*   c                 C  s^   d  |j dd¡¡}tttttgtf  t| |dƒƒ}|sLt	d|j› d�ƒ‚||  
|j¡|ƒS )z$Translate a functional pseudo-class.zxpath_{}_functionú-Ú_NúThe pseudo-class :z() is unknown)rj   ÚnameÚreplacer   r   r   r    r   r[   r   r]   rV   )r,   rˆ   Úmethod_namerp   r   r   r   Úxpath_function^  s    
þz GenericTranslator.xpath_functionr   )Úpseudor*   c                 C  sZ   d  |j dd¡¡}ttttgtf  t| |dƒƒ}|sJtd|j› d�ƒ‚||  	|j
¡ƒS )zTranslate a pseudo-class.zxpath_{}_pseudor‰   rŠ   Nr‹   z is unknown)rj   Úidentr�   r   r   r   r    r[   r   r]   rV   )r,   r�   rŽ   rp   r   r   r   Úxpath_pseudoi  s    ÿzGenericTranslator.xpath_pseudor   )rV   r*   c                 C  sÞ   | j |j }tttttt gtf t| d|› �ƒƒ}| jrF|j	 
¡ }n|j	}t|ƒ}|jrx|j› d|› �}|ovt|jƒ}|r†d| }nd|  |¡› d�}|jdu r¨d}n"| jrÂtt|jjƒ 
¡ }n|jj}||  |j¡||ƒS )z Translate an attribute selector.Zxpath_attrib_ú:ú@zattribute::*[name() = r0   N)Úattribute_operator_mappingÚoperatorr   r   r    r#   r   r[   Úlower_case_attribute_namesÚattribrn   Úis_safe_nameÚ	namespacer<   r|   Úlower_case_attribute_valuesr]   rV   )r,   rV   r–   rp   rŒ   Úsafer˜   r|   r   r   r   Úxpath_attribt  s*    þ

zGenericTranslator.xpath_attribr   )Úclass_selectorr*   c                 C  s   |   |j¡}|  |d|j¡S )zTranslate a class selector.z@class)r]   rV   Úxpath_attrib_includesÚ
class_name)r,   rž   r]   r   r   r   Úxpath_class�  s    zGenericTranslator.xpath_classr   )Úid_selectorr*   c                 C  s   |   |j¡}|  |d|j¡S )zTranslate an ID selector.z@id)r]   rV   Úxpath_attrib_equalsrN   )r,   r¢   r]   r   r   r   Ú
xpath_hash•  s    zGenericTranslator.xpath_hashr
   c                 C  sr   |j }|sd}d}ntt|ƒƒ}| jr.| ¡ }|jrV|j› d|› �}|oTtt|jƒƒ}| j|d�}|sn| ¡  |S )z'Translate a type or universal selector.r"   Tr“   )r'   )r'   r$   r™   Úlower_case_element_namesrn   rš   r_   r=   )r,   rV   r'   rœ   r]   r   r   r   Úxpath_elementš  s    zGenericTranslator.xpath_element)Úleftr}   r*   c                 C  s   |  d|¡S )z;right is a child, grand-child or further descendant of leftz/descendant-or-self::*/©rE   ©r,   r§   r}   r   r   r   Úxpath_descendant_combinator°  s    z-GenericTranslator.xpath_descendant_combinatorc                 C  s   |  d|¡S )z#right is an immediate child of leftú/r¨   r©   r   r   r   Úxpath_child_combinator¶  s    z(GenericTranslator.xpath_child_combinatorc                 C  s   |  d|¡}| ¡  | d¡S )z)right is a sibling immediately after leftú/following-sibling::zposition() = 1)rE   r=   r:   )r,   r§   r}   r]   r   r   r   Ú xpath_direct_adjacent_combinatorº  s    z2GenericTranslator.xpath_direct_adjacent_combinatorc                 C  s   |  d|¡S )z1right is a sibling after left, immediately or notr­   r¨   r©   r   r   r   Ú"xpath_indirect_adjacent_combinatorÂ  s    z4GenericTranslator.xpath_indirect_adjacent_combinatorc                 C  s   |j d|ddd�S )zHright is a child, grand-child or further descendant of left; select leftz[descendant::r0   T)rC   rD   r¨   r©   r   r   r   Ú$xpath_relation_descendant_combinatorÈ  s    ÿz6GenericTranslator.xpath_relation_descendant_combinatorc                 C  s   |j d|dd�S )z0right is an immediate child of left; select leftz[./r0   ©rC   r¨   r©   r   r   r   Úxpath_relation_child_combinatorÐ  s    z1GenericTranslator.xpath_relation_child_combinatorc                 C  s   |  d|j› d�¡S )z6right is a sibling immediately after left; select leftz following-sibling::*[(name() = 'z') and (position() = 1)])r:   r'   r©   r   r   r   Ú)xpath_relation_direct_adjacent_combinatorÖ  s    ÿz;GenericTranslator.xpath_relation_direct_adjacent_combinatorc                 C  s   |j d|dd�S )z>right is a sibling after left, immediately or not; select leftz[following-sibling::r0   r±   r¨   r©   r   r   r   Ú+xpath_relation_indirect_adjacent_combinatorÞ  s    z=GenericTranslator.xpath_relation_indirect_adjacent_combinatorT)r]   rˆ   Úlastr=   r*   c              
     s”  zt |jƒ\}}W n8 tyJ } z td|j›d�ƒ|‚W Y d }~n
d }~0 0 |d }|dkrh|dkrh|S |dk r‚|dk r‚| d¡S |rŠdn|j› }	|s¤d|	› d�}
nd	|	› d�}
|dkrÌ| |
› d
|› �¡S g }|dkrö|dkrô| |
› d|› �¡ n| |
› d|› �¡ t|ƒdk�r\|
}| t|ƒ }|dk�rFd|› d|› d�}| |› d|› d�¡ t|ƒdk�rndnd‰ | d 	‡ fdd„|D ƒ¡¡ |S )NzInvalid series: 'rd   é   r   ry   r"   úcount(preceding-sibling::r9   úcount(following-sibling::ú = z >= z <= r8   z +z mod z = 0z(%s)z%sz and c                 3  s   | ]}ˆ | V  qd S r+   r   )rU   Ú
expression©Útemplater   r   rX   f  r�   z=GenericTranslator.xpath_nth_child_function.<locals>.<genexpr>)
r   Ú	argumentsÚ
ValueErrorr   r:   r'   ÚappendÚabsÚlenrE   )r,   r]   rˆ   rµ   r=   ÚaÚbÚexZb_min_1ZnodetestZsiblings_countZexpressionsr§   Zb_negr   r»   r   Úxpath_nth_child_functionæ  s>    *+

ÿz*GenericTranslator.xpath_nth_child_function©r]   rˆ   r*   c                 C  s   | j ||dd�S )NT)rµ   )rÅ   ©r,   r]   rˆ   r   r   r   Úxpath_nth_last_child_functionj  s    z/GenericTranslator.xpath_nth_last_child_functionc                 C  s"   |j dkrtdƒ‚| j||dd�S )Nr"   ú"*:nth-of-type() is not implementedF)r=   ©r'   r   rÅ   rÇ   r   r   r   Úxpath_nth_of_type_functiono  s    
z,GenericTranslator.xpath_nth_of_type_functionc                 C  s$   |j dkrtdƒ‚| j||ddd�S )Nr"   rÉ   TF)rµ   r=   rÊ   rÇ   r   r   r   Úxpath_nth_last_of_type_functionv  s
    
ÿz1GenericTranslator.xpath_nth_last_of_type_functionc                 C  sN   |  ¡ dgdgfvr$td|j›�ƒ‚tt|jd jƒ}| d|  |¡› d�¡S )NÚSTRINGÚIDENTz7Expected a single string or ident for :contains(), got r   zcontains(., r9   ©Úargument_typesr   r½   r   r#   r|   r:   r<   ©r,   r]   rˆ   r|   r   r   r   Úxpath_contains_function  s    
ÿz)GenericTranslator.xpath_contains_functionc                 C  sN   |  ¡ dgdgfvr$td|j›�ƒ‚tt|jd jƒ}| d|  |¡› d�¡S )NrÍ   rÎ   ú3Expected a single string or ident for :lang(), got r   zlang(r9   rÏ   rÑ   r   r   r   Úxpath_lang_function‹  s    
ÿz%GenericTranslator.xpath_lang_function©r]   r*   c                 C  s
   |  d¡S )Nznot(parent::*)©r:   ©r,   r]   r   r   r   Úxpath_root_pseudo•  s    z#GenericTranslator.xpath_root_pseudoc                 C  s
   |  d¡S )NÚ1rÖ   r×   r   r   r   Úxpath_scope_pseudo�  s    z$GenericTranslator.xpath_scope_pseudoc                 C  s
   |  d¡S )Nzcount(preceding-sibling::*) = 0rÖ   r×   r   r   r   Úxpath_first_child_pseudo   s    z*GenericTranslator.xpath_first_child_pseudoc                 C  s
   |  d¡S )Nzcount(following-sibling::*) = 0rÖ   r×   r   r   r   Úxpath_last_child_pseudo£  s    z)GenericTranslator.xpath_last_child_pseudoc                 C  s&   |j dkrtdƒ‚| d|j › d�¡S )Nr"   z"*:first-of-type is not implementedr·   ú) = 0©r'   r   r:   r×   r   r   r   Úxpath_first_of_type_pseudo¦  s    
z,GenericTranslator.xpath_first_of_type_pseudoc                 C  s&   |j dkrtdƒ‚| d|j › d�¡S )Nr"   z!*:last-of-type is not implementedr¸   rÝ   rÞ   r×   r   r   r   Úxpath_last_of_type_pseudo«  s    
z+GenericTranslator.xpath_last_of_type_pseudoc                 C  s
   |  d¡S )Nzcount(parent::*/child::*) = 1rÖ   r×   r   r   r   Úxpath_only_child_pseudo°  s    z)GenericTranslator.xpath_only_child_pseudoc                 C  s&   |j dkrtdƒ‚| d|j › d�¡S )Nr"   z!*:only-of-type is not implementedzcount(parent::*/child::z) = 1rÞ   r×   r   r   r   Úxpath_only_of_type_pseudo³  s    
z+GenericTranslator.xpath_only_of_type_pseudoc                 C  s
   |  d¡S )Nznot(*) and not(string-length())rÖ   r×   r   r   r   Úxpath_empty_pseudo¸  s    z$GenericTranslator.xpath_empty_pseudoc                 C  s
   |  d¡S )z:Common implementation for pseudo-classes that never match.ry   rÖ   r×   r   r   r   Úpseudo_never_matches»  s    z&GenericTranslator.pseudo_never_matchesr@   )r]   rŒ   r|   r*   c                 C  s   |rJ ‚|  |¡ |S r+   rÖ   ©r,   r]   rŒ   r|   r   r   r   Úxpath_attrib_existsË  s    
z%GenericTranslator.xpath_attrib_existsc                 C  s*   |d usJ ‚|  |› d|  |¡› �¡ |S )Nr¹   ©r:   r<   rå   r   r   r   r£   Ò  s    z%GenericTranslator.xpath_attrib_equalsc              
   C  sR   |d usJ ‚|r4|  d|› d|› d|  |¡› �¡ n|  |› d|  |¡› �¡ |S )Nrx   z) or z != rç   rå   r   r   r   Úxpath_attrib_differentÙ  s
    $z(GenericTranslator.xpath_attrib_differentc                 C  sJ   |r<t |ƒr<|  d| d ¡}| |› d|› d|› d�¡ n
| d¡ |S )NrG   z* and contains(concat(' ', normalize-space(z	), ' '), r9   ry   )Úis_non_whitespacer<   r:   )r,   r]   rŒ   r|   Úargr   r   r   rŸ   ä  s    ÿ
z'GenericTranslator.xpath_attrib_includesc                 C  sP   |d usJ ‚|   |¡}|   |d ¡}| |› d|› d|› d|› d|› d�
¡ |S )Nr‰   z and (r¹   z or starts-with(ú, z)))r<   r:   )r,   r]   rŒ   r|   rê   Zarg_dashr   r   r   Úxpath_attrib_dashmatchð  s    
 ÿz(GenericTranslator.xpath_attrib_dashmatchc              	   C  s6   |r(|  |› d|› d|  |¡› d�¡ n
|  d¡ |S )Nz and starts-with(rë   r9   ry   rç   rå   r   r   r   Úxpath_attrib_prefixmatchü  s    ÿ
z*GenericTranslator.xpath_attrib_prefixmatchc                 C  sH   |r:|  |› d|› d|› dt|ƒd › d|  |¡› �	¡ n
|  d¡ |S )Nz and substring(z, string-length(z)-r¶   z) = ry   )r:   rÁ   r<   rå   r   r   r   Úxpath_attrib_suffixmatch  s    ,ÿ
z*GenericTranslator.xpath_attrib_suffixmatchc              	   C  s6   |r(|  |› d|› d|  |¡› d�¡ n
|  d¡ |S )Nz and contains(rë   r9   ry   rç   rå   r   r   r   Úxpath_attrib_substringmatch  s    ÿ
z-GenericTranslator.xpath_attrib_substringmatchN)rO   )rO   F)FT)Gr   r   r   r   rs   r•   Zid_attributeÚlang_attributer¥   r—   r›   r    r_   rY   rS   ra   Ústaticmethodr<   r]   rv   rz   r~   r†   r‡   r�   r’   r�   r¡   r¤   r¦   rª   r¬   r®   r¯   r°   r²   r³   r´   rÅ   rÈ   rË   rÌ   rÒ   rÔ   rØ   rÚ   rÛ   rÜ   rß   rà   rá   râ   rã   rä   Úxpath_link_pseudoZxpath_visited_pseudoZxpath_hover_pseudoZxpath_active_pseudoZxpath_focus_pseudoZxpath_target_pseudoÚxpath_enabled_pseudoÚxpath_disabled_pseudoÚxpath_checked_pseudoræ   r£   rè   rŸ   rì   rí   rî   rï   r   r   r   r   r;   †   s¨   üø  ü#			  û 	
r;   c                   @  sx   e Zd ZdZdZddddœdd„Zd	d	d
œdd„Zd	dd	dœdd„Zd	d	d
œdd„Zd	d	d
œdd„Z	d	d	d
œdd„Z
dS )ÚHTMLTranslatoraê  
    Translator for (X)HTML documents.

    Has a more useful implementation of some pseudo-classes based on
    HTML-specific element names and attribute names, as described in
    the `HTML5 specification`_. It assumes no-quirks mode.
    The API is the same as :class:`GenericTranslator`.

    .. _HTML5 specification: http://www.w3.org/TR/html5/links.html#selectors

    :param xhtml:
        If false (the default), element names and attribute names
        are case-insensitive.

    ÚlangFr$   r%   )Úxhtmlr*   c                 C  s   || _ |sd| _d| _d S )NT)rø   r¥   r—   )r,   rø   r   r   r   r-   3  s    zHTMLTranslator.__init__r    rÕ   c                 C  s
   |  d¡S )NzŠ(@selected and name(.) = 'option') or (@checked and (name(.) = 'input' or name(.) = 'command')and (@type = 'checkbox' or @type = 'radio'))rÖ   r×   r   r   r   rõ   :  s    ÿz#HTMLTranslator.xpath_checked_pseudor   rÆ   c                 C  sd   |  ¡ dgdgfvr$td|j›�ƒ‚|jd j}|s8J ‚|  | ¡ d ¡}| d| j› d|› d�¡S )	NrÍ   rÎ   rÓ   r   r‰   z<ancestor-or-self::*[@lang][1][starts-with(concat(translate(@zE, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), '-'), z)])rÐ   r   r½   r|   r<   rn   r:   rð   )r,   r]   rˆ   r|   rê   r   r   r   rÔ   C  s    
ÿþüÿz"HTMLTranslator.xpath_lang_functionc                 C  s
   |  d¡S )NzA@href and (name(.) = 'a' or name(.) = 'link' or name(.) = 'area')rÖ   r×   r   r   r   rò   S  s    ÿz HTMLTranslator.xpath_link_pseudoc                 C  s
   |  d¡S )Na¥  
        (
            @disabled and
            (
                (name(.) = 'input' and @type != 'hidden') or
                name(.) = 'button' or
                name(.) = 'select' or
                name(.) = 'textarea' or
                name(.) = 'command' or
                name(.) = 'fieldset' or
                name(.) = 'optgroup' or
                name(.) = 'option'
            )
        ) or (
            (
                (name(.) = 'input' and @type != 'hidden') or
                name(.) = 'button' or
                name(.) = 'select' or
                name(.) = 'textarea'
            )
            and ancestor::fieldset[@disabled]
        )
        rÖ   r×   r   r   r   rô   [  s    ÿz$HTMLTranslator.xpath_disabled_pseudoc                 C  s
   |  d¡S )Na'  
        (
            @href and (
                name(.) = 'a' or
                name(.) = 'link' or
                name(.) = 'area'
            )
        ) or (
            (
                name(.) = 'command' or
                name(.) = 'fieldset' or
                name(.) = 'optgroup'
            )
            and not(@disabled)
        ) or (
            (
                (name(.) = 'input' and @type != 'hidden') or
                name(.) = 'button' or
                name(.) = 'select' or
                name(.) = 'textarea' or
                name(.) = 'keygen'
            )
            and not (@disabled or ancestor::fieldset[@disabled])
        ) or (
            name(.) = 'option' and not(
                @disabled or ancestor::optgroup[@disabled]
            )
        )
        rÖ   r×   r   r   r   ró   y  s    ÿz#HTMLTranslator.xpath_enabled_pseudoN)F)r   r   r   r   rð   r-   rõ   rÔ   rò   rô   ró   r   r   r   r   rö      s   	rö   ))r   Ú
__future__r   ÚreÚcollections.abcr   Útypingr   r   r   Zcssselect.parserr   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   Ztyping_extensionsr   ÚRuntimeErrorr   r    ÚcompileÚsplitri   Úmatchr™   ré   r;   rö   r   r   r   r   Ú<module>   s&   LD     