a
    h77                     @   s   d Z ddlZddlmZ ddlZddlmZ g dZedddd	d
 Z	edddej
ddddd Zej
dddd Zdd Zdd ZdddZdddZdS )a  
*****
Pydot
*****

Import and export NetworkX graphs in Graphviz dot format using pydot.

Either this module or nx_agraph can be used to interface with graphviz.

Examples
--------
>>> G = nx.complete_graph(5)
>>> PG = nx.nx_pydot.to_pydot(G)
>>> H = nx.nx_pydot.from_pydot(PG)

See Also
--------
 - pydot:         https://github.com/erocarrera/pydot
 - Graphviz:      https://www.graphviz.org
 - DOT Language:  http://www.graphviz.org/doc/info/lang.html
    N)getpreferredencoding)	open_file)	write_dotread_dotgraphviz_layoutpydot_layoutto_pydot
from_pydot   w)modec                 C   s.   d}t j|tdd t| }||  dS )zgWrite NetworkX graph G to Graphviz dot format on path.

    Path can be a string or a file handle.
    znx.nx_pydot.write_dot depends on the pydot package, which has known issues and is not actively maintained. Consider using nx.nx_agraph.write_dot instead.

See https://github.com/networkx/networkx/issues/5723   
stacklevelN)warningswarnDeprecationWarningr   writeZ	to_string)GpathmsgP r   G/var/www/auris/lib/python3.9/site-packages/networkx/drawing/nx_pydot.pyr   &   s    r   rZpydot_read_dot)namegraphsc                 C   s:   ddl }d}tj|tdd |  }||}t|d S )aO  Returns a NetworkX :class:`MultiGraph` or :class:`MultiDiGraph` from the
    dot file with the passed path.

    If this file contains multiple graphs, only the first such graph is
    returned. All graphs _except_ the first are silently ignored.

    Parameters
    ----------
    path : str or file
        Filename or file handle.

    Returns
    -------
    G : MultiGraph or MultiDiGraph
        A :class:`MultiGraph` or :class:`MultiDiGraph`.

    Notes
    -----
    Use `G = nx.Graph(nx.nx_pydot.read_dot(path))` to return a :class:`Graph` instead of a
    :class:`MultiGraph`.
    r   Nznx.nx_pydot.read_dot depends on the pydot package, which has known issues and is not actively maintained. Consider using nx.nx_agraph.read_dot instead.

See https://github.com/networkx/networkx/issues/5723r   r   )pydotr   r   r   readgraph_from_dot_datar	   )r   r   r   dataZP_listr   r   r   r   8   s    
r   )r   c              	   C   s  d}t j|tdd | dr$d}nd}|  dkrL|rBt }qbt }n|rZt }nt	 }| 
 d}|d	kr~||_|  D ]2}|
 d}|d
v rq|j|fi |  q|  D ]}| }| }	| }
g }g }t|tr||d n |d D ]}||d qt|	trB||	d n |	d D ]}||d qJ|D ]&}|D ]}|j||fi |
 qnqfq|  }|r||jd< z|  d |jd< W n ttfy   Y n0 z|  d |jd< W n ttfy   Y n0 |S )a  Returns a NetworkX graph from a Pydot graph.

    Parameters
    ----------
    P : Pydot graph
      A graph created with Pydot

    Returns
    -------
    G : NetworkX multigraph
        A MultiGraph or MultiDiGraph.

    Examples
    --------
    >>> K5 = nx.complete_graph(5)
    >>> A = nx.nx_pydot.to_pydot(K5)
    >>> G = nx.nx_pydot.from_pydot(A)  # return MultiGraph

    # make a Graph instead of MultiGraph
    >>> G = nx.Graph(nx.nx_pydot.from_pydot(A))

    znx.nx_pydot.from_pydot depends on the pydot package, which has known issues and is not actively maintained.

See https://github.com/networkx/networkx/issues/5723r   r   NFTgraph" )noder!   edgenodesr   r$   r%   )r   r   r   Z
get_strictget_typenxZ
MultiGraphZGraphZMultiDiGraphZDiGraphget_namestripr   Zget_node_listadd_nodeZget_attributesZget_edge_list
get_sourceZget_destination
isinstancestrappendadd_edger!   Zget_node_defaults
IndexError	TypeErrorZget_edge_defaults)r   r   Z
multiedgesNr   pneuvattrsdZunodesZvnodesZsource_nodeZdestination_nodeZpattrr   r   r   r	   c   sd    




r	   c                 C   s    d| v o| d dkp| d dkS )N:r   r"   r   )r:   r   r   r   _check_colon_quotes   s    r>   c                 C   s  ddl }d}tj|tdd |  r*d}nd}t| dkoD|   }| j}| j	
di }|dkrz|jd||d	|}n |jd
| d
f||d	|}z|jf i | j	d  W n ty   Y n0 z|jf i | j	d  W n ty   Y n0 | jddD ]n\}}	dd |	 D }
t|}t|pBtdd |
 D }|rRtd|j|fi |
}|| q|  r| jdddD ]\}}}}dd | D }t|t| }}t|pt|ptdd | D }|rtd|j||fdt|i|}|| qn| jddD ]\}}}dd | D }t|t| }}t|pt|ptdd | D }|rtd|j||fi |}|| q*|S )a  Returns a pydot graph from a NetworkX graph N.

    Parameters
    ----------
    N : NetworkX graph
      A graph created with NetworkX

    Examples
    --------
    >>> K5 = nx.complete_graph(5)
    >>> P = nx.nx_pydot.to_pydot(K5)

    Notes
    -----

    r   Nznx.nx_pydot.to_pydot depends on the pydot package, which has known issues and is not actively maintained.

