Generate relative paths for documentation.

We keep track of the current nesting depth in our Context,
and use this to generate the correct relative path to the root.
main
Siddharth Bhat 2022-02-15 11:12:17 +00:00
parent 28bb2abe40
commit 91891fc4fd
3 changed files with 33 additions and 21 deletions

View File

@ -61,21 +61,24 @@ def sourceLinker : IO (Name → Option DeclarationRange → String) := do
| some range => s!"{basic}#L{range.pos.line}-L{range.endPos.line}" | some range => s!"{basic}#L{range.pos.line}-L{range.endPos.line}"
| none => basic | none => basic
def htmlOutput (result : AnalyzerResult) (root : String) : IO Unit := do def htmlOutput (result : AnalyzerResult) : IO Unit := do
let config := { root := root, result := result, currentName := none, sourceLinker := ←sourceLinker} let basePath := FilePath.mk "./build/doc/"
let basePath := FilePath.mk "." / "build" / "doc" let config := { depthToRoot := 0, result := result, currentName := none, sourceLinker := ←sourceLinker}
let indexHtml := ReaderT.run index config
let notFoundHtml := ReaderT.run notFound config
FS.createDirAll basePath FS.createDirAll basePath
FS.createDirAll (basePath / "find") FS.createDirAll (basePath / "find")
let indexHtml := ReaderT.run index config
let notFoundHtml := ReaderT.run notFound config
let mut declList := #[] let mut declList := #[]
for (_, mod) in result.moduleInfo.toArray do for (module, mod) in result.moduleInfo.toArray do
for decl in filterMapDocInfo mod.members do for decl in filterMapDocInfo mod.members do
let findHtml := ReaderT.run (findRedirectHtml decl.getName) config
let findDir := basePath / "find" / decl.getName.toString let findDir := basePath / "find" / decl.getName.toString
let findFile := (findDir / "index.html")
-- path: 'basePath/find/decl.getName.toString'
let config := { config with depthToRoot := 2 }
let findHtml := ReaderT.run (findRedirectHtml decl.getName) config
FS.createDirAll findDir FS.createDirAll findDir
FS.writeFile (findDir / "index.html") findHtml.toString FS.writeFile findFile findHtml.toString
let obj := Json.mkObj [("name", decl.getName.toString), ("description", decl.getDocString.getD "")] let obj := Json.mkObj [("name", decl.getName.toString), ("description", decl.getDocString.getD "")]
declList := declList.push obj declList := declList.push obj
let json := Json.arr declList let json := Json.arr declList
@ -88,10 +91,14 @@ def htmlOutput (result : AnalyzerResult) (root : String) : IO Unit := do
FS.writeFile (basePath / "search.js") searchJs FS.writeFile (basePath / "search.js") searchJs
FS.writeFile (basePath / "mathjax-config.js") mathjaxConfigJs FS.writeFile (basePath / "mathjax-config.js") mathjaxConfigJs
for (module, content) in result.moduleInfo.toArray do for (module, content) in result.moduleInfo.toArray do
let fileDir := moduleNameToDirectory basePath module
let filePath := moduleNameToFile basePath module
-- path: 'basePath/module/components/till/last.html'
-- The last component is the file name, so we drop it from the depth to root.
let config := { config with depthToRoot := module.components.dropLast.length }
let moduleHtml := ReaderT.run (moduleToHtml content) config let moduleHtml := ReaderT.run (moduleToHtml content) config
let path := moduleNameToFile basePath module FS.createDirAll $ fileDir
FS.createDirAll $ moduleNameToDirectory basePath module FS.writeFile filePath moduleHtml.toString
FS.writeFile path moduleHtml.toString
end DocGen4 end DocGen4

View File

