packages feed

graphviz 2009.5.1 → 2999.0.0.0

raw patch · 8 files changed

+2242/−893 lines, 8 filesdep +extensible-exceptionsdep ~basePVP ok

version bump matches the API change (PVP)

Dependencies added: extensible-exceptions

Dependency ranges changed: base

API changes (from Hackage documentation)

- Data.GraphViz.Attributes: BL :: PageDir
- Data.GraphViz.Attributes: BR :: PageDir
- Data.GraphViz.Attributes: Dot :: ArrowType
- Data.GraphViz.Attributes: Dpi :: Double -> Attribute
- Data.GraphViz.Attributes: FitX :: ScaleType
- Data.GraphViz.Attributes: FitY :: ScaleType
- Data.GraphViz.Attributes: LB :: PageDir
- Data.GraphViz.Attributes: LT :: PageDir
- Data.GraphViz.Attributes: Minlen :: Double -> Attribute
- Data.GraphViz.Attributes: Nodesep :: Double -> Attribute
- Data.GraphViz.Attributes: None :: DirType
- Data.GraphViz.Attributes: PointList :: [Point] -> PointList
- Data.GraphViz.Attributes: RB :: PageDir
- Data.GraphViz.Attributes: RT :: PageDir
- Data.GraphViz.Attributes: RankSep :: Double -> Attribute
- Data.GraphViz.Attributes: Scale :: ScaleType
- Data.GraphViz.Attributes: TL :: PageDir
- Data.GraphViz.Attributes: TR :: PageDir
- Data.GraphViz.Attributes: Unknown :: String -> String -> Attribute
- Data.GraphViz.Attributes: data ColorType
- Data.GraphViz.Attributes: data ShapeType
- Data.GraphViz.Attributes: data StyleType
- Data.GraphViz.Attributes: instance Eq ColorType
- Data.GraphViz.Attributes: instance Eq PointList
- Data.GraphViz.Attributes: instance Eq ShapeType
- Data.GraphViz.Attributes: instance Eq StyleType
- Data.GraphViz.Attributes: instance Show ColorType
- Data.GraphViz.Attributes: instance Show PointList
- Data.GraphViz.Attributes: instance Show ShapeType
- Data.GraphViz.Attributes: instance Show StyleType
- Data.GraphViz.Attributes: newtype PointList
- Data.GraphViz.Attributes: readArrowType :: Parser Char ArrowType
- Data.GraphViz.Attributes: readAttribute :: Parser Char Attribute
- Data.GraphViz.Attributes: readAttributesList :: Parser Char [Attribute]
- Data.GraphViz.Attributes: readBool :: Parser Char Bool
- Data.GraphViz.Attributes: readColorType :: Parser Char ColorType
- Data.GraphViz.Attributes: readDirType :: Parser Char DirType
- Data.GraphViz.Attributes: readJustification :: Parser Char Justification
- Data.GraphViz.Attributes: readOutputMode :: Parser Char OutputMode
- Data.GraphViz.Attributes: readPageDir :: Parser Char PageDir
- Data.GraphViz.Attributes: readPoint :: Parser Char Point
- Data.GraphViz.Attributes: readPointList :: Parser Char PointList
- Data.GraphViz.Attributes: readRect :: Parser Char Rect
- Data.GraphViz.Attributes: readScaleType :: Parser Char ScaleType
- Data.GraphViz.Attributes: readShapeType :: Parser Char ShapeType
- Data.GraphViz.Attributes: readString :: Parser Char String
- Data.GraphViz.Attributes: readStyleType :: Parser Char StyleType
- Data.GraphViz.Attributes: readVerticalPlacement :: Parser Char VerticalPlacement
- Data.GraphViz.Commands: DotCmd :: GraphvizCommand
- Data.GraphViz.Types: readDotGraph :: Parser Char DotGraph
+ Data.GraphViz.Attributes: AllLayers :: LayerID
+ Data.GraphViz.Attributes: Aspect :: AspectType -> Attribute
+ Data.GraphViz.Attributes: AspectRatio :: Double -> Ratios
+ Data.GraphViz.Attributes: AutoRatio :: Ratios
+ Data.GraphViz.Attributes: AvgDist :: SmoothType
+ Data.GraphViz.Attributes: Bl :: PageDir
+ Data.GraphViz.Attributes: Br :: PageDir
+ Data.GraphViz.Attributes: CenterPoint :: CompassPoint
+ Data.GraphViz.Attributes: Charset :: String -> Attribute
+ Data.GraphViz.Attributes: ClusterRank :: ClusterMode -> Attribute
+ Data.GraphViz.Attributes: ColorName :: String -> Color
+ Data.GraphViz.Attributes: ColorScheme :: String -> Attribute
+ Data.GraphViz.Attributes: Comment :: String -> Attribute
+ Data.GraphViz.Attributes: Compound :: Bool -> Attribute
+ Data.GraphViz.Attributes: CompressRatio :: Ratios
+ Data.GraphViz.Attributes: DPI :: Double -> Attribute
+ Data.GraphViz.Attributes: Damping :: Double -> Attribute
+ Data.GraphViz.Attributes: Dim :: Int -> Attribute
+ Data.GraphViz.Attributes: Dimen :: Int -> Attribute
+ Data.GraphViz.Attributes: DirEdgeConstraints :: (Either String Bool) -> Attribute
+ Data.GraphViz.Attributes: Distortion :: Double -> Attribute
+ Data.GraphViz.Attributes: DotArrow :: ArrowType
+ Data.GraphViz.Attributes: ESep :: (Either Double Point) -> Attribute
+ Data.GraphViz.Attributes: East :: CompassPoint
+ Data.GraphViz.Attributes: EdgeHref :: URL -> Attribute
+ Data.GraphViz.Attributes: EdgeTarget :: String -> Attribute
+ Data.GraphViz.Attributes: EdgeTooltip :: String -> Attribute
+ Data.GraphViz.Attributes: EdgeURL :: URL -> Attribute
+ Data.GraphViz.Attributes: Epsilon :: Double -> Attribute
+ Data.GraphViz.Attributes: ExpandRatio :: Ratios
+ Data.GraphViz.Attributes: FastQT :: QuadType
+ Data.GraphViz.Attributes: FillBoth :: ScaleType
+ Data.GraphViz.Attributes: FillHeight :: ScaleType
+ Data.GraphViz.Attributes: FillRatio :: Ratios
+ Data.GraphViz.Attributes: FillWidth :: ScaleType
+ Data.GraphViz.Attributes: FontNames :: String -> Attribute
+ Data.GraphViz.Attributes: FontPath :: String -> Attribute
+ Data.GraphViz.Attributes: FromBottom :: RankDir
+ Data.GraphViz.Attributes: FromLeft :: RankDir
+ Data.GraphViz.Attributes: FromRight :: RankDir
+ Data.GraphViz.Attributes: FromTop :: RankDir
+ Data.GraphViz.Attributes: Global :: ClusterMode
+ Data.GraphViz.Attributes: GraphDist :: SmoothType
+ Data.GraphViz.Attributes: HSV :: Int -> Int -> Int -> Color
+ Data.GraphViz.Attributes: HeadHref :: URL -> Attribute
+ Data.GraphViz.Attributes: HeadPort :: PortPos -> Attribute
+ Data.GraphViz.Attributes: HeadTarget :: QuotedString -> Attribute
+ Data.GraphViz.Attributes: HeadTooltip :: QuotedString -> Attribute
+ Data.GraphViz.Attributes: HeadURL :: URL -> Attribute
+ Data.GraphViz.Attributes: Href :: URL -> Attribute
+ Data.GraphViz.Attributes: ID :: (Either String URL) -> Attribute
+ Data.GraphViz.Attributes: K :: Double -> Attribute
+ Data.GraphViz.Attributes: LHead :: String -> Attribute
+ Data.GraphViz.Attributes: LL :: String -> [(String, String)] -> LayerList
+ Data.GraphViz.Attributes: LP :: Point -> Attribute
+ Data.GraphViz.Attributes: LRID :: LayerID -> LayerRange
+ Data.GraphViz.Attributes: LRInt :: Int -> LayerID
+ Data.GraphViz.Attributes: LRName :: String -> LayerID
+ Data.GraphViz.Attributes: LRS :: LayerID -> String -> LayerID -> LayerRange
+ Data.GraphViz.Attributes: LTail :: String -> Attribute
+ Data.GraphViz.Attributes: LabelHref :: URL -> Attribute
+ Data.GraphViz.Attributes: LabelTarget :: String -> Attribute
+ Data.GraphViz.Attributes: LabelTooltip :: String -> Attribute
+ Data.GraphViz.Attributes: LabelURL :: URL -> Attribute
+ Data.GraphViz.Attributes: Layer :: LayerRange -> Attribute
+ Data.GraphViz.Attributes: LayerSep :: String -> Attribute
+ Data.GraphViz.Attributes: Layers :: LayerList -> Attribute
+ Data.GraphViz.Attributes: Layout :: String -> Attribute
+ Data.GraphViz.Attributes: Lb :: PageDir
+ Data.GraphViz.Attributes: Levels :: Int -> Attribute
+ Data.GraphViz.Attributes: LevelsGap :: Double -> Attribute
+ Data.GraphViz.Attributes: Local :: ClusterMode
+ Data.GraphViz.Attributes: Lt :: PageDir
+ Data.GraphViz.Attributes: MCLimit :: Double -> Attribute
+ Data.GraphViz.Attributes: MaxIter :: Int -> Attribute
+ Data.GraphViz.Attributes: MaxRank :: RankType
+ Data.GraphViz.Attributes: MinLen :: Int -> Attribute
+ Data.GraphViz.Attributes: MinRank :: RankType
+ Data.GraphViz.Attributes: Mode :: String -> Attribute
+ Data.GraphViz.Attributes: Model :: String -> Attribute
+ Data.GraphViz.Attributes: Mosek :: Bool -> Attribute
+ Data.GraphViz.Attributes: NoCP :: CompassPoint
+ Data.GraphViz.Attributes: NoCluster :: ClusterMode
+ Data.GraphViz.Attributes: NoDir :: DirType
+ Data.GraphViz.Attributes: NoQT :: QuadType
+ Data.GraphViz.Attributes: NoSmooth :: SmoothType
+ Data.GraphViz.Attributes: NodeName :: String -> FocusType
+ Data.GraphViz.Attributes: NodeSep :: Double -> Attribute
+ Data.GraphViz.Attributes: NormalQT :: QuadType
+ Data.GraphViz.Attributes: North :: CompassPoint
+ Data.GraphViz.Attributes: NorthEast :: CompassPoint
+ Data.GraphViz.Attributes: NorthWest :: CompassPoint
+ Data.GraphViz.Attributes: Nslimit :: Double -> Attribute
+ Data.GraphViz.Attributes: Nslimit1 :: Double -> Attribute
+ Data.GraphViz.Attributes: Ordering :: String -> Attribute
+ Data.GraphViz.Attributes: OrientationGraph :: String -> Attribute
+ Data.GraphViz.Attributes: OverlapScaling :: Double -> Attribute
+ Data.GraphViz.Attributes: PP :: CompassPoint -> PortPos
+ Data.GraphViz.Attributes: Pack :: (Either Bool Int) -> Attribute
+ Data.GraphViz.Attributes: PackArray :: Bool -> Bool -> (Maybe Int) -> PackMode
+ Data.GraphViz.Attributes: PackClust :: PackMode
+ Data.GraphViz.Attributes: PackGraph :: PackMode
+ Data.GraphViz.Attributes: PackMode :: PackMode -> Attribute
+ Data.GraphViz.Attributes: PackNode :: PackMode
+ Data.GraphViz.Attributes: PenWidth :: Double -> Attribute
+ Data.GraphViz.Attributes: Peripheries :: Int -> Attribute
+ Data.GraphViz.Attributes: Pin :: Bool -> Attribute
+ Data.GraphViz.Attributes: PowerDist :: SmoothType
+ Data.GraphViz.Attributes: QS :: String -> QuotedString
+ Data.GraphViz.Attributes: QuadTree :: (Either QuadType Bool) -> Attribute
+ Data.GraphViz.Attributes: RNG :: SmoothType
+ Data.GraphViz.Attributes: Random :: STStyle
+ Data.GraphViz.Attributes: Rank :: RankType -> Attribute
+ Data.GraphViz.Attributes: Ranksep :: Double -> Attribute
+ Data.GraphViz.Attributes: RatioOnly :: Double -> AspectType
+ Data.GraphViz.Attributes: RatioPassCount :: Double -> Int -> AspectType
+ Data.GraphViz.Attributes: Rb :: PageDir
+ Data.GraphViz.Attributes: ReMinCross :: Bool -> Attribute
+ Data.GraphViz.Attributes: Rects :: Rect -> Attribute
+ Data.GraphViz.Attributes: RegularStyle :: STStyle
+ Data.GraphViz.Attributes: RepulsiveForce :: Double -> Attribute
+ Data.GraphViz.Attributes: Resolution :: Double -> Attribute
+ Data.GraphViz.Attributes: Root :: (Either String Bool) -> Attribute
+ Data.GraphViz.Attributes: Rt :: PageDir
+ Data.GraphViz.Attributes: ST :: (Maybe STStyle) -> (Maybe Int) -> StartType
+ Data.GraphViz.Attributes: SameRank :: RankType
+ Data.GraphViz.Attributes: SamplePoints :: Int -> Attribute
+ Data.GraphViz.Attributes: SearchSize :: Int -> Attribute
+ Data.GraphViz.Attributes: Self :: STStyle
+ Data.GraphViz.Attributes: ShapeFile :: String -> Attribute
+ Data.GraphViz.Attributes: ShowBoxes :: Int -> Attribute
+ Data.GraphViz.Attributes: SinkRank :: RankType
+ Data.GraphViz.Attributes: Smoothing :: SmoothType -> Attribute
+ Data.GraphViz.Attributes: SortV :: Int -> Attribute
+ Data.GraphViz.Attributes: SourceRank :: RankType
+ Data.GraphViz.Attributes: South :: CompassPoint
+ Data.GraphViz.Attributes: SouthEast :: CompassPoint
+ Data.GraphViz.Attributes: SouthWest :: CompassPoint
+ Data.GraphViz.Attributes: Spline :: (Maybe Point) -> (Maybe Point) -> [Point] -> Spline
+ Data.GraphViz.Attributes: Spring :: SmoothType
+ Data.GraphViz.Attributes: Start :: StartType -> Attribute
+ Data.GraphViz.Attributes: Stl :: StyleName -> (Maybe String) -> Style
+ Data.GraphViz.Attributes: StyleSheet :: String -> Attribute
+ Data.GraphViz.Attributes: TailHref :: URL -> Attribute
+ Data.GraphViz.Attributes: TailPort :: PortPos -> Attribute
+ Data.GraphViz.Attributes: TailTarget :: String -> Attribute
+ Data.GraphViz.Attributes: TailTooltip :: String -> Attribute
+ Data.GraphViz.Attributes: TailURL :: URL -> Attribute
+ Data.GraphViz.Attributes: Target :: String -> Attribute
+ Data.GraphViz.Attributes: Tl :: PageDir
+ Data.GraphViz.Attributes: Tooltip :: String -> Attribute
+ Data.GraphViz.Attributes: Tr :: PageDir
+ Data.GraphViz.Attributes: TriangleSmooth :: SmoothType
+ Data.GraphViz.Attributes: TrueColor :: Bool -> Attribute
+ Data.GraphViz.Attributes: URL :: URL -> Attribute
+ Data.GraphViz.Attributes: UStr :: String -> URL
+ Data.GraphViz.Attributes: UniformScale :: ScaleType
+ Data.GraphViz.Attributes: VP :: Double -> Double -> Double -> Maybe FocusType -> ViewPort
+ Data.GraphViz.Attributes: Vertices :: [Point] -> Attribute
+ Data.GraphViz.Attributes: ViewPort :: ViewPort -> Attribute
+ Data.GraphViz.Attributes: VoroMargin :: Double -> Attribute
+ Data.GraphViz.Attributes: West :: CompassPoint
+ Data.GraphViz.Attributes: XY :: Point -> FocusType
+ Data.GraphViz.Attributes: Z :: Double -> Attribute
+ Data.GraphViz.Attributes: data AspectType
+ Data.GraphViz.Attributes: data ClusterMode
+ Data.GraphViz.Attributes: data Color
+ Data.GraphViz.Attributes: data CompassPoint
+ Data.GraphViz.Attributes: data FocusType
+ Data.GraphViz.Attributes: data LayerID
+ Data.GraphViz.Attributes: data LayerList
+ Data.GraphViz.Attributes: data LayerRange
+ Data.GraphViz.Attributes: data PackMode
+ Data.GraphViz.Attributes: data QuadType
+ Data.GraphViz.Attributes: data RankDir
+ Data.GraphViz.Attributes: data RankType
+ Data.GraphViz.Attributes: data Ratios
+ Data.GraphViz.Attributes: data STStyle
+ Data.GraphViz.Attributes: data Shape
+ Data.GraphViz.Attributes: data SmoothType
+ Data.GraphViz.Attributes: data Spline
+ Data.GraphViz.Attributes: data StartType
+ Data.GraphViz.Attributes: data Style
+ Data.GraphViz.Attributes: data StyleName
+ Data.GraphViz.Attributes: data ViewPort
+ Data.GraphViz.Attributes: defLayerSep :: [Char]
+ Data.GraphViz.Attributes: focus :: ViewPort -> Maybe FocusType
+ Data.GraphViz.Attributes: hVal :: ViewPort -> Double
+ Data.GraphViz.Attributes: hue :: Color -> Int
+ Data.GraphViz.Attributes: instance Eq AspectType
+ Data.GraphViz.Attributes: instance Eq ClusterMode
+ Data.GraphViz.Attributes: instance Eq Color
+ Data.GraphViz.Attributes: instance Eq CompassPoint
+ Data.GraphViz.Attributes: instance Eq FocusType
+ Data.GraphViz.Attributes: instance Eq LayerID
+ Data.GraphViz.Attributes: instance Eq LayerList
+ Data.GraphViz.Attributes: instance Eq LayerRange
+ Data.GraphViz.Attributes: instance Eq PackMode
+ Data.GraphViz.Attributes: instance Eq PortPos
+ Data.GraphViz.Attributes: instance Eq QuadType
+ Data.GraphViz.Attributes: instance Eq QuotedString
+ Data.GraphViz.Attributes: instance Eq RankDir
+ Data.GraphViz.Attributes: instance Eq RankType
+ Data.GraphViz.Attributes: instance Eq Ratios
+ Data.GraphViz.Attributes: instance Eq STStyle
+ Data.GraphViz.Attributes: instance Eq Shape
+ Data.GraphViz.Attributes: instance Eq SmoothType
+ Data.GraphViz.Attributes: instance Eq Spline
+ Data.GraphViz.Attributes: instance Eq StartType
+ Data.GraphViz.Attributes: instance Eq Style
+ Data.GraphViz.Attributes: instance Eq StyleName
+ Data.GraphViz.Attributes: instance Eq URL
+ Data.GraphViz.Attributes: instance Eq ViewPort
+ Data.GraphViz.Attributes: instance Parseable ArrowType
+ Data.GraphViz.Attributes: instance Parseable AspectType
+ Data.GraphViz.Attributes: instance Parseable Attribute
+ Data.GraphViz.Attributes: instance Parseable ClusterMode
+ Data.GraphViz.Attributes: instance Parseable Color
+ Data.GraphViz.Attributes: instance Parseable CompassPoint
+ Data.GraphViz.Attributes: instance Parseable DirType
+ Data.GraphViz.Attributes: instance Parseable FocusType
+ Data.GraphViz.Attributes: instance Parseable Justification
+ Data.GraphViz.Attributes: instance Parseable LayerID
+ Data.GraphViz.Attributes: instance Parseable LayerList
+ Data.GraphViz.Attributes: instance Parseable LayerRange
+ Data.GraphViz.Attributes: instance Parseable OutputMode
+ Data.GraphViz.Attributes: instance Parseable PackMode
+ Data.GraphViz.Attributes: instance Parseable PageDir
+ Data.GraphViz.Attributes: instance Parseable Point
+ Data.GraphViz.Attributes: instance Parseable PortPos
+ Data.GraphViz.Attributes: instance Parseable QuadType
+ Data.GraphViz.Attributes: instance Parseable QuotedString
+ Data.GraphViz.Attributes: instance Parseable RankDir
+ Data.GraphViz.Attributes: instance Parseable RankType
+ Data.GraphViz.Attributes: instance Parseable Ratios
+ Data.GraphViz.Attributes: instance Parseable Rect
+ Data.GraphViz.Attributes: instance Parseable STStyle
+ Data.GraphViz.Attributes: instance Parseable ScaleType
+ Data.GraphViz.Attributes: instance Parseable Shape
+ Data.GraphViz.Attributes: instance Parseable SmoothType
+ Data.GraphViz.Attributes: instance Parseable Spline
+ Data.GraphViz.Attributes: instance Parseable StartType
+ Data.GraphViz.Attributes: instance Parseable Style
+ Data.GraphViz.Attributes: instance Parseable StyleName
+ Data.GraphViz.Attributes: instance Parseable URL
+ Data.GraphViz.Attributes: instance Parseable VerticalPlacement
+ Data.GraphViz.Attributes: instance Parseable ViewPort
+ Data.GraphViz.Attributes: instance Read ArrowType
+ Data.GraphViz.Attributes: instance Read AspectType
+ Data.GraphViz.Attributes: instance Read Attribute
+ Data.GraphViz.Attributes: instance Read ClusterMode
+ Data.GraphViz.Attributes: instance Read Color
+ Data.GraphViz.Attributes: instance Read CompassPoint
+ Data.GraphViz.Attributes: instance Read DirType
+ Data.GraphViz.Attributes: instance Read FocusType
+ Data.GraphViz.Attributes: instance Read Justification
+ Data.GraphViz.Attributes: instance Read LayerID
+ Data.GraphViz.Attributes: instance Read LayerList
+ Data.GraphViz.Attributes: instance Read LayerRange
+ Data.GraphViz.Attributes: instance Read OutputMode
+ Data.GraphViz.Attributes: instance Read PackMode
+ Data.GraphViz.Attributes: instance Read PageDir
+ Data.GraphViz.Attributes: instance Read Point
+ Data.GraphViz.Attributes: instance Read PortPos
+ Data.GraphViz.Attributes: instance Read QuadType
+ Data.GraphViz.Attributes: instance Read QuotedString
+ Data.GraphViz.Attributes: instance Read RankDir
+ Data.GraphViz.Attributes: instance Read RankType
+ Data.GraphViz.Attributes: instance Read Ratios
+ Data.GraphViz.Attributes: instance Read Rect
+ Data.GraphViz.Attributes: instance Read STStyle
+ Data.GraphViz.Attributes: instance Read ScaleType
+ Data.GraphViz.Attributes: instance Read Shape
+ Data.GraphViz.Attributes: instance Read SmoothType
+ Data.GraphViz.Attributes: instance Read Spline
+ Data.GraphViz.Attributes: instance Read StartType
+ Data.GraphViz.Attributes: instance Read Style
+ Data.GraphViz.Attributes: instance Read StyleName
+ Data.GraphViz.Attributes: instance Read URL
+ Data.GraphViz.Attributes: instance Read VerticalPlacement
+ Data.GraphViz.Attributes: instance Read ViewPort
+ Data.GraphViz.Attributes: instance Show AspectType
+ Data.GraphViz.Attributes: instance Show ClusterMode
+ Data.GraphViz.Attributes: instance Show Color
+ Data.GraphViz.Attributes: instance Show CompassPoint
+ Data.GraphViz.Attributes: instance Show FocusType
+ Data.GraphViz.Attributes: instance Show LayerID
+ Data.GraphViz.Attributes: instance Show LayerList
+ Data.GraphViz.Attributes: instance Show LayerRange
+ Data.GraphViz.Attributes: instance Show PackMode
+ Data.GraphViz.Attributes: instance Show PortPos
+ Data.GraphViz.Attributes: instance Show QuadType
+ Data.GraphViz.Attributes: instance Show QuotedString
+ Data.GraphViz.Attributes: instance Show RankDir
+ Data.GraphViz.Attributes: instance Show RankType
+ Data.GraphViz.Attributes: instance Show Ratios
+ Data.GraphViz.Attributes: instance Show STStyle
+ Data.GraphViz.Attributes: instance Show Shape
+ Data.GraphViz.Attributes: instance Show SmoothType
+ Data.GraphViz.Attributes: instance Show Spline
+ Data.GraphViz.Attributes: instance Show StartType
+ Data.GraphViz.Attributes: instance Show Style
+ Data.GraphViz.Attributes: instance Show StyleName
+ Data.GraphViz.Attributes: instance Show URL
+ Data.GraphViz.Attributes: instance Show ViewPort
+ Data.GraphViz.Attributes: newtype PortPos
+ Data.GraphViz.Attributes: newtype QuotedString
+ Data.GraphViz.Attributes: newtype URL
+ Data.GraphViz.Attributes: parseColor :: Parse Color
+ Data.GraphViz.Attributes: parseLayerName :: Parse String
+ Data.GraphViz.Attributes: parseLayerSep :: Parse String
+ Data.GraphViz.Attributes: parsePoint :: Parse Point
+ Data.GraphViz.Attributes: parseSpline :: Parse Spline
+ Data.GraphViz.Attributes: qStr :: QuotedString -> String
+ Data.GraphViz.Attributes: saturation :: Color -> Int
+ Data.GraphViz.Attributes: showColor :: Color -> String
+ Data.GraphViz.Attributes: showPoint :: Point -> String
+ Data.GraphViz.Attributes: showSpline :: Spline -> String
+ Data.GraphViz.Attributes: urlString :: URL -> String
+ Data.GraphViz.Attributes: usedByClusters :: Attribute -> Bool
+ Data.GraphViz.Attributes: usedByEdges :: Attribute -> Bool
+ Data.GraphViz.Attributes: usedByGraphs :: Attribute -> Bool
+ Data.GraphViz.Attributes: usedByNodes :: Attribute -> Bool
+ Data.GraphViz.Attributes: usedBySubGraphs :: Attribute -> Bool
+ Data.GraphViz.Attributes: value :: Color -> Int
+ Data.GraphViz.Attributes: wVal :: ViewPort -> Double
+ Data.GraphViz.Attributes: zVal :: ViewPort -> Double
+ Data.GraphViz.Commands: Dot :: GraphvizCommand
+ Data.GraphViz.ParserCombinators: char :: Char -> Parse Char
+ Data.GraphViz.ParserCombinators: class Parseable a
+ Data.GraphViz.ParserCombinators: commaSep :: (Parseable a, Parseable b) => Parse (a, b)
+ Data.GraphViz.ParserCombinators: commaSep' :: Parse a -> Parse b -> Parse (a, b)
+ Data.GraphViz.ParserCombinators: hasString :: String -> Parse Bool
+ Data.GraphViz.ParserCombinators: instance (Parseable a) => Parseable [a]
+ Data.GraphViz.ParserCombinators: instance (Parseable a, Parseable b) => Parseable (Either a b)
+ Data.GraphViz.ParserCombinators: instance Parseable Bool
+ Data.GraphViz.ParserCombinators: instance Parseable Char
+ Data.GraphViz.ParserCombinators: instance Parseable Double
+ Data.GraphViz.ParserCombinators: instance Parseable Int
+ Data.GraphViz.ParserCombinators: newline :: Parse String
+ Data.GraphViz.ParserCombinators: optionalQuoted :: Parse a -> Parse a
+ Data.GraphViz.ParserCombinators: optionalQuotedString :: String -> Parse String
+ Data.GraphViz.ParserCombinators: parse :: (Parseable a) => Parse a
+ Data.GraphViz.ParserCombinators: parseAndSpace :: Parse a -> Parse a
+ Data.GraphViz.ParserCombinators: parseBoolField :: String -> Parse Bool
+ Data.GraphViz.ParserCombinators: parseField :: (Parseable a) => String -> Parse a
+ Data.GraphViz.ParserCombinators: parseList :: (Parseable a) => Parse [a]
+ Data.GraphViz.ParserCombinators: quotedParse :: Parse a -> Parse a
+ Data.GraphViz.ParserCombinators: quotedString :: Parse String
+ Data.GraphViz.ParserCombinators: skipToNewline :: Parse ()
+ Data.GraphViz.ParserCombinators: string :: String -> Parse String
+ Data.GraphViz.ParserCombinators: stringBlock :: Parse String
+ Data.GraphViz.ParserCombinators: strings :: [String] -> Parse String
+ Data.GraphViz.ParserCombinators: type Parse a = Parser Char a
+ Data.GraphViz.ParserCombinators: whitespace :: Parse String
+ Data.GraphViz.ParserCombinators: whitespace' :: Parse String
+ Data.GraphViz.Types: HTML :: URL -> GraphID
+ Data.GraphViz.Types: Num :: Double -> GraphID
+ Data.GraphViz.Types: QStr :: QuotedString -> GraphID
+ Data.GraphViz.Types: Str :: String -> GraphID
+ Data.GraphViz.Types: data GraphID
+ Data.GraphViz.Types: graphID :: DotGraph -> Maybe GraphID
+ Data.GraphViz.Types: instance Eq DotEdge
+ Data.GraphViz.Types: instance Eq DotGraph
+ Data.GraphViz.Types: instance Eq DotNode
+ Data.GraphViz.Types: instance Eq GraphID
+ Data.GraphViz.Types: instance Parseable DotEdge
+ Data.GraphViz.Types: instance Parseable DotGraph
+ Data.GraphViz.Types: instance Parseable DotNode
+ Data.GraphViz.Types: instance Parseable GraphID
+ Data.GraphViz.Types: instance Read DotEdge
+ Data.GraphViz.Types: instance Read DotGraph
+ Data.GraphViz.Types: instance Read DotNode
+ Data.GraphViz.Types: instance Read GraphID
+ Data.GraphViz.Types: instance Show GraphID
+ Data.GraphViz.Types: invalidAttributes :: DotGraph -> ([Attribute], [(DotNode, Attribute)], [(DotEdge, Attribute)])
+ Data.GraphViz.Types: isValidGraph :: DotGraph -> Bool
+ Data.GraphViz.Types: makeStrict :: DotGraph -> DotGraph
+ Data.GraphViz.Types: parseDotGraph :: Parse DotGraph
+ Data.GraphViz.Types: setID :: GraphID -> DotGraph -> DotGraph
+ Data.GraphViz.Types: strictGraph :: DotGraph -> Bool
- Data.GraphViz.Attributes: BgColor :: ColorType -> Attribute
+ Data.GraphViz.Attributes: BgColor :: Color -> Attribute
- Data.GraphViz.Attributes: Bold :: StyleType
+ Data.GraphViz.Attributes: Bold :: StyleName
- Data.GraphViz.Attributes: Box3d :: ShapeType
+ Data.GraphViz.Attributes: Box3d :: Shape
- Data.GraphViz.Attributes: BoxShape :: ShapeType
+ Data.GraphViz.Attributes: BoxShape :: Shape
- Data.GraphViz.Attributes: Circle :: ShapeType
+ Data.GraphViz.Attributes: Circle :: Shape
- Data.GraphViz.Attributes: Color :: ColorType -> Attribute
+ Data.GraphViz.Attributes: Color :: (Either Color [Color]) -> Attribute
- Data.GraphViz.Attributes: Component :: ShapeType
+ Data.GraphViz.Attributes: Component :: Shape
- Data.GraphViz.Attributes: Dashed :: StyleType
+ Data.GraphViz.Attributes: Dashed :: StyleName
- Data.GraphViz.Attributes: Diagonals :: StyleType
+ Data.GraphViz.Attributes: Diagonals :: StyleName
- Data.GraphViz.Attributes: DiamondShape :: ShapeType
+ Data.GraphViz.Attributes: DiamondShape :: Shape
- Data.GraphViz.Attributes: Dotted :: StyleType
+ Data.GraphViz.Attributes: Dotted :: StyleName
- Data.GraphViz.Attributes: Doublecircle :: ShapeType
+ Data.GraphViz.Attributes: Doublecircle :: Shape
- Data.GraphViz.Attributes: Doubleoctagon :: ShapeType
+ Data.GraphViz.Attributes: Doubleoctagon :: Shape
- Data.GraphViz.Attributes: Egg :: ShapeType
+ Data.GraphViz.Attributes: Egg :: Shape
- Data.GraphViz.Attributes: Ellipse :: ShapeType
+ Data.GraphViz.Attributes: Ellipse :: Shape
- Data.GraphViz.Attributes: FillColor :: ColorType -> Attribute
+ Data.GraphViz.Attributes: FillColor :: Color -> Attribute
- Data.GraphViz.Attributes: Filled :: StyleType
+ Data.GraphViz.Attributes: Filled :: StyleName
- Data.GraphViz.Attributes: Folder :: ShapeType
+ Data.GraphViz.Attributes: Folder :: Shape
- Data.GraphViz.Attributes: FontColor :: ColorType -> Attribute
+ Data.GraphViz.Attributes: FontColor :: Color -> Attribute
- Data.GraphViz.Attributes: HeadLabel :: String -> Attribute
+ Data.GraphViz.Attributes: HeadLabel :: (Either String URL) -> Attribute
- Data.GraphViz.Attributes: Hexagon :: ShapeType
+ Data.GraphViz.Attributes: Hexagon :: Shape
- Data.GraphViz.Attributes: House :: ShapeType
+ Data.GraphViz.Attributes: House :: Shape
- Data.GraphViz.Attributes: Invhouse :: ShapeType
+ Data.GraphViz.Attributes: Invhouse :: Shape
- Data.GraphViz.Attributes: Invisible :: StyleType
+ Data.GraphViz.Attributes: Invisible :: StyleName
- Data.GraphViz.Attributes: Invtrapezium :: ShapeType
+ Data.GraphViz.Attributes: Invtrapezium :: Shape
- Data.GraphViz.Attributes: Invtriangle :: ShapeType
+ Data.GraphViz.Attributes: Invtriangle :: Shape
- Data.GraphViz.Attributes: Label :: String -> Attribute
+ Data.GraphViz.Attributes: Label :: (Either String URL) -> Attribute
- Data.GraphViz.Attributes: LabelFontColor :: ColorType -> Attribute
+ Data.GraphViz.Attributes: LabelFontColor :: Color -> Attribute
- Data.GraphViz.Attributes: Margin :: Double -> Double -> Attribute
+ Data.GraphViz.Attributes: Margin :: (Either Double Point) -> Attribute
- Data.GraphViz.Attributes: Mcircle :: ShapeType
+ Data.GraphViz.Attributes: Mcircle :: Shape
- Data.GraphViz.Attributes: Mdiamond :: ShapeType
+ Data.GraphViz.Attributes: Mdiamond :: Shape
- Data.GraphViz.Attributes: Msquare :: ShapeType
+ Data.GraphViz.Attributes: Msquare :: Shape
- Data.GraphViz.Attributes: NoShape :: ShapeType
+ Data.GraphViz.Attributes: NoShape :: Shape
- Data.GraphViz.Attributes: Note :: ShapeType
+ Data.GraphViz.Attributes: Note :: Shape
- Data.GraphViz.Attributes: Octagon :: ShapeType
+ Data.GraphViz.Attributes: Octagon :: Shape
- Data.GraphViz.Attributes: Overlap :: Bool -> Attribute
+ Data.GraphViz.Attributes: Overlap :: (Either String Bool) -> Attribute
- Data.GraphViz.Attributes: Pad :: Double -> Double -> Attribute
+ Data.GraphViz.Attributes: Pad :: (Either Double Point) -> Attribute
- Data.GraphViz.Attributes: Page :: Double -> Double -> Attribute
+ Data.GraphViz.Attributes: Page :: Point -> Attribute
- Data.GraphViz.Attributes: Parallelogram :: ShapeType
+ Data.GraphViz.Attributes: Parallelogram :: Shape
- Data.GraphViz.Attributes: PenColor :: ColorType -> Attribute
+ Data.GraphViz.Attributes: PenColor :: Color -> Attribute
- Data.GraphViz.Attributes: Pentagon :: ShapeType
+ Data.GraphViz.Attributes: Pentagon :: Shape
- Data.GraphViz.Attributes: Plaintext :: ShapeType
+ Data.GraphViz.Attributes: Plaintext :: Shape
- Data.GraphViz.Attributes: PointShape :: ShapeType
+ Data.GraphViz.Attributes: PointShape :: Shape
- Data.GraphViz.Attributes: Polygon :: ShapeType
+ Data.GraphViz.Attributes: Polygon :: Shape
- Data.GraphViz.Attributes: Pos :: PointList -> Attribute
+ Data.GraphViz.Attributes: Pos :: (Either Point [Spline]) -> Attribute
- Data.GraphViz.Attributes: RGB :: Word8 -> Word8 -> Word8 -> ColorType
+ Data.GraphViz.Attributes: RGB :: Word8 -> Word8 -> Word8 -> Color
- Data.GraphViz.Attributes: RGBA :: Word8 -> Word8 -> Word8 -> Word8 -> ColorType
+ Data.GraphViz.Attributes: RGBA :: Word8 -> Word8 -> Word8 -> Word8 -> Color
- Data.GraphViz.Attributes: RankDir :: PageDir -> Attribute
+ Data.GraphViz.Attributes: RankDir :: RankDir -> Attribute
- Data.GraphViz.Attributes: Ratio :: Double -> Attribute
+ Data.GraphViz.Attributes: Ratio :: Ratios -> Attribute
- Data.GraphViz.Attributes: Rectangle :: ShapeType
+ Data.GraphViz.Attributes: Rectangle :: Shape
- Data.GraphViz.Attributes: Rotate :: Double -> Attribute
+ Data.GraphViz.Attributes: Rotate :: Int -> Attribute
- Data.GraphViz.Attributes: Rounded :: StyleType
+ Data.GraphViz.Attributes: Rounded :: StyleName
- Data.GraphViz.Attributes: Sep :: Double -> Attribute
+ Data.GraphViz.Attributes: Sep :: (Either Double Point) -> Attribute
- Data.GraphViz.Attributes: Septagon :: ShapeType
+ Data.GraphViz.Attributes: Septagon :: Shape
- Data.GraphViz.Attributes: Shape :: ShapeType -> Attribute
+ Data.GraphViz.Attributes: Shape :: Shape -> Attribute
- Data.GraphViz.Attributes: Size :: Double -> Double -> Attribute
+ Data.GraphViz.Attributes: Size :: Point -> Attribute
- Data.GraphViz.Attributes: Solid :: StyleType
+ Data.GraphViz.Attributes: Solid :: StyleName
- Data.GraphViz.Attributes: Splines :: (Maybe Bool) -> Attribute
+ Data.GraphViz.Attributes: Splines :: (Either Bool String) -> Attribute
- Data.GraphViz.Attributes: Style :: StyleType -> Attribute
+ Data.GraphViz.Attributes: Style :: Style -> Attribute
- Data.GraphViz.Attributes: Tab :: ShapeType
+ Data.GraphViz.Attributes: Tab :: Shape
- Data.GraphViz.Attributes: TailLabel :: String -> Attribute
+ Data.GraphViz.Attributes: TailLabel :: (Either String URL) -> Attribute
- Data.GraphViz.Attributes: Trapezium :: ShapeType
+ Data.GraphViz.Attributes: Trapezium :: Shape
- Data.GraphViz.Attributes: Triangle :: ShapeType
+ Data.GraphViz.Attributes: Triangle :: Shape
- Data.GraphViz.Attributes: Tripleoctagon :: ShapeType
+ Data.GraphViz.Attributes: Tripleoctagon :: Shape
- Data.GraphViz.Attributes: alpha :: ColorType -> Word8
+ Data.GraphViz.Attributes: alpha :: Color -> Word8
- Data.GraphViz.Attributes: blue :: ColorType -> Word8
+ Data.GraphViz.Attributes: blue :: Color -> Word8
- Data.GraphViz.Attributes: green :: ColorType -> Word8
+ Data.GraphViz.Attributes: green :: Color -> Word8
- Data.GraphViz.Attributes: red :: ColorType -> Word8
+ Data.GraphViz.Attributes: red :: Color -> Word8
- Data.GraphViz.Types: DotGraph :: [Attribute] -> [DotNode] -> [DotEdge] -> Bool -> DotGraph
+ Data.GraphViz.Types: DotGraph :: Bool -> Bool -> Maybe GraphID -> [Attribute] -> [DotNode] -> [DotEdge] -> DotGraph

