Produce edges in a breadth-first-search starting at source.

    Neighbors appear in the order a linguist would expect in a syntax tree.
    The result will only contain edges that express a dominance or spanning
    relation, i.e. edges expressing pointing or precedence relations will
    be ignored.

    Parameters
    ----------
    G : DiscourseDocumentGraph

    source : node
       Specify starting node for breadth-first search and return edges in
       the component reachable from source.

    Returns
    -------
    edges: generator
       A generator of edges in the breadth-first-search.

def sorted_bfs_edges(G, source=None):
    """Produce edges in a breadth-first-search starting at source.

    Neighbors appear in the order a linguist would expect in a syntax tree.
    The result will only contain edges that express a dominance or spanning
    relation, i.e. edges expressing pointing or precedence relations will
    be ignored.

    Parameters
    ----------
    G : DiscourseDocumentGraph

    source : node
       Specify starting node for breadth-first search and return edges in
       the component reachable from source.

    Returns
    -------
    edges: generator
       A generator of edges in the breadth-first-search.
    """
    if source is None:
        source = G.root

    xpos = horizontal_positions(G, source)
    visited = set([source])
    source_children = get_child_nodes(G, source)
    queue = deque([(source, iter(sorted(source_children,
                                        key=lambda x: xpos[x])))])
    while queue:
        parent, children = queue[0]
        try:
            child = next(children)
            if child not in visited:
                yield parent, child
                visited.add(child)
                grandchildren = get_child_nodes(G, child)
                queue.append((child, iter(sorted(grandchildren,
                                                 key=lambda x: xpos[x]))))
        except StopIteration:
            queue.popleft()