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
parent
28bb2abe40
commit
91891fc4fd
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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 ".")
|
||||||
|
|
10
Main.lean
10
Main.lean
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue