diff --git a/Data/Graph/Analysis.hs b/Data/Graph/Analysis.hs
--- a/Data/Graph/Analysis.hs
+++ b/Data/Graph/Analysis.hs
@@ -48,7 +48,7 @@
 
 -- | The library version.
 version :: String
-version = "0.3"
+version = "0.4"
 
 {- |
    This represents the information that's being passed in that we want
diff --git a/Data/Graph/Analysis/Algorithms/Common.hs b/Data/Graph/Analysis/Algorithms/Common.hs
--- a/Data/Graph/Analysis/Algorithms/Common.hs
+++ b/Data/Graph/Analysis/Algorithms/Common.hs
@@ -123,12 +123,14 @@
  -}
 
 -- | Finds all cliques (i.e. maximal complete subgraphs) in the given graph.
-cliquesIn    :: (Graph g) => g a b -> [[LNode a]]
+cliquesIn    :: (DynGraph g) => g a b -> [[LNode a]]
 cliquesIn gr = map (addLabels gr) (cliquesIn' gr)
 
 -- | Finds all cliques in the graph, without including labels.
-cliquesIn'    :: (Graph g) => g a b -> [NGroup]
-cliquesIn' gr = filter (isClique gr) (findRegular gr)
+cliquesIn'    :: (DynGraph g) => g a b -> [NGroup]
+cliquesIn' gr = filter (isClique gr') (findRegular gr')
+    where
+      gr' = mkSimple gr
 
 -- | Determine if the given list of nodes is indeed a clique,
 --   and not a smaller subgraph of a clique.
@@ -192,8 +194,7 @@
 
 -- | Find all cycles in the given graph, returning just the nodes.
 cyclesIn' :: (DynGraph g) => g a b -> [NGroup]
-cyclesIn' = filter (not . single) -- Exclude trivial cycles, i.e. loops
-            . concat . unfoldr findCycles
+cyclesIn' = concat . unfoldr findCycles . mkSimple
 
 -- | Find all cycles in the given graph, excluding those that are also cliques.
 uniqueCycles   :: (DynGraph g) => g a b -> [LNGroup a]
@@ -244,8 +245,8 @@
               $ filterNodes' isChainStart g'
     where
       -- Try to make this work on two-element cycles, undirected
-      -- graphs, etc.
-      g' = oneWay g
+      -- graphs, etc.  Also remove multiple edges, etc.
+      g' = oneWay $ mkSimple g
 
 -- | Find the chain starting with the given 'Node'.
 getChain     :: (Graph g) => g a b -> Node -> NGroup
diff --git a/Data/Graph/Analysis/Reporting.hs b/Data/Graph/Analysis/Reporting.hs
--- a/Data/Graph/Analysis/Reporting.hs
+++ b/Data/Graph/Analysis/Reporting.hs
@@ -20,10 +20,12 @@
       -- $utilities
       today,
       tryCreateDirectory,
-      createGraph
+      createGraph,
+      maximumSize
     ) where
 
 import Data.GraphViz
+import Data.GraphViz.Attributes
 import Data.Graph.Analysis.Visualisation
 
 import Data.Time
@@ -81,6 +83,7 @@
                 | Definition DocInline DocElement
                 | DocImage DocInline Location
                 | GraphImage DocGraph
+                  deriving (Show)
 
 data DocInline = Text String
                | BlankSpace
@@ -88,6 +91,7 @@
                | Bold DocInline
                | Emphasis DocInline
                | DocLink DocInline Location
+                 deriving (Show)
 
 type DocGraph = (FilePath,DocInline,DotGraph)
 
@@ -134,3 +138,6 @@
       loc = File filename
       img = DocImage inl loc
 
+-- | The recommended maximum size for graphs.
+maximumSize :: Attribute
+maximumSize = Size 15 10
diff --git a/Data/Graph/Analysis/Reporting/Pandoc.hs b/Data/Graph/Analysis/Reporting/Pandoc.hs
--- a/Data/Graph/Analysis/Reporting/Pandoc.hs
+++ b/Data/Graph/Analysis/Reporting/Pandoc.hs
@@ -154,7 +154,7 @@
 
 -- | Conversion of simple inline elements.
 inlines                   :: DocInline -> [Inline]
-inlines (Text str)        = intersperse Space $ map Str (words str)
+inlines (Text str)        = [Str str]
 inlines BlankSpace        = [Space]
 inlines (Grouping grp)    = concat . intersperse [Space] $ map inlines grp
 inlines (Bold inl)        = [Strong (inlines inl)]
