
    wgy                        d Z ddlm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lmZ ddlmZmZ ddlZddlmZ dd	lmZ g d
Zd Zd Zd Z edd       ej6                  dd      dd              Z ej6                  dd      dd       Z G d de      Z G d de      ZdZ d Z!d Z"d dZ# edd      d d       Z$y)!a  
Read graphs in GML format.

"GML, the Graph Modelling Language, is our proposal for a portable
file format for graphs. GML's key features are portability, simple
syntax, extensibility and flexibility. A GML file consists of a
hierarchical key-value lists. Graphs can be annotated with arbitrary
data structures. The idea for a common file format was born at the
GD'95; this proposal is the outcome of many discussions. GML is the
standard file format in the Graphlet graph editor system. It has been
overtaken and adapted by several other systems for drawing graphs."

GML files are stored using a 7-bit ASCII encoding with any extended
ASCII characters (iso8859-1) appearing as HTML character entities.
You will need to give some thought into how the exported data should
interact with different languages and even different Python versions.
Re-importing from gml is also a concern.

Without specifying a `stringizer`/`destringizer`, the code is capable of
writing `int`/`float`/`str`/`dict`/`list` data as required by the GML
specification.  For writing other data types, and for reading data other
than `str` you need to explicitly supply a `stringizer`/`destringizer`.

For additional documentation on the GML file format, please see the
`GML website <https://web.archive.org/web/20190207140002/http://www.fim.uni-passau.de/index.php?id=17297&L=1>`_.

Several example graphs in GML format may be found on Mark Newman's
`Network data page <http://www-personal.umich.edu/~mejn/netdata/>`_.
    N)literal_eval)defaultdict)Enum)StringIO)Any
NamedTuple)NetworkXError)	open_file)read_gml	parse_gmlgenerate_gml	write_gmlc                 p    d }t        j                  d||       } t        | t              r| S t        |       S )zUse XML character references to escape characters.

    Use XML character references for unprintable or non-ASCII
    characters, double quotes and ampersands in a string
    c                 X    | j                  d      }dt        t        |            z   dz   S )Nr   z&#;)groupstrord)mchs     [/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/networkx/readwrite/gml.pyfixupzescape.<locals>.fixup6   s'    WWQZc#b'l"S((    z[^ -~]|[&"])resub
isinstancer   textr   s     r   escaper   /   s3    ) 66--DdC(47c$i7r   c                 6    d }t        j                  d||       S )z?Replace XML character references with the referenced charactersc                    | j                  d      }|d   dk(  r'|d   dk(  rt        |dd d      }n&t        |dd       }n	 t        j                  |dd    }	 t        |      S # t        $ r |cY S w xY w# t        t        f$ r |cY S w xY w)	Nr      #   x      )r   inthtmlentitydefsname2codepointKeyErrorchr
ValueErrorOverflowError)r   r   codes      r   r   zunescape.<locals>.fixupA   s    wwqz7c>Aw#~4":r*4":%44T!BZ@	t9   M* 	K	s$   A$ 
A5 $A21A25B	B	z,&(?:[0-9A-Za-z]+|#(?:[0-9]+|x[0-9A-Fa-f]+));)r   r   r   s     r   unescaper1   >   s    & 66@%NNr   c                     t        | t              r| }	 t        |       S t	        | d      # t        $ r}t	        |d      |d}~ww xY w)a(  Convert a Python literal to the value it represents.

    Parameters
    ----------
    rep : string
        A Python literal.

    Returns
    -------
    value : object
        The value of the Python literal.

    Raises
    ------
    ValueError
        If `rep` is not a Python literal.
    z is not a valid Python literalN is not a string)r   r   r   SyntaxErrorr.   )reporig_reperrs      r   literal_destringizerr8   W   sc    $ #s	U$$ C7"2344  	U|+IJKQTT	Us   