@ -14,10 +14,9 @@ open scoped DocGen4.Jsx
open Lean System Widget Elab open Lean System Widget Elab
structure SiteContext where structure SiteContext where
root : String
result : AnalyzerResult result : AnalyzerResult
depthToRoot: Nat
currentName : Option Name currentName : Option Name
-- Generates a URL pointing to the source of the given module Name
sourceLinker : Name → Option DeclarationRange → String sourceLinker : Name → Option DeclarationRange → String
def setCurrentName (name : Name) (ctx : SiteContext) := {ctx with currentName := some name} def setCurrentName (name : Name) (ctx : SiteContext) := {ctx with currentName := some name}
@ -25,7 +24,13 @@ def setCurrentName (name : Name) (ctx : SiteContext) := {ctx with currentName :=
abbrev HtmlT := ReaderT SiteContext abbrev HtmlT := ReaderT SiteContext
abbrev HtmlM := HtmlT Id abbrev HtmlM := HtmlT Id
def getRoot : HtmlM String := do pure (←read).root def getRoot : HtmlM String := do
let rec go: Nat -> String
| 0 => "./"
| Nat.succ n' => "../" ++ go n'
let d <- SiteContext.depthToRoot <$> read
return (go d)
def getResult : HtmlM AnalyzerResult := do pure (←read).result def getResult : HtmlM AnalyzerResult := do pure (←read).result
def getCurrentName : HtmlM (Option Name) := do pure (←read).currentName def getCurrentName : HtmlM (Option Name) := do pure (←read).currentName
def getSourceUrl (module : Name) (range : Option DeclarationRange): HtmlM String := do pure $ (←read).sourceLinker module range def getSourceUrl (module : Name) (range : Option DeclarationRange): HtmlM String := do pure $ (←read).sourceLinker module range
@ -35,12 +40,14 @@ def templateExtends {α β : Type} (base : α → HtmlM β) (new : HtmlM α) : H
def moduleNameToLink (n : Name) : HtmlM String := do def moduleNameToLink (n : Name) : HtmlM String := do
let parts := n.components.map Name.toString let parts := n.components.map Name.toString
pure $ (←getRoot) ++ (parts.intersperse "/").foldl (· ++ ·) "" ++ ".html" pure $ (<- getRoot) ++ (parts.intersperse "/").foldl (. ++ ·) "" ++ ".html"
def moduleNameToFile (basePath : FilePath) (n : Name) : FilePath := def moduleNameToFile (basePath : FilePath) (n : Name) : FilePath :=
let parts := n.components.map Name.toString let parts := n.components.map Name.toString
FilePath.withExtension (basePath / parts.foldl (· / ·) (FilePath.mk ".")) "html" FilePath.withExtension (basePath / parts.foldl (· / ·) (FilePath.mk ".")) "html"
def moduleNameToDirectory (basePath : FilePath) (n : Name) : FilePath := def moduleNameToDirectory (basePath : FilePath) (n : Name) : FilePath :=
let parts := n.components.dropLast.map Name.toString let parts := n.components.dropLast.map Name.toString
basePath / parts.foldl (· / ·) (FilePath.mk ".") basePath / parts.foldl (· / ·) (FilePath.mk ".")

View File

@ -3,15 +3,13 @@ import Lean
open DocGen4 Lean IO open DocGen4 Lean IO
def main (args : List String) : IO Unit := do def main (modules : List String) : IO Unit := do
if args.isEmpty then if modules.isEmpty then
IO.println "Usage: doc-gen4 root/url/ Module1 Module2 ..." IO.println "Usage: doc-gen4 Module1 Module2 ..."
IO.Process.exit 1 IO.Process.exit 1
return return
let root := args.head!
let modules := args.tail!
let path ← lakeSetupSearchPath (←getLakePath) modules.toArray let path ← lakeSetupSearchPath (←getLakePath) modules.toArray
IO.println s!"Loading modules from: {path}" IO.println s!"Loading modules from: {path}"
let doc ← load $ modules.map Name.mkSimple let doc ← load $ modules.map Name.mkSimple
IO.println "Outputting HTML" IO.println "Outputting HTML"
htmlOutput doc root htmlOutput doc