@@ -4,13 +4,17 @@ module Swarm.DocGen (
4
4
generateDocs ,
5
5
GenerateDocs (.. ),
6
6
EditorType (.. ),
7
+ SheetType (.. ),
7
8
8
9
-- ** Formatted keyword lists
9
10
keywordsCommands ,
10
11
keywordsDirections ,
11
12
operatorNames ,
12
- builtinCommandsListEmacs ,
13
+ builtinFunctionList ,
13
14
editorList ,
15
+
16
+ -- ** Wiki pages
17
+ commandsPage ,
14
18
) where
15
19
16
20
import Control.Lens (view , (^.) )
@@ -19,6 +23,7 @@ import Control.Monad.Except (ExceptT, runExceptT)
19
23
import Data.Bifunctor (Bifunctor (bimap ))
20
24
import Data.Containers.ListUtils (nubOrd )
21
25
import Data.Foldable (toList )
26
+ import Data.List (transpose )
22
27
import Data.Map.Lazy (Map )
23
28
import Data.Map.Lazy qualified as Map
24
29
import Data.Maybe (fromMaybe )
@@ -34,8 +39,11 @@ import Swarm.Game.Recipe (Recipe, loadRecipes, recipeInputs, recipeOutputs, reci
34
39
import Swarm.Game.Robot (installedDevices , robotInventory , setRobotID )
35
40
import Swarm.Game.Scenario (Scenario , loadScenario , scenarioRobots )
36
41
import Swarm.Game.WorldGen (testWorld2Entites )
37
- import Swarm.Language.Syntax (Const (.. ), ConstMeta (.. ))
42
+ import Swarm.Language.Capability (capabilityName , constCaps )
43
+ import Swarm.Language.Pretty (prettyText )
44
+ import Swarm.Language.Syntax (Const (.. ))
38
45
import Swarm.Language.Syntax qualified as Syntax
46
+ import Swarm.Language.Typecheck (inferConst )
39
47
import Swarm.Util (isRightOr )
40
48
import Text.Dot (Dot , NodeId , (.->.) )
41
49
import Text.Dot qualified as Dot
@@ -53,11 +61,15 @@ data GenerateDocs where
53
61
RecipeGraph :: GenerateDocs
54
62
-- | Keyword lists for editors.
55
63
EditorKeywords :: Maybe EditorType -> GenerateDocs
64
+ CheatSheet :: Maybe SheetType -> GenerateDocs
56
65
deriving (Eq , Show )
57
66
58
67
data EditorType = Emacs | VSCode
59
68
deriving (Eq , Show , Enum , Bounded )
60
69
70
+ data SheetType = Entities | Commands | Capabilities | Recipes
71
+ deriving (Eq , Show , Enum , Bounded )
72
+
61
73
generateDocs :: GenerateDocs -> IO ()
62
74
generateDocs = \ case
63
75
RecipeGraph -> generateRecipe >>= putStrLn
@@ -72,6 +84,11 @@ generateDocs = \case
72
84
putStrLn $ replicate 40 ' -'
73
85
generateEditorKeywords et
74
86
mapM_ editorGen [minBound .. maxBound ]
87
+ CheatSheet s -> case s of
88
+ Nothing -> error " Not implemented"
89
+ Just st -> case st of
90
+ Commands -> T. putStrLn commandsPage
91
+ _ -> error " Not implemented"
75
92
76
93
-- ----------------------------------------------------------------------------
77
94
-- GENERATE KEYWORDS: LIST OF WORDS TO BE HIGHLIGHTED
@@ -81,24 +98,30 @@ generateEditorKeywords :: EditorType -> IO ()
81
98
generateEditorKeywords = \ case
82
99
Emacs -> do
83
100
putStrLn " (x-builtins '("
84
- T. putStr . editorList Emacs $ map constSyntax builtinCommandsEmacs
101
+ T. putStr $ builtinFunctionList Emacs
85
102
putStrLn " ))\n (x-commands '("
86
103
T. putStr $ keywordsCommands Emacs
87
104
T. putStr $ keywordsDirections Emacs
88
105
putStrLn " ))"
89
106
VSCode -> do
90
107
putStrLn " Functions and commands:"
91
- T. putStrLn $ keywordsCommands VSCode
108
+ T. putStrLn $ builtinFunctionList VSCode <> " | " <> keywordsCommands VSCode
92
109
putStrLn " \n Directions:"
93
110
T. putStrLn $ keywordsDirections VSCode
94
111
putStrLn " \n Operators:"
95
112
T. putStrLn operatorNames
96
113
97
- builtinCommandsEmacs :: [Const ]
98
- builtinCommandsEmacs = [ If , Run , Return , Try , Fail , Force , Fst , Snd ]
114
+ commands :: [Const ]
115
+ commands = filter Syntax. isCmd Syntax. allConst
99
116
100
- builtinCommandsListEmacs :: Text
101
- builtinCommandsListEmacs = editorList Emacs $ map constSyntax builtinCommandsEmacs
117
+ operators :: [Const ]
118
+ operators = filter Syntax. isOperator Syntax. allConst
119
+
120
+ builtinFunctions :: [Const ]
121
+ builtinFunctions = filter Syntax. isBuiltinFunction Syntax. allConst
122
+
123
+ builtinFunctionList :: EditorType -> Text
124
+ builtinFunctionList e = editorList e $ map constSyntax builtinFunctions
102
125
103
126
editorList :: EditorType -> [Text ] -> Text
104
127
editorList = \ case
@@ -112,27 +135,99 @@ constSyntax = Syntax.syntax . Syntax.constInfo
112
135
113
136
-- | Get formatted list of basic functions/commands.
114
137
keywordsCommands :: EditorType -> Text
115
- keywordsCommands e = editorList e $ map constSyntax (filter isFunc Syntax. allConst)
116
- where
117
- isFunc c = Syntax. isUserFunc c && (e /= Emacs || c `notElem` builtinCommandsEmacs)
138
+ keywordsCommands e = editorList e $ map constSyntax commands
118
139
119
140
-- | Get formatted list of directions.
120
141
keywordsDirections :: EditorType -> Text
121
142
keywordsDirections e = editorList e $ map (Syntax. dirSyntax . Syntax. dirInfo) Syntax. allDirs
122
143
123
144
operatorNames :: Text
124
- operatorNames = T. intercalate " |" $ map (escape . constSyntax) ( filter isOperator Syntax. allConst)
145
+ operatorNames = T. intercalate " |" $ map (escape . constSyntax) operators
125
146
where
126
147
special :: String
127
148
special = " *+$[]|^"
128
149
slashNotComment = \ case
129
150
' /' -> " /(?![/|*])"
130
151
c -> T. singleton c
131
152
escape = T. concatMap (\ c -> if c `elem` special then T. snoc " \\\\ " c else slashNotComment c)
132
- isOperator c = case Syntax. constMeta $ Syntax. constInfo c of
133
- ConstMUnOp {} -> True
134
- ConstMBinOp {} -> True
135
- ConstMFunc {} -> False
153
+
154
+ -- ----------------------------------------------------------------------------
155
+ -- GENERATE TABLES: COMMANDS, ENTITIES AND CAPABILITIES TO MARKDOWN TABLE
156
+ -- ----------------------------------------------------------------------------
157
+
158
+ wrap :: Char -> Text -> Text
159
+ wrap c = T. cons c . flip T. snoc c
160
+
161
+ codeQuote :: Text -> Text
162
+ codeQuote = wrap ' `'
163
+
164
+ escapeTable :: Text -> Text
165
+ escapeTable = T. concatMap (\ c -> if c == ' |' then T. snoc " \\ " c else T. singleton c)
166
+
167
+ separatingLine :: [Int ] -> Text
168
+ separatingLine ws = T. cons ' |' . T. concat $ map (flip T. snoc ' |' . flip T. replicate " -" . (2 + )) ws
169
+
170
+ listToRow :: [Int ] -> [Text ] -> Text
171
+ listToRow mw xs = wrap ' |' . T. intercalate " |" $ zipWith format mw xs
172
+ where
173
+ format w x = wrap ' ' x <> T. replicate (w - T. length x) " "
174
+
175
+ maxWidths :: [[Text ]] -> [Int ]
176
+ maxWidths = map (maximum . map T. length ) . transpose
177
+
178
+ -- ---------
179
+ -- COMMANDS
180
+ -- ---------
181
+
182
+ commandHeader :: [Text ]
183
+ commandHeader = [" Syntax" , " Type" , " Capability" , " Description" ]
184
+
185
+ commandToList :: Const -> [Text ]
186
+ commandToList c =
187
+ map
188
+ escapeTable
189
+ [ addLink (T. pack $ " #" <> show c) . codeQuote $ constSyntax c
190
+ , codeQuote . prettyText $ inferConst c
191
+ , maybe " " capabilityName $ constCaps c
192
+ , Syntax. briefDoc . Syntax. constDoc $ Syntax. constInfo c
193
+ ]
194
+ where
195
+ addLink l t = T. concat [" [" , t, " ](" , l, " )" ]
196
+
197
+ constTable :: [Const ] -> Text
198
+ constTable cs = T. unlines $ header <> map (listToRow mw) commandRows
199
+ where
200
+ mw = maxWidths (commandHeader : commandRows)
201
+ commandRows = map commandToList cs
202
+ header = [listToRow mw commandHeader, separatingLine mw]
203
+
204
+ commandToSection :: Const -> Text
205
+ commandToSection c =
206
+ T. unlines $
207
+ [ " ## " <> T. pack (show c)
208
+ , " "
209
+ , " - syntax: " <> codeQuote (constSyntax c)
210
+ , " - type: " <> (codeQuote . prettyText $ inferConst c)
211
+ , maybe " " ((" - required capabilities: " <> ) . capabilityName) $ constCaps c
212
+ , " "
213
+ , Syntax. briefDoc . Syntax. constDoc $ Syntax. constInfo c
214
+ ]
215
+ <> let l = Syntax. longDoc . Syntax. constDoc $ Syntax. constInfo c
216
+ in if T. null l then [] else [" " , l]
217
+
218
+ commandsPage :: Text
219
+ commandsPage =
220
+ T. intercalate " \n\n " $
221
+ [ " # Commands"
222
+ , constTable commands
223
+ , " # Builtin functions"
224
+ , " These functions are evaluated immediately once they have enough arguments."
225
+ , constTable builtinFunctions
226
+ , " # Operators"
227
+ , constTable operators
228
+ , " # Detailed descriptions"
229
+ ]
230
+ <> map commandToSection (commands <> builtinFunctions <> operators)
136
231
137
232
-- ----------------------------------------------------------------------------
138
233
-- GENERATE GRAPHVIZ: ENTITY DEPENDENCIES BY RECIPES
0 commit comments