{- |
   Module      : Data.GraphViz.Types.Canonical
   Description : The canonical representation of Dot graphs.
   Copyright   : (c) Matthew Sackman, Ivan Lazar Miljenovic
   License     : 3-Clause BSD-style
   Maintainer  : Ivan.Miljenovic@gmail.com

   A canonical Dot graph requires that within each graph/sub-graph,
   the statements are in the following order:

   * global attributes

   * sub-graphs/clusters

   * nodes

   * edges

   This Dot graph representation is ideally suited for converting
   other data structures to Dot form (especially with the help of
   @graphElemsToDot@ from "Data.GraphViz").

   If you require arbitrary ordering of statements, then use
   "Data.GraphViz.Types.Generalised".

   The sample graph could be implemented (this is actually the result
   of calling @canonicalise@ from "Data.GraphViz.Algorithms" on the
   generalised one) as:

   > DotGraph { strictGraph = False
   >          , directedGraph = True
   >          , graphID = Just (Str "G")
   >          , graphStatements = DotStmts { attrStmts = []
   >                                       , subGraphs = [ DotSG { isCluster = True
   >                                                             , subGraphID = Just (Num (Int 0))
   >                                                             , subGraphStmts = DotStmts { attrStmts = [ GraphAttrs [ style filled
   >                                                                                                                   , color LightGray
   >                                                                                                                   , textLabel "process #1"]
   >                                                                                                      , NodeAttrs [style filled, color White]]
   >                                                                                        , subGraphs = []
   >                                                                                        , nodeStmts = [ DotNode "a0" []
   >                                                                                                      , DotNode "a1" []
   >                                                                                                      , DotNode "a2" []
   >                                                                                                      , DotNode "a3" []]
   >                                                                                        , edgeStmts = [ DotEdge "a0" "a1" []
   >                                                                                                      , DotEdge "a1" "a2" []
   >                                                                                                      , DotEdge "a2" "a3" []
   >                                                                                                      , DotEdge "a3" "a0" []]}}
   >                                                     , DotSG { isCluster = True
   >                                                             , subGraphID = Just (Num (Int 1))
   >                                                             , subGraphStmts = DotStmts { attrStmts = [ GraphAttrs [textLabel "process #2", color Blue]
   >                                                                                                      , NodeAttrs [style filled]]
   >                                                                                        , subGraphs = []
   >                                                                                        , nodeStmts = [ DotNode "b0" []
   >                                                                                                      , DotNode "b1" []
   >                                                                                                      , DotNode "b2" []
   >                                                                                                      , DotNode "b3" []]
   >                                                                                        , edgeStmts = [ DotEdge "b0" "b1" []
   >                                                                                                      , DotEdge "b1" "b2" []
   >                                                                                                      , DotEdge "b2" "b3" []]}}]
   >                                       , nodeStmts = [ DotNode "end" [shape MSquare]
   >                                                     , DotNode "start" [shape MDiamond]]
   >                                       , edgeStmts = [ DotEdge "start" "a0" []
   >                                                     , DotEdge "start" "b0" []
   >                                                     , DotEdge "a1" "b3" []
   >                                                     , DotEdge "b2" "a3" []
   >                                                     , DotEdge "a3" "end" []
   >                                                     , DotEdge "b3" "end" []]}}

   Note that whilst the above graph represents the same Dot graph as
   specified in "Data.GraphViz.Types.Generalised", etc., it /may/ be
   drawn slightly differently by the various Graphviz tools.

 -}
module Data.GraphViz.Types.Canonical
       ( DotGraph(..)
         -- * Sub-components of a @DotGraph@.
       , DotStatements(..)
       , DotSubGraph(..)
         -- * Re-exported from @Data.GraphViz.Types@
       , GraphID(..)
       , GlobalAttributes(..)
       , DotNode(..)
       , DotEdge(..)
       ) where

import Data.GraphViz.Internal.State        (AttributeType (..))
import Data.GraphViz.Internal.Util         (bool)
import Data.GraphViz.Parsing
import Data.GraphViz.Printing
import Data.GraphViz.Types.Internal.Common

import Control.Arrow ((&&&))

-- -----------------------------------------------------------------------------

