haphviz 0.1.0.1 → 0.1.0.2
raw patch · 2 files changed
+65/−3 lines, 2 filesdep ~basePVP: minor bump suggested
API additions: PVP suggests at least a minor version bump
Dependency ranges changed: base
API changes (from Hackage documentation)
+ Text.Dot.Gen.FSA: fsaGraph :: [Text] -> Text -> [Text] -> [(Text, Text, Text)] -> DotGraph
Files
- haphviz.cabal +10/−3
- src/Text/Dot/Gen/FSA.hs +55/−0
haphviz.cabal view
@@ -2,9 +2,15 @@ -- documentation, see http://haskell.org/cabal/users-guide/ name: haphviz-version: 0.1.0.1+version: 0.1.0.2 synopsis: Graphviz code generation with Haskell-description: Graphviz code generation with Haskell+description:+ There are multiple ways to describe this package:++ - "A Turing-complete encoding system for graphviz"+ - "A graph visualization code generation EDSL"+ - "An easy way to draw graphs"+ author: Tom Sydney Kerckhove maintainer: syd.kerckhove@gmail.com copyright: Tom Sydney Kerckhove 2015@@ -20,11 +26,12 @@ library exposed-modules: Text.Dot+ Text.Dot.Gen.FSA other-modules: Text.Dot.Gen Text.Dot.Render Text.Dot.Types.Internal -- other-extensions: - build-depends: base >= 4.6 && < 4.9+ build-depends: base >= 4.6 && < 4.10 , text >= 1.2 && < 1.3 , mtl >= 2.2 && < 2.3 hs-source-dirs: src
+ src/Text/Dot/Gen/FSA.hs view
@@ -0,0 +1,55 @@+{-# LANGUAGE OverloadedStrings #-}+module Text.Dot.Gen.FSA where++import Text.Dot++import Control.Monad (forM, forM_, when)+import Data.Maybe (fromMaybe, isNothing)++import Data.Text+import qualified Data.Text as T+import qualified Data.Text.IO as T++-- | An easy way to generate an FSA visualization+fsaGraph :: [Text] -- ^ Set of states+ -> Text -- Initial state+ -> [Text] -- Accepting states+ -> [(Text, Text, Text)] -- ^ Edges: From, To, Symbol+ -> DotGraph+fsaGraph states initial accepting edges = graph_ directed $ do+ nodeDec [width =: "0", height =: "0"] -- Nodes as small as possible+ rankdir leftRight++ stateNodes <- forM states $ \s -> do+ n <- newNode+ genNode n $+ if s `elem` accepting+ then [label =: s, shape =: "doublecircle"]+ else [label =: s]+ return (s, n)++ -- Check that accepting states are actually states+ forM_ accepting $ \s -> do+ when+ (isNothing $ lookup s stateNodes)+ (error $ "Accepting state is not in the set of states: " ++ T.unpack s)++ -- Draw an edge from an invisible state to the initial state+ case lookup initial stateNodes of+ Nothing -> error "Initial state is not in the set of states"+ Just initialNode -> do+ n <- newNode+ genNode n ["style" =: "invis"]+ n --> initialNode++ -- Draw the edges+ forM_ edges $ \(from, to, symbol) -> do+ let fromNode = fromMaybe+ (error $ "From node not found: " ++ T.unpack from)+ (lookup from stateNodes)+ let toNode = fromMaybe+ (error $ "To node not found: " ++ T.unpack to)+ (lookup to stateNodes)+ genEdge fromNode toNode [label =: symbol]++