func Marshal(g graph.Graph, name, prefix, indent string, strict bool) ([]byte, error) {
	var p printer
	p.indent = indent
	p.prefix = prefix
	p.visited = make(map[edge]bool)
	if strict {
		p.buf.WriteString("strict ")
	}
	err := p.print(g, name, false, false)
	if err != nil {
		return nil, err
	}
	return p.buf.Bytes(), nil
}
Marshal returns the DOT encoding for the graph g, applying the prefix
and indent to the encoding. Name is used to specify the graph name. If
name is empty and g implements Graph, the returned string from DOTID
will be used. If strict is true the output bytes will be prefixed with
the DOT "strict" keyword.

Graph serialization will work for a graph.Graph without modification,
however, advanced GraphViz DOT features provided by Marshal depend on
implementation of the Node, Attributer, Porter, Attributers, Structurer,
Subgrapher and Graph interfaces.
package dot
import (
	"bytes"
	"errors"
	"fmt"
	"sort"
	"strings"
	"gonum.org/v1/gonum/graph"
	"gonum.org/v1/gonum/graph/encoding"
	"gonum.org/v1/gonum/graph/internal/ordered"
)
type Node interface {
	DOTID() string
}
type Attributers interface {
	DOTAttributers() (graph, node, edge encoding.Attributer)
}
type Porter interface {
	FromPort() (port, compass string)
	ToPort() (port, compass string)
}
type Structurer interface {
	Structure() []Graph
}
type Graph interface {
	graph.Graph
	DOTID() string
}
type Subgrapher interface {
	Subgraph() graph.Graph
}