-- | A Dot graph in canonical form.
data DotGraph n = DotGraph { forall n. DotGraph n -> Bool
strictGraph     :: Bool  -- ^ If 'True', no multiple edges are drawn.
                           , forall n. DotGraph n -> Bool
directedGraph   :: Bool
                           , forall n. DotGraph n -> Maybe GraphID
graphID         :: Maybe GraphID
                           , forall n. DotGraph n -> DotStatements n
graphStatements :: DotStatements n
                           }
                deriving (DotGraph n -> DotGraph n -> Bool
(DotGraph n -> DotGraph n -> Bool)
-> (DotGraph n -> DotGraph n -> Bool) -> Eq (DotGraph n)
forall n. Eq n => DotGraph n -> DotGraph n -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall n. Eq n => DotGraph n -> DotGraph n -> Bool
== :: DotGraph n -> DotGraph n -> Bool
$c/= :: forall n. Eq n => DotGraph n -> DotGraph n -> Bool
/= :: DotGraph n -> DotGraph n -> Bool
Eq, Eq (DotGraph n)
Eq (DotGraph n) =>
(DotGraph n -> DotGraph n -> Ordering)
-> (DotGraph n -> DotGraph n -> Bool)
-> (DotGraph n -> DotGraph n -> Bool)
-> (DotGraph n -> DotGraph n -> Bool)
-> (DotGraph n -> DotGraph n -> Bool)
-> (DotGraph n -> DotGraph n -> DotGraph n)
-> (DotGraph n -> DotGraph n -> DotGraph n)
-> Ord (DotGraph n)
DotGraph n -> DotGraph n -> Bool
DotGraph n -> DotGraph n -> Ordering
DotGraph n -> DotGraph n -> DotGraph n
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall n. Ord n => Eq (DotGraph n)
forall n. Ord n => DotGraph n -> DotGraph n -> Bool
forall n. Ord n => DotGraph n -> DotGraph n -> Ordering
forall n. Ord n => DotGraph n -> DotGraph n -> DotGraph n
$ccompare :: forall n. Ord n => DotGraph n -> DotGraph n -> Ordering
compare :: DotGraph n -> DotGraph n -> Ordering
$c< :: forall n. Ord n => DotGraph n -> DotGraph n -> Bool
< :: DotGraph n -> DotGraph n -> Bool
$c<= :: forall n. Ord n => DotGraph n -> DotGraph n -> Bool
<= :: DotGraph n -> DotGraph n -> Bool
$c> :: forall n. Ord n => DotGraph n -> DotGraph n -> Bool
> :: DotGraph n -> DotGraph n -> Bool
$c>= :: forall n. Ord n => DotGraph n -> DotGraph n -> Bool
>= :: DotGraph n -> DotGraph n -> Bool
$cmax :: forall n. Ord n => DotGraph n -> DotGraph n -> DotGraph n
max :: DotGraph n -> DotGraph n -> DotGraph n
$cmin :: forall n. Ord n => DotGraph n -> DotGraph n -> DotGraph n
min :: DotGraph n -> DotGraph n -> DotGraph n
Ord, Int -> DotGraph n -> ShowS
[DotGraph n] -> ShowS
DotGraph n -> String
(Int -> DotGraph n -> ShowS)
-> (DotGraph n -> String)
-> ([DotGraph n] -> ShowS)
-> Show (DotGraph n)
forall n. Show n => Int -> DotGraph n -> ShowS
forall n. Show n => [DotGraph n] -> ShowS
forall n. Show n => DotGraph n -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall n. Show n => Int -> DotGraph n -> ShowS
showsPrec :: Int -> DotGraph n -> ShowS
$cshow :: forall n. Show n => DotGraph n -> String
show :: DotGraph n -> String
$cshowList :: forall n. Show n => [DotGraph n] -> ShowS
showList :: [DotGraph n] -> ShowS
Show, ReadPrec [DotGraph n]
ReadPrec (DotGraph n)
Int -> ReadS (DotGraph n)
ReadS [DotGraph n]
(Int -> ReadS (DotGraph n))
-> ReadS [DotGraph n]
-> ReadPrec (DotGraph n)
-> ReadPrec [DotGraph n]
-> Read (DotGraph n)
forall n. Read n => ReadPrec [DotGraph n]
forall n. Read n => ReadPrec (DotGraph n)
forall n. Read n => Int -> ReadS (DotGraph n)
forall n. Read n => ReadS [DotGraph n]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: forall n. Read n => Int -> ReadS (DotGraph n)
readsPrec :: Int -> ReadS (DotGraph n)
$creadList :: forall n. Read n => ReadS [DotGraph n]
readList :: ReadS [DotGraph n]
$creadPrec :: forall n. Read n => ReadPrec (DotGraph n)
readPrec :: ReadPrec (DotGraph n)
$creadListPrec :: forall n. Read n => ReadPrec [DotGraph n]
readListPrec :: ReadPrec [DotGraph n]
Read)

