U
    d/e0                     @   s  d Z ddlZddlZddlmZ ddlmZ ddlmZ ddd	gZeed
ddZ	eedddZ
eedddZeeeedddZeeeedddZG dd dZG dd dZeedddZeedddZeeedddZG d d	 d	ejejZdS )!z"Create DOT code with method-calls.    N   )_tools)base)quotingGraphSyntaxDigraphSyntaxDot)linereturnc                 C   s   d|  dS )zReturn comment header line.z// 
 )r	   r   r   0/tmp/pip-unpacked-wheel-n8ok7rre/graphviz/dot.pycomment   s    r   namer
   c                 C   s   d|  dS )zReturn DOT graph head line.zgraph {
r   r   r   r   r   
graph_head   s    r   c                 C   s   d|  dS )zReturn DOT digraph head line.zdigraph r   r   r   r   r   r   digraph_head   s    r   tailheadattrr
   c                 C   s   d|  d| | dS )z%Return DOT graph edge statement line.	z -- r   r   r   r   r   r   r   r   
graph_edge   s    r   c                 C   s   d|  d| | dS )z'Return DOT digraph edge statement line.r   z -> r   r   r   r   r   r   digraph_edge!   s    r   c                   @   s    e Zd ZdZeeZeeZdS )r   zDOT graph head and edge syntax.N)	__name__
__module____qualname____doc__staticmethodr   _headr   _edger   r   r   r   r   &   s   c                   @   s    e Zd ZdZeeZeeZdS )r   z!DOT digraph head and edge syntax.N)	r   r   r   r    r!   r   r"   r   r#   r   r   r   r   r   .   s   c                 C   s   d|  dS )zReturn DOT subgraph head line.z	subgraph r   r   r   r   r   r   subgraph6   s    r$   c                 C   s
   |  dS )z$Return plain DOT subgraph head line.r   r   r   r   r   r   subgraph_plain;   s    r%   )leftrightr
   c                 C   s   d|  | dS )zReturn DOT node statement line.r   r   r   )r&   r'   r   r   r   node@   s    r(   c                       s  e Zd ZU dZeed< eeZee	e	dddZ
ee	e	dddZdZeeZeeZee ZZee	e	d	d
dZee	e	e	e	dddZee	e	e	dddZddddddddeje	 eje	 edd fddZ fddZejddd4eddddZejddd5eeje	 dd d!Z ejd"dd6e	eje	 dd#d$d%Zejd&dd7e	e	eje	 dd'd(d)Z!dd*d+d,Z"ejd-dd8eje	 dd.d/d0Z#ejd-dd9eje	 eje	 d1d2d3Z  Z$S ):r   zAssemble DOT source code.directedr   c                 C   s   t ddS )zReturn DOT head line.*must be implemented by concrete subclassesNNotImplementedErrorr   r   r   r   r"   L   s    z	Dot._headc                 C   s   d|  | S )zReturn DOT strict head line.zstrict )r"   )clsr   r   r   r   _head_strictQ   s    zDot._head_strictz}
)r&   r
   c                 C   s   |  |dS )N )_attr)r-   r&   r   r   r   _attr_plain^   s    zDot._attr_plainr   c                 C   s   t ddS )zReturn DOT edge statement line.r*   Nr+   r   r   r   r   r#   b   s    z	Dot._edge)r   r   r
   c                C   s   | j ||ddS )z%Return plain DOT edge statement line.r/   r   )r#   )r-   r   r   r   r   r   _edge_plaing   s    zDot._edge_plainNFr   r   
graph_attr	node_attr	edge_attrbodystrict)r   r   r8   r
   c          	         s|   t  jf | || _|| _|d k	r*t|ni | _|d k	r@t|ni | _|d k	rVt|ni | _|d k	rlt|ng | _	|| _
d S N)super__init__r   r   dictr4   r5   r6   listr7   r8   )	selfr   r   r4   r5   r6   r7   r8   kwargs	__class__r   r   r;   l   s    zDot.__init__c              	      s8   t  j| j| jt| jt| jt| jt| j	| j
dS )z3Return the kwargs to create a copy of the instance.r3   )r:   _copy_kwargsr   r   r<   r4   r5   r6   r=   r7   r8   )r>   r?   r@   r   r   rB      s    
zDot._copy_kwargsr   )Zsupported_number)
keep_attrsr
   c                 C   s0   |s"| j | j| jfD ]}|  q| j  dS )zReset content to an empty body, clear graph/node/egde_attr mappings.

        Args:
            keep_attrs (bool): preserve graph/node/egde_attr mappings
        N)r4   r5   r6   clearr7   )r>   rC   ar   r   r   rD      s    
z	Dot.clear)r$   r
   c                 c   s   | j r| | j V  |r:| jr&td| jr2| jn| j}n| jrF| jn| j}|| jrd| 	| jd ndV  dD ]0}t
| | d}|rp| || jd|dV  qp| jE dH  | jV  dS )zYield the DOT source code line by line (as graph or subgraph).

        Yields: Line ending with a newline (``'\n'``).
        zsubgraphs cannot be strict r/   graphr(   edger0   N)r?   )r   _commentr8   
ValueErrorr   	_subgraph_subgraph_plainr.   r"   _quotegetattrr0   
_attr_listr7   _tail)r>   r$   r   kwattrsr   r   r   __iter__   s     zDot.__iter__   )r   labelr
   c                 K   s6   |  |}| j|||d}| ||}| j| dS )zCreate a node.

        Args:
            name: Unique identifier for the node inside the source.
            label: Caption to be displayed (defaults to the node ``name``).
            attrs: Any additional node attributes (must be strings).
        r?   