diff --git a/Data/Graph/Analysis/Utils.hs b/Data/Graph/Analysis/Utils.hs
--- a/Data/Graph/Analysis/Utils.hs
+++ b/Data/Graph/Analysis/Utils.hs
@@ -23,10 +23,11 @@
       addLabels,
       filterNodes,
       filterNodes',
-      -- ** Graph manipulation
       pathValues,
+      -- ** Graph manipulation
       undir,
       oneWay,
+      mkSimple,
       nlmap,
       -- ** Graph layout
       -- | These next two are re-exported from "Data.GraphViz"
@@ -114,14 +115,14 @@
 filterNodes'     :: (Graph g) => (g a b -> Node -> Bool) -> g a b -> [Node]
 filterNodes' p g = filter (p g) (nodes g)
 
--- -----------------------------------------------------------------------------
-
--- | Manipulating graphs.
-
 -- | Extract the actual 'LNode's from an 'LPath'.
 pathValues          :: LPath a -> [LNode a]
 pathValues (LP lns) = lns
 
+-- -----------------------------------------------------------------------------
+
+-- | Manipulating graphs.
+
 {- |
    Make the graph undirected, i.e. for every edge from A to B, there
    exists an edge from B to A.  The provided function
@@ -147,6 +148,19 @@
 oneWay = gmap rmPre
     where
       rmPre (p,n,l,s) = (p \\ s,n,l,s)
+
+-- | Makes the graph a simple one, by removing all duplicate edges and loops.
+--   The edges removed if duplicates exist are arbitrary.
+mkSimple :: (DynGraph gr) => gr a b -> gr a b
+mkSimple = gmap simplify
+    where
+      rmLoops n = filter ((/=) n . snd)
+      rmDups = nubBy ((==) `on` snd)
+      simpleEdges n = rmDups . rmLoops n
+      simplify (p,n,l,s) = (p',n,l,s')
+          where
+            p' = simpleEdges n p
+            s' = simpleEdges n s
 
 -- | Map over the labels on the nodes, using the node values as well.
 nlmap   :: (DynGraph gr) => (LNode a -> c) -> gr a b -> gr c b
diff --git a/Data/Graph/Analysis/Visualisation.hs b/Data/Graph/Analysis/Visualisation.hs
--- a/Data/Graph/Analysis/Visualisation.hs
+++ b/Data/Graph/Analysis/Visualisation.hs
@@ -53,26 +53,27 @@
    application.
 -}
 
--- | Turns the graph into 'DotGraph' format with the given title.
---   Nodes are labelled, edges aren't.
-graphviz     :: (Graph g, Show a, Ord b) => String -> g a b -> DotGraph
-graphviz t g = graphToDot g attrs nattrs eattrs
+-- | Turns the graph into 'DotGraph' format with the given title and graph
+--   attributes.  Nodes are labelled, edges aren't.
+graphviz        :: (Graph g, Show a, Ord b) => String -> g a b -> [Attribute]
+                -> DotGraph
+graphviz t g as = graphToDot g attrs nattrs eattrs
     where
-      attrs = [Label t]
+      attrs = Label t : as
       nattrs (_,a) = [Label (show a)]
       eattrs _ = []
 
--- | Turns the graph into 'DotGraph' format with the given title.
---   Cluster the nodes based upon their 'ClusterLabel' clusters.
+-- | Turns the graph into 'DotGraph' format with the given title and graph
+--   attributes.  Cluster the nodes based upon their 'ClusterLabel' clusters.
 --   Nodes and clusters are labelled, edges aren't.
 graphvizClusters :: (Graph g, Show c, ClusterLabel a c, Ord b) =>
-                    String -> g a b -> DotGraph
-graphvizClusters t g = clusterGraphToDot g atts assignCluster catts natts eatts
+                    String -> g a b -> [Attribute] -> DotGraph
+graphvizClusters t g as = clusterGraphToDot g atts assignCluster cas nas eas
     where
-      atts = [Label t]
-      catts c = [Label (show c)]
-      natts (_,a) = [Label (nodelabel a)]
-      eatts _ = []
+      atts = Label t : as
+      cas c = [Label (show c)]
+      nas (_,a) = [Label (nodelabel a)]
+      eas _ = []
 
 -- | The possible Graphviz outputs, obtained by running /dot -Txxx/.
 --   Note that it is not possible to choose between output variants,
diff --git a/Graphalyze.cabal b/Graphalyze.cabal
--- a/Graphalyze.cabal
+++ b/Graphalyze.cabal
@@ -1,5 +1,5 @@
 Name:                Graphalyze
-Version:             0.3
+Version:             0.4
 Synopsis:            Graph-Theoretic Analysis library.
 Description:         A library to use graph theory to analyse the relationships
                         inherent in discrete data.