instance (PrintDot n) => PrintDot (DotGraph n) where
  unqtDot :: DotGraph n -> DotCode
unqtDot = (DotGraph n -> DotCode)
-> (DotGraph n -> AttributeType)
-> (DotGraph n -> DotStatements n)
-> (DotStatements n -> DotCode)
-> DotGraph n
-> DotCode
forall a stmts.
(a -> DotCode)
-> (a -> AttributeType)
-> (a -> stmts)
-> (stmts -> DotCode)
-> a
-> DotCode
printStmtBased DotGraph n -> DotCode
forall {n}. DotGraph n -> DotCode
printGraphID' (AttributeType -> DotGraph n -> AttributeType
forall a b. a -> b -> a
const AttributeType
GraphAttribute)
                           DotGraph n -> DotStatements n
forall n. DotGraph n -> DotStatements n
graphStatements DotStatements n -> DotCode
forall a. PrintDot a => a -> DotCode
toDot
    where
      printGraphID' :: DotGraph n -> DotCode
printGraphID' = (DotGraph n -> Bool)
-> (DotGraph n -> Bool)
-> (DotGraph n -> Maybe GraphID)
-> DotGraph n
-> DotCode
forall a.
(a -> Bool) -> (a -> Bool) -> (a -> Maybe GraphID) -> a -> DotCode
printGraphID DotGraph n -> Bool
forall n. DotGraph n -> Bool
strictGraph DotGraph n -> Bool
forall n. DotGraph n -> Bool
directedGraph DotGraph n -> Maybe GraphID
forall n. DotGraph n -> Maybe GraphID
graphID

instance (ParseDot n) => ParseDot (DotGraph n) where
  parseUnqt :: Parse (DotGraph n)
parseUnqt = (Bool -> Bool -> Maybe GraphID -> DotStatements n -> DotGraph n)
-> Parse (DotStatements n -> DotGraph n)
forall a. (Bool -> Bool -> Maybe GraphID -> a) -> Parse a
parseGraphID Bool -> Bool -> Maybe GraphID -> DotStatements n -> DotGraph n
forall n.
Bool -> Bool -> Maybe GraphID -> DotStatements n -> DotGraph n
DotGraph
              Parse (DotStatements n -> DotGraph n)
-> Parser GraphvizState (DotStatements n) -> Parse (DotGraph n)
forall a b.
Parser GraphvizState (a -> b)
-> Parser GraphvizState a -> Parser GraphvizState b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> AttributeType
-> Parser GraphvizState (DotStatements n)
-> Parser GraphvizState (DotStatements n)
forall a. AttributeType -> Parse a -> Parse a
parseBracesBased AttributeType
GraphAttribute Parser GraphvizState (DotStatements n)
forall a. ParseDot a => Parse a
parseUnqt

  parse :: Parse (DotGraph n)
parse = Parse (DotGraph n)
forall a. ParseDot a => Parse a
parseUnqt -- Don't want the option of quoting

-- | Assumed to be an injective mapping function.
instance Functor DotGraph where
  fmap :: forall a b. (a -> b) -> DotGraph a -> DotGraph b
fmap a -> b
f DotGraph a
g = DotGraph a
g { graphStatements = fmap f $ graphStatements g }

-- -----------------------------------------------------------------------------