attributesN)rN   rP   _noder7   append)r>   r   rV   _attributesrS   	attr_listr	   r   r   r   r(      s    
zDot.node   )	tail_name	head_namerV   r
   c                 K   sD   |  |}|  |}| j|||d}| j|||d}| j| dS )a  Create an edge between two nodes.

        Args:
            tail_name: Start node identifier
                (format: ``node[:port[:compass]]``).
            head_name: End node identifier
                (format: ``node[:port[:compass]]``).
            label: Caption to be displayed near the edge.
            attrs: Any additional edge attributes (must be strings).

        Note:
            The ``tail_name`` and ``head_name`` strings are separated
            by (optional) colon(s) into ``node`` name, ``port`` name,
            and ``compass`` (e.g. ``sw``).
            See :ref:`details in the User Guide <node-ports-compass>`.
        rW   r   N)_quote_edgerP   r#   r7   rZ   )r>   r^   r_   rV   r[   rS   r\   r	   r   r   r   rI      s
    

zDot.edge)r
   c                    s.   | j  | j|  j fdd|D 7  _dS )a  Create a bunch of edges.

        Args:
            tail_head_iter: Iterable of ``(tail_name, head_name)`` pairs
                (format:``node[:port[:compass]]``).


        Note:
            The ``tail_name`` and ``head_name`` strings are separated
            by (optional) colon(s) into ``node`` name, ``port`` name,
            and ``compass`` (e.g. ``sw``).
            See :ref:`details in the User Guide <node-ports-compass>`.
        c                    s$   g | ]\}} ||d qS ))r   r   r   ).0thrI   quoter   r   
<listcomp>   s   zDot.edges.<locals>.<listcomp>N)r2   r`   r7   )r>   Ztail_head_iterr   rd   r   edges   s
    z	Dot.edges   )rR   r
   c                 K   sz   |dk	r"|  dkr"td||s*|rv|dkrN| jd||d}| |}n| jd||d}| ||}| j| dS )aB  Add a general or graph/node/edge attribute statement.

        Args:
            kw: Attributes target
                (``None`` or ``'graph'``, ``'node'``, ``'edge'``).
            attrs: Attributes to be set (must be strings, may be empty).

        See the :ref:`usage examples in the User Guide <attributes>`.
        NrG   z1attr statement must target graph, node, or edge: rW   )lowerrK   Z_a_listr1   rP   r0   r7   rZ   )r>   rR   r[   rS   a_listr	   r\   r   r   r   r      s    zDot.attr)r   r   c              	      s   |dkr\|   }|dd |j||||||dd | jf | tj fdd}	|	| dS ||||||g}
tdd |
D std	|j| jkrt| d
||  j	dd |j
ddD 7  _	dS )a  Add the current content of the given sole ``graph`` argument
            as subgraph or return a context manager
            returning a new graph instance
            created with the given (``name``, ``comment``, etc.) arguments
            whose content is added as subgraph
            when leaving the context manager's ``with``-block.

        Args:
            graph: An instance of the same kind
                (:class:`.Graph`, :class:`.Digraph`) as the current graph
                (sole argument in non-with-block use).
            name: Subgraph name (``with``-block use).
            comment: Subgraph comment (``with``-block use).
            graph_attr: Subgraph-level attribute-value mapping
                (``with``-block use).
            node_attr: Node-level attribute-value mapping
                (``with``-block use).
            edge_attr: Edge-level attribute-value mapping
                (``with``-block use).
            body: Verbatim lines to add to the subgraph ``body``
                (``with``-block use).

        See the :ref:`usage examples in the User Guide <subgraphs-clusters>`.

        When used as a context manager, the returned new graph instance
        uses ``strict=None`` and the parent graph's values
        for ``directory``, ``format``, ``engine``, and ``encoding`` by default.

        Note:
            If the ``name`` of the subgraph begins with
            ``'cluster'`` (all lowercase)
            the layout engine will treat it as a special cluster subgraph.
        Nfilenamer3   c                 3   s    V  |    dS )z*Return subgraph and add to parent on exit.Nr$   parentrl   r   r   subgraph_contextmanager<  s    z-Dot.subgraph.<locals>.subgraph_contextmanagerrm   c                 s   s   | ]}|d kV  qd S r9   r   )ra   rE   r   r   r   	<genexpr>E  s     zDot.subgraph.<locals>.<genexpr>z)graph must be sole argument of subgraph()z( cannot add subgraph of different kind: c                 S   s   g | ]}d | qS )r   r   )ra   r	   r   r   r   rf   L  s     z Dot.subgraph.<locals>.<listcomp>Trl   )rB   popupdaterA   
contextlibcontextmanagerallrK   r)   r7   rT   )r>   rH   r   r   r4   r5   r6   r7   r?   ro   argsr   rl   r   r$     s(    '   
zDot.subgraph)F)F)NN)NN)NN)NNNNNNN)%r   r   r   r    bool__annotations__r!   r   rJ   strr"   classmethodr.   rQ   r$   rL   r%   rM   r(   rY   r0   r1   r#   r2   typingOptionalr;   rB   r   Zdeprecate_positional_argsrD   IteratorrT   rI   rg   r   __classcell__r   r   r@   r   r   E   s   
    



  
  
  

         )r    rs   r{   r/   r   r   r   __all__ry   r   r   r   r   r   r   r   r$   r%   r(   ZQuoteZBaser   r   r   r   r   <module>   s"   