- 	A
AA
rb)modeT)graphsreturns_graphc                 2    d }t         ||       ||      }|S )a  Read graph in GML format from `path`.

    Parameters
    ----------
    path : filename or filehandle
        The filename or filehandle to read from.

    label : string, optional
        If not None, the parsed nodes will be renamed according to node
        attributes indicated by `label`. Default value: 'label'.

    destringizer : callable, optional
        A `destringizer` that recovers values stored as strings in GML. If it
        cannot convert a string to a value, a `ValueError` is raised. Default
        value : None.

    Returns
    -------
    G : NetworkX graph
        The parsed graph.

    Raises
    ------
    NetworkXError
        If the input cannot be parsed.

    See Also
    --------
    write_gml, parse_gml
    literal_destringizer

    Notes
    -----
    GML files are stored using a 7-bit ASCII encoding with any extended
    ASCII characters (iso8859-1) appearing as HTML character entities.
    Without specifying a `stringizer`/`destringizer`, the code is capable of
    writing `int`/`float`/`str`/`dict`/`list` data as required by the GML
    specification.  For writing other data types, and for reading data other
    than `str` you need to explicitly supply a `stringizer`/`destringizer`.

    For additional documentation on the GML file format, please see the
    `GML url <https://web.archive.org/web/20190207140002/http://www.fim.uni-passau.de/index.php?id=17297&L=1>`_.

    See the module docstring :mod:`networkx.readwrite.gml` for more details.

    Examples
    --------
    >>> G = nx.path_graph(4)
    >>> nx.write_gml(G, "test.gml")

    GML values are interpreted as strings by default:

    >>> H = nx.read_gml("test.gml")
    >>> H.nodes
    NodeView(('0', '1', '2', '3'))

    When a `destringizer` is provided, GML values are converted to the provided type.
    For example, integer nodes can be recovered as shown below:

    >>> J = nx.read_gml("test.gml", destringizer=int)
    >>> J.nodes
    NodeView((0, 1, 2, 3))

    c              3      K   | D ]B  }	 |j                  d      }t        |t              st	        |       } |r|d   dk(  r|d d }| D y # t        $ r}t        d      |d }~ww xY ww)Nasciiinput is not ASCII-encodedr'   
)decodeUnicodeDecodeErrorr	   r   r   )linesliner7   s      r   filter_lineszread_gml.<locals>.filter_lines   s}      		DK{{7+ dC(E
RD(CRyJ		 & K#$@AsJKs'   A(A1A(	A%A  A%%A(parse_gml_lines)pathlabeldestringizerrF   Gs        r   r   r   s   s"    H
 	T*E<@AHr   c                 >    d fd}t         ||       ||      }|S )a3  Parse GML graph from a string or iterable.

    Parameters
    ----------
    lines : string or iterable of strings
       Data in GML format.

    label : string, optional
        If not None, the parsed nodes will be renamed according to node
        attributes indicated by `label`. Default value: 'label'.

    destringizer : callable, optional
        A `destringizer` that recovers values stored as strings in GML. If it
        cannot convert a string to a value, a `ValueError` is raised. Default
        value : None.

    Returns
    -------
    G : NetworkX graph
        The parsed graph.

    Raises
    ------
    NetworkXError
        If the input cannot be parsed.

    See Also
    --------
    write_gml, read_gml

    Notes
    -----
    This stores nested GML attributes as dictionaries in the NetworkX graph,
    node, and edge attribute structures.

    GML files are stored using a 7-bit ASCII encoding with any extended
    ASCII characters (iso8859-1) appearing as HTML character entities.
    Without specifying a `stringizer`/`destringizer`, the code is capable of
    writing `int`/`float`/`str`/`dict`/`list` data as required by the GML
    specification.  For writing other data types, and for reading data other
    than `str` you need to explicitly supply a `stringizer`/`destringizer`.

    For additional documentation on the GML file format, please see the
    `GML url <https://web.archive.org/web/20190207140002/http://www.fim.uni-passau.de/index.php?id=17297&L=1>`_.

    See the module docstring :mod:`networkx.readwrite.gml` for more details.
    c                     t        | t              r	 | j                  d       t        | t
              st        |       } | S # t        $ r}t	        d      |d }~ww xY w)Nr?   r@   )r   bytesrB   rC   r	   r   )rE   r7   s     r   decode_linezparse_gml.<locals>.decode_line   sZ    dE"KG$ $$t9D	 & K#$@AsJKs   A   	A	AAc              3      K   t        | t              r# |       } | j                         } | E d {    y | D ]<  } |      }|r|d   dk(  r|d d }|j                  d      dk7  rt	        d      | > y 7 Gw)Nr'   rA   zinput line contains newline)r   r   