data DotStatements n = DotStmts { forall n. DotStatements n -> [GlobalAttributes]
attrStmts :: [GlobalAttributes]
                                , forall n. DotStatements n -> [DotSubGraph n]
subGraphs :: [DotSubGraph n]
                                , forall n. DotStatements n -> [DotNode n]
nodeStmts :: [DotNode n]
                                , forall n. DotStatements n -> [DotEdge n]
edgeStmts :: [DotEdge n]
                                }
                     deriving (DotStatements n -> DotStatements n -> Bool
(DotStatements n -> DotStatements n -> Bool)
-> (DotStatements n -> DotStatements n -> Bool)
-> Eq (DotStatements n)
forall n. Eq n => DotStatements n -> DotStatements n -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall n. Eq n => DotStatements n -> DotStatements n -> Bool
== :: DotStatements n -> DotStatements n -> Bool
$c/= :: forall n. Eq n => DotStatements n -> DotStatements n -> Bool
/= :: DotStatements n -> DotStatements n -> Bool
Eq, Eq (DotStatements n)
Eq (DotStatements n) =>
(DotStatements n -> DotStatements n -> Ordering)
-> (DotStatements n -> DotStatements n -> Bool)
-> (DotStatements n -> DotStatements n -> Bool)
-> (DotStatements n -> DotStatements n -> Bool)
-> (DotStatements n -> DotStatements n -> Bool)
-> (DotStatements n -> DotStatements n -> DotStatements n)
-> (DotStatements n -> DotStatements n -> DotStatements n)
-> Ord (DotStatements n)
DotStatements n -> DotStatements n -> Bool
DotStatements n -> DotStatements n -> Ordering
DotStatements n -> DotStatements n -> DotStatements n
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall n. Ord n => Eq (DotStatements n)
forall n. Ord n => DotStatements n -> DotStatements n -> Bool
forall n. Ord n => DotStatements n -> DotStatements n -> Ordering
forall n.
Ord n =>
DotStatements n -> DotStatements n -> DotStatements n
$ccompare :: forall n. Ord n => DotStatements n -> DotStatements n -> Ordering
compare :: DotStatements n -> DotStatements n -> Ordering
$c< :: forall n. Ord n => DotStatements n -> DotStatements n -> Bool
< :: DotStatements n -> DotStatements n -> Bool
$c<= :: forall n. Ord n => DotStatements n -> DotStatements n -> Bool
<= :: DotStatements n -> DotStatements n -> Bool
$c> :: forall n. Ord n => DotStatements n -> DotStatements n -> Bool
> :: DotStatements n -> DotStatements n -> Bool
$c>= :: forall n. Ord n => DotStatements n -> DotStatements n -> Bool
>= :: DotStatements n -> DotStatements n -> Bool
$cmax :: forall n.
Ord n =>
DotStatements n -> DotStatements n -> DotStatements n
max :: DotStatements n -> DotStatements n -> DotStatements n
$cmin :: forall n.
Ord n =>
DotStatements n -> DotStatements n -> DotStatements n
min :: DotStatements n -> DotStatements n -> DotStatements n
Ord, Int -> DotStatements n -> ShowS
[DotStatements n] -> ShowS
DotStatements n -> String
(Int -> DotStatements n -> ShowS)
-> (DotStatements n -> String)
-> ([DotStatements n] -> ShowS)
-> Show (DotStatements n)
forall n. Show n => Int -> DotStatements n -> ShowS
forall n. Show n => [DotStatements n] -> ShowS
forall n. Show n => DotStatements n -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall n. Show n => Int -> DotStatements n -> ShowS
showsPrec :: Int -> DotStatements n -> ShowS
$cshow :: forall n. Show n => DotStatements n -> String
show :: DotStatements n -> String
$cshowList :: forall n. Show n => [DotStatements n] -> ShowS
showList :: [DotStatements n] -> ShowS
Show, ReadPrec [DotStatements n]
ReadPrec (DotStatements n)
Int -> ReadS (DotStatements n)
ReadS [DotStatements n]
(Int -> ReadS (DotStatements n))
-> ReadS [DotStatements n]
-> ReadPrec (DotStatements n)
-> ReadPrec [DotStatements n]
-> Read (DotStatements n)
forall n. Read n => ReadPrec [DotStatements n]
forall n. Read n => ReadPrec (DotStatements n)
forall n. Read n => Int -> ReadS (DotStatements n)
forall n. Read n => ReadS [DotStatements n]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: forall n. Read n => Int -> ReadS (DotStatements n)
readsPrec :: Int -> ReadS (DotStatements n)
$creadList :: forall n. Read n => ReadS [DotStatements n]
readList :: ReadS [DotStatements n]
$creadPrec :: forall n. Read n => ReadPrec (DotStatements n)
readPrec :: ReadPrec (DotStatements n)
$creadListPrec :: forall n. Read n => ReadPrec [DotStatements n]
readListPrec :: ReadPrec [DotStatements n]
Read)

