U
    :gJ                     @   s   d dl mZ ddlmZmZmZmZ ddlmZ d*ddZ	dd	 Z
d+d
dZd,ddZdd Zd-ddZdd Zdd Zd.ddZd/ddZd0ddZd1ddZd2dd Zd!d" Zd#d$ Zd%d& Zd3d(d)Zd'S )4    )chain   )AtRuleDeclaration
ParseErrorQualifiedRule)parse_component_value_listFc                 C   s   t | trt| |} t| S )aq  Iterate component values out of string or component values iterable.

    :type input: :obj:`str` or :term:`iterable`
    :param input: A string or an iterable of :term:`component values`.
    :type skip_comments: :obj:`bool`
    :param skip_comments: If the input is a string, ignore all CSS comments.
    :returns: An iterator yielding :term:`component values`.

    )
isinstancestrr   iter)inputskip_comments r   3/tmp/pip-unpacked-wheel-62y3g4yj/tinycss2/parser.py_to_token_iterator   s    


r   c                 C   s    | D ]}|j dkr|  S qdS )zReturn the next significant (neither whitespace or comment) token.

    :type tokens: :term:`iterator`
    :param tokens: An iterator yielding :term:`component values`.
    :returns: A :term:`component value`, or :obj:`None`.

    
whitespacecommentN)type)tokenstokenr   r   r   _next_significant   s    
r   c                 C   sR   t | |}t|}t|}|dkr0tddddS |dk	rJt|j|jddS |S dS )a  Parse a single :diagram:`component value`.

    This is used e.g. for an attribute value
    referred to by ``attr(foo length)``.

    :type input: :obj:`str` or :term:`iterable`
    :param input: A string or an iterable of :term:`component values`.
    :type skip_comments: :obj:`bool`
    :param skip_comments: If the input is a string, ignore all CSS comments.
    :returns:
        A :term:`component value` (that is neither whitespace or comment),
        or a :class:`~tinycss2.ast.ParseError`.

    Nr   emptyInput is emptyextra-inputzGot more than one token)r   r   r   source_linesource_column)r   r   r   firstsecondr   r   r   parse_one_component_value#   s    
  r   c                 C   s2   t | |}t|}|dkr(tddddS t||S )a?  Parse a single :diagram:`declaration`.

    This is used e.g. for a declaration in an `@supports
    <https://drafts.csswg.org/css-conditional/#at-supports>`_ test.

    :type input: :obj:`str` or :term:`iterable`
    :param input: A string or an iterable of :term:`component values`.
    :type skip_comments: :obj:`bool`
    :param skip_comments: If the input is a string, ignore all CSS comments.
    :returns:
        A :class:`~tinycss2.ast.Declaration`
        or :class:`~tinycss2.ast.ParseError`.

    Any whitespace or comment before the ``:`` colon is dropped.

    Nr   r   r   )r   r   r   _parse_declaration)r   r   r   first_tokenr   r   r   parse_one_declaration?   s
    