splitlinesfindr	   )rD   rE   rP   s     r   rF   zparse_gml.<locals>.filter_lines  s     eS!&E$$&E "4(DH,9D99T?b('(EFF
 s   .A;A9AA;rG   )rD   rJ   rK   rF   rL   rP   s        @r   r   r      s(    d 	U+ULAAHr   c                   ,    e Zd ZdZdZdZdZdZdZdZ	dZ
y	)
Patternz?encodes the index of each token-matching pattern in `tokenize`.r   r"   r$   r&            N)__name__
__module____qualname____doc__KEYSREALSINTSSTRINGS
DICT_STARTDICT_ENDCOMMENT_WHITESPACE r   r   rU   rU     s)    IDEDGJHr   rU   c                   6    e Zd ZU eed<   eed<   eed<   eed<   y)TokencategoryvaluerE   positionN)rY   rZ   r[   rU   __annotations__r   r)   rd   r   r   rf   rf   !  s    J
IMr   rf   _networkx_list_startc           
            fd}d   fd fdfd fd} |        |       }|j                  dd      }|j                  d	d      }|s+|rt        j                         nt        j                         }n*|rt        j                         nt        j
                         }|j                         D 	
ci c]  \  }	}
|	d
vs|	|
 }}	}
|j                  j                  |       d }|j                  dg       }i }t               }t        t        |t              r|n|g      D ]q  \  }} ||dd|      }||v rt        d|d      |9|dk7  r4 ||d||      }||v rt        d|d      |j                  |       |||<    |j                   |fi | s |j                  dg       }t        t        |t              r|n|g      D ]  \  }} ||dd|      } ||dd|      }||vrt        d| d|      ||vrt        d| d|      |sO|j#                  ||      s |j$                  ||fi | p|rdnd}d| d|| |d}t        j                  |      |j                  dd      }|F|j#                  |||      r3|rdnd}d| d|| |d|d	}d}t        j                  |d z   |z          |j$                  |||fi | 	 ||dk7  rt        j&                  ||      }|S c c}
}	w )!zParse GML `lines` into a graph.c            	   3     K   g d} t        j                  dj                  d | D                    }d}g }D ]  }d}|rA|j                  |j	                                |d   dk(  rdj                  |      }g }n]|dz  }I|j                  d      dk(  rC|j	                         d   dk7  r-|j	                         d   dk7  r|j                         g}|dz  }t        |      }||k  r|j                  ||      }| d	||d   d
|dz    d|dz    d}t        |      t        t        |             D ]  }	|j                  |	dz         }
|
|	dk(  r|
j                         }n$|	dk(  rt        |
      }n|	dk(  rt        |
      }n|
}|	dk7  rt        t        |	      ||dz   |dz          |t        |
      z  } n ||k  r|dz  } t        d d |dz   d       y w)N)z[A-Za-z][0-9A-Za-z_]*\bz>[+-]?(?:[0-9]*\.[0-9]+|[0-9]+\.[0-9]*|INF)(?:[Ee][+-]?[0-9]+)?z[+-]?[0-9]+z".*?"z\[z\]z#.*$|\s+|c              3   (   K   | ]
  }d | d  yw)()Nrd   ).0patterns     r   	<genexpr>z4parse_gml_lines.<locals>.tokenize.<locals>.<genexpr>9  s     $Lq	^$Ls   r   r'   " r"   zcannot tokenize  at (, rq   r$   rX   )r   compilejoinappendstripcountrstriplenmatchr	   ranger   floatr)   rf   rU   )patternstokenslineno
multilinesrE   poslengthr   r   ir   rh   rD   s               r   tokenizez!parse_gml_lines.<locals>.tokenize.  s    	
 CHH$L8$LLM
 /	DC
 !!$**,/8s? 88J/D!#JaKF::c?a'zz|A#-$**,r2Bc2I '+kkm_