instance (PrintDot n) => PrintDot (DotStatements n) where
  unqtDot :: DotStatements n -> DotCode
unqtDot DotStatements n
stmts = DotCodeM [Doc] -> DotCode
forall (m :: * -> *). Functor m => m [Doc] -> m Doc
vcat (DotCodeM [Doc] -> DotCode) -> DotCodeM [Doc] -> DotCode
forall a b. (a -> b) -> a -> b
$ [DotCode] -> DotCodeM [Doc]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence [ [GlobalAttributes] -> DotCode
forall a. PrintDot a => a -> DotCode
unqtDot ([GlobalAttributes] -> DotCode) -> [GlobalAttributes] -> DotCode
forall a b. (a -> b) -> a -> b
$ DotStatements n -> [GlobalAttributes]
forall n. DotStatements n -> [GlobalAttributes]
attrStmts DotStatements n
stmts
                                  , [DotSubGraph n] -> DotCode
forall a. PrintDot a => a -> DotCode
unqtDot ([DotSubGraph n] -> DotCode) -> [DotSubGraph n] -> DotCode
forall a b. (a -> b) -> a -> b
$ DotStatements n -> [DotSubGraph n]
forall n. DotStatements n -> [DotSubGraph n]
subGraphs DotStatements n
stmts
                                  , [DotNode n] -> DotCode
forall a. PrintDot a => a -> DotCode
unqtDot ([DotNode n] -> DotCode) -> [DotNode n] -> DotCode
forall a b. (a -> b) -> a -> b
$ DotStatements n -> [DotNode n]
forall n. DotStatements n -> [DotNode n]
nodeStmts DotStatements n
stmts
                                  , [DotEdge n] -> DotCode
forall a. PrintDot a => a -> DotCode
unqtDot ([DotEdge n] -> DotCode) -> [DotEdge n] -> DotCode
forall a b. (a -> b) -> a -> b
$ DotStatements n -> [DotEdge n]
forall n. DotStatements n -> [DotEdge n]
edgeStmts DotStatements n
stmts
                                  ]

instance (ParseDot n) => ParseDot (DotStatements n) where
  parseUnqt :: Parse (DotStatements n)
parseUnqt = do [GlobalAttributes]
atts <- Parse [GlobalAttributes]
forall a. ParseDot a => Parse [a]
tryParseList
                 Parse ()
newline'
                 [DotSubGraph n]
sGraphs <- Parse [DotSubGraph n]
forall a. ParseDot a => Parse [a]
tryParseList
                 Parse ()
newline'
                 [DotNode n]
nodes <- Parse [DotNode n]
forall a. ParseDot a => Parse [a]
tryParseList
                 Parse ()
newline'
                 [DotEdge n]
edges <- Parse [DotEdge n]
forall a. ParseDot a => Parse [a]
tryParseList
                 DotStatements n -> Parse (DotStatements n)
forall a. a -> Parser GraphvizState a
forall (m :: * -> *) a. Monad m => a -> m a
return (DotStatements n -> Parse (DotStatements n))
-> DotStatements n -> Parse (DotStatements n)
forall a b. (a -> b) -> a -> b
$ [GlobalAttributes]
-> [DotSubGraph n] -> [DotNode n] -> [DotEdge n] -> DotStatements n
forall n.
[GlobalAttributes]
-> [DotSubGraph n] -> [DotNode n] -> [DotEdge n] -> DotStatements n
DotStmts [GlobalAttributes]
atts [DotSubGraph n]
sGraphs [DotNode n]
nodes [DotEdge n]
edges

  parse :: Parse (DotStatements n)
parse = Parse (DotStatements n)
forall a. ParseDot a => Parse a
parseUnqt -- Don't want the option of quoting
          Parse (DotStatements n) -> ShowS -> Parse (DotStatements n)
forall a. Parser GraphvizState a -> ShowS -> Parser GraphvizState a
forall (p :: * -> *) a. Commitment p => p a -> ShowS -> p a
`adjustErr`
          (String
"Not a valid set of statements\n\t"String -> ShowS
forall a. [a] -> [a] -> [a]
++)