Files

+ Changelog view
@@ -0,0 +1,52 @@+Changes since 2009.5.1+======================++* Fixed a bug where the Show instance and read function for DotEdge+  had the from/to nodes the wrong way round.  This was not immediately+  noticed since the Graph -> DotGraph functions created them the wrong+  way round, so for those users who only used these this was not+  apparent.  Spotted by Neil Brown.++* Greatly improved Attribute usage: almost all attributes are now+  covered with allowed values.++* Extend DotGraph to include whether a graph is strict or not and if+  it has an ID.  Also move the directedGraph field.++* Make "Dot" refer to the actual dot command and DotArrow refer to the+  ArrowType (rather than DotCmd and Dot as before).++* Make the Data.GraphViz.ParserCombinators module available to end+  users again, but not re-exported by Data.GraphViz; it has a warning+  message up the top not to be used.  It is there purely for+  documentative purposes.++* Use extensible-exceptions so that base < 4 is once again supported.++* Follow the PVP rather than using dates for versions:+  http://www.haskell.org/haskellwiki/Package_versioning_policy++Changes since 2008.9.20:+========================++* Support polyparse >= 1.1 (as opposed to < 1.3)++* Require base == 4.* (i.e. GHC 6.10.*) due to new exception handling.++* Include functions from Graphalyze-0.5 for running GraphViz commands,+  etc.++* Module re-organisation.++* The Data.GraphViz.ParserCombinators module is no longer available to+  end users.++* Improved Haddock documentation.++Changes since 2008.9.6+======================++* Differentiate between undirected and directed graphs (previously+  only directed graphs were supported).++* Clustering support was added.
Data/GraphViz.hs view
@@ -1,7 +1,3 @@-{-# LANGUAGE NamedFieldPuns-           , ScopedTypeVariables-           #-}- {- |    Module      : Data.GraphViz    Description : GraphViz bindings for Haskell.@@ -16,13 +12,7 @@     Information about GraphViz and the Dot language can be found at:    <http://graphviz.org/>--   Note that this module re-exports the "Data.GraphViz.Attributes"-   module, which exports a constructor that clashes with-   'Prelude.LT'.  As such, you may need to import either this module-   or the @Prelude@ qualified or hiding @LT@.--   -}+ -}  module Data.GraphViz     ( graphToDot@@ -35,33 +25,30 @@     , module Data.GraphViz.Types     , module Data.GraphViz.Attributes     , module Data.GraphViz.Commands-    )-    where+    ) where +import Data.GraphViz.Types+import Data.GraphViz.Types.Clustering+import Data.GraphViz.Attributes+import Data.GraphViz.Commands+import Data.GraphViz.ParserCombinators(runParser)+ import Data.Graph.Inductive.Graph-import Data.List-import Data.Function import qualified Data.Set as Set-import Text.ParserCombinators.Poly.Lazy-import Control.Monad+import Control.Arrow((&&&)) import Data.Maybe import qualified Data.Map as Map-import System.IO+import System.IO(hGetContents) import System.IO.Unsafe(unsafePerformIO) -import Data.GraphViz.Types-import Data.GraphViz.Types.Clustering-import Data.GraphViz.Attributes-import Data.GraphViz.Commands- -- -----------------------------------------------------------------------------  -- | Determine if the given graph is undirected or directed. isUndir   :: (Ord b, Graph g) => g a b -> Bool-isUndir g = all hasFlip edges+isUndir g = all hasFlip es     where-      edges = labEdges g-      eSet = Set.fromList edges+      es = labEdges g+      eSet = Set.fromList es       hasFlip e = Set.member (flippedEdge e) eSet       flippedEdge (f,t,l) = (t,f,l) @@ -70,8 +57,8 @@ -- | Convert a graph to GraphViz's /Dot/ format. graphToDot :: (Ord b, Graph gr) => gr a b -> [Attribute]            -> (LNode a -> [Attribute]) -> (LEdge b -> [Attribute]) -> DotGraph-graphToDot graph graphAttributes fmtNode fmtEdge-    = clusterGraphToDot graph graphAttributes clusterBy fmtCluster fmtNode fmtEdge+graphToDot graph gAttributes fmtNode fmtEdge+    = clusterGraphToDot graph gAttributes clusterBy fmtCluster fmtNode fmtEdge       where         clusterBy :: LNode a -> NodeCluster () a         clusterBy = N@@ -84,17 +71,23 @@                   -> [Attribute] -> (LNode a -> NodeCluster c a)                   -> (c -> [Attribute]) -> (LNode a -> [Attribute])                   -> (LEdge b -> [Attribute]) -> DotGraph-clusterGraphToDot graph graphAttributes clusterBy fmtCluster fmtNode fmtEdge-    = DotGraph { graphAttributes, graphNodes, graphEdges, directedGraph }+clusterGraphToDot graph gAttrs clusterBy fmtCluster fmtNode fmtEdge+    = DotGraph { strictGraph     = False+               , directedGraph   = dirGraph+               , graphID         = Nothing+               , graphAttributes = gAttrs+               , graphNodes      = ns+               , graphEdges      = es+               }       where-        graphNodes = clustersToNodes clusterBy fmtCluster fmtNode graph-        directedGraph = not $ isUndir graph-        graphEdges = catMaybes . map mkDotEdge . labEdges $ graph-        mkDotEdge e@(f,t,_) = if (directedGraph || f <= t)-                              then Just $ DotEdge {edgeHeadNodeID = t-                                                  ,edgeTailNodeID = f-                                                  ,edgeAttributes = fmtEdge e-                                                  ,directedEdge = directedGraph}+        dirGraph = not $ isUndir graph+        ns = clustersToNodes clusterBy fmtCluster fmtNode graph+        es = mapMaybe mkDotEdge . labEdges $ graph+        mkDotEdge e@(f,t,_) = if dirGraph || f <= t+                              then Just DotEdge {edgeHeadNodeID = f+                                                ,edgeTailNodeID = t+                                                ,edgeAttributes = fmtEdge e+                                                ,directedEdge = dirGraph}                               else Nothing  -- -----------------------------------------------------------------------------@@ -105,31 +98,35 @@ -- | Run the graph via dot to get positional information and then --   combine that information back into the original graph. --   Note that this doesn't support graphs with clusters.-graphToGraph :: forall gr a b . (Ord b, Graph gr) =>-                gr a b -> [Attribute] -> (LNode a -> [Attribute]) -> (LEdge b -> [Attribute]) -> IO (gr (AttributeNode a) (AttributeEdge b))-graphToGraph gr graphAttributes fmtNode fmtEdge-    = do { out <- graphvizWithHandle command dot DotOutput hGetContents-         ; let res = fromJust out-         ; (length res) `seq` return ()-         ; return $ rebuildGraphWithAttributes res-         }+graphToGraph :: (Ord b, Graph gr) => gr a b -> [Attribute]+                -> (LNode a -> [Attribute]) -> (LEdge b -> [Attribute])+                -> IO (gr (AttributeNode a) (AttributeEdge b))+graphToGraph gr gAttributes fmtNode fmtEdge+    = do output <- graphvizWithHandle command dot DotOutput hGetContents+         let res = fromJust output+         length res `seq` return ()+         return $ rebuildGraphWithAttributes res     where       undirected = isUndir gr       command = if undirected then undirCommand else dirCommand-      dot = graphToDot gr graphAttributes fmtNode fmtEdge-      rebuildGraphWithAttributes :: String -> gr (AttributeNode a) (AttributeEdge b)+      dot = graphToDot gr gAttributes fmtNode fmtEdge       rebuildGraphWithAttributes dotResult = mkGraph lnodes ledges           where-            lnodes = map (\(n, l) -> (n, (fromJust $ Map.lookup n nodeMap, l))) . labNodes $ gr-            ledges = map createEdges . labEdges $ gr-            (DotGraph { graphEdges, graphNodes }) = fst . runParser readDotGraph $ dotResult-            nodeMap = Map.fromList . map (\n -> (nodeID n, nodeAttributes n)) $ graphNodes-            edgeMap = Map.fromList . map (\e -> ((edgeTailNodeID e, edgeHeadNodeID e), edgeAttributes e)) $ graphEdges-            createEdges (f,t,l) = if (undirected && f > t)-                                  then (f,t,getLabel (t,f))-                                  else (f,t,getLabel (f,t))+            lnodes = map (\(n, l) -> (n, (fromJust $ Map.lookup n nodeMap, l)))+                     $ labNodes gr+            ledges = map createEdges $ labEdges gr+            createEdges (f, t, l) = if undirected && f > t+                                    then (f, t, getLabel (t,f))+                                    else (f, t, getLabel (f,t))                 where-                  getLabel c = (fromJust $ Map.lookup c edgeMap,l)+                  getLabel c = (fromJust $ Map.lookup c edgeMap, l)+            DotGraph { graphNodes = ns, graphEdges = es}+                = fst . runParser parseDotGraph $ dotResult+            nodeMap = Map.fromList $ map (nodeID &&& nodeAttributes) ns+            edgeMap = Map.fromList $ map (\e -> ( ( edgeTailNodeID e+                                                  , edgeHeadNodeID e)+                                                , edgeAttributes e)+                                         ) es  -- | Pass the plain graph through 'graphToGraph'.  This is an @IO@ action, --   however since the state doesn't change it's safe to use 'unsafePerformIO'
Data/GraphViz/Attributes.hs view
@@ -1,692 +1,1702 @@-{-# LANGUAGE NamedFieldPuns-           , ScopedTypeVariables-           #-}--{- |-   Module      : Data.GraphViz.Attributes-   Description : Definition of the GraphViz attributes.-   Copyright   : (c) Matthew Sackman, Ivan Lazar Miljenovic-   License     : 3-Clause BSD-style-   Maintainer  : Ivan.Miljenovic@gmail.com--   This module defines the various attributes that different parts of-   a GraphViz graph can have.  Note that when using this module, you-   may need to either import it or @Prelude@ qualified or hiding-   @LT@, as this module exports a constructor with the same name.-  -}--module Data.GraphViz.Attributes where--import Prelude hiding (LT)--import Data.Word-import Numeric-import Text.ParserCombinators.Poly.Lazy-import Control.Monad-import Data.Maybe--import Data.GraphViz.ParserCombinators--data ArrowType = Normal   | Inv-               | Dot      | InvDot-               | ODot     | InvODot-               | NoArrow  | Tee-               | Empty    | InvEmpty-               | Diamond  | ODiamond-               | EDiamond | Crow-               | Box      | OBox-               | Open     | HalfOpen-               | Vee-                 deriving (Eq)--instance Show ArrowType where-    show Normal   = "normal"-    show Inv      = "inv"-    show Dot      = "dot"-    show InvDot   = "invdot"-    show ODot     = "odot"-    show InvODot  = "invodot"-    show NoArrow  = "none"-    show Tee      = "tee"-    show Empty    = "empty"-    show InvEmpty = "invempty"-    show Diamond  = "diamond"-    show ODiamond = "odiamond"-    show EDiamond = "ediamond"-    show Crow     = "crow"-    show Box      = "box"-    show OBox     = "obox"-    show Open     = "open"-    show HalfOpen = "halfopen"-    show Vee      = "vee"--readArrowType :: Parser Char ArrowType-readArrowType-              = oneOf [ optionalQuotedString "normal" >> return Normal-                      , optionalQuotedString "inv" >> return Inv-                      , optionalQuotedString "dot" >> return Dot-                      , optionalQuotedString "invdot" >> return InvDot-                      , optionalQuotedString "odot" >> return ODot-                      , optionalQuotedString "invodot" >> return InvODot-                      , optionalQuotedString "noarrow" >> return NoArrow-                      , optionalQuotedString "tee" >> return Tee-                      , optionalQuotedString "empty" >> return Empty-                      , optionalQuotedString "invempty" >> return InvEmpty-                      , optionalQuotedString "diamond" >> return Diamond-                      , optionalQuotedString "odiamond" >> return ODiamond-                      , optionalQuotedString "ediamond" >> return EDiamond-                      , optionalQuotedString "crow" >> return Crow-                      , optionalQuotedString "box" >> return Box-                      , optionalQuotedString "obox" >> return OBox-                      , optionalQuotedString "open" >> return Open-                      , optionalQuotedString "halfopen" >> return HalfOpen-                      , optionalQuotedString "vee" >> return Vee-                      ]--data ColorType = RGB { red :: Word8-                      , green :: Word8-                      , blue :: Word8-                      }-                | RGBA { red :: Word8-                       , green :: Word8-                       , blue :: Word8-                       , alpha :: Word8-                       }-                  deriving (Eq)--instance Show ColorType where-    show (RGB { red, green, blue })-        = show $ '#' : foldr showWord8Pad "" [red, green, blue]-    show (RGBA { red, green, blue, alpha })-        = show $ '#' : foldr showWord8Pad "" [red, green, blue, alpha]--showWord8Pad :: Word8 -> String -> String-showWord8Pad w s = padding ++ simple ++ s-    where-      simple = showHex w ""-      padding = replicate count '0'-      count = (2 - (findCols 1 w))-      findCols :: Int -> Word8 -> Int-      findCols c n-          | n < 16 = c-          | otherwise = findCols (c+1) (n `div` 16)--readColorType :: Parser Char ColorType-readColorType-              = do { string "\"#"-                   ; digits <- many $ noneOf ['"']-                   ; char '"'-                   ; let c = readHexPairs digits-                   ; return $ case c of-                                [r,g,b]-                                    -> RGB r g b-                                [r,g,b,a]-                                    -> RGBA r g b a-                                _ -> error $ "Unexpected pairs: " ++ show c-                   }-    where-          readHexPairs :: String -> [Word8]-          readHexPairs [] = []-          readHexPairs (h1:h2:h')-              = let [(n, [])] = readHex [h1,h2] in n : readHexPairs h'-          readHexPairs c = error $ "Error in readHexPairs: " ++ (show c)--data DirType = Forward | Back | Both | None-               deriving (Eq)--instance Show DirType where-    show Forward = "forward"-    show Back = "back"-    show Both = "both"-    show None = "none"--readDirType :: Parser Char DirType-readDirType-              = oneOf [optionalQuotedString "forward" >> return Forward-                      ,optionalQuotedString "back" >> return Back-                      ,optionalQuotedString "both" >> return Both-                      ,optionalQuotedString "none" >> return None-                      ]--data OutputMode = BreadthFirst | NodesFirst | EdgesFirst-                  deriving (Eq)--instance Show OutputMode where-    show BreadthFirst = "breadthfirst"-    show NodesFirst = "nodesfirst"-    show EdgesFirst = "edgesfirst"--readOutputMode :: Parser Char OutputMode-readOutputMode-              = oneOf [ optionalQuotedString "breadthfirst" >> return BreadthFirst-                      , optionalQuotedString "nodesfirst" >> return NodesFirst-                      , optionalQuotedString "edgesfirst" >> return EdgesFirst-                      ]--data PageDir = BL | BR | TL | TR | RB | RT | LB | LT-               deriving (Eq)--instance Show PageDir where-    show BL = "BL"-    show BR = "BR"-    show TL = "TL"-    show TR = "TR"-    show RB = "RB"-    show RT = "RT"-    show LB = "LB"-    show LT = "LT"--readPageDir :: Parser Char PageDir-readPageDir-              = oneOf [ optionalQuotedString "BL" >> return BL-                      , optionalQuotedString "BR" >> return BR-                      , optionalQuotedString "TL" >> return TL-                      , optionalQuotedString "TR" >> return TR-                      , optionalQuotedString "RB" >> return RB-                      , optionalQuotedString "RT" >> return RT-                      , optionalQuotedString "LB" >> return LB-                      , optionalQuotedString "LT" >> return LT-                      ]--data ShapeType-    = BoxShape-    | Polygon-    | Ellipse-    | Circle-    | PointShape-    | Egg-    | Triangle-    | Plaintext-    | DiamondShape-    | Trapezium-    | Parallelogram-    | House-    | Pentagon-    | Hexagon-    | Septagon-    | Octagon-    | Doublecircle-    | Doubleoctagon-    | Tripleoctagon-    | Invtriangle-    | Invtrapezium-    | Invhouse-    | Mdiamond-    | Msquare-    | Mcircle-    | Rectangle-    | NoShape-    | Note-    | Tab-    | Folder-    | Box3d-    | Component-      deriving (Eq)--instance Show ShapeType where-    show BoxShape = "box"-    show Polygon = "polygon"-    show Ellipse = "ellipse"-    show Circle = "circle"-    show PointShape = "point"-    show Egg = "egg"-    show Triangle = "triangle"-    show Plaintext = "plaintext"-    show DiamondShape = "diamond"-    show Trapezium = "trapezium"-    show Parallelogram = "parallelogram"-    show House = "house"-    show Pentagon = "pentagon"-    show Hexagon = "hexagon"-    show Septagon = "septagon"-    show Octagon = "octagon"-    show Doublecircle = "doublecircle"-    show Doubleoctagon = "doubleoctagon"-    show Tripleoctagon = "tripleoctagon"-    show Invtriangle = "invtriangle"-    show Invtrapezium = "invtrapezium"-    show Invhouse = "invhouse"-    show Mdiamond = "mdiamond"-    show Msquare = "msquare"-    show Mcircle = "mcircle"-    show Rectangle = "rectangle"-    show NoShape = "none"-    show Note = "note"-    show Tab = "tab"-    show Folder = "folder"-    show Box3d = "box3d"-    show Component = "component"--readShapeType :: Parser Char ShapeType-readShapeType-              = oneOf [ optionalQuotedString "box" >> return BoxShape-                      , optionalQuotedString "polygon" >> return Polygon-                      , optionalQuotedString "ellipse" >> return Ellipse-                      , optionalQuotedString "circle" >> return Circle-                      , optionalQuotedString "point" >> return PointShape-                      , optionalQuotedString "egg" >> return Egg-                      , optionalQuotedString "triangle" >> return Triangle-                      , optionalQuotedString "plaintext" >> return Plaintext-                      , optionalQuotedString "diamond" >> return DiamondShape-                      , optionalQuotedString "trapezium" >> return Trapezium-                      , optionalQuotedString "parallelogram" >> return Parallelogram-                      , optionalQuotedString "house" >> return House-                      , optionalQuotedString "pentagon" >> return Pentagon-                      , optionalQuotedString "hexagon" >> return Hexagon-                      , optionalQuotedString "septagon" >> return Septagon-                      , optionalQuotedString "octagon" >> return Octagon-                      , optionalQuotedString "doublecircle" >> return Doublecircle-                      , optionalQuotedString "doubleoctagon" >> return Doubleoctagon-                      , optionalQuotedString "tripleoctagon" >> return Tripleoctagon-                      , optionalQuotedString "invtriangle" >> return Invtriangle-                      , optionalQuotedString "invtrapezium" >> return Invtrapezium-                      , optionalQuotedString "invhouse" >> return Invhouse-                      , optionalQuotedString "mdiamond" >> return Mdiamond-                      , optionalQuotedString "msquare" >> return Msquare-                      , optionalQuotedString "mcircle" >> return Mcircle-                      , optionalQuotedString "rectangle" >> return Rectangle-                      , optionalQuotedString "none" >> return NoShape-                      , optionalQuotedString "note" >> return Note-                      , optionalQuotedString "tab" >> return Tab-                      , optionalQuotedString "folder" >> return Folder-                      , optionalQuotedString "box3d" >> return Box3d-                      , optionalQuotedString "component" >> return Component-                      ]--data StyleType = Filled | Invisible | Diagonals | Rounded | Dashed | Dotted | Solid | Bold-                 deriving (Eq)--instance Show StyleType where-    show Filled = "filled"-    show Invisible = "invisible"-    show Diagonals = "diagonals"-    show Rounded = "rounded"-    show Dashed = "dashed"-    show Dotted = "dotted"-    show Solid = "solid"-    show Bold = "bold"--readStyleType :: Parser Char StyleType-readStyleType-              = oneOf [ optionalQuotedString "filled" >> return Filled-                      , optionalQuotedString "invisible" >> return Invisible-                      , optionalQuotedString "diagonals" >> return Diagonals-                      , optionalQuotedString "rounded" >> return Rounded-                      , optionalQuotedString "dashed" >> return Dashed-                      , optionalQuotedString "dotted" >> return Dotted-                      , optionalQuotedString "solid" >> return Solid-                      , optionalQuotedString "bold" >> return Bold-                      ]--data Point = Point Int Int-           | PointD Double Double-             deriving (Eq)--newtype PointList = PointList [Point]-                    deriving (Eq)--instance Show Point where-    show (Point x y) = show $ (show x) ++ (',':(show y))-    show (PointD x y) = show $ (show x) ++ (',':(show y))--instance Show PointList where-    show (PointList points) = show $ case foldr s "" points of-                                       [] -> ""-                                       str -> tail str-        where-          s (Point x y) acc = ' ':((show x) ++ (',':((show y) ++ acc)))-          s (PointD x y) acc = ' ':((show x) ++ (',':((show y) ++ acc)))--readPoint :: Parser Char Point-readPoint = char '"' >> oneOf [readPointI, readPointD]-    where-      readPointI = do { x <- number-                      ; char ','-                      ; y <- number-                      ; char '"'-                      ; return $ Point x y-                      }-      readPointD = do { x <- floatingNumber-                      ; char ','-                      ; y <- floatingNumber-                      ; char '"'-                      ; return $ PointD x y-                      }--readPointList :: Parser Char PointList-readPointList-    = do { char '"'-         ; points <- many pointPair-         ; char '"'-         ; return $ PointList points-         }-    where-          pointPair-              = do { x <- number-                   ; char ','-                   ; y <- number-                   ; optional (char ' ')-                   ; return $ Point x y-                   }--data Rect = Rect Point Point-            deriving (Eq)--instance Show Rect where-    show (Rect (Point x1 y1) (Point x2 y2))-        = show $ (show x1) ++ (',': ((show y1) ++ (',': ((show x2) ++ (',': (show y2))))))-    show (Rect (Point x1 y1) (PointD x2 y2))-        = show $ (show x1) ++ (',': ((show y1) ++ (',': ((show x2) ++ (',': (show y2))))))-    show (Rect (PointD x1 y1) (Point x2 y2))-        = show $ (show x1) ++ (',': ((show y1) ++ (',': ((show x2) ++ (',': (show y2))))))-    show (Rect (PointD x1 y1) (PointD x2 y2))-        = show $ (show x1) ++ (',': ((show y1) ++ (',': ((show x2) ++ (',': (show y2))))))--readRect :: Parser Char Rect-readRect = do { char '"'-              ; x1 <- number-              ; char ','-              ; y1 <- number-              ; char ','-              ; x2 <- number-              ; char ','-              ; y2 <- number-              ; char '"'-              ; return (Rect (Point x1 y1) (Point x2 y2))-              }--data ScaleType = Scale | NoScale | FitX | FitY-                 deriving (Eq)--instance Show ScaleType where-    show Scale = "true"-    show NoScale = "false"-    show FitX = "width"-    show FitY = "height"--readScaleType :: Parser Char ScaleType-readScaleType = oneOf [ optionalQuotedString "true" >> return Scale-                      , optionalQuotedString "false" >> return NoScale-                      , optionalQuotedString "width" >> return FitX-                      , optionalQuotedString "height" >> return FitY-                      ]--data Justification = JLeft | JRight | JCenter-                     deriving (Eq)--instance Show Justification where-    show JLeft = "l"-    show JRight = "r"-    show JCenter = "c"--readJustification :: Parser Char Justification-readJustification = oneOf [ optionalQuotedString "l" >> return JLeft-                          , optionalQuotedString "r" >> return JRight-                          , optionalQuotedString "c" >> return JCenter-                          ]--data VerticalPlacement = VTop | VCenter | VBottom-                         deriving (Eq)--instance Show VerticalPlacement where-    show VTop = "t"-    show VCenter = "c"-    show VBottom = "b"--readVerticalPlacement :: Parser Char VerticalPlacement-readVerticalPlacement-              = oneOf [ optionalQuotedString "t" >> return VTop-                      , optionalQuotedString "c" >> return VCenter-                      , optionalQuotedString "b" >> return VBottom-                      ]--data Attribute-    = ArrowHead ArrowType-    | ArrowSize Double-    | ArrowTail ArrowType-    | Bb Rect-    | BgColor ColorType-    | Center Bool-    | Color ColorType-    | Concentrate Bool-    | Constraint Bool-    | Decorate Bool-    | DefaultDist Double-    | Dir DirType-    | Dpi Double-    | FillColor ColorType-    | FixedSize Bool-    | FontColor ColorType-    | FontName String-    | FontSize Double-    | Group String-    | HeadClip Bool-    | HeadLabel String-    | Height Double-    | Image String-    | ImageScale ScaleType-    | Label String-    | LabelAngle Double-    | LabelDistance Double-    | LabelFloat Bool-    | LabelFontColor ColorType-    | LabelFontName String-    | LabelFontSize Double-    | LabelJust Justification-    | LabelLoc VerticalPlacement-    | Landscape Bool-    | Len Double-    | Margin Double Double-    | MinDist Double-    | Minlen Double-    | Nodesep Double-    | NoJustify Bool-    | Normalize Bool-    | Orientation Double-    | OutputOrder OutputMode-    | Overlap Bool-    | Pad Double Double-    | Page Double Double-    | PageDir PageDir-    | PenColor ColorType-    | Pos PointList-    | Quantum Double-    | RankDir PageDir-    | RankSep Double-    | Ratio Double-    | Regular Bool-    | Rotate Double-    | SameHead String-    | SameTail String-    | Sep Double-    | Shape ShapeType-    | Sides Int-    | Size Double Double-    | Skew Double-    | Splines (Maybe Bool)-    | Style StyleType-    | TailClip Bool-    | TailLabel String-    | Weight Double-    | Width Double-    | Unknown String String-      deriving (Eq)--instance Show Attribute where-    show (ArrowHead arrowtype) = "arrowhead=" ++ (show arrowtype)-    show (ArrowSize double) = "arrowsize=" ++ (show double)-    show (ArrowTail arrowtype) = "arrowtail=" ++ (show arrowtype)-    show (Bb rect) = "bb=" ++ (show rect)-    show (BgColor colortype) = "bgcolor=" ++ (show colortype)-    show (Center bool) = "center=" ++ (show bool)-    show (Color colortype) = "color=" ++ (show colortype)-    show (Concentrate bool) = "concentrate=" ++ (show bool)-    show (Constraint bool) = "constraint=" ++ (show bool)-    show (Decorate bool) = "decorate=" ++ (show bool)-    show (DefaultDist double) = "defaultdist=" ++ (show double)-    show (Dir dirtype) = "dir=" ++ (show dirtype)-    show (Dpi double) = "dpi=" ++ (show double)-    show (FillColor colortype) = "fillcolor=" ++ (show colortype)-    show (FixedSize bool) = "fixedsize=" ++ (show bool)-    show (FontColor colortype) = "fontcolor=" ++ (show colortype)-    show (FontName string) = "fontname=" ++ (show string)-    show (FontSize double) = "fontsize=" ++ (show double)-    show (Group string) = "group=" ++ (show string)-    show (HeadClip bool) = "headclip=" ++ (show bool)-    show (HeadLabel string) = "headlabel=" ++ (show string)-    show (Height double) = "height=" ++ (show double)-    show (Image string) = "image=" ++ (show string)-    show (ImageScale scaletype) = "imagescale=" ++ (show scaletype)-    show (Label string) = "label=" ++ (show string)-    show (LabelAngle double) = "labelangle=" ++ (show double)-    show (LabelDistance double) = "labeldistance=" ++ (show double)-    show (LabelFloat bool) = "labelfloat=" ++ (show bool)-    show (LabelFontColor colortype) = "labelfontcolor=" ++ (show colortype)-    show (LabelFontName string) = "labelfontname=" ++ (show string)-    show (LabelFontSize double) = "labelfontsize=" ++ (show double)-    show (LabelJust justification) = "labeljust=" ++ (show justification)-    show (LabelLoc verticalplacement) = "labelloc=" ++ (show verticalplacement)-    show (Landscape bool) = "landscape=" ++ (show bool)-    show (Len double) = "len=" ++ (show double)-    show (Margin double1 double2) = "margin=" ++ (show $ PointD double1 double2)-    show (MinDist double) = "mindist=" ++ (show double)-    show (Minlen double) = "minlen=" ++ (show double)-    show (Nodesep double) = "nodesep=" ++ (show double)-    show (NoJustify bool) = "nojustify=" ++ (show bool)-    show (Normalize bool) = "normalize=" ++ (show bool)-    show (Orientation double) = "orientation=" ++ (show double)-    show (OutputOrder outputmode) = "outputorder=" ++ (show outputmode)-    show (Overlap bool) = "overlap=" ++ (show bool)-    show (Pad double1 double2) = "pad=" ++ (show $ PointD double1 double2)-    show (Page double1 double2) = "page=" ++ (show $ PointD double1 double2)-    show (PageDir pagedir) = "pagedir=" ++ (show pagedir)-    show (PenColor colortype) = "pencolor=" ++ (show colortype)-    show (Pos pointlist) = "pos=" ++ (show pointlist)-    show (Quantum double) = "quantum=" ++ (show double)-    show (RankDir pagedir) = "rankdir=" ++ (show pagedir)-    show (RankSep double) = "ranksep=" ++ (show double)-    show (Ratio double) = "ratio=" ++ (show double)-    show (Regular bool) = "regular=" ++ (show bool)-    show (Rotate double) = "rotate=" ++ (show double)-    show (SameHead string) = "samehead=" ++ (show string)-    show (SameTail string) = "sametail=" ++ (show string)-    show (Sep double) = "sep=" ++ (show double)-    show (Shape shapetype) = "shape=" ++ (show shapetype)-    show (Sides int) = "sides=" ++ (show int)-    show (Size double1 double2) = "size=" ++ (show $ PointD double1 double2)-    show (Skew double) = "skew=" ++ (show double)-    show (Splines maybebool) = "splines=" ++ (show (fromMaybe [] (liftM show maybebool)))-    show (Style styletype) = "style=" ++ (show styletype)-    show (TailClip bool) = "tailclip=" ++ (show bool)-    show (TailLabel string) = "taillabel=" ++ (show string)-    show (Weight double) = "weight=" ++ (show double)-    show (Width double) = "width=" ++ (show double)-    show (Unknown key value) = (show key) ++ ('=':(show . show $ value))--readBool :: Parser Char Bool-readBool = oneOf [ (optionalQuotedString "true" >> return True)-                 , (optionalQuotedString "false" >> return False)-                 , (optionalQuotedString "True" >> return True)-                 , (optionalQuotedString "False" >> return False)-                 ]--readString :: Parser Char String-readString = oneOf [quoted, nonquoted]-    where-      quoted = do { char '"'-                  ; str <- liftM concat . many . oneOf $ [nonescaped, escapedPair]-                  ; char '"'-                  ; return str-                  }-      nonquoted = many $ noneOf ['"', ' ', ',', '\t', '\n', '\r', ']']-      escapedPair = do { char '\\'-                       ; oneOf [ char '"' >> return "\""-                               , char 't' >> return "\t"-                               , char 'n' >> return "\n"-                               , char 'r' >> return "\r"-                               , satisfy (const True) >>= \c -> return ['\\', c]-                               ]-                       }-      nonescaped = liftM (: []) . noneOf $ ['\\', '"']--readAttribute :: Parser Char Attribute-readAttribute-              = oneOf-                [ string "arrowhead=" >> readArrowType >>= return . ArrowHead-                , string "arrowsize=" >> optionalQuoted floatingNumber >>= return . ArrowSize-                , string "arrowtail=" >> readArrowType >>= return . ArrowTail-                , string "bb=" >> readRect >>= return . Bb-                , string "bgcolor=" >> readColorType >>= return . BgColor-                , string "center=" >> readBool >>= return . Center-                , string "color=" >> readColorType >>= return . Color-                , string "concentrate=" >> readBool >>= return . Concentrate-                , string "constraint=" >> readBool >>= return . Constraint-                , string "decorate=" >> readBool >>= return . Decorate-                , string "defaultdist=" >> optionalQuoted floatingNumber >>= return . DefaultDist-                , string "dir=" >> readDirType >>= return . Dir-                , string "dpi=" >> optionalQuoted floatingNumber >>= return . Dpi-                , string "fillcolor=" >> readColorType >>= return . FillColor-                , string "fixedsize=" >> readBool >>= return . FixedSize-                , string "fontcolor=" >> readColorType >>= return . FontColor-                , string "fontname=" >> readString >>= return . FontName-                , string "fontsize=" >> optionalQuoted floatingNumber >>= return . FontSize-                , string "group=" >> readString >>= return . Group-                , string "headclip=" >> readBool >>= return . HeadClip-                , string "headlabel=" >> readString >>= return . HeadLabel-                , string "height=" >> optionalQuoted floatingNumber >>= return . Height-                , string "image=" >> readString >>= return . Image-                , string "imagescale=" >> readScaleType >>= return . ImageScale-                , string "label=" >> readString >>= return . Label-                , string "labelangle=" >> optionalQuoted floatingNumber >>= return . LabelAngle-                , string "labeldistance=" >> optionalQuoted floatingNumber >>= return . LabelDistance-                , string "labelfloat=" >> readBool >>= return . LabelFloat-                , string "labelfontcolor=" >> readColorType >>= return . LabelFontColor-                , string "labelfontname=" >> readString >>= return . LabelFontName-                , string "labelfontsize=" >> optionalQuoted floatingNumber >>= return . LabelFontSize-                , string "labeljust=" >> readJustification >>= return . LabelJust-                , string "labelloc=" >> readVerticalPlacement >>= return . LabelLoc-                , string "landscape=" >> readBool >>= return . Landscape-                , string "len=" >> optionalQuoted floatingNumber >>= return . Len-                , string "margin=" >> readPoint >>= \(PointD x y) -> return $ Margin x y-                , string "mindist=" >> optionalQuoted floatingNumber >>= return . MinDist-                , string "minlen=" >> optionalQuoted floatingNumber >>= return . Minlen-                , string "nodesep=" >> optionalQuoted floatingNumber >>= return . Nodesep-                , string "nojustify=" >> readBool >>= return . NoJustify-                , string "normalize=" >> readBool >>= return . Normalize-                , string "orientation=" >> optionalQuoted floatingNumber >>= return . Orientation-                , string "outputorder=" >> readOutputMode >>= return . OutputOrder-                , string "overlap=" >> readBool >>= return . Overlap-                , string "pad=" >> readPoint >>= \(PointD x y) -> return $ Pad x y-                , string "page=" >> readPoint >>= \(PointD x y) -> return $ Page x y-                , string "pagedir=" >> readPageDir >>= return . PageDir-                , string "pencolor=" >> readColorType >>= return . PenColor-                , string "pos=" >> readPointList >>= return . Pos-                , string "quantum=" >> optionalQuoted floatingNumber >>= return . Quantum-                , string "rankdir=" >> readPageDir >>= return . RankDir-                , string "ranksep=" >> optionalQuoted floatingNumber >>= return . RankSep-                , string "ratio=" >> optionalQuoted floatingNumber >>= return . Ratio-                , string "regular=" >> readBool >>= return . Regular-                , string "rotate=" >> optionalQuoted floatingNumber >>= return . Rotate-                , string "samehead=" >> readString >>= return . SameHead-                , string "sametail=" >> readString >>= return . SameTail-                , string "sep=" >> optionalQuoted floatingNumber >>= return . Sep-                , string "shape=" >> readShapeType >>= return . Shape-                , string "sides=" >> optionalQuoted number >>= return . Sides-                , string "size=" >> readPoint >>= \(PointD x y) -> return $ Size x y-                , string "skew=" >> optionalQuoted floatingNumber >>= return . Skew-                , string "splines=" >> (oneOf [(string "\"\"" >> return Nothing), readBool >>= return . Just]) >>= return . Splines-                , string "style=" >> readStyleType >>= return . Style-                , string "tailclip=" >> readBool >>= return . TailClip-                , string "taillabel=" >> readString >>= return . TailLabel-                , string "weight=" >> optionalQuoted floatingNumber >>= return . Weight-                , string "width=" >> optionalQuoted floatingNumber >>= return . Width-                , many (noneOf ['=', '"', ' ', ',', '\t', '\n', '\r', ']']) >>= \key -> char '=' >> readString >>= return . Unknown key-                ]--readAttributesList :: Parser Char [Attribute]-readAttributesList = do { char '['-                        ; as <- many (optional whitespace >> readAttribute >>= \a -> optional whitespace >> optional (char ',') >> return a)-                        ; optional whitespace-                        ; char ']'-                        ; return as-                        }+{- |+   Module      : Data.GraphViz.Attributes+   Description : Definition of the GraphViz attributes.+   Copyright   : (c) Matthew Sackman, Ivan Lazar Miljenovic+   License     : 3-Clause BSD-style+   Maintainer  : Ivan.Miljenovic@gmail.com++   This module defines the various attributes that different parts of+   a GraphViz graph can have.  These attributes are based on the+   documentation found at:++     <http://graphviz.org/doc/info/attrs.html>++   For more information on usage, etc. please see that document.++   A summary of known current constraints\/limitations\/differences:++   * Parsing of quoted strings might not always work if they are a+     sub-part of another Attribute (e.g. a quoted name in 'LayerList').+     In fact, parsing with quotes is iffy for everything; specifically+     when they are and aren't allowed.++   * 'ColorScheme' is ignored when parsing 'Color' values++   * ColorList and PointfList are defined as actual lists (but+     'LayerList' is not).++   * 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 two 'LabelLoc' attributes have been combined.++   * The defined 'LayerSep' is not used to parse 'LayerRange' or+     'LayerList'; the default (@[' ', ':', '\t']@) is instead used.++   * @SplineType@ has been replaced with @['Spline']@.++   * Only polygon-based 'Shape's are available.++   * Device-dependent 'StyleName' values are not available.++   * 'PortPos' only has the 'CompassPoint' option, not+     @PortName[:CompassPoint]@ (since record shapes aren't allowed,+     and parsing HTML-like labels could be problematic).++   * Not every 'Attribute' is fully documented/described.  In+     particular, a lot of them are listed as having a 'String' value,+     when actually only certain Strings are allowed.++ -}++module Data.GraphViz.Attributes where++import Data.GraphViz.ParserCombinators++import Data.Char(isDigit, isHexDigit)+import Data.Word+import Numeric+import Control.Monad+import Data.Maybe++-- -----------------------------------------------------------------------------++{- |++   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.++   Note also that the default values are taken from the specification+   page listed above, and might not correspond fully with the names of+   the permitted values.+-}+data Attribute+    = Damping Double                          -- ^ /Valid for/: G; /Default/: 0.99; /Minimum/: 0.0; /Notes/: neato only+    | K Double                                -- ^ /Valid for/: GC; /Default/: 0.3; /Minimum/: 0; /Notes/: sfdp, fdp only+    | URL URL                                 -- ^ /Valid for/: ENGC; /Default/: \<none\>; /Notes/: svg, postscript, map only+    | ArrowHead ArrowType                     -- ^ /Valid for/: E; /Default/: Normal+    | ArrowSize Double                        -- ^ /Valid for/: E; /Default/: 1.0; /Minimum/: 0.0+    | ArrowTail ArrowType                     -- ^ /Valid for/: E; /Default/: Normal+    | Aspect AspectType                       -- ^ /Valid for/: G; /Notes/: dot only+    | Bb Rect                                 -- ^ /Valid for/: G; /Notes/: write only+    | BgColor Color                           -- ^ /Valid for/: GC; /Default/: \<none\>+    | Center Bool                             -- ^ /Valid for/: G; /Default/: false+    | Charset String                          -- ^ /Valid for/: G; /Default/: \"UTF-8\"+    | ClusterRank ClusterMode                 -- ^ /Valid for/: G; /Default/: local; /Notes/: dot only+    | Color (Either Color [Color])            -- ^ /Valid for/: ENC; /Default/: black+    | ColorScheme String                      -- ^ /Valid for/: ENCG; /Default/: \"\"+    | Comment String                          -- ^ /Valid for/: ENG; /Default/: \"\"+    | Compound Bool                           -- ^ /Valid for/: G; /Default/: false; /Notes/: dot only+    | Concentrate Bool                        -- ^ /Valid for/: G; /Default/: false+    | Constraint Bool                         -- ^ /Valid for/: E; /Default/: true; /Notes/: dot only+    | Decorate Bool                           -- ^ /Valid for/: E; /Default/: false+    | DefaultDist Double                      -- ^ /Valid for/: G; /Default/: 1+(avg. len)*sqrt(|V|); /Minimum/: epsilon; /Notes/: neato only+    | Dim Int                                 -- ^ /Valid for/: G; /Default/: 2; /Minimum/: 2; /Notes/: sfdp, fdp, neato only+    | Dimen Int                               -- ^ /Valid for/: G; /Default/: 2; /Minimum/: 2; /Notes/: sfdp, fdp, neato only+    | Dir DirType                             -- ^ /Valid for/: E; /Default/: forward(directed)/none(undirected)+    | DirEdgeConstraints (Either String Bool) -- ^ /Valid for/: G; /Default/: false; /Notes/: neato only+    | Distortion Double                       -- ^ /Valid for/: N; /Default/: 0.0; /Minimum/: -100.0+    | DPI Double                              -- ^ /Valid for/: G; /Default/: 96.0 | 0.0; /Notes/: svg, bitmap output only+    | EdgeURL URL                             -- ^ /Valid for/: E; /Default/: \"\"; /Notes/: svg, map only+    | EdgeHref URL                            -- ^ /Valid for/: E; /Default/: \"\"; /Notes/: svg, map only+    | EdgeTarget String                       -- ^ /Valid for/: E; /Default/: \<none\>; /Notes/: svg, map only+    | EdgeTooltip String                      -- ^ /Valid for/: E; /Default/: \"\"; /Notes/: svg, cmap only+    | Epsilon Double                          -- ^ /Valid for/: G; /Default/: .0001 * # nodes(mode == KK) | .0001(mode == major); /Notes/: neato only+    | ESep (Either Double Point)              -- ^ /Valid for/: G; /Default/: +3; /Notes/: not dot+    | FillColor Color                         -- ^ /Valid for/: NC; /Default/: lightgrey(nodes) | black(clusters)+    | FixedSize Bool                          -- ^ /Valid for/: N; /Default/: false+    | FontColor Color                         -- ^ /Valid for/: ENGC; /Default/: black+    | FontName String                         -- ^ /Valid for/: ENGC; /Default/: \"Times-Roman\"+    | FontNames String                        -- ^ /Valid for/: G; /Default/: \"\"; /Notes/: svg only+    | FontPath String                         -- ^ /Valid for/: G; /Default/: system-dependent+    | FontSize Double                         -- ^ /Valid for/: ENGC; /Default/: 14.0; /Minimum/: 1.0+    | Group String                            -- ^ /Valid for/: N; /Default/: \"\"; /Notes/: dot only+    | HeadURL URL                             -- ^ /Valid for/: E; /Default/: \"\"; /Notes/: svg, map only+    | HeadClip Bool                           -- ^ /Valid for/: E; /Default/: true+    | HeadHref URL                            -- ^ /Valid for/: E; /Default/: \"\"; /Notes/: svg, map only+    | HeadLabel (Either String URL)           -- ^ /Valid for/: E; /Default/: \"\"+    | HeadPort PortPos                        -- ^ /Valid for/: E; /Default/: center+    | HeadTarget QuotedString                 -- ^ /Valid for/: E; /Default/: \<none\>; /Notes/: svg, map only+    | HeadTooltip QuotedString                -- ^ /Valid for/: E; /Default/: \"\"; /Notes/: svg, cmap only+    | Height Double                           -- ^ /Valid for/: N; /Default/: 0.5; /Minimum/: 0.02+    | Href URL                                -- ^ /Valid for/: E; /Default/: \"\"; /Notes/: svg, postscript, map only+    | ID (Either String URL)                  -- ^ /Valid for/: GNE; /Default/: \"\"; /Notes/: svg, postscript, map only+    | Image String                            -- ^ /Valid for/: N; /Default/: \"\"+    | ImageScale ScaleType                    -- ^ /Valid for/: N; /Default/: false+    | Label (Either String URL)               -- ^ /Valid for/: ENGC; /Default/: \"\N\" (nodes) | \"\" (otherwise)+    | LabelURL URL                            -- ^ /Valid for/: E; /Default/: \"\"; /Notes/: svg, map only+    | LabelAngle Double                       -- ^ /Valid for/: E; /Default/: -25.0; /Minimum/: -180.0+    | LabelDistance Double                    -- ^ /Valid for/: E; /Default/: 1.0; /Minimum/: 0.0+    | LabelFloat Bool                         -- ^ /Valid for/: E; /Default/: false+    | LabelFontColor Color                    -- ^ /Valid for/: E; /Default/: black+    | LabelFontName String                    -- ^ /Valid for/: E; /Default/: \"Times-Roman\"+    | LabelFontSize Double                    -- ^ /Valid for/: E; /Default/: 14.0; /Minimum/: 1.0+    | LabelHref URL                           -- ^ /Valid for/: E; /Default/: \"\"; /Notes/: svg, map only+    | LabelJust Justification                 -- ^ /Valid for/: GC; /Default/: \"c\"+    | LabelLoc VerticalPlacement              -- ^ /Valid for/: GCN; /Default/: \"t\"(clusters) | \"b\"(root graphs) | \"c\"(clusters)+    | LabelTarget String                      -- ^ /Valid for/: E; /Default/: \<none\>; /Notes/: svg, map only+    | LabelTooltip String                     -- ^ /Valid for/: E; /Default/: \"\"; /Notes/: svg, cmap only+    | Landscape Bool                          -- ^ /Valid for/: G; /Default/: false+    | Layer LayerRange                        -- ^ /Valid for/: EN; /Default/: \"\"+    | Layers LayerList                        -- ^ /Valid for/: G; /Default/: \"\"+    | LayerSep String                         -- ^ /Valid for/: G; /Default/: \" :\t\"+    | Layout String                           -- ^ /Valid for/: G; /Default/: \"\"+    | Len Double                              -- ^ /Valid for/: E; /Default/: 1.0(neato)/0.3(fdp); /Notes/: fdp, neato only+    | Levels Int                              -- ^ /Valid for/: G; /Default/: MAXINT; /Minimum/: 0.0; /Notes/: sfdp only+    | LevelsGap Double                        -- ^ /Valid for/: G; /Default/: 0.0; /Notes/: neato only+    | LHead String                            -- ^ /Valid for/: E; /Default/: \"\"; /Notes/: dot only+    | LP Point                                -- ^ /Valid for/: EGC; /Notes/: write only+    | LTail String                            -- ^ /Valid for/: E; /Default/: \"\"; /Notes/: dot only+    | Margin (Either Double Point)            -- ^ /Valid for/: NG; /Default/: \<device-dependent\>+    | MaxIter Int                             -- ^ /Valid for/: G; /Default/: 100 * # nodes(mode == KK) | 200(mode == major) | 600(fdp); /Notes/: fdp, neato only+    | MCLimit Double                          -- ^ /Valid for/: G; /Default/: 1.0; /Notes/: dot only+    | MinDist Double                          -- ^ /Valid for/: G; /Default/: 1.0; /Minimum/: 0.0; /Notes/: circo only+    | MinLen Int                              -- ^ /Valid for/: E; /Default/: 1; /Minimum/: 0; /Notes/: dot only+    | Mode String                             -- ^ /Valid for/: G; /Default/: \"major\"; /Notes/: neato only+    | Model String                            -- ^ /Valid for/: G; /Default/: \"shortpath\"; /Notes/: neato only+    | Mosek Bool                              -- ^ /Valid for/: G; /Default/: false; /Notes/: neato only; requires the Mosek software+    | NodeSep Double                          -- ^ /Valid for/: G; /Default/: 0.25; /Minimum/: 0.02; /Notes/: dot only+    | NoJustify Bool                          -- ^ /Valid for/: GCNE; /Default/: false+    | Normalize Bool                          -- ^ /Valid for/: G; /Default/: false; /Notes/: not dot+    | Nslimit Double                          -- ^ /Valid for/: G; /Notes/: dot only+    | Nslimit1 Double                         -- ^ /Valid for/: G; /Notes/: dot only+    | Ordering String                         -- ^ /Valid for/: G; /Default/: \"\"; /Notes/: dot only+    | Orientation Double                      -- ^ /Valid for/: N; /Default/: 0.0; /Minimum/: 360.0+    | OrientationGraph String                 -- ^ /Valid for/: G; /Default/: \"\"; /Notes/: Landscape if \"[lL]*\" and rotate not defined+    | OutputOrder OutputMode                  -- ^ /Valid for/: G; /Default/: breadthfirst+    | Overlap (Either String Bool)            -- ^ /Valid for/: G; /Default/: true; /Notes/: not dot+    | OverlapScaling Double                   -- ^ /Valid for/: G; /Default/: -4; /Minimum/: -1.0e10; /Notes/: prism only+    | Pack (Either Bool Int)                  -- ^ /Valid for/: G; /Default/: false; /Notes/: not dot+    | PackMode PackMode                       -- ^ /Valid for/: G; /Default/: node; /Notes/: not dot+    | Pad (Either Double Point)               -- ^ /Valid for/: G; /Default/: 0.0555 (4 points)+    | Page Point                              -- ^ /Valid for/: G+    | PageDir PageDir                         -- ^ /Valid for/: G; /Default/: BL+    | PenColor Color                          -- ^ /Valid for/: C; /Default/: black+    | PenWidth Double                         -- ^ /Valid for/: CNE; /Default/: 1.0; /Minimum/: 0.0+    | Peripheries Int                         -- ^ /Valid for/: NC; /Default/: shape default(nodes) | 1(clusters); /Minimum/: 0+    | Pin Bool                                -- ^ /Valid for/: N; /Default/: false; /Notes/: fdp, neato only+    | Pos (Either Point [Spline])             -- ^ /Valid for/: EN+    | QuadTree (Either QuadType Bool)         -- ^ /Valid for/: G; /Default/: \"normal\"; /Notes/: sfdp only+    | Quantum Double                          -- ^ /Valid for/: G; /Default/: 0.0; /Minimum/: 0.0+    | Rank RankType                           -- ^ /Valid for/: S; /Notes/: dot only+    | RankDir RankDir                         -- ^ /Valid for/: G; /Default/: TB; /Notes/: dot only+    | Ranksep Double                          -- ^ /Valid for/: G; /Default/: 0.5(dot) | 1.0(twopi); /Minimum/: 0.02; /Notes/: twopi, dot only+    | Ratio Ratios                            -- ^ /Valid for/: G+    | Rects Rect                              -- ^ /Valid for/: N; /Notes/: write only+    | Regular Bool                            -- ^ /Valid for/: N; /Default/: false+    | ReMinCross Bool                         -- ^ /Valid for/: G; /Default/: false; /Notes/: dot only+    | RepulsiveForce Double                   -- ^ /Valid for/: G; /Default/: 1.0; /Minimum/: 0.0; /Notes/: sfdp only+    | Resolution Double                       -- ^ /Valid for/: G; /Default/: 96.0 | 0.0; /Notes/: svg, bitmap output only+    | Root (Either String Bool)               -- ^ /Valid for/: GN; /Default/: \"\"(graphs) | false(nodes); /Notes/: circo, twopi only+    | Rotate Int                              -- ^ /Valid for/: G; /Default/: 0+    | SameHead String                         -- ^ /Valid for/: E; /Default/: \"\"; /Notes/: dot only+    | SameTail String                         -- ^ /Valid for/: E; /Default/: \"\"; /Notes/: dot only+    | SamplePoints Int                        -- ^ /Valid for/: N; /Default/: 8(output) | 20(overlap and image maps)+    | SearchSize Int                          -- ^ /Valid for/: G; /Default/: 30; /Notes/: dot only+    | Sep (Either Double Point)               -- ^ /Valid for/: G; /Default/: +4; /Notes/: not dot+    | Shape Shape                             -- ^ /Valid for/: N; /Default/: ellipse+    | ShapeFile String                        -- ^ /Valid for/: N; /Default/: \"\"+    | ShowBoxes Int                           -- ^ /Valid for/: ENG; /Default/: 0; /Minimum/: 0; /Notes/: dot only+    | Sides Int                               -- ^ /Valid for/: N; /Default/: 4; /Minimum/: 0+    | Size Point                              -- ^ /Valid for/: G+    | Skew Double                             -- ^ /Valid for/: N; /Default/: 0.0; /Minimum/: -100.0+    | Smoothing SmoothType                    -- ^ /Valid for/: G; /Default/: \"none\"; /Notes/: sfdp only+    | SortV Int                               -- ^ /Valid for/: GCN; /Default/: 0; /Minimum/: 0+    | Splines (Either Bool String)            -- ^ /Valid for/: G+    | Start StartType                         -- ^ /Valid for/: G; /Default/: \"\"; /Notes/: fdp, neato only+    | Style Style                             -- ^ /Valid for/: ENC+    | StyleSheet String                       -- ^ /Valid for/: G; /Default/: \"\"; /Notes/: svg only+    | TailURL URL                             -- ^ /Valid for/: E; /Default/: \"\"; /Notes/: svg, map only+    | TailClip Bool                           -- ^ /Valid for/: E; /Default/: true+    | TailHref URL                            -- ^ /Valid for/: E; /Default/: \"\"; /Notes/: svg, map only+    | TailLabel (Either String URL)           -- ^ /Valid for/: E; /Default/: \"\"+    | TailPort PortPos                        -- ^ /Valid for/: E; /Default/: center+    | TailTarget String                       -- ^ /Valid for/: E; /Default/: \<none\>; /Notes/: svg, map only+    | TailTooltip String                      -- ^ /Valid for/: E; /Default/: \"\"; /Notes/: svg, cmap only+    | Target String                           -- ^ /Valid for/: ENGC; /Default/: \<none\>; /Notes/: svg, map only+    | Tooltip String                          -- ^ /Valid for/: NEC; /Default/: \"\"; /Notes/: svg, cmap only+    | TrueColor Bool                          -- ^ /Valid for/: G; /Notes/: bitmap output only+    | Vertices [Point]                        -- ^ /Valid for/: N; /Notes/: write only+    | ViewPort ViewPort                       -- ^ /Valid for/: G; /Default/: \"\"+    | VoroMargin Double                       -- ^ /Valid for/: G; /Default/: 0.05; /Minimum/: 0.0; /Notes/: not dot+    | Weight Double                           -- ^ /Valid for/: E; /Default/: 1.0; /Minimum/: 0(dot) | 1(neato,fdp,sfdp)+    | Width Double                            -- ^ /Valid for/: N; /Default/: 0.75; /Minimum/: 0.01+    | Z Double                                -- ^ /Valid for/: N; /Default/: 0.0; /Minimum/: -MAXFLOAT | -1000+      deriving (Eq, Read)++instance Show Attribute where+    show (Damping v)            = "Damping=" ++ show v+    show (K v)                  = "K=" ++ show v+    show (URL v)                = "URL=" ++ show v+    show (ArrowHead v)          = "arrowhead=" ++ show v+    show (ArrowSize v)          = "arrowsize=" ++ show v+    show (ArrowTail v)          = "arrowtail=" ++ show v+    show (Aspect v)             = "aspect=" ++ show v+    show (Bb v)                 = "bb=" ++ show v+    show (BgColor v)            = "bgcolor=" ++ show v+    show (Center v)             = "center=" ++ show v+    show (Charset v)            = "charset=" ++ v+    show (ClusterRank v)        = "clusterrank=" ++ show v+    show (Color v)              = "color=" ++ show v+    show (ColorScheme v)        = "colorscheme=" ++ v+    show (Comment v)            = "comment=" ++ v+    show (Compound v)           = "compound=" ++ show v+    show (Concentrate v)        = "concentrate=" ++ show v+    show (Constraint v)         = "constraint=" ++ show v+    show (Decorate v)           = "decorate=" ++ show v+    show (DefaultDist v)        = "defaultdist=" ++ show v+    show (Dim v)                = "dim=" ++ show v+    show (Dimen v)              = "dimen=" ++ show v+    show (Dir v)                = "dir=" ++ show v+    show (DirEdgeConstraints v) = "diredgeconstraints=" ++ show v+    show (Distortion v)         = "distortion=" ++ show v+    show (DPI v)                = "dpi=" ++ show v+    show (EdgeURL v)            = "edgeURL=" ++ show v+    show (EdgeHref v)           = "edgehref=" ++ show v+    show (EdgeTarget v)         = "edgetarget=" ++ v+    show (EdgeTooltip v)        = "edgetooltip=" ++ v+    show (Epsilon v)            = "epsilon=" ++ show v+    show (ESep v)               = "esep=" ++ show v+    show (FillColor v)          = "fillcolor=" ++ show v+    show (FixedSize v)          = "fixedsize=" ++ show v+    show (FontColor v)          = "fontcolor=" ++ show v+    show (FontName v)           = "fontname=" ++ v+    show (FontNames v)          = "fontnames=" ++ v+    show (FontPath v)           = "fontpath=" ++ v+    show (FontSize v)           = "fontsize=" ++ show v+    show (Group v)              = "group=" ++ v+    show (HeadURL v)            = "headURL=" ++ show v+    show (HeadClip v)           = "headclip=" ++ show v+    show (HeadHref v)           = "headhref=" ++ show v+    show (HeadLabel v)          = "headlabel=" ++ show v+    show (HeadPort v)           = "headport=" ++ show v+    show (HeadTarget v)         = "headtarget=" ++ show v+    show (HeadTooltip v)        = "headtooltip=" ++ show v+    show (Height v)             = "height=" ++ show v+    show (Href v)               = "href=" ++ show v+    show (ID v)                 = "id=" ++ show v+    show (Image v)              = "image=" ++ v+    show (ImageScale v)         = "imagescale=" ++ show v+    show (Label v)              = "label=" ++ show v+    show (LabelURL v)           = "labelURL=" ++ show v+    show (LabelAngle v)         = "labelangle=" ++ show v+    show (LabelDistance v)      = "labeldistance=" ++ show v+    show (LabelFloat v)         = "labelfloat=" ++ show v+    show (LabelFontColor v)     = "labelfontcolor=" ++ show v+    show (LabelFontName v)      = "labelfontname=" ++ v+    show (LabelFontSize v)      = "labelfontsize=" ++ show v+    show (LabelHref v)          = "labelhref=" ++ show v+    show (LabelJust v)          = "labeljust=" ++ show v+    show (LabelLoc v)           = "labelloc=" ++ show v+    show (LabelTarget v)        = "labeltarget=" ++ v+    show (LabelTooltip v)       = "labeltooltip=" ++ v+    show (Landscape v)          = "landscape=" ++ show v+    show (Layer v)              = "layer=" ++ show v+    show (Layers v)             = "layers=" ++ show v+    show (LayerSep v)           = "layersep=" ++ v+    show (Layout v)             = "layout=" ++ v+    show (Len v)                = "len=" ++ show v+    show (Levels v)             = "levels=" ++ show v+    show (LevelsGap v)          = "levelsgap=" ++ show v+    show (LHead v)              = "lhead=" ++ v+    show (LP v)                 = "lp=" ++ show v+    show (LTail v)              = "ltail=" ++ v+    show (Margin v)             = "margin=" ++ show v+    show (MaxIter v)            = "maxiter=" ++ show v+    show (MCLimit v)            = "mclimit=" ++ show v+    show (MinDist v)            = "mindist=" ++ show v+    show (MinLen v)             = "minlen=" ++ show v+    show (Mode v)               = "mode=" ++ v+    show (Model v)              = "model=" ++ v+    show (Mosek v)              = "mosek=" ++ show v+    show (NodeSep v)            = "nodesep=" ++ show v+    show (NoJustify v)          = "nojustify=" ++ show v+    show (Normalize v)          = "normalize=" ++ show v+    show (Nslimit v)            = "nslimit=" ++ show v+    show (Nslimit1 v)           = "nslimit1=" ++ show v+    show (Ordering v)           = "ordering=" ++ v+    show (Orientation v)        = "orientation=" ++ show v+    show (OrientationGraph v)   = "orientation=" ++ v+    show (OutputOrder v)        = "outputorder=" ++ show v+    show (Overlap v)            = "overlap=" ++ show v+    show (OverlapScaling v)     = "overlap_scaling=" ++ show v+    show (Pack v)               = "pack=" ++ show v+    show (PackMode v)           = "packmode=" ++ show v+    show (Pad v)                = "pad=" ++ show v+    show (Page v)               = "page=" ++ show v+    show (PageDir v)            = "pagedir=" ++ show v+    show (PenColor v)           = "pencolor=" ++ show v+    show (PenWidth v)           = "penwidth=" ++ show v+    show (Peripheries v)        = "peripheries=" ++ show v+    show (Pin v)                = "pin=" ++ show v+    show (Pos v)                = "pos=" ++ show v+    show (QuadTree v)           = "quadtree=" ++ show v+    show (Quantum v)            = "quantum=" ++ show v+    show (Rank v)               = "rank=" ++ show v+    show (RankDir v)            = "rankdir=" ++ show v+    show (Ranksep v)            = "ranksep=" ++ show v+    show (Ratio v)              = "ratio=" ++ show v+    show (Rects v)              = "rects=" ++ show v+    show (Regular v)            = "regular=" ++ show v+    show (ReMinCross v)         = "remincross=" ++ show v+    show (RepulsiveForce v)     = "repulsiveforce=" ++ show v+    show (Resolution v)         = "resolution=" ++ show v+    show (Root v)               = "root=" ++ show v+    show (Rotate v)             = "rotate=" ++ show v+    show (SameHead v)           = "samehead=" ++ v+    show (SameTail v)           = "sametail=" ++ v+    show (SamplePoints v)       = "samplepoints=" ++ show v+    show (SearchSize v)         = "searchsize=" ++ show v+    show (Sep v)                = "sep=" ++ show v+    show (Shape v)              = "shape=" ++ show v+    show (ShapeFile v)          = "shapefile=" ++ v+    show (ShowBoxes v)          = "showboxes=" ++ show v+    show (Sides v)              = "sides=" ++ show v+    show (Size v)               = "size=" ++ show v+    show (Skew v)               = "skew=" ++ show v+    show (Smoothing v)          = "smoothing=" ++ show v+    show (SortV v)              = "sortv=" ++ show v+    show (Splines v)            = "splines=" ++ show v+    show (Start v)              = "start=" ++ show v+    show (Style v)              = "style=" ++ show v+    show (StyleSheet v)         = "stylesheet=" ++ v+    show (TailURL v)            = "tailURL=" ++ show v+    show (TailClip v)           = "tailclip=" ++ show v+    show (TailHref v)           = "tailhref=" ++ show v+    show (TailLabel v)          = "taillabel=" ++ show v+    show (TailPort v)           = "tailport=" ++ show v+    show (TailTarget v)         = "tailtarget=" ++ v+    show (TailTooltip v)        = "tailtooltip=" ++ v+    show (Target v)             = "target=" ++ v+    show (Tooltip v)            = "tooltip=" ++ v+    show (TrueColor v)          = "truecolor=" ++ show v+    show (Vertices v)           = "vertices=" ++ show v+    show (ViewPort v)           = "viewport=" ++ show v+    show (VoroMargin v)         = "voro_margin=" ++ show v+    show (Weight v)             = "weight=" ++ show v+    show (Width v)              = "width=" ++ show v+    show (Z v)                  = "z=" ++ show v++instance Parseable Attribute where+    parse = oneOf [ liftM Damping            $ parseField "Damping"+                  , liftM K                  $ parseField "K"+                  , liftM URL                $ parseField "URL"+                  , liftM ArrowHead          $ parseField "arrowhead"+                  , liftM ArrowSize          $ parseField "arrowsize"+                  , liftM ArrowTail          $ parseField "arrowtail"+                  , liftM Aspect             $ parseField "aspect"+                  , liftM Bb                 $ parseField "bb"+                  , liftM BgColor            $ parseField "bgcolor"+                  , liftM Center             $ parseBoolField "center"+                  , liftM Charset            $ parseField "charset"+                  , liftM ClusterRank        $ parseField "clusterrank"+                  , liftM Color              $ parseField "color"+                  , liftM ColorScheme        $ parseField "colorscheme"+                  , liftM Comment            $ parseField "comment"+                  , liftM Compound           $ parseBoolField "compound"+                  , liftM Concentrate        $ parseBoolField "concentrate"+                  , liftM Constraint         $ parseBoolField "constraint"+                  , liftM Decorate           $ parseBoolField "decorate"+                  , liftM DefaultDist        $ parseField "defaultdist"+                  , liftM Dim                $ parseField "dim"+                  , liftM Dimen              $ parseField "dimen"+                  , liftM Dir                $ parseField "dir"+                  , liftM DirEdgeConstraints $ parseField "diredgeconstraints"+                  , liftM Distortion         $ parseField "distortion"+                  , liftM DPI                $ parseField "dpi"+                  , liftM EdgeURL            $ parseField "edgeURL"+                  , liftM EdgeHref           $ parseField "edgehref"+                  , liftM EdgeTarget         $ parseField "edgetarget"+                  , liftM EdgeTooltip        $ parseField "edgetooltip"+                  , liftM Epsilon            $ parseField "epsilon"+                  , liftM ESep               $ parseField "esep"+                  , liftM FillColor          $ parseField "fillcolor"+                  , liftM FixedSize          $ parseBoolField "fixedsize"+                  , liftM FontColor          $ parseField "fontcolor"+                  , liftM FontName           $ parseField "fontname"+                  , liftM FontNames          $ parseField "fontnames"+                  , liftM FontPath           $ parseField "fontpath"+                  , liftM FontSize           $ parseField "fontsize"+                  , liftM Group              $ parseField "group"+                  , liftM HeadURL            $ parseField "headURL"+                  , liftM HeadClip           $ parseBoolField "headclip"+                  , liftM HeadHref           $ parseField "headhref"+                  , liftM HeadLabel          $ parseField "headlabel"+                  , liftM HeadPort           $ parseField "headport"+                  , liftM HeadTarget         $ parseField "headtarget"+                  , liftM HeadTooltip        $ parseField "headtooltip"+                  , liftM Height             $ parseField "height"+                  , liftM Href               $ parseField "href"+                  , liftM ID                 $ parseField "id"+                  , liftM Image              $ parseField "image"+                  , liftM ImageScale         $ parseField "imagescale"+                  , liftM Label              $ parseField "label"+                  , liftM LabelURL           $ parseField "labelURL"+                  , liftM LabelAngle         $ parseField "labelangle"+                  , liftM LabelDistance      $ parseField "labeldistance"+                  , liftM LabelFloat         $ parseBoolField "labelfloat"+                  , liftM LabelFontColor     $ parseField "labelfontcolor"+                  , liftM LabelFontName      $ parseField "labelfontname"+                  , liftM LabelFontSize      $ parseField "labelfontsize"+                  , liftM LabelHref          $ parseField "labelhref"+                  , liftM LabelJust          $ parseField "labeljust"+                  , liftM LabelLoc           $ parseField "labelloc"+                  , liftM LabelTarget        $ parseField "labeltarget"+                  , liftM LabelTooltip       $ parseField "labeltooltip"+                  , liftM Landscape          $ parseBoolField "landscape"+                  , liftM Layer              $ parseField "layer"+                  , liftM Layers             $ parseField "layers"+                  , liftM LayerSep           $ parseField "layersep"+                  , liftM Layout             $ parseField "layout"+                  , liftM Len                $ parseField "len"+                  , liftM Levels             $ parseField "levels"+                  , liftM LevelsGap          $ parseField "levelsgap"+                  , liftM LHead              $ parseField "lhead"+                  , liftM LP                 $ parseField "lp"+                  , liftM LTail              $ parseField "ltail"+                  , liftM Margin             $ parseField "margin"+                  , liftM MaxIter            $ parseField "maxiter"+                  , liftM MCLimit            $ parseField "mclimit"+                  , liftM MinDist            $ parseField "mindist"+                  , liftM MinLen             $ parseField "minlen"+                  , liftM Mode               $ parseField "mode"+                  , liftM Model              $ parseField "model"+                  , liftM Mosek              $ parseBoolField "mosek"+                  , liftM NodeSep            $ parseField "nodesep"+                  , liftM NoJustify          $ parseBoolField "nojustify"+                  , liftM Normalize          $ parseBoolField "normalize"+                  , liftM Nslimit            $ parseField "nslimit"+                  , liftM Nslimit1           $ parseField "nslimit1"+                  , liftM Ordering           $ parseField "ordering"+                  , liftM Orientation        $ parseField "orientation"+                  , liftM OrientationGraph   $ parseField "orientation"+                  , liftM OutputOrder        $ parseField "outputorder"+                  , liftM Overlap            $ parseField "overlap"+                  , liftM OverlapScaling     $ parseField "overlap_scaling"+                  , liftM Pack               $ parseField "pack"+                  , liftM PackMode           $ parseField "packmode"+                  , liftM Pad                $ parseField "pad"+                  , liftM Page               $ parseField "page"+                  , liftM PageDir            $ parseField "pagedir"+                  , liftM PenColor           $ parseField "pencolor"+                  , liftM PenWidth           $ parseField "penwidth"+                  , liftM Peripheries        $ parseField "peripheries"+                  , liftM Pin                $ parseBoolField "pin"+                  , liftM Pos                $ parseField "pos"+                  , liftM QuadTree           $ parseField "quadtree"+                  , liftM Quantum            $ parseField "quantum"+                  , liftM Rank               $ parseField "rank"+                  , liftM RankDir            $ parseField "rankdir"+                  , liftM Ranksep            $ parseField "ranksep"+                  , liftM Ratio              $ parseField "ratio"+                  , liftM Rects              $ parseField "rects"+                  , liftM Regular            $ parseBoolField "regular"+                  , liftM ReMinCross         $ parseBoolField "remincross"+                  , liftM RepulsiveForce     $ parseField "repulsiveforce"+                  , liftM Resolution         $ parseField "resolution"+                  , liftM Root               $ parseField "root"+                  , liftM Rotate             $ parseField "rotate"+                  , liftM SameHead           $ parseField "samehead"+                  , liftM SameTail           $ parseField "sametail"+                  , liftM SamplePoints       $ parseField "samplepoints"+                  , liftM SearchSize         $ parseField "searchsize"+                  , liftM Sep                $ parseField "sep"+                  , liftM Shape              $ parseField "shape"+                  , liftM ShapeFile          $ parseField "shapefile"+                  , liftM ShowBoxes          $ parseField "showboxes"+                  , liftM Sides              $ parseField "sides"+                  , liftM Size               $ parseField "size"+                  , liftM Skew               $ parseField "skew"+                  , liftM Smoothing          $ parseField "smoothing"+                  , liftM SortV              $ parseField "sortv"+                  , liftM Splines            $ parseField "splines"+                  , liftM Start              $ parseField "start"+                  , liftM Style              $ parseField "style"+                  , liftM StyleSheet         $ parseField "stylesheet"+                  , liftM TailURL            $ parseField "tailURL"+                  , liftM TailClip           $ parseBoolField "tailclip"+                  , liftM TailHref           $ parseField "tailhref"+                  , liftM TailLabel          $ parseField "taillabel"+                  , liftM TailPort           $ parseField "tailport"+                  , liftM TailTarget         $ parseField "tailtarget"+                  , liftM TailTooltip        $ parseField "tailtooltip"+                  , liftM Target             $ parseField "target"+                  , liftM Tooltip            $ parseField "tooltip"+                  , liftM TrueColor          $ parseBoolField "truecolor"+                  , liftM Vertices           $ parseField "vertices"+                  , liftM ViewPort           $ parseField "viewport"+                  , liftM VoroMargin         $ parseField "voro_margin"+                  , liftM Weight             $ parseField "weight"+                  , liftM Width              $ parseField "width"+                  , liftM Z                  $ parseField "z"+                  ]++-- | Determine if this Attribute is valid for use with Graphs.+usedByGraphs                      :: Attribute -> Bool+usedByGraphs Damping{}            = True+usedByGraphs K{}                  = True+usedByGraphs URL{}                = True+usedByGraphs Aspect{}             = True+usedByGraphs Bb{}                 = True+usedByGraphs BgColor{}            = True+usedByGraphs Center{}             = True+usedByGraphs Charset{}            = True+usedByGraphs ClusterRank{}        = True+usedByGraphs ColorScheme{}        = True+usedByGraphs Comment{}            = True+usedByGraphs Compound{}           = True+usedByGraphs Concentrate{}        = True+usedByGraphs DefaultDist{}        = True+usedByGraphs Dim{}                = True+usedByGraphs Dimen{}              = True+usedByGraphs DirEdgeConstraints{} = True+usedByGraphs DPI{}                = True+usedByGraphs Epsilon{}            = True+usedByGraphs ESep{}               = True+usedByGraphs FontColor{}          = True+usedByGraphs FontName{}           = True+usedByGraphs FontNames{}          = True+usedByGraphs FontPath{}           = True+usedByGraphs FontSize{}           = True+usedByGraphs ID{}                 = True+usedByGraphs Label{}              = True+usedByGraphs LabelJust{}          = True+usedByGraphs LabelLoc{}           = True+usedByGraphs Landscape{}          = True+usedByGraphs Layers{}             = True+usedByGraphs LayerSep{}           = True+usedByGraphs Layout{}             = True+usedByGraphs Levels{}             = True+usedByGraphs LevelsGap{}          = True+usedByGraphs LP{}                 = True+usedByGraphs Margin{}             = True+usedByGraphs MaxIter{}            = True+usedByGraphs MCLimit{}            = True+usedByGraphs MinDist{}            = True+usedByGraphs Mode{}               = True+usedByGraphs Model{}              = True+usedByGraphs Mosek{}              = True+usedByGraphs NodeSep{}            = True+usedByGraphs NoJustify{}          = True+usedByGraphs Normalize{}          = True+usedByGraphs Nslimit{}            = True+usedByGraphs Nslimit1{}           = True+usedByGraphs Ordering{}           = True+usedByGraphs OrientationGraph{}   = True+usedByGraphs OutputOrder{}        = True+usedByGraphs Overlap{}            = True+usedByGraphs OverlapScaling{}     = True+usedByGraphs Pack{}               = True+usedByGraphs PackMode{}           = True+usedByGraphs Pad{}                = True+usedByGraphs Page{}               = True+usedByGraphs PageDir{}            = True+usedByGraphs QuadTree{}           = True+usedByGraphs Quantum{}            = True+usedByGraphs RankDir{}            = True+usedByGraphs Ranksep{}            = True+usedByGraphs Ratio{}              = True+usedByGraphs ReMinCross{}         = True+usedByGraphs RepulsiveForce{}     = True+usedByGraphs Resolution{}         = True+usedByGraphs Root{}               = True+usedByGraphs Rotate{}             = True+usedByGraphs SearchSize{}         = True+usedByGraphs Sep{}                = True+usedByGraphs ShowBoxes{}          = True+usedByGraphs Size{}               = True+usedByGraphs Smoothing{}          = True+usedByGraphs SortV{}              = True+usedByGraphs Splines{}            = True+usedByGraphs Start{}              = True+usedByGraphs StyleSheet{}         = True+usedByGraphs Target{}             = True+usedByGraphs TrueColor{}          = True+usedByGraphs ViewPort{}           = True+usedByGraphs VoroMargin{}         = True+usedByGraphs _                    = False++-- | Determine if this Attribute is valid for use with Clusters.+usedByClusters               :: Attribute -> Bool+usedByClusters K{}           = True+usedByClusters URL{}         = True+usedByClusters BgColor{}     = True+usedByClusters Color{}       = True+usedByClusters ColorScheme{} = True+usedByClusters FillColor{}   = True+usedByClusters FontColor{}   = True+usedByClusters FontName{}    = True+usedByClusters FontSize{}    = True+usedByClusters Label{}       = True+usedByClusters LabelJust{}   = True+usedByClusters LabelLoc{}    = True+usedByClusters LP{}          = True+usedByClusters NoJustify{}   = True+usedByClusters PenColor{}    = True+usedByClusters PenWidth{}    = True+usedByClusters Peripheries{} = True+usedByClusters Rank{}        = True+usedByClusters SortV{}       = True+usedByClusters Style{}       = True+usedByClusters Target{}      = True+usedByClusters Tooltip{}     = True+usedByClusters _             = False++-- | Determine if this Attribute is valid for use with SubGraphs.+usedBySubGraphs        :: Attribute -> Bool+usedBySubGraphs Rank{} = True+usedBySubGraphs _      = False++-- | Determine if this Attribute is valid for use with Nodes.+usedByNodes                :: Attribute -> Bool+usedByNodes URL{}          = True+usedByNodes Color{}        = True+usedByNodes ColorScheme{}  = True+usedByNodes Comment{}      = True+usedByNodes Distortion{}   = True+usedByNodes FillColor{}    = True+usedByNodes FixedSize{}    = True+usedByNodes FontColor{}    = True+usedByNodes FontName{}     = True+usedByNodes FontSize{}     = True+usedByNodes Group{}        = True+usedByNodes Height{}       = True+usedByNodes ID{}           = True+usedByNodes Image{}        = True+usedByNodes ImageScale{}   = True+usedByNodes Label{}        = True+usedByNodes LabelLoc{}     = True+usedByNodes Layer{}        = True+usedByNodes Margin{}       = True+usedByNodes NoJustify{}    = True+usedByNodes Orientation{}  = True+usedByNodes PenWidth{}     = True+usedByNodes Peripheries{}  = True+usedByNodes Pin{}          = True+usedByNodes Pos{}          = True+usedByNodes Rects{}        = True+usedByNodes Regular{}      = True+usedByNodes Root{}         = True+usedByNodes SamplePoints{} = True+usedByNodes Shape{}        = True+usedByNodes ShapeFile{}    = True+usedByNodes ShowBoxes{}    = True+usedByNodes Sides{}        = True+usedByNodes Skew{}         = True+usedByNodes SortV{}        = True+usedByNodes Style{}        = True+usedByNodes Target{}       = True+usedByNodes Tooltip{}      = True+usedByNodes Vertices{}     = True+usedByNodes Width{}        = True+usedByNodes Z{}            = True+usedByNodes _              = False++-- | Determine if this Attribute is valid for use with Edges.+usedByEdges                  :: Attribute -> Bool+usedByEdges URL{}            = True+usedByEdges ArrowHead{}      = True+usedByEdges ArrowSize{}      = True+usedByEdges ArrowTail{}      = True+usedByEdges Color{}          = True+usedByEdges ColorScheme{}    = True+usedByEdges Comment{}        = True+usedByEdges Constraint{}     = True+usedByEdges Decorate{}       = True+usedByEdges Dir{}            = True+usedByEdges EdgeURL{}        = True+usedByEdges EdgeHref{}       = True+usedByEdges EdgeTarget{}     = True+usedByEdges EdgeTooltip{}    = True+usedByEdges FontColor{}      = True+usedByEdges FontName{}       = True+usedByEdges FontSize{}       = True+usedByEdges HeadURL{}        = True+usedByEdges HeadClip{}       = True+usedByEdges HeadHref{}       = True+usedByEdges HeadLabel{}      = True+usedByEdges HeadPort{}       = True+usedByEdges HeadTarget{}     = True+usedByEdges HeadTooltip{}    = True+usedByEdges Href{}           = True+usedByEdges ID{}             = True+usedByEdges Label{}          = True+usedByEdges LabelURL{}       = True+usedByEdges LabelAngle{}     = True+usedByEdges LabelDistance{}  = True+usedByEdges LabelFloat{}     = True+usedByEdges LabelFontColor{} = True+usedByEdges LabelFontName{}  = True+usedByEdges LabelFontSize{}  = True+usedByEdges LabelHref{}      = True+usedByEdges LabelTarget{}    = True+usedByEdges LabelTooltip{}   = True+usedByEdges Layer{}          = True+usedByEdges Len{}            = True+usedByEdges LHead{}          = True+usedByEdges LP{}             = True+usedByEdges LTail{}          = True+usedByEdges MinLen{}         = True+usedByEdges NoJustify{}      = True+usedByEdges PenWidth{}       = True+usedByEdges Pos{}            = True+usedByEdges SameHead{}       = True+usedByEdges SameTail{}       = True+usedByEdges ShowBoxes{}      = True+usedByEdges Style{}          = True+usedByEdges TailURL{}        = True+usedByEdges TailClip{}       = True+usedByEdges TailHref{}       = True+usedByEdges TailLabel{}      = True+usedByEdges TailPort{}       = True+usedByEdges TailTarget{}     = True+usedByEdges TailTooltip{}    = True+usedByEdges Target{}         = True+usedByEdges Tooltip{}        = True+usedByEdges Weight{}         = True+usedByEdges _                = False++-- -----------------------------------------------------------------------------++newtype URL = UStr { urlString :: String }+    deriving (Eq, Read)++instance Show URL where+    show u = '<' : urlString u ++ ">"++instance Parseable URL where+    parse = do char open+               cnt <- many1 $ satisfy ((/=) close)+               char close+               return $ UStr cnt+        where+          open = '<'+          close = '>'++-- -----------------------------------------------------------------------------++data ArrowType = Normal   | Inv+               | DotArrow | InvDot+               | ODot     | InvODot+               | NoArrow  | Tee+               | Empty    | InvEmpty+               | Diamond  | ODiamond+               | EDiamond | Crow+               | Box      | OBox+               | Open     | HalfOpen+               | Vee+                 deriving (Eq, Read)++instance Show ArrowType where+    show Normal   = "normal"+    show Inv      = "inv"+    show DotArrow = "dot"+    show InvDot   = "invdot"+    show ODot     = "odot"+    show InvODot  = "invodot"+    show NoArrow  = "none"+    show Tee      = "tee"+    show Empty    = "empty"+    show InvEmpty = "invempty"+    show Diamond  = "diamond"+    show ODiamond = "odiamond"+    show EDiamond = "ediamond"+    show Crow     = "crow"+    show Box      = "box"+    show OBox     = "obox"+    show Open     = "open"+    show HalfOpen = "halfopen"+    show Vee      = "vee"++instance Parseable ArrowType where+    parse = optionalQuoted+            $ oneOf [ string "normal"   >> return Normal+                    , string "inv"      >> return Inv+                    , string "dot"      >> return DotArrow+                    , string "invdot"   >> return InvDot+                    , string "odot"     >> return ODot+                    , string "invodot"  >> return InvODot+                    , string "none"     >> return NoArrow+                    , string "tee"      >> return Tee+                    , string "empty"    >> return Empty+                    , string "invempty" >> return InvEmpty+                    , string "diamond"  >> return Diamond+                    , string "odiamond" >> return ODiamond+                    , string "ediamond" >> return EDiamond+                    , string "crow"     >> return Crow+                    , string "box"      >> return Box+                    , string "obox"     >> return OBox+                    , string "open"     >> return Open+                    , string "halfopen" >> return HalfOpen+                    , string "vee"      >> return Vee+                    ]++-- -----------------------------------------------------------------------------++data AspectType = RatioOnly Double+                | RatioPassCount Double Int+                  deriving (Eq, Read)++instance Show AspectType where+    show (RatioOnly r)        = show r+    show (RatioPassCount r p) = show $ show r ++ ',' : show p++instance Parseable AspectType where+    parse = oneOf [ liftM RatioOnly parse+                  , quotedParse $ do r <- parse+                                     char ','+                                     whitespace'+                                     p <- parse+                                     return $ RatioPassCount r p+                  ]++-- -----------------------------------------------------------------------------++data Rect = Rect Point Point+            deriving (Eq, Read)++instance Show Rect where+    show (Rect p1 p2) = show $ show p1 ++ ',' : show p2++instance Parseable Rect where+    parse = liftM (uncurry Rect) . quotedParse+            $ commaSep' parsePoint parsePoint++-- -----------------------------------------------------------------------------++data Color = RGB { red   :: Word8+                 , green :: Word8+                 , blue  :: Word8+                 }+           | RGBA { red   :: Word8+                  , green :: Word8+                  , blue  :: Word8+                  , alpha :: Word8+                  }+           | HSV { hue        :: Int+                 , saturation :: Int+                 , value      :: Int+                 }+           | ColorName String+             deriving (Eq, Read)++instance Show Color where+    show = show . showColor++    showList cs s = show $ go cs+        where+          go []      = s+          go [c]     = showColor c ++ s+          go (c:cs') = showColor c ++ ':' : go cs'++showColor :: Color -> String+showColor (RGB r g b)      = show $ '#' : foldr showWord8Pad "" [r,g,b]+showColor (RGBA r g b a)   = show $ '#' : foldr showWord8Pad "" [r,g,b,a]+showColor (HSV h s v)      = show $ show h ++ " " ++ show s ++ " " ++ show v+showColor (ColorName name) = name++showWord8Pad :: Word8 -> String -> String+showWord8Pad w s = padding ++ simple ++ s+    where+      simple = showHex w ""+      padding = replicate count '0'+      count = 2 - findCols 1 w+      findCols :: Int -> Word8 -> Int+      findCols c n+          | n < 16 = c+          | otherwise = findCols (c+1) (n `div` 16)++instance Parseable Color where+    parse = quotedParse parseColor++    parseList = quotedParse $ sepBy1 parseColor (char ':')++parseColor :: Parse Color+parseColor = oneOf [ parseHexBased+                   , parseHSV+                   , liftM ColorName parse -- Should we check it is a colour?+                   ]+    where+      parseHexBased+          = do char '#'+               cs <- many1 parse2Hex+               return $ case cs of+                          [r,g,b] -> RGB r g b+                          [r,g,b,a] -> RGBA r g b a+                          _ -> error $ "Not a valid hex Color specification: "+                               ++ show cs+      parseHSV = do h <- parse+                    parseSep+                    s <- parse+                    parseSep+                    v <- parse+                    return $ HSV h s v+      parseSep = oneOf [ string ","+                       , whitespace+                       ]+      parse2Hex = do c1 <- satisfy isHexDigit+                     c2 <- satisfy isHexDigit+                     let [(n, [])] = readHex [c1, c2]+                     return n++-- -----------------------------------------------------------------------------++data ClusterMode = Local+                 | Global+                 | NoCluster+                   deriving (Eq, Read)++instance Show ClusterMode where+    show Local     = "local"+    show Global    = "global"+    show NoCluster = "none"++instance Parseable ClusterMode where+    parse = optionalQuoted+            . oneOf+            $ [ string "local"  >> return Local+              , string "global" >> return Global+              , string "none"   >> return NoCluster+              ]++-- -----------------------------------------------------------------------------++data DirType = Forward | Back | Both | NoDir+               deriving (Eq, Read)++instance Show DirType where+    show Forward = "forward"+    show Back    = "back"+    show Both    = "both"+    show NoDir   = "none"++instance Parseable DirType where+    parse = optionalQuoted+            $ oneOf [ string "forward" >> return Forward+                    , string "back"    >> return Back+                    , string "both"    >> return Both+                    , string "none"    >> return NoDir+                    ]++-- -----------------------------------------------------------------------------++data Point = Point Int Int+           | PointD Double Double+             deriving (Eq, Read)++instance Show Point where+    show = show . showPoint++    showList ps s = unwords (map showPoint ps) ++ s++showPoint :: Point -> String+showPoint (Point  x y) = show x ++ ',' : show y+showPoint (PointD x y) = show x ++ ',' : show y++instance Parseable Point where+    parse = quotedParse parsePoint++    parseList = quotedParse $ sepBy1 parsePoint whitespace++parsePoint :: Parse Point+parsePoint = oneOf [ liftM (uncurry Point)  commaSep+                   , liftM (uncurry PointD) commaSep+                   ]++-- -----------------------------------------------------------------------------++data LayerRange = LRID LayerID+                | LRS LayerID String LayerID+                  deriving (Eq, Read)++instance Show LayerRange where+    show (LRID lid)        = show lid+    show (LRS id1 sep id2) = show $ show id1 ++ sep ++ show id2++instance Parseable LayerRange where+    parse = oneOf [ liftM LRID parse+                  , do id1 <- parse+                       sep <- parseLayerSep+                       id2 <- parse+                       return $ LRS id1 sep id2+                  ]++parseLayerSep :: Parse String+parseLayerSep = many1 . oneOf+                $ map char defLayerSep++defLayerSep :: [Char]+defLayerSep = [' ', ':', '\t']++parseLayerName :: Parse String+parseLayerName = many1 $ satisfy (flip notElem defLayerSep)++data LayerID = AllLayers+             | LRInt Int+             | LRName String+               deriving (Eq, Read)++instance Show LayerID where+    show AllLayers   = "all"+    show (LRInt n)   = show n+    show (LRName nm) = nm++instance Parseable LayerID where+    parse = oneOf [ optionalQuotedString "all" >> return AllLayers+                  , liftM LRInt $ optionalQuoted parse+                  , liftM LRName parseLayerName+                  ]++-- | The list represent (Separator, Name)+data LayerList = LL String [(String, String)]+                 deriving (Eq, Read)++instance Show LayerList where+    show (LL l1 ols) = l1 ++ concatMap (uncurry (++)) ols++instance Parseable LayerList where+    parse = do l1 <- parseLayerName+               ols <- many $ do sep <- parseLayerSep+                                lnm <- parseLayerName+                                return (sep, lnm)+               return $ LL l1 ols++-- -----------------------------------------------------------------------------++data OutputMode = BreadthFirst | NodesFirst | EdgesFirst+                  deriving (Eq, Read)++instance Show OutputMode where+    show BreadthFirst = "breadthfirst"+    show NodesFirst = "nodesfirst"+    show EdgesFirst = "edgesfirst"++instance Parseable OutputMode where+    parse = optionalQuoted+            $ oneOf [ string "breadthfirst" >> return BreadthFirst+                    , string "nodesfirst"   >> return NodesFirst+                    , string "edgesfirst"   >> return EdgesFirst+                    ]++-- -----------------------------------------------------------------------------++data PackMode = PackNode+              | PackClust+              | PackGraph+              | PackArray Bool Bool (Maybe Int) -- ^ Sort by cols, sort+                                                -- by user, number of+                                                -- rows/cols+                deriving (Eq, Read)++instance Show PackMode where+    show PackNode           = "node"+    show PackClust          = "clust"+    show PackGraph          = "graph"+    show (PackArray c u mi) = addNum . isU . isC . isUnder+                              $ "array"+        where+          addNum = maybe id (flip (++) . show) mi+          isUnder = if c || u+                    then flip (++) "_"+                    else id+          isC = if c+                then flip (++) "c"+                else id+          isU = if u+                then flip (++) "u"+                else id++instance Parseable PackMode where+    parse = optionalQuoted+            $ oneOf [ string "node" >> return PackNode+                    , string "clust" >> return PackClust+                    , string "graph" >> return PackGraph+                    , do string "array"+                         mcu <- optional $ do char '_'+                                              many1 $ satisfy (not . isDigit)+                         let c = hasChar mcu 'c'+                             u = hasChar mcu 'u'+                         mi <- optional parse+                         return $ PackArray c u mi+                    ]+        where+          hasChar ms c = maybe False (elem c) ms++-- -----------------------------------------------------------------------------++-- | Upper-case first character is major order;+--   lower-case second character is minor order.+data PageDir = Bl | Br | Tl | Tr | Rb | Rt | Lb | Lt+               deriving (Eq, Read)++instance Show PageDir where+    show Bl = "BL"+    show Br = "BR"+    show Tl = "TL"+    show Tr = "TR"+    show Rb = "RB"+    show Rt = "RT"+    show Lb = "LB"+    show Lt = "LT"++instance Parseable PageDir where+    parse = optionalQuoted+            $ oneOf [ string "BL" >> return Bl+                    , string "BR" >> return Br+                    , string "TL" >> return Tl+                    , string "TR" >> return Tr+                    , string "RB" >> return Rb+                    , string "RT" >> return Rt+                    , string "LB" >> return Lb+                    , string "LT" >> return Lt+                    ]++-- -----------------------------------------------------------------------------++-- | The number of points in the list must be equivalent to 1 mod 3;+--   note that this is not checked.+data Spline = Spline (Maybe Point) (Maybe Point) [Point]+              deriving (Eq, Read)++instance Show Spline where+    show = show . showSpline++    showList ss o = show $ go ss+        where+          go []      = o+          go [s]     = showSpline s ++ o+          go (s:ss') = showSpline s ++ ';' : go ss'++showSpline                   :: Spline -> String+showSpline (Spline ms me ps) = addS . addE+                               . unwords+                               $ map showPoint ps+    where+      addP t = maybe id (\p -> (++) $ t : ',' : show p)+      addS = addP 's' ms+      addE = addP 'e' me++instance Parseable Spline where+    parse = quotedParse parseSpline++    parseList = quotedParse $ sepBy1 parseSpline (char ';')++parseSpline :: Parse Spline+parseSpline = do ms <- parseP 's'+                 whitespace+                 me <- parseP 'e'+                 whitespace+                 ps <- sepBy1 parsePoint whitespace+                 return $ Spline ms me ps+    where+      parseP t = optional $ do char t+                               char ';'+                               parse++-- -----------------------------------------------------------------------------++data QuadType = NormalQT+              | FastQT+              | NoQT+                deriving (Eq, Read)++instance Show QuadType where+    show NormalQT = "normal"+    show FastQT   = "fast"+    show NoQT     = "none"++instance Parseable QuadType where+    parse = optionalQuoted+            $ oneOf [ string "normal" >> return NormalQT+                    , string "fast"   >> return FastQT+                    , string "none"   >> return NoQT+                    ]++-- -----------------------------------------------------------------------------++data RankType = SameRank+              | MinRank+              | SourceRank+              | MaxRank+              | SinkRank+                deriving (Eq, Read)++instance Show RankType where+    show SameRank   = "same"+    show MinRank    = "min"+    show SourceRank = "source"+    show MaxRank    = "max"+    show SinkRank   = "sink"++instance Parseable RankType where+    parse = optionalQuoted+            $ oneOf [ string "same"   >> return SameRank+                    , string "min"    >> return MinRank+                    , string "source" >> return SourceRank+                    , string "max"    >> return MaxRank+                    , string "sink"   >> return SinkRank+                    ]++-- -----------------------------------------------------------------------------++data RankDir = FromTop+             | FromLeft+             | FromBottom+             | FromRight+               deriving (Eq, Read)++instance Show RankDir where+    show FromTop    = "TB"+    show FromLeft   = "LR"+    show FromBottom = "BT"+    show FromRight  = "RL"++instance Parseable RankDir where+    parse = optionalQuoted+            $ oneOf [ string "TB" >> return FromTop+                    , string "LR" >> return FromLeft+                    , string "BT" >> return FromBottom+                    , string "RL" >> return FromRight+                    ]++-- -----------------------------------------------------------------------------++data Shape+    = BoxShape+    | Polygon+    | Ellipse+    | Circle+    | PointShape+    | Egg+    | Triangle+    | Plaintext+    | DiamondShape+    | Trapezium+    | Parallelogram+    | House+    | Pentagon+    | Hexagon+    | Septagon+    | Octagon+    | Doublecircle+    | Doubleoctagon+    | Tripleoctagon+    | Invtriangle+    | Invtrapezium+    | Invhouse+    | Mdiamond+    | Msquare+    | Mcircle+    | Rectangle+    | NoShape+    | Note+    | Tab+    | Folder+    | Box3d+    | Component+      deriving (Eq, Read)++instance Show Shape where+    show BoxShape      = "box"+    show Polygon       = "polygon"+    show Ellipse       = "ellipse"+    show Circle        = "circle"+    show PointShape    = "point"+    show Egg           = "egg"+    show Triangle      = "triangle"+    show Plaintext     = "plaintext"+    show DiamondShape  = "diamond"+    show Trapezium     = "trapezium"+    show Parallelogram = "parallelogram"+    show House         = "house"+    show Pentagon      = "pentagon"+    show Hexagon       = "hexagon"+    show Septagon      = "septagon"+    show Octagon       = "octagon"+    show Doublecircle  = "doublecircle"+    show Doubleoctagon = "doubleoctagon"+    show Tripleoctagon = "tripleoctagon"+    show Invtriangle   = "invtriangle"+    show Invtrapezium  = "invtrapezium"+    show Invhouse      = "invhouse"+    show Mdiamond      = "mdiamond"+    show Msquare       = "msquare"+    show Mcircle       = "mcircle"+    show Rectangle     = "rectangle"+    show NoShape       = "none"+    show Note          = "note"+    show Tab           = "tab"+    show Folder        = "folder"+    show Box3d         = "box3d"+    show Component     = "component"++instance Parseable Shape where+    parse = optionalQuoted+            $ oneOf [ string "box"           >> return BoxShape+                    , string "polygon"       >> return Polygon+                    , string "ellipse"       >> return Ellipse+                    , string "circle"        >> return Circle+                    , string "point"         >> return PointShape+                    , string "egg"           >> return Egg+                    , string "triangle"      >> return Triangle+                    , string "plaintext"     >> return Plaintext+                    , string "diamond"       >> return DiamondShape+                    , string "trapezium"     >> return Trapezium+                    , string "parallelogram" >> return Parallelogram+                    , string "house"         >> return House+                    , string "pentagon"      >> return Pentagon+                    , string "hexagon"       >> return Hexagon+                    , string "septagon"      >> return Septagon+                    , string "octagon"       >> return Octagon+                    , string "doublecircle"  >> return Doublecircle+                    , string "doubleoctagon" >> return Doubleoctagon+                    , string "tripleoctagon" >> return Tripleoctagon+                    , string "invtriangle"   >> return Invtriangle+                    , string "invtrapezium"  >> return Invtrapezium+                    , string "invhouse"      >> return Invhouse+                    , string "mdiamond"      >> return Mdiamond+                    , string "msquare"       >> return Msquare+                    , string "mcircle"       >> return Mcircle+                    , string "rectangle"     >> return Rectangle+                    , string "none"          >> return NoShape+                    , string "note"          >> return Note+                    , string "tab"           >> return Tab+                    , string "folder"        >> return Folder+                    , string "box3d"         >> return Box3d+                    , string "component"     >> return Component+                    ]++-- -----------------------------------------------------------------------------++data SmoothType = NoSmooth+                | AvgDist+                | GraphDist+                | PowerDist+                | RNG+                | Spring+                | TriangleSmooth+                  deriving (Eq, Read)++instance Show SmoothType where+    show NoSmooth       = "none"+    show AvgDist        = "avg_dist"+    show GraphDist      = "graph_dist"+    show PowerDist      = "power_dist"+    show RNG            = "rng"+    show Spring         = "spring"+    show TriangleSmooth = "triangle"++instance Parseable SmoothType where+    parse = optionalQuoted+            $ oneOf [ string "none"       >> return NoSmooth+                    , string "avg_dist"   >> return AvgDist+                    , string "graph_dist" >> return GraphDist+                    , string "power_dist" >> return PowerDist+                    , string "rng"        >> return RNG+                    , string "spring"     >> return Spring+                    , string "triangle"   >> return TriangleSmooth+                    ]++-- -----------------------------------------------------------------------------++-- | It it assumed that at least one of these is @Just{}@.+data StartType = ST (Maybe STStyle) (Maybe Int) -- Use a Word?+                 deriving (Eq, Read)++instance Show StartType where+    show (ST ms mi) = maybe id ((++) . show) ms+                      $ maybe "" show mi++instance Parseable StartType where+    parse = optionalQuoted+            $ do ms <- optional parse+                 mi <- optional parse+                 return $ ST ms mi++data STStyle = RegularStyle+             | Self+             | Random+               deriving (Eq, Read)++instance Show STStyle where+    show RegularStyle = "regular"+    show Self         = "self"+    show Random       = "random"++instance Parseable STStyle where+    parse = oneOf [ string "regular" >> return RegularStyle+                  , string "self"    >> return Self+                  , string "random"  >> return Random+                  ]++-- -----------------------------------------------------------------------------++data Style = Stl StyleName (Maybe String)+             deriving (Eq, Read)++instance Show Style where+    show (Stl nm marg) = maybe snm+                               (\arg -> show $ snm ++ '(' : arg ++ ")")+                               marg+        where+          snm = show nm++instance Parseable Style where+    parse = oneOf [ optionalQuoted $ liftM (\nm -> Stl nm Nothing) parse+                  , quotedParse $ do nm <- parse+                                     char '('+                                     arg <- many1+                                            $ satisfy (flip notElem "()")++                                     char ')'+                                     return $ Stl nm (Just arg)+                  ]++data StyleName = Dashed    -- ^ Nodes and Edges+               | Dotted    -- ^ Nodes and Edges+               | Solid     -- ^ Nodes and Edges+               | Bold      -- ^ Nodes and Edges+               | Invisible -- ^ Nodes and Edges+               | Filled    -- ^ Nodes and Clusters+               | Diagonals -- ^ Nodes only+               | Rounded   -- ^ Nodes and Clusters+                 deriving (Eq, Read)++instance Show StyleName where+    show Filled    = "filled"+    show Invisible = "invis"+    show Diagonals = "diagonals"+    show Rounded   = "rounded"+    show Dashed    = "dashed"+    show Dotted    = "dotted"+    show Solid     = "solid"+    show Bold      = "bold"++instance Parseable StyleName where+    parse = optionalQuoted+            $ oneOf [ string "filled"    >> return Filled+                    , string "invis"     >> return Invisible+                    , string "diagonals" >> return Diagonals+                    , string "rounded"   >> return Rounded+                    , string "dashed"    >> return Dashed+                    , string "dotted"    >> return Dotted+                    , string "solid"     >> return Solid+                    , string "bold"      >> return Bold+                    ]++-- -----------------------------------------------------------------------------++newtype PortPos = PP CompassPoint+    deriving (Eq, Read)++instance Show PortPos where+    show (PP cp) = show cp++instance Parseable PortPos where+    parse = liftM PP parse++data CompassPoint = North+                  | NorthEast+                  | East+                  | SouthEast+                  | South+                  | SouthWest+                  | West+                  | NorthWest+                  | CenterPoint+                  | NoCP+                    deriving (Eq, Read)++instance Show CompassPoint where+    show North       = "n"+    show NorthEast   = "ne"+    show East        = "e"+    show SouthEast   = "se"+    show South       = "s"+    show SouthWest   = "sw"+    show West        = "w"+    show NorthWest   = "nw"+    show CenterPoint = "c"+    show NoCP        = "_"++instance Parseable CompassPoint where+    parse = optionalQuoted+            $ oneOf [ string "n"  >> return North+                    , string "ne" >> return NorthEast+                    , string "e"  >> return East+                    , string "se" >> return SouthEast+                    , string "s"  >> return South+                    , string "sw" >> return SouthWest+                    , string "w"  >> return West+                    , string "nw" >> return NorthWest+                    , string "c"  >> return CenterPoint+                    , string "_"  >> return NoCP+                    ]++-- -----------------------------------------------------------------------------++data ViewPort = VP { wVal  :: Double+                   , hVal  :: Double+                   , zVal  :: Double+                   , focus :: Maybe FocusType+                   }+                deriving (Eq, Read)++instance Show ViewPort where+    show vp = show+              . maybe id (flip (++) . show) (focus vp)+              $ show (wVal vp)+              ++ ',' : show (hVal vp)+              ++ ',' : show (zVal vp)++instance Parseable ViewPort where+    parse = quotedParse+            $ do wv <- parse+                 char ','+                 hv <- parse+                 char ','+                 zv <- parse+                 mf <- optional $ char ',' >> parse+                 return $ VP wv hv zv mf++data FocusType = XY Point+               | NodeName String+                 deriving (Eq, Read)++instance Show FocusType where+    show (XY p)        = showPoint p+    show (NodeName nm) = nm++instance Parseable FocusType where+    parse = oneOf [ liftM XY parsePoint+                  , liftM NodeName stringBlock+                  ]++-- -----------------------------------------------------------------------------++-- | Note that 'VCenter' is only valid for Nodes.+data VerticalPlacement = VTop+                       | VCenter+                       | VBottom+                         deriving (Eq, Read)++instance Show VerticalPlacement where+    show VTop    = "t"+    show VCenter = "c"+    show VBottom = "b"++instance Parseable VerticalPlacement where+    parse = optionalQuoted+            $ oneOf [ string "t" >> return VTop+                    , string "c" >> return VCenter+                    , string "b" >> return VBottom+                    ]+++-- -----------------------------------------------------------------------------++data ScaleType = UniformScale+               | NoScale+               | FillWidth+               | FillHeight+               | FillBoth+                 deriving (Eq, Read)++instance Show ScaleType where+    show UniformScale = "true"+    show NoScale      = "false"+    show FillWidth    = "width"+    show FillHeight   = "height"+    show FillBoth     = "both"++instance Parseable ScaleType where+    parse = optionalQuoted+            $ oneOf [ string "true"   >> return UniformScale+                    , string "false"  >> return NoScale+                    , string "width"  >> return FillWidth+                    , string "height" >> return FillHeight+                    , string "both"   >> return FillBoth+                    ]++-- -----------------------------------------------------------------------------++data Justification = JLeft+                   | JRight+                   | JCenter+                     deriving (Eq, Read)++instance Show Justification where+    show JLeft   = "l"+    show JRight  = "r"+    show JCenter = "c"++instance Parseable Justification where+    parse = optionalQuoted+            $ oneOf [ string "l" >> return JLeft+                    , string "r" >> return JRight+                    , string "c" >> return JCenter+                    ]++-- -----------------------------------------------------------------------------++data Ratios = AspectRatio Double+            | FillRatio+            | CompressRatio+            | ExpandRatio+            | AutoRatio+              deriving (Eq, Read)++instance Show Ratios where+    show (AspectRatio r) = show r+    show FillRatio       = "fill"+    show CompressRatio   = "compress"+    show ExpandRatio     = "expand"+    show AutoRatio       = "auto"++instance Parseable Ratios where+    parse = optionalQuoted+            $ oneOf [ liftM AspectRatio parse+                    , string "fill"     >> return FillRatio+                    , string "compress" >> return CompressRatio+                    , string "expand"   >> return ExpandRatio+                    , string "auto"     >> return AutoRatio+                    ]++-- -----------------------------------------------------------------------------++-- | Represents 'String's that definitely have quotes around them.+newtype QuotedString = QS { qStr :: String }+    deriving (Eq, Read)++instance Show QuotedString where+    show = show . qStr++instance Parseable QuotedString where+    parse = liftM (QS . tail . init) quotedString++-- -----------------------------------------------------------------------------
Data/GraphViz/Commands.hs view
@@ -30,15 +30,15 @@ import System.Process import Data.Array.IO import Control.Concurrent-import Control.Exception+import Control.Exception.Extensible  import Data.GraphViz.Types  -- | The available Graphviz commands.-data GraphvizCommand = DotCmd | Neato | TwoPi | Circo | Fdp+data GraphvizCommand = Dot | Neato | TwoPi | Circo | Fdp  instance Show GraphvizCommand where-    show DotCmd = "dot"+    show Dot    = "dot"     show Neato  = "neato"     show TwoPi  = "twopi"     show Circo  = "circo"@@ -46,7 +46,7 @@  -- | The default command for directed graphs. dirCommand :: GraphvizCommand-dirCommand = DotCmd+dirCommand = Dot  -- | The default command for undirected graphs. undirCommand :: GraphvizCommand@@ -62,7 +62,9 @@ --   Note that it is not possible to choose between output variants, --   and that not all of these may be available on your system. -----   This will probably be improved in future.+--   This will probably be improved in future.  For now, more+--   information is available from:+--     <http://graphviz.org/doc/info/output.html> data GraphvizOutput = Canon                     | Cmap                     | Cmapx@@ -156,7 +158,8 @@ runGraphvizCommand :: GraphvizCommand -> DotGraph -> GraphvizOutput                    -> FilePath -> IO Bool runGraphvizCommand  cmd gr t fp-    = do pipe <- tryJust catcher $ openFile fp WriteMode+    = do pipe <- tryJust (\(SomeException _) -> return ())+                 $ openFile fp WriteMode          case pipe of            (Left _)  -> return False            (Right f) -> do file <- graphvizWithHandle cmd gr t (flip squirt f)@@ -164,26 +167,23 @@                            case file of                              (Just _) -> return True                              _        -> return False-    where-      catcher   :: IOError -> Maybe ()-      catcher _ = Just ()  -- graphvizWithHandle sometimes throws an error about handles not--- being closed properly: investigate.+-- being closed properly: investigate (now on the official TODO).  -- | Run the chosen Graphviz command on this graph, but send the result to the --   given handle rather than to a file. --   The result is wrapped in 'Maybe' rather than throwing an error. graphvizWithHandle :: (Show a) => GraphvizCommand -> DotGraph -> GraphvizOutput-                   -> (Handle -> IO a) -> IO (Maybe a)+                      -> (Handle -> IO a) -> IO (Maybe a) graphvizWithHandle cmd gr t f-    = do (inp, outp, errp, proc) <- runInteractiveCommand command+    = do (inp, outp, errp, prc) <- runInteractiveCommand command          forkIO $ hPrint inp gr >> hClose inp          forkIO $ (hGetContents errp >>= hPutStr stderr >> hClose errp)          a <- f outp          -- Don't close outp until f finishes.          a `seq` hClose outp-         exitCode <- waitForProcess proc+         exitCode <- waitForProcess prc          case exitCode of            ExitSuccess -> return (Just a)            _           -> return Nothing
Data/GraphViz/ParserCombinators.hs view
@@ -8,50 +8,231 @@    Maintainer  : Ivan.Miljenovic@gmail.com     This module defines simple helper functions for use with-   @Text.ParserCombinators.Poly.Lazy@.+   "Text.ParserCombinators.Poly.Lazy".++   Note that the 'Parseable' instances for 'Bool', etc. match those+   specified for use with GraphViz (e.g. non-zero integers are+   equivalent to 'True').++   You should not be using this module; rather, it is here for+   informative/documentative reasons.  If you want to parse a+   @'Data.GraphViz.Types.DotGraph'@, you should use+   @'Data.GraphViz.Types.parseDotGraph'@ rather than its 'Parseable'+   instance.+ -} -module Data.GraphViz.ParserCombinators where+module Data.GraphViz.ParserCombinators+    ( module Text.ParserCombinators.Poly.Lazy+    , Parse+    , Parseable(..)+    , stringBlock+    , quotedString+    , parseAndSpace+    , string+    , strings+    , hasString+    , char+    , whitespace+    , whitespace'+    , optionalQuotedString+    , optionalQuoted+    , quotedParse+    , newline+    , skipToNewline+    , parseField+    , parseBoolField+    , commaSep+    , commaSep'+    ) where  import Text.ParserCombinators.Poly.Lazy+import Data.Char( digitToInt+                , isAsciiLower+                , isAsciiUpper+                , isDigit+                , isSpace+                , toLower+                )+import Data.Function(on)+import Data.Maybe(isJust)+import Data.Ratio((%)) import Control.Monad -string :: String -> Parser Char String+-- -----------------------------------------------------------------------------+-- Based off code from Text.Parse in the polyparse library++-- | A @ReadS@-like type alias.+type Parse a = Parser Char a++class Parseable a where+    parse :: Parse a++    parseList :: Parse [a]+    parseList = oneOf [ char '[' >> whitespace' >> char ']' >> return []+                      , bracketSep (parseAndSpace $ char '[')+                                   (parseAndSpace $ char ',')+                                   (parseAndSpace $ char ']')+                                   (parseAndSpace parse)+                      ]++instance Parseable Int where+    parse = parseInt++instance Parseable Double where+    parse = parseSigned parseFloat++instance Parseable Bool where+    parse = oneOf [ string "true" >> return True+                  , string "false" >> return False+                  , liftM (zero /=) parseInt+                  ]+        where+          zero :: Int+          zero = 0++instance Parseable Char where+    parse = next++    parseList = oneOf [ stringBlock+                      , quotedString+                      ]++-- | Used when quotes are explicitly required;+--   note that the quotes are not stripped off.++instance (Parseable a) => Parseable [a] where+    parse = parseList++instance (Parseable a, Parseable b) => Parseable (Either a b) where+    parse = oneOf [ liftM Left parse+                  , liftM Right parse+                  ]++stringBlock :: Parse String+stringBlock = do frst <- satisfy frstCond+                 rest <- many (satisfy restCond)+                 return $ frst : rest+    where+      frstCond c = any ($c) [ isAsciiUpper+                            , isAsciiLower+                            , (==) '_'+                            , \ x -> x >= '\200' && x <= '\377'+                            ]+      restCond c = frstCond c || isDigit c++quotedString :: Parse String+quotedString = do w <- word+                  if head w == '"'+                     then return w+                     else fail $ "Not a quoted string: " ++ w++word :: Parse String+word = P (\s-> case lex s of+                   []         -> Failure s  "no input? (impossible)"+                   [("","")]  -> Failure "" "no input?"+                   [("",s')]  -> Failure s' "lexing failed?"+                   ((x,s'):_) -> Success s' x+         )++parseSigned :: Real a => Parse a -> Parse a+parseSigned p = do '-' <- next; commit (fmap negate p)+                `onFail`+                p++parseInt :: (Integral a) => Parse a+parseInt = do cs <- many1 (satisfy isDigit)+              return (foldl1 (\n d-> n*radix+d)+                                   (map (fromIntegral . digitToInt) cs))+           `adjustErr` (++ "\nexpected one or more digits")+    where+      radix = 10++parseFloat :: (RealFrac a) => Parse a+parseFloat = do ds   <- many1 (satisfy isDigit)+                frac <- (do '.' <- next+                            many (satisfy isDigit)+                              `adjustErrBad` (++"expected digit after .")+                         `onFail` return [] )+                expn  <- parseExp `onFail` return 0+                ( return . fromRational . (* (10^^(expn - length frac)))+                  . (%1) . fst+                  . runParser parseInt) (ds++frac)+             `onFail`+             do w <- many (satisfy (not.isSpace))+                case map toLower w of+                  "nan"      -> return (0/0)+                  "infinity" -> return (1/0)+                  _          -> fail "expected a floating point number"+  where parseExp = do 'e' <- fmap toLower next+                      commit (do '+' <- next; parseInt+                              `onFail`+                              parseSigned parseInt)++-- -----------------------------------------------------------------------------++parseAndSpace   :: Parse a -> Parse a+parseAndSpace p = p `discard` whitespace'++string :: String -> Parse String string = mapM char -strings :: [String] -> Parser Char String+strings :: [String] -> Parse String strings = oneOf . map string -char :: Char -> Parser Char Char-char = satisfy . (==)+hasString :: String -> Parse Bool+hasString = liftM isJust . optional . string -noneOf :: (Eq a) => [a] -> Parser a a-noneOf t = satisfy (\x -> and . map ((/= x) $) $ t)+char   :: Char -> Parse Char+char c = satisfy (((==) `on` toLower) c)+         `adjustErr`+         (++ "\nnot the expected char: " ++ [c]) -digit :: Parser Char Char-digit = oneOf . map char $ ['0'..'9']+noneOf :: (Eq a) => [a] -> Parser a a+noneOf t = satisfy (\x -> all (/= x) t) -number :: (Num a, Read a) => Parser Char a-number = liftM read $ many1 digit+whitespace :: Parse String+whitespace = many1 (satisfy isSpace) -floatingNumber :: (Floating a, Read a) => Parser Char a-floatingNumber = do { a::Integer <- number-                    ; char '.'-                    ; b::Integer <- number-                    ; return . read $ (show a) ++ ('.':(show b))-                    }+whitespace' :: Parse String+whitespace' = many (satisfy isSpace) -whitespace :: Parser Char String-whitespace = many1 (oneOf . map char $ [' ', '\t'])+optionalQuotedString :: String -> Parse String+optionalQuotedString = optionalQuoted . string -optionalQuotedString :: String -> Parser Char String-optionalQuotedString s = oneOf [string s, char '"' >> string s >>= \s' -> char '"' >> return s']+optionalQuoted   :: Parse a -> Parse a+optionalQuoted p = oneOf [ p+                         , quotedParse p+                         ] -optionalQuoted :: Parser Char a -> Parser Char a-optionalQuoted p = oneOf [p, char '"' >> p >>= \r -> char '"' >> return r]+quotedParse   :: Parse a -> Parse a+quotedParse p = char '"' >> p `discard` char '"' -newline :: Parser Char String+newline :: Parse String newline = oneOf . map string $ ["\r\n", "\n", "\r"] -skipToNewline :: Parser Char ()+skipToNewline :: Parse () skipToNewline = many (noneOf ['\n','\r']) >> newline >> return ()++parseField     :: (Parseable a) => String -> Parse a+parseField fld = do string fld+                    whitespace'+                    char '='+                    whitespace'+                    parse++parseBoolField     :: String -> Parse Bool+parseBoolField fld = oneOf [ parseField fld+                           , string fld >> return True+                           ]++commaSep :: (Parseable a, Parseable b) => Parse (a, b)+commaSep = commaSep' parse parse++commaSep'       :: Parse a -> Parse b -> Parse (a,b)+commaSep' pa pb = do a <- pa+                     whitespace'+                     char ','+                     whitespace'+                     b <- pb+                     return (a,b)
Data/GraphViz/Types.hs view
@@ -1,7 +1,3 @@-{-# LANGUAGE NamedFieldPuns-           , ScopedTypeVariables-           #-}- {- |    Module      : Data.GraphViz.Types    Description : Definition of the GraphViz types.@@ -10,41 +6,81 @@    Maintainer  : Ivan.Miljenovic@gmail.com     This module defines the overall types and methods that interact-   with them for the GraphViz library.+   with them for the GraphViz library.  The specifications are based+   loosely upon the information available at:+     <http://graphviz.org/doc/info/lang.html> -}  module Data.GraphViz.Types     ( DotGraph(..)+    , GraphID(..)     , DotNode(..)     , DotEdge(..)-    , readDotGraph+    , parseDotGraph+    , setID+    , makeStrict+    , isValidGraph+    , invalidAttributes     ) where -import Data.Maybe-import Control.Monad-import Text.ParserCombinators.Poly.Lazy- import Data.GraphViz.Attributes import Data.GraphViz.ParserCombinators +import Data.Maybe+import Control.Monad+ -- -----------------------------------------------------------------------------  -- | The internal representation of a graph in Dot form.-data DotGraph = DotGraph { graphAttributes :: [Attribute]-                         , graphNodes :: [DotNode]-                         , graphEdges :: [DotEdge]-                         , directedGraph :: Bool+data DotGraph = DotGraph { strictGraph     :: Bool+                         , directedGraph   :: Bool+                         , graphID         :: Maybe GraphID+                         , graphAttributes :: [Attribute]+                         , graphNodes      :: [DotNode]+                         , graphEdges      :: [DotEdge]                          }+                deriving (Eq, Read) +-- | A strict graph disallows multiple edges.+makeStrict   :: DotGraph -> DotGraph+makeStrict g = g { strictGraph = True }++setID     :: GraphID -> DotGraph -> DotGraph+setID i g = g { graphID = Just i }++-- | Check if all the @Attribute@s are being used correctly.+isValidGraph   :: DotGraph -> Bool+isValidGraph g = null gas && null nas && null eas+    where+      (gas, nas, eas) = invalidAttributes g++-- | Return all those @Attribute@s which aren't being used properly.+invalidAttributes   :: DotGraph -> ( [Attribute]+                                   , [(DotNode, Attribute)]+                                   , [(DotEdge, Attribute)]+                                   )+invalidAttributes g = ( invalidGraphAttributes g+                      , concatMap invalidNodeAttributes $ graphNodes g+                      , concatMap invalidEdgeAttributes $ graphEdges g+                      )++invalidGraphAttributes :: DotGraph -> [Attribute]+invalidGraphAttributes = filter (not . usedByGraphs) . graphAttributes+ instance Show DotGraph where-    show (DotGraph { graphAttributes, graphNodes, graphEdges, directedGraph })-        = unlines $ gType : " {" : (rest ++ ["}"])+    show g+        = unlines $ (hdr ++ " {") : (rest ++ ["}"])         where-          gType = if directedGraph then dirGraph else undirGraph-          rest = case graphAttributes of+          hdr = strct . addId $ gType+          strct = if strictGraph g+                  then ("strict " ++)+                  else id+          addId = maybe id (\ i -> flip (++) $ ' ' : show i) $ graphID g+          gType = if directedGraph g then dirGraph else undirGraph+          rest = case graphAttributes g of                    [] -> nodesEdges-                   a -> ("\tgraph " ++ (show a) ++ ";") : nodesEdges-          nodesEdges = (map show graphNodes) ++ (map show graphEdges)+                   a -> ("\tgraph " ++ show a ++ ";") : nodesEdges+          nodesEdges = map show (graphNodes g) ++ map show (graphEdges g)  dirGraph :: String dirGraph = "digraph"@@ -52,10 +88,69 @@ undirGraph :: String undirGraph = "graph" +-- | Parse a limited subset of the Dot language to form a 'DotGraph'+--   (that is, the caveats listed in "Data.GraphViz.Attributes" aside,+--   Dot graphs are parsed if they match the layout of DotGraph).+parseDotGraph :: Parse DotGraph+parseDotGraph = parse++instance Parseable DotGraph where+    parse = do isStrict <- parseAndSpace $ hasString "strict"+               gType <- strings [dirGraph,undirGraph]+               gId <- optional (parse `discard` whitespace)+               whitespace+               char '{'+               skipToNewline+               as <- liftM concat $+                     many (whitespace' >>+                           oneOf [ string "edge" >> skipToNewline >> return []+                                 , string "node" >> skipToNewline >> return []+                                 , string "graph" >> whitespace+                                              >> parse `discard` skipToNewline+                                 ]+                          )+               ns <- many1 (whitespace' >> parse `discard` skipToNewline)+               es <- many1 (whitespace' >> parse `discard` skipToNewline)+               char '}'+               return DotGraph { strictGraph = isStrict+                               , directedGraph = gType == dirGraph+                               , graphID = gId+                               , graphAttributes = as+                               , graphNodes = ns+                               , graphEdges = es+                               }++            `adjustErr`+            (++ "\nNot a valid DotGraph")+ -- ----------------------------------------------------------------------------- +data GraphID = Str String+             | Num Double+             | QStr QuotedString+             | HTML URL+               deriving (Eq, Read)++instance Show GraphID where+    show (Str str)  = str+    show (Num n)    = show n+    show (QStr str) = show str+    show (HTML url) = show url++instance Parseable GraphID where+    parse = oneOf [ liftM Str stringBlock+                  , liftM Num parse+                  , liftM QStr parse+                  , liftM HTML parse+                  ]+            `adjustErr`+            (++ "\nNot a valid GraphID")++-- -----------------------------------------------------------------------------+ -- | A node in 'DotGraph' is either a singular node, or a cluster --   containing nodes (or more clusters) within it.+--   At the moment, clusters are not parsed. data DotNode     = DotNode { nodeID :: Int               , nodeAttributes :: [Attribute]@@ -64,24 +159,46 @@                  , clusterAttributes :: [Attribute]                  , clusterElems      :: [DotNode]                  }+      deriving (Eq, Read) +invalidNodeAttributes                :: DotNode -> [(DotNode, Attribute)]+invalidNodeAttributes n@DotNode{}    = map ((,) n)+                                       . filter (not . usedByNodes)+                                       $ nodeAttributes n+invalidNodeAttributes c@DotCluster{} = cErr ++ nErr+    where+      cErr = map ((,) c) . filter (not . usedByClusters)+             $ clusterAttributes c+      nErr = concatMap invalidNodeAttributes $ clusterElems c+ instance Show DotNode where-    show n = init . unlines . addTabs $ nodesToString n+    show = init . unlines . addTabs . nodesToString  nodesToString :: DotNode -> [String]-nodesToString (DotNode { nodeID, nodeAttributes })-    | null nodeAttributes = [nID ++ ";"]-    | otherwise           = [nID ++ (' ':((show nodeAttributes) ++ ";"))]+nodesToString n@(DotNode {})+    | null nAs  = [nID ++ ";"]+    | otherwise = [nID ++ (' ':(show nAs ++ ";"))]     where-      nID = show nodeID-nodesToString (DotCluster { clusterID, clusterAttributes, clusterElems })-    = ["subgraph cluster_" ++ clusterID ++ " {"] ++ (addTabs inner) ++ ["}"]+      nID = show $ nodeID n+      nAs = nodeAttributes n+nodesToString c@(DotCluster {})+    = ["subgraph cluster_" ++ clusterID c ++ " {"] ++ addTabs inner ++ ["}"]     where-      inner = case clusterAttributes of+      inner = case clusterAttributes c of                 [] -> nodes-                a  -> ("graph " ++ (show a) ++ ";") : nodes-      nodes = concatMap nodesToString clusterElems+                a  -> ("graph " ++ show a ++ ";") : nodes+      nodes = concatMap nodesToString $ clusterElems c ++instance Parseable DotNode where+    parse = do nId <- parse+               as <- optional (whitespace >> parse)+               char ';'+               return DotNode { nodeID = nId+                              , nodeAttributes = fromMaybe [] as }+            `adjustErr`+            (++ "\nNot a valid DotNode")+ -- | Prefix each 'String' with a tab character. addTabs :: [String] -> [String] addTabs = map ('\t':)@@ -94,15 +211,22 @@                        , edgeAttributes :: [Attribute]                        , directedEdge   :: Bool                        }+             deriving (Eq, Read) +invalidEdgeAttributes   :: DotEdge -> [(DotEdge, Attribute)]+invalidEdgeAttributes e = map ((,) e)+                          . filter (not . usedByEdges)+                          $ edgeAttributes e+ instance Show DotEdge where-    show (DotEdge { edgeHeadNodeID, edgeTailNodeID, edgeAttributes, directedEdge })-        = '\t' : ((show edgeTailNodeID) ++ edge ++ (show edgeHeadNodeID) ++ attributes)+    show e+        = '\t' : (show (edgeHeadNodeID e)+                  ++ edge ++ show (edgeTailNodeID e) ++ attributes)           where-            edge = " " ++ (if directedEdge then dirEdge else undirEdge) ++ " "-            attributes = case edgeAttributes of+            edge = " " ++ (if directedEdge e then dirEdge else undirEdge) ++ " "+            attributes = case edgeAttributes e of                            [] -> ";"-                           a  -> ' ':((show a) ++ ";")+                           a  -> ' ':(show a ++ ";")  dirEdge :: String dirEdge = "->"@@ -110,52 +234,21 @@ undirEdge :: String undirEdge = "--" --- --------------------------------------------------------------------------------- | Parse a 'DotNode'-readDotNode :: Parser Char DotNode-readDotNode = do { optional whitespace-                 ; nodeID <- number-                 ; as <- optional (whitespace >> readAttributesList)-                 ; char ';'-                 ; skipToNewline-                 ; return (DotNode { nodeID, nodeAttributes = fromMaybe [] as })-                 }---- | Parse a 'DotEdge'-readDotEdge :: Parser Char DotEdge-readDotEdge = do { optional whitespace-                 ; edgeTailNodeID <- number-                 ; whitespace-                 ; edge <- strings [dirEdge,undirEdge]-                 ; whitespace-                 ; edgeHeadNodeID <- number-                 ; as <- optional (whitespace >> readAttributesList)-                 ; char ';'-                 ; skipToNewline-                 ; return (DotEdge { edgeHeadNodeID-                                   , edgeTailNodeID-                                   , edgeAttributes = fromMaybe [] as-                                   , directedEdge = edge == dirEdge })-                 }+instance Parseable DotEdge where+    parse = do whitespace'+               eHead <- parse+               whitespace+               edgeType <- strings [dirEdge,undirEdge]+               whitespace+               eTail <- parse+               as <- optional (whitespace >> parse)+               char ';'+               return DotEdge { edgeHeadNodeID = eHead+                              , edgeTailNodeID = eTail+                              , edgeAttributes = fromMaybe [] as+                              , directedEdge   = edgeType == dirEdge+                              }+            `adjustErr`+            (++ "\nNot a valid DotEdge") --- | Parse a 'DotGraph'-readDotGraph :: Parser Char DotGraph-readDotGraph = do { d <- strings [dirGraph,undirGraph]-                  ; let directedGraph = d == dirGraph-                  ; whitespace-                  ; char '{'-                  ; skipToNewline-                  ; graphAttributes-                      <- liftM concat $-                         many (optional whitespace >>-                               oneOf [ (string "edge" >> skipToNewline >> return [])-                                     , (string "node" >> skipToNewline >> return [])-                                     , (string "graph" >> whitespace >> readAttributesList >>= \as -> skipToNewline >> return as)-                                     ]-                              )-                  ; graphNodes <- many readDotNode-                  ; graphEdges <- many readDotEdge-                  ; char '}'-                  ; return $ DotGraph { graphAttributes, graphNodes, graphEdges, directedGraph }-                  }+-- -----------------------------------------------------------------------------
TODO view
@@ -1,10 +1,16 @@ Areas to work on: -* Add support for Data.Graph-style graphs.+* Utilise the generic graph class once it is finalised.  * Allow user to choose whether or not the graph is meant to be   directed or undirected. -* Ensure Data.GraphViz.Attributes contains all supported attributes for Dot.+* Improve parsing to fully (or at least follow more closely) support Dot. -* Remove (or at least minimise) usage of extensions.+* Improve clustering/subgraph support.++* Use a PrettyPrinter rather than Show to generate Dot output.++* Improve Output support.++* Find and fix the handle closing bug with graphvizWithHandle.
graphviz.cabal view
@@ -1,37 +1,47 @@ Name:               graphviz-Version:            2009.5.1+Version:            2999.0.0.0 Stability:          Beta-Copyright:          Matthew Sackman, Ivan Lazar Miljenovic-Category:           Graphics-Maintainer:         Ivan.Miljenovic@gmail.com-Author:             Matthew Sackman, Ivan Lazar Miljenovic+Synopsis:           GraphViz wrapper for Haskell.+Description:        Provides convenient functions to convert FGL+                      graphs into the Dot language used by the+                      GraphViz <http://graphviz.org/> programs with a+                      large degree of customisation for layout, etc.++                    Also allows a limited amount of parsing of Dot,+                      and usage of GraphViz to attach positional data+                      to each node and edge in the graph.+Category:           Graphs, Graphics License:            BSD3 License-File:       LICENSE-Extra-Source-Files: TODO-Cabal-Version:      >= 1.6+Copyright:          Matthew Sackman, Ivan Lazar Miljenovic+Author:             Matthew Sackman, Ivan Lazar Miljenovic+Maintainer:         Ivan.Miljenovic@gmail.com Build-Type:         Simple-Synopsis:           GraphViz wrapper for Haskell.-Description:-  Provides convenient functions to convert FGL graphs into the Dot-  language used by the GraphViz (http://graphviz.org/) programs with a-  large degree of customisation for layout, etc.+Cabal-Version:      >= 1.6+Extra-Source-Files: TODO+                    Changelog -  Also allows a limited amount of parsing of Dot, and usage of-  GraphViz to attach positional data to each node and edge in the-  graph.+Source-Repository head+    Type:         darcs+    Location:     http://code.haskell.org/graphviz  Library {-        Build-Depends:     base == 4.*, containers, process, array,-                           fgl, polyparse >= 1.1+        Build-Depends:     base >= 3 && < 5,+                           extensible-exceptions,+                           containers,+                           process,+                           array,+                           fgl,+                           polyparse >= 1.1          Exposed-Modules:   Data.GraphViz                            Data.GraphViz.Types                            Data.GraphViz.Commands                            Data.GraphViz.Attributes+                           Data.GraphViz.ParserCombinators          Other-Modules:     Data.GraphViz.Types.Clustering-                           Data.GraphViz.ParserCombinators -        Ghc-Options:       -Wall -fno-warn-name-shadowing+        Ghc-Options:       -Wall         Ghc-Prof-Options:  -prof -auto-all }