! YF,T3/=*4:,eFQJ<r#PQ'RSTA'**s8}- A!KKA.E(6$)LLNE!V$)%LE!V$'JE$)E6"'
E6A:sQw"OOs5z) ,( aKF_/	` D$
A..s   EGA4G Gc                 ^    | \  }}}}|t        |      nd}t        d| d| d| d| d	      )NEOFz	expected z, found rw   rx   rq   )reprr	   )
curr_tokenexpectedrg   rh   r   r   s         r   
unexpectedz#parse_gml_lines.<locals>.unexpectedn  sH    '1$%$0Ueiz%fXRPSuTUVWWr   c                 L    | j                   |k(  rt              S  | |       y N)rg   next)r   rg   r   r   r   s      r   consumez parse_gml_lines.<locals>.consumes  s%    (*<:x(r   c                 &   t        t              }| j                  t        j                  k(  ru| j
                  }t        	      } | j                  }|t        j                  k(  s|t        j                  k(  r| j
                  }t        	      } n|t        j                  k(  r=t        | j
                  dd       }r		  |      }|dk(  rd}|dk(  rg }t        	      } n|t        j                  k(  r |       \  } }nr|dv r6	 t        t        | j
                              }r		  |      }t        	      } n8| j
                  dv r!t        | j
                        }t        	      } n	 
| d	       ||   j!                         | j                  t        j                  k(  rud
 }|j#                         D ci c]  \  }}| ||       }}}| |fS # t        $ r Y w xY w# t        $ r Y w xY w# t        $ r d} 
