Repository: networkx/networkx

Issue:
label in gml output should be quoted
The output of the `write_gml` function currently (1.11) does not quote the label values, but I do think it should according to the [GML spec.](http://www.fim.uni-passau.de/fileadmin/files/lehrstuhl/brandenburg/projekte/gml/gml-technical-report.pdf). Because of this, tools like Cytoscape, jhive and gml2gv fails to read the gml file.

A node from my output:
```
  node [
    id 0
    label 1203
  ]
```
that should be 

```
  node [
    id 0
    label "1203"
  ]
```


Discussion:
That seems fine to me.  

Resolving patch:
diff --git a/networkx/readwrite/gml.py b/networkx/readwrite/gml.py
--- a/networkx/readwrite/gml.py
+++ b/networkx/readwrite/gml.py
@@ -565,7 +565,7 @@ def generate_gml(G, stringizer=None):
     Notes
     -----
     Graph attributes named 'directed', 'multigraph', 'node' or
-    'edge',node attributes named 'id' or 'label', edge attributes
+    '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.
@@ -581,7 +581,10 @@ def stringize(key, value, ignored_keys, indent, in_list=False):
             key = str(key)
         if key not in ignored_keys:
             if isinstance(value, (int, long)):
-                yield indent + key + ' ' + str(value)
+                if key == 'label':
+                    yield indent + key + ' "' + str(value) + '"'
+                else:
+                    yield indent + key + ' ' + str(value)
             elif isinstance(value, float):
                 text = repr(value).upper()
                 # GML requires that a real literal contain a decimal point, but
@@ -590,7 +593,10 @@ def stringize(key, value, ignored_keys, indent, in_list=False):
                 epos = text.rfind('E')
                 if epos != -1 and text.find('.', 0, epos) == -1:
                     text = text[:epos] + '.' + text[epos:]
-                yield indent + key + ' ' + text
+                if key == 'label':
+                    yield indent + key + ' "' + test + '"'
+                else:
+                    yield indent + key + ' ' + text
             elif isinstance(value, dict):
                 yield indent + key + ' ['
                 next_indent = indent + '  '


Test patch:
diff --git a/networkx/readwrite/tests/test_gml.py b/networkx/readwrite/tests/test_gml.py
--- a/networkx/readwrite/tests/test_gml.py
+++ b/networkx/readwrite/tests/test_gml.py
@@ -180,6 +180,19 @@ def test_read_gml(self):
         os.close(fd)
         os.unlink(fname)
 
+    def test_labels_are_strings(self):
+        # GML requires labels to be strings (i.e., in quotes)
+        answer = """graph [
+  node [
+    id 0
+    label "1203"
+  ]
+]"""
+        G = nx.Graph()
+        G.add_node(1203)
+        data = '\n'.join(nx.generate_gml(G, stringizer=literal_stringizer))
+        assert_equal(data, answer)
+
     def test_relabel_duplicate(self):
         data = """
 graph
@@ -240,12 +253,29 @@ def test_quotes(self):
   name "path_graph(1)"
   node [
     id 0
-    label 0
+    label "0"
     demo "This is &#34;quoted&#34; and this is a copyright: &#169;"
   ]
 ]"""
         assert_equal(data, answer)
 
+    def test_unicode_node(self):
+        node = 'node' + unichr(169)
+        G = nx.Graph()
+        G.add_node(node)
+        fobj = tempfile.NamedTemporaryFile()
+        nx.write_gml(G, fobj)
+        fobj.seek(0)
+        # Should be bytes in 2.x and 3.x
+        data = fobj.read().strip().decode('ascii')
+        answer = """graph [
+  node [
+    id 0
+    label "node&#169;"
+  ]
+]"""
+        assert_equal(data, answer)
+
     def test_name(self):
         G = nx.parse_gml('graph [ name "x" node [ id 0 label "x" ] ]')
         assert_equal('x', G.graph['name'])
@@ -261,7 +291,7 @@ def test_graph_types(self):
                     gml += ' directed ' + str(int(directed))
                 if multigraph is not None:
                     gml += ' multigraph ' + str(int(multigraph))
-                gml += ' node [ id 0 label 0 ]'
+                gml += ' node [ id 0 label "0" ]'
                 gml += ' edge [ source 0 target 0 ]'
                 gml += ' ]'
                 G = nx.parse_gml(gml)
@@ -274,7 +304,7 @@ def test_graph_types(self):
                     gml += '  multigraph 1\n'
                 gml += """  node [
     id 0
-    label 0
+    label "0"
   ]
   edge [
     source 0