r"   c                 C   s.   | D ]$}|dkr d S |r|dkr d S qd S )N;}r   )r   nestedr   r   r   r   _consume_remnantsW   s
    r&   Tc                 C   sn  | }|j dkr4t|| t|j|jdd|j  dS t|}|dkr`t|| t|j|jddS |dkrt|| t|j|jddS g }d	}d
}d
}t|D ]\}	}
|d	kr|
dkrd}|	}nT|dkr|
j dkr|
jdkrd}n2|
j dkrd	}|
j dkr|rd}nd}nd}||
 q|dkr2||d= |rP|rPt|j|jddS t	|j|j|j
|j||dkS )a  Parse a declaration.

    Consume :obj:`tokens` until the end of the declaration or the first error.

    :type first_token: :term:`component value`
    :param first_token: The first component value of the rule.
    :type tokens: :term:`iterator`
    :param tokens: An iterator yielding :term:`component values`.
    :type nested: :obj:`bool`
    :param nested: Whether the declaration is nested or top-level.
    :returns:
        A :class:`~tinycss2.ast.Declaration`
        or :class:`~tinycss2.ast.ParseError`.

    identinvalidz+Expected <ident> for declaration name, got .Nz,Expected ':' after declaration name, got EOF:z6Expected ':' after declaration name, got {colon.type}.valueF!ZbangZ	importantr   {} blockTzDeclaration contains {} block)r   r&   r   r   r   r   	enumeratelower_valueappendr   r+   )r!   r   r%   namecolonr+   stateZcontains_non_whitespaceZcontains_simple_blockir   Zbang_positionr   r   r   r    _   s~    

  
  
  

      r    c                 C   s   g }g }| dkrR| j dkrR|D ]2}|dkr8||  qR|| |j dkr qRqt| t|dd}|j dkrr|S t|||}t| |dddS dS )z#Consume declaration or nested rule.r#   r-   T)r%   declaration)
stop_tokenr%   N)r   r0   r    r   r   _consume_qualified_rule)r!   r   Zdeclaration_tokensZsemicolon_tokenr   r5   r   r   r   _consume_blocks_content   s&    


  
r8   c                 C   s2   g }|D ]}|dkr q$| | qt| t|S )zLike :func:`_parse_declaration`, but stop at the first ``;``.

    Deprecated, use :func:`_consume_blocks_content` instead.

    r#   )r0   r    r   )r!   r   Zother_declaration_tokensr   r   r   r   _consume_declaration_in_list   s    r9   c                 C   s   t | |}g }|D ]l}|jdkr0|s~|| q|jdkrJ|s~|| q|jdkrf|t|| q|dkr|t|| q|S )u  Parse a block’s contents.

    This is used e.g. for the :attr:`~tinycss2.ast.QualifiedRule.content`
    of a style rule or ``@page`` rule, or for the ``style`` attribute of an
    HTML element.

    In contexts that don’t expect any at-rule and/or qualified rule,
    all :class:`~tinycss2.ast.AtRule` and/or
    :class:`~tinycss2.ast.QualifiedRule` objects should simply be rejected as
    invalid.

    :type input: :obj:`str` or :term:`iterable`
    :param input: A string or an iterable of :term:`component values`.
    :type skip_comments: :obj:`bool`
    :param skip_comments:
        Ignore CSS comments at the top-level of the list.
        If the input is a string, ignore all comments.
    :type skip_whitespace: :obj:`bool`
    :param skip_whitespace:
        Ignore whitespace at the top-level of the list.
        Whitespace is still preserved
        in the :attr:`~tinycss2.ast.Declaration.value` of declarations
        and the :attr:`~tinycss2.ast.AtRule.prelude`
        and :attr:`~tinycss2.ast.AtRule.content` of at-rules.
    :returns:
        A list of
        :class:`~tinycss2.ast.Declaration`,
        :class:`~tinycss2.ast.AtRule`,
        :class:`~tinycss2.ast.QualifiedRule`,
        :class:`~tinycss2.ast.Comment` (if ``skip_comments`` is false),
        :class:`~tinycss2.ast.WhitespaceToken`
        (if ``skip_whitespace`` is false),
        and :class:`~tinycss2.ast.ParseError` objects

    r   r   
at-keywordr#   )r   r   r0   _consume_at_ruler8   r   r   Zskip_whitespacer   resultr   r   r   r   parse_blocks_contents   s    $



r>   c                 C   s   t | |}g }|D ]l}|jdkr0|s~|| q|jdkrJ|s~|| q|jdkrf|t|| q|dkr|t|| q|S )u  Parse a :diagram:`declaration list` (which may also contain at-rules).

    Deprecated and removed from CSS Syntax Level 3. Use
    :func:`parse_blocks_contents` instead.

    This is used e.g. for the :attr:`~tinycss2.ast.QualifiedRule.content`
    of a style rule or ``@page`` rule, or for the ``style`` attribute of an
    HTML element.

    In contexts that don’t expect any at-rule, all
    :class:`~tinycss2.ast.AtRule` objects should simply be rejected as invalid.

    :type input: :obj:`str` or :term:`iterable`
    :param input: A string or an iterable of :term:`component values`.
    :type skip_comments: :obj:`bool`
    :param skip_comments:
        Ignore CSS comments at the top-level of the list.
        If the input is a string, ignore all comments.
    :type skip_whitespace: :obj:`bool`
    :param skip_whitespace:
        Ignore whitespace at the top-level of the list.
        Whitespace is still preserved
        in the :attr:`~tinycss2.ast.Declaration.value` of declarations
        and the :attr:`~tinycss2.ast.AtRule.prelude`
        and :attr:`~tinycss2.ast.AtRule.content` of at-rules.
    :returns:
        A list of
        :class:`~tinycss2.ast.Declaration`,
        :class:`~tinycss2.ast.AtRule`,
        :class:`~tinycss2.ast.Comment` (if ``skip_comments`` is false),
        :class:`~tinycss2.ast.WhitespaceToken`
        (if ``skip_whitespace`` is false),
        and :class:`~tinycss2.ast.ParseError` objects

    r   r   r:   r#   )r   r   r0   r;   r9   r<   r   r   r   parse_declaration_list   s    $



r?   c                 C   s^   t | |}t|}|dkr(tddddS t||}t|}|dk	rZt|j|jdd|j S |S )a  Parse a single :diagram:`qualified rule` or :diagram:`at-rule`.

    This would be used e.g. by `insertRule()
    <https://drafts.csswg.org/cssom/#dom-cssstylesheet-insertrule>`_
    in an implementation of CSSOM.

    :type input: :obj:`str` or :term:`iterable`
    :param input: A string or an iterable of :term:`component values`.
    :type skip_comments: :obj:`bool`
    :param skip_comments:
        If the input is a string, ignore all CSS comments.
    :returns:
        A :class:`~tinycss2.ast.QualifiedRule`,
        :class:`~tinycss2.ast.AtRule`,
        or :class:`~tinycss2.ast.ParseError` objects.

    Any whitespace or comment before or after the rule is dropped.

    Nr   r   r   r   z4Expected a single rule, got %s after the first rule.)r   r   r   _consume_ruler   r   r   )r   r   r   r   Zrulenextr   r   r   parse_one_rule4  s    

  rB   c                 C   s`   t | |}g }|D ]H}|jdkr0|sZ|| q|jdkrJ|sZ|| q|t|| q|S )a  Parse a non-top-level :diagram:`rule list`.

    Deprecated and removed from CSS Syntax. Use :func:`parse_blocks_contents`
    instead.

    This is used for parsing the :attr:`~tinycss2.ast.AtRule.content`
    of nested rules like ``@media``.
    This differs from :func:`parse_stylesheet` in that
    top-level ``<!--`` and ``-->`` tokens are not ignored.

    :type input: :obj:`str` or :term:`iterable`
    :param input: A string or an iterable of :term:`component values`.
    :type skip_comments: :obj:`bool`
    :param skip_comments:
        Ignore CSS comments at the top-level of the list.
        If the input is a string, ignore all comments.
    :type skip_whitespace: :obj:`bool`
    :param skip_whitespace:
        Ignore whitespace at the top-level of the list.
        Whitespace is still preserved
        in the :attr:`~tinycss2.ast.QualifiedRule.prelude`
        and the :attr:`~tinycss2.ast.QualifiedRule.content` of rules.
    :returns:
        A list of
        :class:`~tinycss2.ast.QualifiedRule`,
        :class:`~tinycss2.ast.AtRule`,
        :class:`~tinycss2.ast.Comment` (if ``skip_comments`` is false),
        :class:`~tinycss2.ast.WhitespaceToken`
        (if ``skip_whitespace`` is false),
        and :class:`~tinycss2.ast.ParseError` objects.

    r   r   r   r   r0   r@   r<   r   r   r   parse_rule_listV  s    !


rD   c                 C   sh   t | |}g }|D ]P}|jdkr0|sb|| q|jdkrJ|sb|| q|dkr|t|| q|S )a  Parse :diagram:`stylesheet` from text.

    This is used e.g. for a ``<style>`` HTML element.

    This differs from :func:`parse_rule_list` in that
    top-level ``<!--`` and ``-->`` tokens are ignored.
    This is a legacy quirk for the ``<style>`` HTML element.

    :type input: :obj:`str` or :term:`iterable`
    :param input: A string or an iterable of :term:`component values`.
    :type skip_comments: :obj:`bool`
    :param skip_comments:
        Ignore CSS comments at the top-level of the stylesheet.
        If the input is a string, ignore all comments.
    :type skip_whitespace: :obj:`bool`
    :param skip_whitespace:
        Ignore whitespace at the top-level of the stylesheet.
        Whitespace is still preserved
        in the :attr:`~tinycss2.ast.QualifiedRule.prelude`
        and the :attr:`~tinycss2.ast.QualifiedRule.content` of rules.
    :returns:
        A list of
        :class:`~tinycss2.ast.QualifiedRule`,
        :class:`~tinycss2.ast.AtRule`,
        :class:`~tinycss2.ast.Comment` (if ``skip_comments`` is false),
        :class:`~tinycss2.ast.WhitespaceToken`
        (if ``skip_whitespace`` is false),
        and :class:`~tinycss2.ast.ParseError` objects.

    r   r   )z<!--z-->rC   r<   r   r   r   parse_stylesheet  s    


rE   c                 C   s   | j dkrt| |S t| |S )a  Parse a qualified rule or at-rule.

    Consume just enough of :obj:`tokens` for this rule.

    :type first_token: :term:`component value`
    :param first_token: The first component value of the rule.
    :type tokens: :term:`iterator`
    :param tokens: An iterator yielding :term:`component values`.
    :returns:
        A :class:`~tinycss2.ast.QualifiedRule`,
        :class:`~tinycss2.ast.AtRule`,
        or :class:`~tinycss2.ast.ParseError`.

    r:   )r   r;   r7   )r!   r   r   r   r   r@     s    

r@   c                 C   sX   g }d}|D ]0}|j dkr&|j} q>n|dkr2 q>|| qt| j| j| j| j||S )a  Parse an at-rule.

    Consume just enough of :obj:`tokens` for this rule.

    :type at_keyword: :class:`AtKeywordToken`
    :param at_keyword: The at-rule keyword token starting this rule.
    :type tokens: :term:`iterator`
    :param tokens: An iterator yielding :term:`component values`.
    :type nested: :obj:`bool`
    :param nested: Whether the at-rule is nested or top-level.
    :returns:
        A :class:`~tinycss2.ast.QualifiedRule`,
        or :class:`~tinycss2.ast.ParseError`.

    Nr-   r#   )r   contentr0   r   r   r   r+   r/   )Z
at_keywordr   preluderF   r   r   r   r   r;     s"    
    r;   c                 C   s   t | j| jd| dS )z6Create rule parse error raised because of given token.r(   z. reached before {} block for a qualified rule.)r   r   r   )r   r1   r   r   r   _rule_error  s      rH   Nc                 C   s   | |krt | dS | jdkr&g }| }nP| g}|D ]6}||krJt |d  S |jdkr\|} qv|| q0t |d dS t| j| j||jS )a  Consume a qualified rule.

    Consume just enough of :obj:`tokens` for this rule.

    :type first_token: :term:`component value`
    :param first_token: The first component value of the rule.
    :type tokens: :term:`iterator`
    :param tokens: An iterator yielding :term:`component values`.
    :type nested: :obj:`bool`
    :param nested: Whether the rule is nested or top-level.
    :type stop_token: :class:`~tinycss2.ast.Node`
    :param stop_token: A token that ends rule parsing when met.

    z
Stop tokenr-   EOF)rH   r   r0   r   r   r   rF   )r!   r   r%   r6   rG   blockr   r   r   r   r7     s(    


   r7   )F)F)F)T)FF)FF)F)FF)FF)FN)	itertoolsr   astr   r   r   r   	tokenizerr   r   r   r   r"   r&   r    r8   r9   r>   r?   rB   rD   rE   r@   r;   rH   r7   r   r   r   r   <module>   s*   



J
4
4
"
/
-   