instance Functor DotStatements where
  fmap :: forall a b. (a -> b) -> DotStatements a -> DotStatements b
fmap a -> b
f DotStatements a
stmts = DotStatements a
stmts { subGraphs = map (fmap f) $ subGraphs stmts
                       , nodeStmts = map (fmap f) $ nodeStmts stmts
                       , edgeStmts = map (fmap f) $ edgeStmts stmts
                       }

-- -----------------------------------------------------------------------------

data DotSubGraph n = DotSG { forall n. DotSubGraph n -> Bool
isCluster     :: Bool
                           , forall n. DotSubGraph n -> Maybe GraphID
subGraphID    :: Maybe GraphID
                           , forall n. DotSubGraph n -> DotStatements n
subGraphStmts :: DotStatements n
                           }
                   deriving (DotSubGraph n -> DotSubGraph n -> Bool
(DotSubGraph n -> DotSubGraph n -> Bool)
-> (DotSubGraph n -> DotSubGraph n -> Bool) -> Eq (DotSubGraph n)
forall n. Eq n => DotSubGraph n -> DotSubGraph n -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall n. Eq n => DotSubGraph n -> DotSubGraph n -> Bool
== :: DotSubGraph n -> DotSubGraph n -> Bool
$c/= :: forall n. Eq n => DotSubGraph n -> DotSubGraph n -> Bool
/= :: DotSubGraph n -> DotSubGraph n -> Bool
Eq, Eq (DotSubGraph n)
Eq (DotSubGraph n) =>
(DotSubGraph n -> DotSubGraph n -> Ordering)
-> (DotSubGraph n -> DotSubGraph n -> Bool)
-> (DotSubGraph n -> DotSubGraph n -> Bool)
-> (DotSubGraph n -> DotSubGraph n -> Bool)
-> (DotSubGraph n -> DotSubGraph n -> Bool)
-> (DotSubGraph n -> DotSubGraph n -> DotSubGraph n)
-> (DotSubGraph n -> DotSubGraph n -> DotSubGraph n)
-> Ord (DotSubGraph n)
DotSubGraph n -> DotSubGraph n -> Bool
DotSubGraph n -> DotSubGraph n -> Ordering
DotSubGraph n -> DotSubGraph n -> DotSubGraph n
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall n. Ord n => Eq (DotSubGraph n)
forall n. Ord n => DotSubGraph n -> DotSubGraph n -> Bool
forall n. Ord n => DotSubGraph n -> DotSubGraph n -> Ordering
forall n. Ord n => DotSubGraph n -> DotSubGraph n -> DotSubGraph n
$ccompare :: forall n. Ord n => DotSubGraph n -> DotSubGraph n -> Ordering
compare :: DotSubGraph n -> DotSubGraph n -> Ordering
$c< :: forall n. Ord n => DotSubGraph n -> DotSubGraph n -> Bool
< :: DotSubGraph n -> DotSubGraph n -> Bool
$c<= :: forall n. Ord n => DotSubGraph n -> DotSubGraph n -> Bool
<= :: DotSubGraph n -> DotSubGraph n -> Bool
$c> :: forall n. Ord n => DotSubGraph n -> DotSubGraph n -> Bool
> :: DotSubGraph n -> DotSubGraph n -> Bool
$c>= :: forall n. Ord n => DotSubGraph n -> DotSubGraph n -> Bool
>= :: DotSubGraph n -> DotSubGraph n -> Bool
$cmax :: forall n. Ord n => DotSubGraph n -> DotSubGraph n -> DotSubGraph n
max :: DotSubGraph n -> DotSubGraph n -> DotSubGraph n
$cmin :: forall n. Ord n => DotSubGraph n -> DotSubGraph n -> DotSubGraph n
min :: DotSubGraph n -> DotSubGraph n -> DotSubGraph n
Ord, Int -> DotSubGraph n -> ShowS
[DotSubGraph n] -> ShowS
DotSubGraph n -> String
(Int -> DotSubGraph n -> ShowS)
-> (DotSubGraph n -> String)
-> ([DotSubGraph n] -> ShowS)
-> Show (DotSubGraph n)
forall n. Show n => Int -> DotSubGraph n -> ShowS
forall n. Show n => [DotSubGraph n] -> ShowS
forall n. Show n => DotSubGraph n -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall n. Show n => Int -> DotSubGraph n -> ShowS
showsPrec :: Int -> DotSubGraph n -> ShowS
$cshow :: forall n. Show n => DotSubGraph n -> String
show :: DotSubGraph n -> String
$cshowList :: forall n. Show n => [DotSubGraph n] -> ShowS
showList :: [DotSubGraph n] -> ShowS
Show, ReadPrec [DotSubGraph n]
ReadPrec (DotSubGraph n)
Int -> ReadS (DotSubGraph n)
ReadS [DotSubGraph n]
(Int -> ReadS (DotSubGraph n))
-> ReadS [DotSubGraph n]
-> ReadPrec (DotSubGraph n)
-> ReadPrec [DotSubGraph n]
-> Read (DotSubGraph n)
forall n. Read n => ReadPrec [DotSubGraph n]
forall n. Read n => ReadPrec (DotSubGraph n)
forall n. Read n => Int -> ReadS (DotSubGraph n)
forall n. Read n => ReadS [DotSubGraph n]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: forall n. Read n => Int -> ReadS (DotSubGraph n)
readsPrec :: Int -> ReadS (DotSubGraph n)
$creadList :: forall n. Read n => ReadS [DotSubGraph n]
readList :: ReadS [DotSubGraph n]
$creadPrec :: forall n. Read n => ReadPrec (DotSubGraph n)
readPrec :: ReadPrec (DotSubGraph n)
$creadListPrec :: forall n. Read n => ReadPrec [DotSubGraph n]
readListPrec :: ReadPrec [DotSubGraph n]
Read)

