Skip to content

Commit

Permalink
Filter recipe graph (#2033)
Browse files Browse the repository at this point in the history
* add filter options to the recipe graph to cut down the noise
  • Loading branch information
xsebek authored Jul 14, 2024
1 parent 35c385a commit 363f108
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 12 deletions.
11 changes: 9 additions & 2 deletions app/doc/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ import Data.Foldable qualified
import Data.Maybe (fromMaybe)
import Data.Text qualified as T
import Options.Applicative
import Swarm.Doc.Gen (GenerateDocs (..), PageAddress (..), SheetType (..), generateDocs)
import Swarm.Doc.Gen (EdgeFilter (..), GenerateDocs (..), PageAddress (..), SheetType (..), generateDocs)
import Swarm.Doc.Keyword (EditorType (..))

cliParser :: Parser GenerateDocs
cliParser =
subparser $
mconcat
[ command "recipes" (info (pure RecipeGraph) $ progDesc "Output graphviz dotfile of entity dependencies based on recipes")
[ command "recipes" (info (RecipeGraph <$> edgeFilter <**> helper) $ progDesc "Output graphviz dotfile of entity dependencies based on recipes")
, command "editors" (info (EditorKeywords <$> editor <**> helper) $ progDesc "Output editor keywords")
, command "keys" (info (pure SpecialKeyNames) $ progDesc "Output list of recognized special key names")
, command "cheatsheet" (info (CheatSheet <$> address <*> cheatsheet <**> helper) $ progDesc "Output nice Wiki tables")
Expand All @@ -30,6 +30,13 @@ cliParser =
, Just Emacs <$ switch (long "emacs" <> help "Generate for the Emacs editor")
, Just Vim <$ switch (long "vim" <> help "Generate for the Vim editor")
]
edgeFilter :: Parser EdgeFilter
edgeFilter =
Data.Foldable.asum
[ pure NoFilter
, FilterForward <$ switch (long "forward" <> help "Show only forward edges")
, FilterNext <$ switch (long "next" <> help "Show only edges to next group")
]
address :: Parser PageAddress
address =
let replace a b = T.unpack . T.replace a b . T.pack
Expand Down
39 changes: 29 additions & 10 deletions src/swarm-doc/Swarm/Doc/Gen.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ module Swarm.Doc.Gen (

-- ** Recipe graph data
RecipeGraphData (..),
EdgeFilter (..),
classicScenarioRecipeGraphData,
ignoredEntities,
) where
Expand All @@ -25,6 +26,7 @@ import Control.Lens (view, (^.))
import Control.Monad (zipWithM, zipWithM_)
import Data.Containers.ListUtils (nubOrd)
import Data.Foldable (toList)
import Data.List qualified as List
import Data.List.Extra (enumerate)
import Data.Map.Lazy (Map, (!))
import Data.Map.Lazy qualified as Map
Expand Down Expand Up @@ -64,7 +66,7 @@ import Text.Dot qualified as Dot
-- | An enumeration of the kinds of documentation we can generate.
data GenerateDocs where
-- | Entity dependencies by recipes.
RecipeGraph :: GenerateDocs
RecipeGraph :: EdgeFilter -> GenerateDocs
-- | Keyword lists for editors.
EditorKeywords :: Maybe EditorType -> GenerateDocs
-- | List of special key names recognized by 'Swarm.Language.Syntax.Key' command
Expand All @@ -78,7 +80,7 @@ data GenerateDocs where
-- | Generate the requested kind of documentation to stdout.
generateDocs :: GenerateDocs -> IO ()
generateDocs = \case
RecipeGraph -> generateRecipe >>= putStrLn
RecipeGraph ef -> generateRecipe ef >>= putStrLn
EditorKeywords e ->
case e of
Just et -> generateEditorKeywords et
Expand Down Expand Up @@ -139,13 +141,22 @@ generateSpecialKeyNames =
-- GENERATE GRAPHVIZ: ENTITY DEPENDENCIES BY RECIPES
-- ----------------------------------------------------------------------------

generateRecipe :: IO String
generateRecipe = do
generateRecipe :: EdgeFilter -> IO String
generateRecipe ef = do
graphData <- classicScenarioRecipeGraphData
return . Dot.showDot $ recipesToDot graphData
return . Dot.showDot $ recipesToDot graphData ef

recipesToDot :: RecipeGraphData -> Dot ()
recipesToDot graphData = do
data EdgeFilter = NoFilter | FilterForward | FilterNext
deriving (Eq, Show)

filterEdge :: EdgeFilter -> Int -> Int -> Bool
filterEdge ef i o = case ef of
NoFilter -> True
FilterForward -> i <= o
FilterNext -> i + 1 == o

recipesToDot :: RecipeGraphData -> EdgeFilter -> Dot ()
recipesToDot graphData ef = do
Dot.attribute ("rankdir", "LR")
Dot.attribute ("ranksep", "2")
world <- diamond "World"
Expand Down Expand Up @@ -222,15 +233,17 @@ recipesToDot graphData = do
-- --------------------------------------------------------------------------
-- add node for the world and draw a line to each entity found in the wild
-- finally draw recipes
let recipeInOut r = [(snd i, snd o) | i <- r ^. recipeInputs, o <- r ^. recipeOutputs]
recipeReqOut r = [(snd q, snd o) | q <- r ^. recipeCatalysts, o <- r ^. recipeOutputs]
let eFilter = filterEdge ef
lvl e = fromMaybe (-1) $ List.findIndex (Set.member e) levels
recipeInOut r = [(i, o) | (_, i) <- r ^. recipeInputs, (_, o) <- r ^. recipeOutputs, lvl i `eFilter` lvl o]
recipeReqOut r = [(q, o) | (_, q) <- r ^. recipeCatalysts, (_, o) <- r ^. recipeOutputs, lvl q `eFilter` lvl o]
recipesToPairs f rs = both nid <$> nubOrd (concatMap f rs)
mapM_ (uncurry (.->.)) (recipesToPairs recipeInOut recipes)
mapM_ (uncurry (---<>)) (recipesToPairs recipeReqOut recipes)
-- --------------------------------------------------------------------------
-- also draw an edge for each entity that "yields" another entity
let yieldPairs = mapMaybe (\e -> (e ^. entityName,) <$> (e ^. entityYields)) . toList $ rgAllEntities graphData
mapM_ (uncurry (.->.)) (both getE <$> yieldPairs)
mapM_ (uncurry (.-<>.)) (both getE <$> yieldPairs)

data RecipeGraphData = RecipeGraphData
{ rgWorldEntities :: Set Entity
Expand Down Expand Up @@ -336,6 +349,12 @@ diamond = customNode [("shape", "diamond")]
hiddenNode :: Dot NodeId
hiddenNode = Dot.node [("style", "invis")]

-- | Edge for yielded entities.
(.-<>.) :: NodeId -> NodeId -> Dot ()
e1 .-<>. e2 = Dot.edge e1 e2 attrs
where
attrs = [("arrowhead", "diamond"), ("color", "purple")]

-- | Hidden edge - used for layout.
(.~>.) :: NodeId -> NodeId -> Dot ()
i .~>. j = Dot.edge i j [("style", "invis")]
Expand Down

0 comments on commit 363f108

Please sign in to comment.