Get the `graph` as Geoff string. The edges between the nodes
    have relationship name `edge_rel_name`. The code
    below shows a simple example::

        # create a graph
        import networkx as nx
        G = nx.Graph()
        G.add_nodes_from([1, 2, 3])
        G.add_edge(1, 2)
        G.add_edge(2, 3)

        # get the geoff string
        geoff_string = graph2geoff(G, 'LINKS_TO')

    If the properties are not json encodable, please pass a custom JSON encoder
    class. See `JSONEncoder
    <http://docs.python.org/2/library/json.html#json.JSONEncoder/>`_.

    Parameters
    ----------
    graph : Graph or DiGraph
        a NetworkX Graph or a DiGraph
    edge_rel_name : str
        relationship name between the nodes
    encoder: JSONEncoder or None
        JSONEncoder object. Defaults to JSONEncoder.

    Returns
    -------
    geoff : str
        a Geoff string

def graph2geoff(graph, edge_rel_name, encoder=None):
    """ Get the `graph` as Geoff string. The edges between the nodes
    have relationship name `edge_rel_name`. The code
    below shows a simple example::

        # create a graph
        import networkx as nx
        G = nx.Graph()
        G.add_nodes_from([1, 2, 3])
        G.add_edge(1, 2)
        G.add_edge(2, 3)

        # get the geoff string
        geoff_string = graph2geoff(G, 'LINKS_TO')

    If the properties are not json encodable, please pass a custom JSON encoder
    class. See `JSONEncoder
    <http://docs.python.org/2/library/json.html#json.JSONEncoder/>`_.

    Parameters
    ----------
    graph : Graph or DiGraph
        a NetworkX Graph or a DiGraph
    edge_rel_name : str
        relationship name between the nodes
    encoder: JSONEncoder or None
        JSONEncoder object. Defaults to JSONEncoder.

    Returns
    -------
    geoff : str
        a Geoff string
    """
    if encoder is None:
        encoder = json.JSONEncoder()
    is_digraph = isinstance(graph, nx.DiGraph)

    lines = []
    lapp = lines.append
    for node_name, properties in graph.nodes(data=True):
        lapp(node2geoff(node_name, properties, encoder))

    for from_node, to_node, properties in graph.edges(data=True):
        lapp(edge2geoff(from_node, to_node, properties, edge_rel_name, encoder))
        if not is_digraph:
            lapp(edge2geoff(to_node, from_node, properties, edge_rel_name,
                          encoder))

    return '\n'.join(lines)