instance (PrintDot n) => PrintDot (DotSubGraph n) where
  unqtDot :: DotSubGraph n -> DotCode
unqtDot = (DotSubGraph n -> DotCode)
-> (DotSubGraph n -> AttributeType)
-> (DotSubGraph n -> DotStatements n)
-> (DotStatements n -> DotCode)
-> DotSubGraph n
-> DotCode
forall a stmts.
(a -> DotCode)
-> (a -> AttributeType)
-> (a -> stmts)
-> (stmts -> DotCode)
-> a
-> DotCode
printStmtBased DotSubGraph n -> DotCode
forall n. DotSubGraph n -> DotCode
printSubGraphID' DotSubGraph n -> AttributeType
forall n. DotSubGraph n -> AttributeType
subGraphAttrType
                           DotSubGraph n -> DotStatements n
forall n. DotSubGraph n -> DotStatements n
subGraphStmts DotStatements n -> DotCode
forall a. PrintDot a => a -> DotCode
toDot

  unqtListToDot :: [DotSubGraph n] -> DotCode
unqtListToDot = (DotSubGraph n -> DotCode)
-> (DotSubGraph n -> AttributeType)
-> (DotSubGraph n -> DotStatements n)
-> (DotStatements n -> DotCode)
-> [DotSubGraph n]
-> DotCode
forall a stmts.
(a -> DotCode)
-> (a -> AttributeType)
-> (a -> stmts)
-> (stmts -> DotCode)
-> [a]
-> DotCode
printStmtBasedList DotSubGraph n -> DotCode
forall n. DotSubGraph n -> DotCode
printSubGraphID' DotSubGraph n -> AttributeType
forall n. DotSubGraph n -> AttributeType
subGraphAttrType
                                     DotSubGraph n -> DotStatements n
forall n. DotSubGraph n -> DotStatements n
subGraphStmts DotStatements n -> DotCode
forall a. PrintDot a => a -> DotCode
toDot

  listToDot :: [DotSubGraph n] -> DotCode
listToDot = [DotSubGraph n] -> DotCode
forall a. PrintDot a => [a] -> DotCode
unqtListToDot

subGraphAttrType :: DotSubGraph n -> AttributeType
subGraphAttrType :: forall n. DotSubGraph n -> AttributeType
subGraphAttrType = AttributeType -> AttributeType -> Bool -> AttributeType
forall a. a -> a -> Bool -> a
bool AttributeType
SubGraphAttribute AttributeType
ClusterAttribute (Bool -> AttributeType)
-> (DotSubGraph n -> Bool) -> DotSubGraph n -> AttributeType
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DotSubGraph n -> Bool
forall n. DotSubGraph n -> Bool
isCluster

