U
    d/e                  
   @   s|  d Z ddlZddlZddlZddlZddlmZ ddlmZ dddd	d
dgZe	dej
Ze	dZddddddhZddddddddddh
Ze	dZej	dejd Zeejd!Zejdd"ejejeejefeed#d$dZeed#d%dZejdd"d0eje ed&d'dZejdd"d1eje ed&d(d	ZG d)d* d*Zeed+d,d
ZG d-d. d.eZ eed+d/dZ!dS )2KQuote strings to be valid DOT identifiers, assemble quoted attribute lists.    N   )_tools)
exceptionsquote
quote_edgea_list	attr_listescapenohtmlz<.*>$z8([a-zA-Z_][a-zA-Z0-9_]*|-?(\.[0-9]+|[0-9]+(\.[0-9]*)?))$nodeZedgegraphZdigraphZsubgraphstrictnneesesswwnwc_z(?<!\\)(?:\\{2})*\\$a  
                                            (?P<escaped_backslashes>(?:\\{2})*)
                                            \\?  # treat \" same as "
                                            (?P<literal_quote>")
                                            )flagsz*\g<escaped_backslashes>\\\g<literal_quote>)Zsupported_number)
identifierreturnc                 C   sZ   || rt | tsnB|| r(|  |krV|| rFtjd| tjd d||  dS | S )a  Return DOT identifier from string, quote if needed.

    >>> quote('')  # doctest: +NO_EXE
    '""'

    >>> quote('spam')
    'spam'

    >>> quote('spam spam')
    '"spam spam"'

    >>> quote('-4.2')
    '-4.2'

    >>> quote('.42')
    '.42'

    >>> quote('<<b>spam</b>>')
    '<<b>spam</b>>'

    >>> quote(nohtml('<>'))
    '"<>"'

    >>> print(quote('"'))
    "\""

    >>> print(quote('\\"'))
    "\""

    >>> print(quote('\\\\"'))
    "\\\""

    >>> print(quote('\\\\\\"'))
    "\\\""
    z4expect syntax error scanning invalid quoted string: )category")
isinstanceNoHtmllowerwarningswarnr   ZDotSyntaxWarning)r   Zis_html_stringZis_valid_idZdot_keywordsZ"endswith_odd_number_of_backslashesZescape_unescaped_quotes r#   4/tmp/pip-unpacked-wheel-n8ok7rre/graphviz/quoting.pyr   (   s    *c                 C   sT   |  d\}}}t|g}|rJ| d\}}}|t| |rJ|| d|S )zReturn DOT edge statement node_id from string, quote if needed.

    >>> quote_edge('spam')  # doctest: +NO_EXE
    'spam'

    >>> quote_edge('spam spam:eggs eggs')
    '"spam spam":"eggs eggs"'

    >>> quote_edge('spam:eggs:s')
    'spam:eggs:s'
    :)	partitionr   appendjoin)r   r   r   restpartsportZcompassr#   r#   r$   r   ]   s    

)labelr   c                 C   sl   | dk	rdt |  gng }|r8|dd t|D 7 }|rbt|drPt|}|dd |D 7 }d|S )zReturn assembled DOT a_list string.

    >>> a_list('spam', kwargs={'spam': None, 'ham': 'ham ham', 'eggs': ''})  # doctest: +NO_EXE
    'label=spam eggs="" ham="ham ham"'
    Nzlabel=c                 S   s.   g | ]&\}}|d k	rt | dt | qS N=r   .0kvr#   r#   r$   
<listcomp>}   s    za_list.<locals>.<listcomp>itemsc                 S   s.   g | ]&\}}|d k	rt | dt | qS r-   r/   r0   r#   r#   r$   r4      s     )r   r   Zmapping_itemshasattrr(   )r,   kwargs
attributesresultr#   r#   r$   r   s   s    

c                 C   s"   t | ||d}|sdS d| dS )a  Return assembled DOT attribute list string.

    Sorts ``kwargs`` and ``attributes`` if they are plain dicts
    (to avoid unpredictable order from hash randomization in Python < 3.7).

    >>> attr_list()  # doctest: +NO_EXE
    ''

    >>> attr_list('spam spam', kwargs={'eggs': 'eggs', 'ham': 'ham ham'})
    ' [label="spam spam" eggs=eggs ham="ham ham"]'

    >>> attr_list(kwargs={'spam': None, 'eggs': ''})
    ' [eggs=""]'
    )r8   r9    z [])r   )r,   r8   r9   contentr#   r#   r$   r	      s    c                   @   s0   e Zd ZdZeeZeeZee	Z
eeZdS )Quoter   N)__name__
__module____qualname____doc__staticmethodr   _quoter   Z_quote_edger   Z_a_listr	   Z
_attr_listr#   r#   r#   r$   r>      s
   r>   )r   r   c                 C   s   t | ddS )a  Return string disabling special meaning of backslashes and ``'<...>'``.

    Args:
        s: String in which backslashes and ``'<...>'``
            should be treated as literal.

    Returns:
        Escaped string subclass instance.

    Raises:
        TypeError: If ``s`` is not a ``str``.

    Example:
        >>> import graphviz  # doctest: +NO_EXE
        >>> print(graphviz.escape(r'\l'))
        \\l

    See also:
        Upstream documentation:
        https://www.graphviz.org/doc/info/attrs.html#k:escString
    \z\\)r   replacer   r#   r#   r$   r
      s    c                   @   s   e Zd ZdZdZdS )r   zCString subclass that does not treat ``'<...>'`` as DOT HTML string.r#   N)r?   r@   rA   rB   	__slots__r#   r#   r#   r$   r      s   r   c                 C   s   t | S )a&  Return string not treating ``'<...>'`` as DOT HTML string in quoting.

    Args:
        s: String in which leading ``'<'`` and trailing ``'>'``
            should be treated as literal.

    Returns:
        String subclass instance.

    Raises:
        TypeError: If ``s`` is not a ``str``.

    Example:
        >>> import graphviz  # doctest: +NO_EXE
        >>> g = graphviz.Graph()
        >>> g.node(graphviz.nohtml('<>-*-<>'))
        >>> print(g.source)  # doctest: +NORMALIZE_WHITESPACE
        graph {
            "<>-*-<>"
        }
    )r   rG   r#   r#   r$   r      s    )NNN)NNN)"rB   	functoolsretypingr!   r;   r   r   __all__compileDOTALLZHTML_STRINGZIDZKEYWORDSZCOMPASSZFINAL_ODD_BACKSLASHESVERBOSEZQUOTE_WITH_OPTIONAL_BACKSLASHESpartialsubZESCAPE_UNESCAPED_QUOTESZdeprecate_positional_argsmatchsearchstrr   r   Optionalr   r	   r>   r
   r   r   r#   r#   r#   r$   <module>   sf     


4
    

    

