@@ -4,6 +4,7 @@ import Prelude
44
55import Docs.Search.Config (config)
66import Docs.Search.Declarations (Declarations(..), mkDeclarations)
7+import Docs.Search.DocsJson (DocsJson)
78import Docs.Search.Extra ((>#>))
89import Docs.Search.Index (getPartId)
910import Docs.Search.SearchResult (SearchResult)
@@ -26,7 +27,6 @@ import Data.Set as Set
2627import Data.String.CodePoints (contains) as String
2728import Data.String.CodeUnits (singleton) as String
2829import Data.String.Common (replace) as String
29−import Data.String.Pattern (Pattern(..)) as String
3030import Data.String.Pattern (Pattern(..), Replacement(..))
3131import Data.Traversable (for, for_)
3232import Data.Tuple (Tuple(..), fst, snd)
@@ -38,7 +38,6 @@ import Node.Encoding (Encoding(UTF8))
3838import Node.FS.Aff (exists, mkdir, readTextFile, readdir, stat, writeTextFile)
3939import Node.FS.Stats (isDirectory, isFile)
4040import Node.Process as Process
41−import Docs.Search.DocsJson (DocsJson)
4241
4342main :: Effect Unit
4443main = launchAff_ mainAff
@@ -82,7 +81,7 @@ collectDocsJsons :: String -> Aff (Array DocsJson)
8281collectDocsJsons outputDir = do
8382 paths <- readdir outputDir
8483
85− mbs <- for paths \moduleName -> do
84+ Array.catMaybes <$> for paths \moduleName -> do
8685 let jsonFile = "output/" <> moduleName <> "/docs.json"
8786 doesExist <- fileExists jsonFile
8887 if doesExist then do
@@ -103,8 +102,6 @@ collectDocsJsons outputDir = do
103102 "Couldn't find docs.json for " <> moduleName
104103 pure Nothing
105104
106− pure $ Array.catMaybes mbs
107−
108105writeTypeIndex :: TypeIndex -> Aff Unit
109106writeTypeIndex typeIndex =
110107 for_ entries \(Tuple typeShape results) -> do
@@ -117,33 +114,34 @@ writeTypeIndex typeIndex =
117114 entries :: Array _
118115 entries = Map.toUnfoldableUnordered (unwrap typeIndex)
119116
120−writeIndex :: Declarations -> Aff Unit
121−writeIndex (Declarations trie) = do
122− let
123− prefixes :: Array (List Char)
124− prefixes =
117+-- | Get a mapping from index parts to index contents.
118+getIndex :: Declarations -> Map Int (Array (Tuple String (Array SearchResult)))
119+getIndex (Declarations trie) =
120+ Array.foldr insert mempty parts
121+ where
122+ prefixes :: Array (List Char)
123+ prefixes =
125124 Set.toUnfoldable $
126125 List.foldr (\entry -> Set.insert (List.take 2 $ fst entry)) mempty $
127126 Trie.entriesUnordered trie
128127
129− parts
130− :: Array { prefix :: List Char
131− , results :: Array (Tuple String (Array SearchResult))
132− }
133− parts = prefixes <#> \prefix ->
134− let results =
135− Array.fromFoldable $
136− Trie.query prefix trie <#>
137− \(Tuple path value) ->
138− Tuple (path >#> String.singleton) (Array.fromFoldable value)
139− in
140− { prefix, results }
141−
142− resultsMap :: Map Int (Array (Tuple String (Array SearchResult)))
143− resultsMap = Array.foldr insert mempty parts
144−
145− insert part = Map.insertWith append (getPartId part.prefix) part.results
128+ parts
129+ :: Array { prefix :: List Char
130+ , results :: Array (Tuple String (Array SearchResult))
131+ }
132+ parts = prefixes <#> \prefix ->
133+ let results =
134+ Array.fromFoldable $
135+ Trie.query prefix trie <#>
136+ \(Tuple path value) ->
137+ Tuple (path >#> String.singleton) (Array.fromFoldable value)
138+ in
139+ { prefix, results }
140+
141+ insert part = Map.insertWith append (getPartId part.prefix) part.results
146142
143+writeIndex :: Declarations -> Aff Unit
144+writeIndex = getIndex >>> \resultsMap -> do
147145 for_ (Map.toUnfoldableUnordered resultsMap :: Array _)
148146 \(Tuple indexPartId results) -> do
149147 let header =
@@ -153,17 +151,24 @@ writeIndex (Declarations trie) = do
153151 writeTextFile UTF8 (config.mkIndexPartPath indexPartId) $
154152 header <> stringify (encodeJson results)
155153
154+patchHTML :: String -> Tuple Boolean String
155+patchHTML html =
156+ let
157+ pattern = Pattern "</body>"
158+ patch = "<!-- Docs search index. -->" <>
159+ "<script type=\"text/javascript\" src=\"../docs-search-app.js\"></script>" <>
160+ "<script type=\"text/javascript\">" <>
161+ "window.DocsSearchTypeIndex = {};" <>
162+ "window.DocsSearchIndex = {};" <>
163+ "</script>" <>
164+ "</body>"
165+ in if not $ String.contains (Pattern patch) html
166+ then Tuple true $ String.replace pattern (Replacement patch) html
167+ else Tuple false html
168+
156169patchDocs :: Aff Unit
157170patchDocs = do
158171 let dirname = "generated-docs/"
159− pattern = Pattern "</body>"
160− patch = "<!-- Docs search index. -->" <>
161− "<script type=\"text/javascript\" src=\"../docs-search-app.js\"></script>" <>
162− "<script type=\"text/javascript\">" <>
163− "window.DocsSearchTypeIndex = {};" <>
164− "window.DocsSearchIndex = {};" <>
165− "</script>" <>
166− "</body>"
167172
168173 files <- readdir (dirname <> "html")
169174
@@ -172,9 +177,10 @@ patchDocs = do
172177
173178 whenM (fileExists path) do
174179 contents <- readTextFile UTF8 path
175− when (not $ String.contains (String.Pattern patch) contents) do
176− writeTextFile UTF8 path $
177− String.replace pattern (Replacement patch) contents
180+ case patchHTML contents of
181+ Tuple true patchedContents -> do
182+ writeTextFile UTF8 path patchedContents
183+ _ -> pure unit
178184
179185createDirectories :: Aff Unit
180186createDirectories = do