printSubGraphID' :: DotSubGraph n -> DotCode
printSubGraphID' :: forall n. DotSubGraph n -> DotCode
printSubGraphID' = (DotSubGraph n -> (Bool, Maybe GraphID))
-> DotSubGraph n -> DotCode
forall a. (a -> (Bool, Maybe GraphID)) -> a -> DotCode
printSubGraphID (DotSubGraph n -> Bool
forall n. DotSubGraph n -> Bool
isCluster (DotSubGraph n -> Bool)
-> (DotSubGraph n -> Maybe GraphID)
-> DotSubGraph n
-> (Bool, Maybe GraphID)
forall b c c'. (b -> c) -> (b -> c') -> b -> (c, c')
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& DotSubGraph n -> Maybe GraphID
forall n. DotSubGraph n -> Maybe GraphID
subGraphID)

instance (ParseDot n) => ParseDot (DotSubGraph n) where
  parseUnqt :: Parse (DotSubGraph n)
parseUnqt = (Bool -> Maybe GraphID -> DotStatements n -> DotSubGraph n)
-> Parse (DotStatements n) -> Parse (DotSubGraph n)
forall stmt c.
(Bool -> Maybe GraphID -> stmt -> c) -> Parse stmt -> Parse c
parseSubGraph Bool -> Maybe GraphID -> DotStatements n -> DotSubGraph n
forall n. Bool -> Maybe GraphID -> DotStatements n -> DotSubGraph n
DotSG Parse (DotStatements n)
forall a. ParseDot a => Parse a
parseUnqt
              Parse (DotSubGraph n)
-> Parse (DotSubGraph n) -> Parse (DotSubGraph n)
forall s a. Parser s a -> Parser s a -> Parser s a
`onFail`
              -- Take "anonymous" DotSubGraphs into account.
              (DotStatements n -> DotSubGraph n)
-> Parse (DotStatements n) -> Parse (DotSubGraph n)
forall a b.
(a -> b) -> Parser GraphvizState a -> Parser GraphvizState b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Bool -> Maybe GraphID -> DotStatements n -> DotSubGraph n
forall n. Bool -> Maybe GraphID -> DotStatements n -> DotSubGraph n
DotSG Bool
False Maybe GraphID
forall a. Maybe a
Nothing)
                   (AttributeType -> Parse (DotStatements n) -> Parse (DotStatements n)
forall a. AttributeType -> Parse a -> Parse a
parseBracesBased AttributeType
SubGraphAttribute Parse (DotStatements n)
forall a. ParseDot a => Parse a
parseUnqt)

  parse :: Parse (DotSubGraph n)
parse = Parse (DotSubGraph n)
forall a. ParseDot a => Parse a
parseUnqt -- Don't want the option of quoting
          Parse (DotSubGraph n) -> ShowS -> Parse (DotSubGraph n)
forall a. Parser GraphvizState a -> ShowS -> Parser GraphvizState a
forall (p :: * -> *) a. Commitment p => p a -> ShowS -> p a
`adjustErr`
          (String
"Not a valid Sub Graph\n\t"String -> ShowS
forall a. [a] -> [a] -> [a]
++)

  parseUnqtList :: Parse [DotSubGraph n]
parseUnqtList = Parse (DotSubGraph n) -> Parse () -> Parse [DotSubGraph n]
forall (p :: * -> *) a sep. PolyParse p => p a -> p sep -> p [a]
sepBy (Parse ()
whitespace Parse () -> Parse (DotSubGraph n) -> Parse (DotSubGraph n)
forall a b.
Parser GraphvizState a
-> Parser GraphvizState b -> Parser GraphvizState b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parse (DotSubGraph n)
forall a. ParseDot a => Parse a
parseUnqt) Parse ()
newline'

  parseList :: Parse [DotSubGraph n]
parseList = Parse [DotSubGraph n]
forall a. ParseDot a => Parse [a]
parseUnqtList

instance Functor DotSubGraph where
  fmap :: forall a b. (a -> b) -> DotSubGraph a -> DotSubGraph b
fmap a -> b
f DotSubGraph a
sg = DotSubGraph a
sg { subGraphStmts = fmap f $ subGraphStmts sg }