{-# OPTIONS_HADDOCK hide #-} {-# LANGUAGE FlexibleInstances #-} {- | Module : Data.GraphViz.Internal.State Description : Printing and parsing state. Copyright : (c) Ivan Lazar Miljenovic License : 3-Clause BSD-style Maintainer : Ivan.Miljenovic@gmail.com When printing and parsing Dot code, some items depend on values that are set earlier. -} module Data.GraphViz.Internal.State ( GraphvizStateM(..) , GraphvizState(..) , AttributeType(..) , setAttributeType , getAttributeType , initialState , setDirectedness , getDirectedness , setLayerSep , getLayerSep , setLayerListSep , getLayerListSep , setColorScheme , getColorScheme ) where import Data.GraphViz.Attributes.ColorScheme import Text.ParserCombinators.Poly.StateText (Parser, stQuery, stUpdate) -- ----------------------------------------------------------------------------- class (Monad m) => GraphvizStateM m where modifyGS :: (GraphvizState -> GraphvizState) -> m () getsGS :: (GraphvizState -> a) -> m a instance GraphvizStateM (Parser GraphvizState) where modifyGS = stUpdate getsGS = stQuery data AttributeType = GraphAttribute | SubGraphAttribute | ClusterAttribute | NodeAttribute | EdgeAttribute deriving (Eq, Ord, Show, Read) -- | Several aspects of Dot code are either global or mutable state. data GraphvizState = GS { parseStrictly :: !Bool -- ^ If 'False', allow fallbacks for -- attributes that don't match known -- specification when parsing. , directedEdges :: !Bool , layerSep :: [Char] , layerListSep :: [Char] , attributeType :: !AttributeType , graphColor :: !ColorScheme , clusterColor :: !ColorScheme , nodeColor :: !ColorScheme , edgeColor :: !ColorScheme } deriving (Eq, Ord, Show, Read) initialState :: GraphvizState initialState = GS { parseStrictly = True , directedEdges = True , layerSep = defLayerSep , layerListSep = defLayerListSep , attributeType = GraphAttribute , graphColor = X11 , clusterColor = X11 , nodeColor = X11 , edgeColor = X11 } setDirectedness :: (GraphvizStateM m) => Bool -> m () setDirectedness d = modifyGS (\ gs -> gs { directedEdges = d } ) getDirectedness :: (GraphvizStateM m) => m Bool getDirectedness = getsGS directedEdges setAttributeType :: (GraphvizStateM m) => AttributeType -> m () setAttributeType tp = modifyGS $ \ gs -> gs { attributeType = tp } getAttributeType :: (GraphvizStateM m) => m AttributeType getAttributeType = getsGS attributeType setLayerSep :: (GraphvizStateM m) => [Char] -> m () setLayerSep sep = modifyGS (\ gs -> gs { layerSep = sep } ) getLayerSep :: (GraphvizStateM m) => m [Char] getLayerSep = getsGS layerSep setLayerListSep :: (GraphvizStateM m) => [Char] -> m () setLayerListSep sep = modifyGS (\ gs -> gs { layerListSep = sep } ) getLayerListSep :: (GraphvizStateM m) => m [Char] getLayerListSep = getsGS layerListSep setColorScheme :: (GraphvizStateM m) => ColorScheme -> m () setColorScheme cs = do tp <- getsGS attributeType modifyGS $ \gs -> case tp of GraphAttribute -> gs { graphColor = cs } -- subgraphs don't have specified scheme SubGraphAttribute -> gs { graphColor = cs } ClusterAttribute -> gs { clusterColor = cs } NodeAttribute -> gs { nodeColor = cs } EdgeAttribute -> gs { edgeColor = cs } getColorScheme :: (GraphvizStateM m) => m ColorScheme getColorScheme = do tp <- getsGS attributeType getsGS $ case tp of GraphAttribute -> graphColor -- subgraphs don't have specified scheme SubGraphAttribute -> graphColor ClusterAttribute -> clusterColor NodeAttribute -> nodeColor EdgeAttribute -> edgeColor -- | The default separators for 'LayerSep'. defLayerSep :: [Char] defLayerSep = [' ', ':', '\t'] -- | The default separators for 'LayerListSep'. defLayerListSep :: [Char] defLayerListSep = [',']