See https://github.com/networkx/networkx/issues/5723r   r   Zdigraphr!   r#   )
graph_typestrictr"   r$   r%   T)r    c                 S   s   i | ]\}}t |t |qS r   r.   .0kr8   r   r   r   
<dictcomp>       zto_pydot.<locals>.<dictcomp>c                 s   s"   | ]\}}t |pt |V  qd S Nr>   rB   r   r   r   	<genexpr>  s   zto_pydot.<locals>.<genexpr>zNode names and attributes should not contain ":" unless they are quoted with "".                For example the string 'attribute:data1' should be written as '"attribute:data1"'.                Please refer https://github.com/pydot/pydot/issues/258)r    keysc                 S   s&   i | ]\}}|d krt |t |qS )keyrA   rB   r   r   r   rE     rF   c                 s   s"   | ]\}}t |pt |V  qd S rG   rH   rC   rD   valr   r   r   rI     s   a   Node names and attributes should not contain ":" unless they are quoted with "".                    For example the string 'attribute:data1' should be written as '"attribute:data1"'.                    Please refer https://github.com/pydot/pydot/issues/258rK   c                 S   s   i | ]\}}t |t |qS r   rA   rB   r   r   r   rE   *  rF   c                 s   s"   | ]\}}t |pt |V  qd S rG   rH   rL   r   r   r   rI   0  s   )r#   )r   r   r   r   Zis_directedr(   Znumber_of_selfloopsZis_multigraphr   r!   getZDotZset_node_defaultsKeyErrorZset_edge_defaultsr&   itemsr.   r>   any
ValueErrorNoder+   edgesZEdger0   )r3   r   r   r?   r@   r   Zgraph_defaultsr   r5   ZnodedataZstr_nodedataZraise_errorr4   r7   r8   rK   ZedgedataZstr_edgedatar%   r   r   r   r      s    






r   neatoc                 C   s"   d}t j|tdd t| ||dS )a=  Create node positions using Pydot and Graphviz.

    Returns a dictionary of positions keyed by node.

    Parameters
    ----------
    G : NetworkX Graph
        The graph for which the layout is computed.
    prog : string (default: 'neato')
        The name of the GraphViz program to use for layout.
        Options depend on GraphViz version but may include:
        'dot', 'twopi', 'fdp', 'sfdp', 'circo'
    root : Node from G or None (default: None)
        The node of G from which to start some layout algorithms.

    Returns
    -------
      Dictionary of (x, y) positions keyed by node.

    Examples
    --------
    >>> G = nx.complete_graph(4)
    >>> pos = nx.nx_pydot.graphviz_layout(G)
    >>> pos = nx.nx_pydot.graphviz_layout(G, prog="dot")

    Notes
    -----
    This is a wrapper for pydot_layout.
    znx.nx_pydot.graphviz_layout depends on the pydot package, which has known issues and is not actively maintained. Consider using nx.nx_agraph.graphviz_layout instead.

See https://github.com/networkx/networkx/issues/5723r   r   )r   progroot)r   r   r   r   )r   rV   rW   r   r   r   r   r   A  s    r   c                 C   sV  ddl }d}tj|tdd t| }|dur<|dt| |j|d}t|t d}|d	krt	d
| d t	  t	d t	d t	d t	d| d dS |
|}t|dksJ |d }	i }
|  D ]}t|}t|rtd|| }|	|}t|tr|d }| dd }|dur|d\}}t|t|f|
|< q|
S )a  Create node positions using :mod:`pydot` and Graphviz.

    Parameters
    ----------
    G : Graph
        NetworkX graph to be laid out.
    prog : string  (default: 'neato')
        Name of the GraphViz command to use for layout.
        Options depend on GraphViz version but may include:
        'dot', 'twopi', 'fdp', 'sfdp', 'circo'
    root : Node from G or None (default: None)
        The node of G from which to start some layout algorithms.

    Returns
    -------
    dict
        Dictionary of positions keyed by node.

    Examples
    --------
    >>> G = nx.complete_graph(4)
    >>> pos = nx.nx_pydot.pydot_layout(G)
    >>> pos = nx.nx_pydot.pydot_layout(G, prog="dot")

    Notes
    -----
    If you use complex node objects, they may have the same string
    representation and GraphViz could treat them as the same node.
    The layout may assign both nodes a single location. See Issue #1568
    If this occurs in your case, consider relabeling the nodes just
    for the layout computation using something similar to::

        H = nx.convert_node_labels_to_integers(G, label_attribute='node_label')
        H_layout = nx.nx_pydot.pydot_layout(G, prog='dot')
        G_layout = {H.nodes[n]['node_label']: p for n, p in H_layout.items()}

    r   Nznx.nx_pydot.pydot_layout depends on the pydot package, which has known issues and is not actively maintained.

See https://github.com/networkx/networkx/issues/5723r   r   rW   )rV   )encodingr#   zGraphviz layout with z failedzTo debug what happened try:zP = nx.nx_pydot.to_pydot(G)zP.write_dot("file.dot")zAnd then run z on file.dotr
   zNode names and node attributes should not contain ":" unless they are quoted with "".                For example the string 'attribute:data1' should be written as '"attribute:data1"'.                Please refer https://github.com/pydot/pydot/issues/258r=   ,)r   r   r   r   r   setr.   Z
create_dotr   printr   lenr&   r>   rR   rS   r)   Zget_noder-   listZget_possplitfloat)r   rV   rW   r   r   r   ZD_bytesDZQ_listQZnode_posr5   Zstr_nZ
pydot_noder$   posxxyyr   r   r   r   j  sH    &

r   )rU   N)rU   N)__doc__r   localer   Znetworkxr(   Znetworkx.utilsr   __all__r   	_dispatchr   r	   r>   r   r   r   r   r   r   r   <module>   s    



)

au
)