There might still be a few cases where quotes are still not
escaped/parsed correctly; if you find such a situation, please
let me know; however, you should be able to use String values
directly without having to worry about when quotes are required
or extra escaping of quote characters as PrintDot and
ParseDot instances for String should take care of that
for you.

Note that for an edge, in Dot parlance if the edge goes from
A to B, then A is the tail node and B is the head node
(since A is at the tail end of the arrow).

ColorList, DoubleList and PointfList are defined as actual
lists (but LayerList is not). All of these are assumed to be
non-empty lists. Note that for the ColorAttribute for node
values, only a single Color is valid; edges are allowed multiple
colors with one spline/arrow per color in the list (but you must have
at least one Color in the list). This might be changed in future.

Style is implemented as a list of StyleItem values; note that
empty lists are not allowed.

A lot of values have a possible value of none. These now
have custom constructors. In fact, most constructors have been
expanded upon to give an idea of what they represent rather than
using generic terms.

PointF and Point have been combined, and feature support for pure
Int-based co-ordinates as well as Double ones (i.e. no floating
point-only points for Point). The optional ! and third value
for Point are not available.

Rect uses two Point values to denote the lower-left and
top-right corners.

The actual Dot attributes.

These attributes have been implemented in a permissive manner:
that is, rather than split them up based on which type of value
they are allowed, they have all been included in the one data type,
with functions to determine if they are indeed valid for what
they're being applied to.

To interpret the Valid for listings:

G

Valid for Graphs.

C

Valid for Clusters.

S

Valid for Sub-Graphs (and also Clusters).

N

Valid for Nodes.

E

Valid for Edges.

The Default listings are those that the various Graphviz commands
use if that Attribute isn't specified (in cases where this is
none, this is equivalent to a Nothing value; that is, no value
is used). The Parsing Default listings represent what value is
used (i.e. corresponds to True) when the Attribute name is
listed on its own in Dot source code.

Please note that the UnknownAttributeAttribute is defined for
backwards-compatibility purposes only (specifically, to be able to
parse old Dot code containing Attributes that are no longer valid).
As such, this Attribute should not be used directly. The attribute
name is assumed to match the first type of identifier listed in
Data.GraphViz.Printing (i.e. a non-number that does not need to be
quoted).

Value types for Attributes.

Some Attributes (mainly label-like ones) take a String argument
that allows for extra escape codes. This library doesn't do any
extra checks or special parsing for these escape codes, but usage
of EscString rather than String indicates that the Graphviz
tools will recognise these extra escape codes for these
Attributes.

Dot has a basic grammar of arrow shapes which allows usage of
up to 1,544,761 different shapes from 9 different basic
ArrowShapes. Note that whilst an explicit list is used in the
definition of ArrowType, there must be at least one tuple and a
maximum of 4 (since that is what is required by Dot). For more
information, see: http://graphviz.org/doc/info/arrows.html

The 19 basic arrows shown on the overall attributes page have
been defined below as a convenience. Parsing of the 5
backward-compatible special cases is also supported.

Types representing the Dot grammar for records.

Specifies the sub-values of a record-based label. By default,
the cells are laid out horizontally; use FlipFields to change
the orientation of the fields (can be applied recursively). To
change the default orientation, use RankDir.