| |       Y w xY wc c}}w )Nr"   r'   ()rd   z[])idrJ   sourcetargetzQan int, float, string, '[' or string convertible ASCII value for node id or label>   INFNANzan int, float, string or '['c                 r    t        | t              s| S t        |       dk(  r| d   S | d   t        k(  r| dd  S | S )Nr"   r   )r   listr   LIST_START_VALUE)rh   s    r   clean_dict_valuez;parse_gml_lines.<locals>.parse_kv.<locals>.clean_dict_value  sC    eT*5zQQxQx++QRy Lr   )r   r   rg   rU   r]   rh   r   r^   r_   r`   r1   r.   ra   r   	Exceptionr   r{   items)r   dctkeyrg   rh   msgr   rK   
parse_dictr   r   s          r   parse_kvz!parse_gml_lines.<locals>.parse_kvx  s   $!!W\\1""CfJ!**H7==(H,D"((!&\
W__, !1!1!B!78 ,U 3 D=ED=E!&\
W///$.z$:!
E ==4 (Z-=-=)> ?'%(4U(; &*&\
  %%7!*"2"23E!%fJz+IJHOOE"g !!W\\1j	 ?BiikJ
Us$U++JJ3g & & $. % $% % 4N  #:s348 KsN   >G  G3 %G$ -G3 :H	G! G!$	G0-G3 /G00G3 3H
	H
c                      | t         j                  d      }  |       \  } } | t         j                  d      } | |fS )Nz'['z']')rU   ra   rb   )r   r   r   r   s     r   r   z#parse_gml_lines.<locals>.parse_dict  sC    Z););UC
":.
CZ)9)95A
3r   c                       t                    \  } }| j                  	 | d       d|vrt        d      |d   }t        |t              rt        d      |S )Nr   graphzinput contains no graphz"input contains more than one graph)r   rg   r	   r   r   )r   r   r   r   r   r   s      r   parse_graphz$parse_gml_lines.<locals>.parse_graph  sc    "4<0
C*z5)# 9::GeT" DEEr   directedF
multigraph)nodeedgec           	      r    	 | j                  |      S # t        $ r}t        | d| d|d      |d }~ww xY w)Nz #z has no z
 attribute)popr,   r	   )r   rg   attrr   r7   s        r   pop_attrz!parse_gml_lines.<locals>.pop_attr  sI    	W774=  	W8*Bqc$ LMSVV	Ws    	616r   r   znode id z is duplicatedNznode label r   r   r   zedge #z has undefined source z has undefined target z->z--z (z) is duplicatedr   rx   rq   z6Hint: If multigraph add "multigraph 1" to file header.z is duplicated
)r   nxDiGraphGraphMultiDiGraph
MultiGraphr   r   updategetset	enumerater   r   r	   addadd_nodehas_edgeadd_edgerelabel_nodes)!rD   rJ   rK   r   r   r   r   r   rL   kv
graph_attrr   nodesmappingnode_labelsr   r   r   
node_labeledgesr   r   r   arrowr   r   msg2r   r   r   r   r   s!   ` `                         @@@@@r   rH   rH   +  s6   >/@X
)
AF	 ZFMEyyU+H</J$BJJL"((*!)BOOr}}#(;;=N41aA=M4M!Q$NJNGGNN:W IIfb!EG%Kj&=UE7K 
4dFD!,7(2& ?@@$!$q9J[(#k*~$NOOOOJ'$GBK

2
 IIfb!Ej&=UE7K 44$!4$!4?&+A& LMM?&+A& LMM::ff-

662T2 (dqcF:eWVJoN&&s++((5$'C1::ffc#B (dqcF:eWVJbqIO&&s-?'?$'FGGAJJvvs3d3+4. Ud]Q(He Os   LLc                 V    fdt                |        j                         S )a:  Convert a `value` to a Python literal in GML representation.

    Parameters
    ----------
    value : object
        The `value` to be converted to GML representation.

    Returns
    -------
    rep : string
        A double-quoted Python literal representing value. Unprintable
        characters are replaced by XML character references.

    Raises
    ------
    ValueError
        If `value` cannot be converted to GML.

    Notes
    -----
    The original value can be recovered using the
    :func:`networkx.readwrite.gml.literal_destringizer` function.
    c                    t        | t        t        z        s| Y| du rj                  t	        d             y | du rj                  t	        d             y j                  t	        |              y t        | t              r7t        |       }|d   dk7  r	 | j                  d       j                  |       y t        | t        t        z  t        z  t        z        rj                  t        |              y t        | t              rJj                  d       d}| D ]   }|sj                  d       nd} |       " j                  d	       y t        | t              rt        |       dkD  rJj                  d
       d}| D ]   }|sj                  d       nd} |       " j                  d       y | r.j                  d
        | d          j                  d       y j                  d       y t        | t              rtj                  d       d}| j                         D ]<  \  }} |sj                  d       nd} |       j                  d        |        > j                  d       y t        | t               rJj                  d       d}| D ]   }|sj                  d       nd} |       " j                  d       y | d}t#        |      # t        $ r	 d|z   }Y Uw xY w)NTr"   Fr   ulatin1[,]rp   rq   z,)r   {:}z* cannot be converted into a Python literal)r   r)   boolwriter   r   encodeUnicodeEncodeErrorr   complexrO   r   tupler   dictr   r   r.   )rh   r   firstitemr   r   buf	stringizes         r   r   z%literal_stringizer.<locals>.stringize&  s   eS4Z(EM}		#a&!%		#a&!		#e*%s#;DAw#~&LL* IIdOuw4u<=IId5k"t$IIcNE  IIcN!E$  IIcNu%5zA~		#! $D 		# %dO$ 		#		#%(#		$		$t$IIcNE#kkm !
UIIcN!E#		#% ! IIcNs#IIcNE  IIcN!E$  IIcNIGHCS/!q * &:D&s   K- -K?>K?)r   getvalue)rh   r   r   s    @@r   literal_stringizerr     s'    2E"N *Ce<<>r   c           
   #     K   t        j                  d      dfd	| j                         }d | j                         rd |rd h d}| j                  j                         D ]  \  }} |||d      E d{     t        t        | t        t        |                         }d	d
h}| j                  j                         D ]^  \  }}d dt        ||         z     d
|dd      E d{    |j                         D ]  \  }} |||d      E d{     d ` ddh}ddi}	|r|j                  d       d|	d<    | j                  di |	D ]|  }
d dt        ||
d            z    dt        ||
d            z    |r d|
d   dd      E d{    |
d   j                         D ]  \  }} |||d      E d{     d ~ d y7 c7 7 7 D7 w)a	  Generate a single entry of the graph `G` in GML format.

    Parameters
    ----------
    G : NetworkX graph
        The graph to be converted to GML.

    stringizer : callable, optional
        A `stringizer` which converts non-int/non-float/non-dict values into
        strings. If it cannot convert a value into a string, it should raise a
        `ValueError` to indicate that. Default value: None.

    Returns
    -------
    lines: generator of strings
        Lines of GML data. Newlines are not appended.

    Raises
    ------
    NetworkXError
        If `stringizer` cannot convert a value into a string, or the value to
        convert is not a string while `stringizer` is None.

    See Also
    --------
    literal_stringizer

    Notes
    -----
    Graph attributes named 'directed', 'multigraph', 'node' or
    'edge', node attributes named 'id' or 'label', edge attributes
    named 'source' or 'target' (or 'key' if `G` is a multigraph)
    are ignored because these attribute names are used to encode the graph
    structure.

    GML files are stored using a 7-bit ASCII encoding with any extended
    ASCII characters (iso8859-1) appearing as HTML character entities.
    Without specifying a `stringizer`/`destringizer`, the code is capable of
    writing `int`/`float`/`str`/`dict`/`list` data as required by the GML
    specification.  For writing other data types, and for reading data other
    than `str` you need to explicitly supply a `stringizer`/`destringizer`.

    For additional documentation on the GML file format, please see the
    `GML url <https://web.archive.org/web/20190207140002/http://www.fim.uni-passau.de/index.php?id=17297&L=1>`_.

    See the module docstring :mod:`networkx.readwrite.gml` for more details.

    Examples
    --------
    >>> G = nx.Graph()
    >>> G.add_node("1")
    >>> print("\n".join(nx.generate_gml(G)))
    graph [
      node [
        id 0
        label "1"
      ]
    ]
    >>> G = nx.MultiGraph([("a", "b"), ("a", "b")])
    >>> print("\n".join(nx.generate_gml(G)))
    graph [
      multigraph 1
      node [
        id 0
        label "a"
      ]
      node [
        id 1
        label "b"
      ]
      edge [
        source 0
        target 1
        key 0
      ]
      edge [
        source 0
        target 1
        key 1
      ]
    ]
    z^[A-Za-z][0-9A-Za-z_]*$c              3   *  K   t        | t              st        | d      j                  |       st        | d      t        | t              st        |       } | |vrt        |t        t
        z        rx| dk(  r|| z   dz   t        |      z   dz    y |du r|| z   dz    y |du r|| z   d	z    y |d
k  s|dk\  r|| z   dz   t        |      z   dz    y || z   dz   t        |      z    y t        |t              rt        |      j                         }|t        t        d            j                         k(  rd|z   }n:|j                  d      }|dk7  r$|j                  dd|      dk(  r|d | dz   ||d  z   }| dk(  r|| z   dz   |z   dz    y || z   dz   |z    y t        |t              rB|| z   dz    |dz   }|j                         D ]  \  } } 
| |d|      E d {     |dz    y t        |t              r*| dk(  r%|| z   ddj                  d |D               dz    y t        |t        t        z        re| dk7  r`|s^t!        |      dk(  r|| z   dz   d|dz    t!        |      dk(  r|| z   dz   dt"         dz    |D ]  } 
| |d|d      E d {     y r		  |      }t        |t              st        |d      || z   dz   t'        |      z   dz    y y 7 	7 N# t$        $ r}	t        |d      |	d }	~	ww xY ww)Nr3   z is not a valid keyrJ   z "ru   Tz 1Fz 0i   l        rv   inf+Er'   .r   z [  rd   r   z "(r   c              3   2   K   | ]  }t        |        y wr   )r   )rr   r   s     r   rt   z2generate_gml.<locals>.stringize.<locals>.<genexpr>  s     4LT!W4Ls   z)"r"   z" cannot be converted into a string)r   r   r	   r   r)   r   r   r   upperrfindrS   r   r   r   rz   r   r   r   r.   r   )r   rh   ignored_keysindentin_listr   eposnext_indentvalr7   r   
stringizer
valid_keyss             r   r   zgenerate_gml.<locals>.stringize  sl    #s#3')9 :;;$3')< =>>#s#c(Cl"%t,'> 3,-E
:S@@d] 3,--e^ 3,--X%% 3,-E
:S@@ 3,,s5z99E5)E{((* 4e-3355:D
  ::c?DrzdiiQ&=&C#ET{S04;>'> 3,-4s:: 3,,t33E4(slT))$tm"'++- FJC(eREEEFsl"E5)cWnsltCHH4Le4L,L+MS%QQQE4%<0SG^Gu:? 3,,5)1~==u:? 3,,3C2DA/FFF  EC(c2vtDDDE # *5 1
 "%-'5)3C(DEEslT)F5M9C??q #F F E
 & #+$i'IJ"##sI   G"L%K.&B<L"K1#	L-K3 5:L1L3	L<LLLzgraph [z  directed 1z  multigraph 1>   r   r   r   r   r   Nr   rJ   z  node [z    id rd   z    z  ]r   r   dataTr   keysz  edge [z    source r   z    target r"   r$   r'   r   )F)r   ry   is_multigraphis_directedr   r   r   zipr   r   r   r   r   r   )rL   r   r   r   r   rh   node_idr   attrskwargser   r   s    `         @@r   r   r   r  s    f 56J?@B "J
O 	}}=Lww}} >eT5,===> 3q%A-()G'?Lww}} e#gdm,,,WdB777 ;;= 	DKD% ulFCCC	D h'Ld^FvQWWv c'!A$-000c'!A$-000 !b&999R5;;= 	DKD% ulFCCC	D I9 	> 	8C :Cs\   A>G1G&A6G1:G);(G1#G+$BG1(G-)+G1G/G1)G1+G1-G1/G1r"   wbc                 l    t        | |      D ]%  }|j                  |dz   j                  d             ' y)a  Write a graph `G` in GML format to the file or file handle `path`.

    Parameters
    ----------
    G : NetworkX graph
        The graph to be converted to GML.

    path : filename or filehandle
        The filename or filehandle to write. Files whose names end with .gz or
        .bz2 will be compressed.

    stringizer : callable, optional
        A `stringizer` which converts non-int/non-float/non-dict values into
        strings. If it cannot convert a value into a string, it should raise a
        `ValueError` to indicate that. Default value: None.

    Raises
    ------
    NetworkXError
        If `stringizer` cannot convert a value into a string, or the value to
        convert is not a string while `stringizer` is None.

    See Also
    --------
    read_gml, generate_gml
    literal_stringizer

    Notes
    -----
    Graph attributes named 'directed', 'multigraph', 'node' or
    'edge', node attributes named 'id' or 'label', edge attributes
    named 'source' or 'target' (or 'key' if `G` is a multigraph)
    are ignored because these attribute names are used to encode the graph
    structure.

    GML files are stored using a 7-bit ASCII encoding with any extended
    ASCII characters (iso8859-1) appearing as HTML character entities.
    Without specifying a `stringizer`/`destringizer`, the code is capable of
    writing `int`/`float`/`str`/`dict`/`list` data as required by the GML
    specification.  For writing other data types, and for reading data other
    than `str` you need to explicitly supply a `stringizer`/`destringizer`.

    Note that while we allow non-standard GML to be read from a file, we make
    sure to write GML format. In particular, underscores are not allowed in
    attribute names.
    For additional documentation on the GML file format, please see the
    `GML url <https://web.archive.org/web/20190207140002/http://www.fim.uni-passau.de/index.php?id=17297&L=1>`_.

    See the module docstring :mod:`networkx.readwrite.gml` for more details.

    Examples
    --------
    >>> G = nx.path_graph(4)
    >>> nx.write_gml(G, "test.gml")

    Filenames ending in .gz or .bz2 will be compressed.

    >>> nx.write_gml(G, "test.gml.gz")
    rA   r?   N)r   r   r   )rL   rI   r   rE   s       r   r   r   1  s6    z Q
+ 2

D4K''012r   )rJ   Nr   )%r\   html.entitiesentitiesr*   r   warningsastr   collectionsr   enumr   ior   typingr   r   networkxr   networkx.exceptionr	   networkx.utilsr
   __all__r   r1   r8   _dispatchabler   r   rU   rf   r   rH   r   r   r   rd   r   r   <module>r     s   < ' 	   #   "  , $
@8O258 14T2O 3 Od T2J 3JZ	d 	J  * _DbJ|~ 14=2 =2r   