style: Lean 4 compiler style in output
parent
3a5c0db46b
commit
f74443a673
|
@ -66,10 +66,10 @@ def HtmlM.run (x : HtmlM α) (ctx : SiteContext) (baseCtx : SiteBaseContext) :
|
|||
ReaderT.run x ctx |>.run baseCtx |>.run
|
||||
|
||||
instance [Monad m] : MonadLift HtmlM (HtmlT m) where
|
||||
monadLift x := do pure <| x.run (←readThe SiteContext) (←readThe SiteBaseContext)
|
||||
monadLift x := do return x.run (← readThe SiteContext) (← readThe SiteBaseContext)
|
||||
|
||||
instance [Monad m] : MonadLift BaseHtmlM (BaseHtmlT m) where
|
||||
monadLift x := do pure <| x.run (←readThe SiteBaseContext)
|
||||
monadLift x := do return x.run (← readThe SiteBaseContext)
|
||||
|
||||
/--
|
||||
Obtains the root URL as a relative one to the current depth.
|
||||
|
@ -81,11 +81,11 @@ def getRoot : BaseHtmlM String := do
|
|||
let d <- SiteBaseContext.depthToRoot <$> read
|
||||
return (go d)
|
||||
|
||||
def getHierarchy : BaseHtmlM Hierarchy := do pure (←read).hierarchy
|
||||
def getCurrentName : BaseHtmlM (Option Name) := do pure (←read).currentName
|
||||
def getResult : HtmlM AnalyzerResult := do pure (←read).result
|
||||
def getSourceUrl (module : Name) (range : Option DeclarationRange): HtmlM String := do pure <| (←read).sourceLinker module range
|
||||
def leanInkEnabled? : HtmlM Bool := do pure (←read).leanInkEnabled
|
||||
def getHierarchy : BaseHtmlM Hierarchy := do return (← read).hierarchy
|
||||
def getCurrentName : BaseHtmlM (Option Name) := do return (← read).currentName
|
||||
def getResult : HtmlM AnalyzerResult := do return (← read).result
|
||||
def getSourceUrl (module : Name) (range : Option DeclarationRange): HtmlM String := do return (← read).sourceLinker module range
|
||||
def leanInkEnabled? : HtmlM Bool := do return (← read).leanInkEnabled
|
||||
|
||||
/--
|
||||
If a template is meant to be extended because it for example only provides the
|
||||
|
@ -102,20 +102,20 @@ Returns the doc-gen4 link to a module name.
|
|||
-/
|
||||
def moduleNameToLink (n : Name) : BaseHtmlM String := do
|
||||
let parts := n.components.map Name.toString
|
||||
pure <| (← getRoot) ++ (parts.intersperse "/").foldl (· ++ ·) "" ++ ".html"
|
||||
return (← getRoot) ++ (parts.intersperse "/").foldl (· ++ ·) "" ++ ".html"
|
||||
|
||||
/--
|
||||
Returns the HTML doc-gen4 link to a module name.
|
||||
-/
|
||||
def moduleToHtmlLink (module : Name) : BaseHtmlM Html := do
|
||||
pure <a href={←moduleNameToLink module}>{module.toString}</a>
|
||||
return <a href={← moduleNameToLink module}>{module.toString}</a>
|
||||
|
||||
/--
|
||||
Returns the LeanInk link to a module name.
|
||||
-/
|
||||
def moduleNameToInkLink (n : Name) : BaseHtmlM String := do
|
||||
let parts := "src" :: n.components.map Name.toString
|
||||
pure <| (← getRoot) ++ (parts.intersperse "/").foldl (· ++ ·) "" ++ ".html"
|
||||
return (← getRoot) ++ (parts.intersperse "/").foldl (· ++ ·) "" ++ ".html"
|
||||
|
||||
/--
|
||||
Returns the path to the HTML file that contains information about a module.
|
||||
|
@ -158,13 +158,13 @@ Returns the doc-gen4 link to a declaration name.
|
|||
def declNameToLink (name : Name) : HtmlM String := do
|
||||
let res ← getResult
|
||||
let module := res.moduleNames[res.name2ModIdx.find! name |>.toNat]!
|
||||
pure <| (←moduleNameToLink module) ++ "#" ++ name.toString
|
||||
return (← moduleNameToLink module) ++ "#" ++ name.toString
|
||||
|
||||
/--
|
||||
Returns the HTML doc-gen4 link to a declaration name.
|
||||
-/
|
||||
def declNameToHtmlLink (name : Name) : HtmlM Html := do
|
||||
pure <a href={←declNameToLink name}>{name.toString}</a>
|
||||
return <a href={← declNameToLink name}>{name.toString}</a>
|
||||
|
||||
/--
|
||||
Returns the LeanInk link to a declaration name.
|
||||
|
@ -172,14 +172,14 @@ Returns the LeanInk link to a declaration name.
|
|||
def declNameToInkLink (name : Name) : HtmlM String := do
|
||||
let res ← getResult
|
||||
let module := res.moduleNames[res.name2ModIdx.find! name |>.toNat]!
|
||||
pure <| (←moduleNameToInkLink module) ++ "#" ++ name.toString
|
||||
return (← moduleNameToInkLink module) ++ "#" ++ name.toString
|
||||
|
||||
/--
|
||||
Returns the HTML doc-gen4 link to a declaration name with "break_within"
|
||||
set as class.
|
||||
-/
|
||||
def declNameToHtmlBreakWithinLink (name : Name) : HtmlM Html := do
|
||||
pure <a class="break_within" href={←declNameToLink name}>{name.toString}</a>
|
||||
return <a class="break_within" href={← declNameToLink name}>{name.toString}</a>
|
||||
|
||||
/--
|
||||
In Lean syntax declarations the following pattern is quite common:
|
||||
|
@ -207,8 +207,8 @@ to as much information as possible.
|
|||
-/
|
||||
partial def infoFormatToHtml (i : CodeWithInfos) : HtmlM (Array Html) := do
|
||||
match i with
|
||||
| .text t => pure #[Html.escape t]
|
||||
| .append tt => tt.foldlM (λ acc t => do pure <| acc ++ (←infoFormatToHtml t)) #[]
|
||||
| .text t => return #[Html.escape t]
|
||||
| .append tt => tt.foldlM (fun acc t => do return acc ++ (← infoFormatToHtml t)) #[]
|
||||
| .tag a t =>
|
||||
match a.info.val.info with
|
||||
| Info.ofTermInfo i =>
|
||||
|
@ -217,16 +217,16 @@ partial def infoFormatToHtml (i : CodeWithInfos) : HtmlM (Array Html) := do
|
|||
| .const name _ =>
|
||||
-- TODO: this is some very primitive blacklisting but real Blacklisting needs MetaM
|
||||
-- find a better solution
|
||||
if (←getResult).name2ModIdx.contains name then
|
||||
if (← getResult).name2ModIdx.contains name then
|
||||
match t with
|
||||
| .text t =>
|
||||
let (front, t, back) := splitWhitespaces <| Html.escape t
|
||||
let elem := <a href={←declNameToLink name}>{t}</a>
|
||||
pure #[Html.text front, elem, Html.text back]
|
||||
let elem := <a href={← declNameToLink name}>{t}</a>
|
||||
return #[Html.text front, elem, Html.text back]
|
||||
| _ =>
|
||||
pure #[<a href={←declNameToLink name}>[←infoFormatToHtml t]</a>]
|
||||
return #[<a href={← declNameToLink name}>[← infoFormatToHtml t]</a>]
|
||||
else
|
||||
pure #[<span class="fn">[←infoFormatToHtml t]</span>]
|
||||
return #[<span class="fn">[← infoFormatToHtml t]</span>]
|
||||
| .sort _ =>
|
||||
match t with
|
||||
| .text t =>
|
||||
|
@ -234,21 +234,21 @@ partial def infoFormatToHtml (i : CodeWithInfos) : HtmlM (Array Html) := do
|
|||
let sortLink := <a href={s!"{← getRoot}foundational_types.html"}>{sortPrefix}</a>
|
||||
if rest != [] then
|
||||
rest := " " :: rest
|
||||
pure #[sortLink, Html.text <| String.join rest]
|
||||
return #[sortLink, Html.text <| String.join rest]
|
||||
| _ =>
|
||||
pure #[<a href={s!"{← getRoot}foundational_types.html"}>[← infoFormatToHtml t]</a>]
|
||||
return #[<a href={s!"{← getRoot}foundational_types.html"}>[← infoFormatToHtml t]</a>]
|
||||
| _ =>
|
||||
pure #[<span class="fn">[←infoFormatToHtml t]</span>]
|
||||
| _ => pure #[<span class="fn">[←infoFormatToHtml t]</span>]
|
||||
return #[<span class="fn">[← infoFormatToHtml t]</span>]
|
||||
| _ => return #[<span class="fn">[← infoFormatToHtml t]</span>]
|
||||
|
||||
def baseHtmlHeadDeclarations : BaseHtmlM (Array Html) := do
|
||||
pure #[
|
||||
return #[
|
||||
<meta charset="UTF-8"/>,
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>,
|
||||
<link rel="stylesheet" href={s!"{←getRoot}style.css"}/>,
|
||||
<link rel="stylesheet" href={s!"{←getRoot}src/pygments.css"}/>,
|
||||
<link rel="shortcut icon" href={s!"{←getRoot}favicon.ico"}/>,
|
||||
<link rel="prefetch" href={s!"{←getRoot}/declarations/declaration-data.bmp"} as="image"/>
|
||||
<link rel="stylesheet" href={s!"{← getRoot}style.css"}/>,
|
||||
<link rel="stylesheet" href={s!"{← getRoot}src/pygments.css"}/>,
|
||||
<link rel="shortcut icon" href={s!"{← getRoot}favicon.ico"}/>,
|
||||
<link rel="prefetch" href={s!"{← getRoot}/declarations/declaration-data.bmp"} as="image"/>
|
||||
]
|
||||
|
||||
end DocGen4.Output
|
||||
|
|
|
@ -12,7 +12,7 @@ open Lean Widget
|
|||
def equationLimit : Nat := 200
|
||||
|
||||
def equationToHtml (c : CodeWithInfos) : HtmlM Html := do
|
||||
pure <li class="equation">[←infoFormatToHtml c]</li>
|
||||
return <li class="equation">[← infoFormatToHtml c]</li>
|
||||
|
||||
/--
|
||||
Attempt to render all `simp` equations for this definition. At a size
|
||||
|
@ -23,9 +23,9 @@ defined in `equationLimit` we stop trying since they:
|
|||
def equationsToHtml (i : Process.DefinitionInfo) : HtmlM (Array Html) := do
|
||||
if let some eqs := i.equations then
|
||||
let equationsHtml ← eqs.mapM equationToHtml
|
||||
let filteredEquationsHtml := equationsHtml.filter (λ eq => eq.textLength < equationLimit)
|
||||
let filteredEquationsHtml := equationsHtml.filter (·.textLength < equationLimit)
|
||||
if equationsHtml.size ≠ filteredEquationsHtml.size then
|
||||
pure #[
|
||||
return #[
|
||||
<details>
|
||||
<summary>Equations</summary>
|
||||
<ul class="equations">
|
||||
|
@ -35,7 +35,7 @@ def equationsToHtml (i : Process.DefinitionInfo) : HtmlM (Array Html) := do
|
|||
</details>
|
||||
]
|
||||
else
|
||||
pure #[
|
||||
return #[
|
||||
<details>
|
||||
<summary>Equations</summary>
|
||||
<ul class="equations">
|
||||
|
@ -44,7 +44,7 @@ def equationsToHtml (i : Process.DefinitionInfo) : HtmlM (Array Html) := do
|
|||
</details>
|
||||
]
|
||||
else
|
||||
pure #[]
|
||||
return #[]
|
||||
|
||||
end Output
|
||||
end DocGen4
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace Output
|
|||
|
||||
/--
|
||||
Similar to `Stirng.split` in Lean core, but keeps the separater.
|
||||
e.g. `splitAround "a,b,c" (λ c => c = ',') = ["a", ",", "b", ",", "c"]`
|
||||
e.g. `splitAround "a,b,c" (fun c => c = ',') = ["a", ",", "b", ",", "c"]`
|
||||
-/
|
||||
def splitAround (s : String) (p : Char → Bool) : List String := splitAroundAux s p 0 0 []
|
||||
|
||||
|
@ -81,15 +81,15 @@ def nameToLink? (s : String) : HtmlM (Option String) := do
|
|||
match res.moduleInfo.find! currentName |>.members |> filterMapDocInfo |>.find? (sameEnd ·.getName name) with
|
||||
| some info =>
|
||||
declNameToLink info.getName
|
||||
| _ => pure none
|
||||
| _ => pure none
|
||||
| _ => return none
|
||||
| _ => return none
|
||||
else
|
||||
pure none
|
||||
return none
|
||||
where
|
||||
-- check if two names have the same ending components
|
||||
sameEnd n1 n2 :=
|
||||
List.zip n1.componentsRev n2.componentsRev
|
||||
|>.all λ ⟨a, b⟩ => a == b
|
||||
|>.all fun ⟨a, b⟩ => a == b
|
||||
|
||||
/--
|
||||
Extend links with following rules:
|
||||
|
@ -103,16 +103,16 @@ def extendLink (s : String) : HtmlM String := do
|
|||
-- for intra doc links
|
||||
if s.startsWith "##" then
|
||||
if let some link ← nameToLink? (s.drop 2) then
|
||||
pure link
|
||||
return link
|
||||
else
|
||||
panic! s!"Cannot find {s.drop 2}, only full name and abbrev in current module is supported"
|
||||
-- for id
|
||||
else if s.startsWith "#" then
|
||||
pure s
|
||||
return s
|
||||
-- for absolute and relative urls
|
||||
else if s.startsWith "http" then
|
||||
pure s
|
||||
else pure ((←getRoot) ++ s)
|
||||
return s
|
||||
else return ((← getRoot) ++ s)
|
||||
|
||||
/-- Add attributes for heading. -/
|
||||
def addHeadingAttributes (el : Element) (modifyElement : Element → HtmlM Element) : HtmlM Element := do
|
||||
|
@ -127,12 +127,12 @@ def addHeadingAttributes (el : Element) (modifyElement : Element → HtmlM Eleme
|
|||
|>.insert "id" id
|
||||
|>.insert "class" "markdown-heading"
|
||||
let newContents := (←
|
||||
contents.mapM (λ c => match c with
|
||||
contents.mapM (fun c => match c with
|
||||
| Content.Element e => return Content.Element (← modifyElement e)
|
||||
| _ => pure c))
|
||||
|>.push (Content.Character " ")
|
||||
|>.push (Content.Element anchor)
|
||||
pure ⟨ name, newAttrs, newContents⟩
|
||||
return ⟨ name, newAttrs, newContents⟩
|
||||
|
||||
/-- Extend anchor links. -/
|
||||
def extendAnchor (el : Element) : HtmlM Element := do
|
||||
|
@ -141,7 +141,7 @@ def extendAnchor (el : Element) : HtmlM Element := do
|
|||
let newAttrs ← match attrs.find? "href" with
|
||||
| some href => pure (attrs.insert "href" (← extendLink href))
|
||||
| none => pure attrs
|
||||
pure ⟨ name, newAttrs, contents⟩
|
||||
return ⟨ name, newAttrs, contents⟩
|
||||
|
||||
/-- Automatically add intra documentation link for inline code span. -/
|
||||
def autoLink (el : Element) : HtmlM Element := do
|
||||
|
@ -153,27 +153,27 @@ def autoLink (el : Element) : HtmlM Element := do
|
|||
| Content.Character s =>
|
||||
newContents := newContents ++ (← splitAround s unicodeToSplit |>.mapM linkify).join
|
||||
| _ => newContents := newContents.push c
|
||||
pure ⟨ name, attrs, newContents ⟩
|
||||
return ⟨ name, attrs, newContents ⟩
|
||||
where
|
||||
linkify s := do
|
||||
let link? ← nameToLink? s
|
||||
match link? with
|
||||
| some link =>
|
||||
let attributes := Lean.RBMap.empty.insert "href" link
|
||||
pure [Content.Element <| Element.Element "a" attributes #[Content.Character s]]
|
||||
return [Content.Element <| Element.Element "a" attributes #[Content.Character s]]
|
||||
| none =>
|
||||
let sHead := s.dropRightWhile (λ c => c ≠ '.')
|
||||
let sTail := s.takeRightWhile (λ c => c ≠ '.')
|
||||
let sHead := s.dropRightWhile (· != '.')
|
||||
let sTail := s.takeRightWhile (· != '.')
|
||||
let link'? ← nameToLink? sTail
|
||||
match link'? with
|
||||
| some link' =>
|
||||
let attributes := Lean.RBMap.empty.insert "href" link'
|
||||
pure [
|
||||
return [
|
||||
Content.Character sHead,
|
||||
Content.Element <| Element.Element "a" attributes #[Content.Character sTail]
|
||||
]
|
||||
| none =>
|
||||
pure [Content.Character s]
|
||||
return [Content.Character s]
|
||||
unicodeToSplit (c : Char) : Bool :=
|
||||
charInGeneralCategory c GeneralCategory.separator ||
|
||||
charInGeneralCategory c GeneralCategory.other
|
||||
|
@ -192,19 +192,18 @@ partial def modifyElement (element : Element) : HtmlM Element :=
|
|||
autoLink el
|
||||
-- recursively modify
|
||||
else
|
||||
let newContents ← contents.mapM λ c => match c with
|
||||
let newContents ← contents.mapM fun c => match c with
|
||||
| Content.Element e => return Content.Element (← modifyElement e)
|
||||
| _ => pure c
|
||||
pure ⟨ name, attrs, newContents ⟩
|
||||
return ⟨ name, attrs, newContents ⟩
|
||||
|
||||
/-- Convert docstring to Html. -/
|
||||
def docStringToHtml (s : String) : HtmlM (Array Html) := do
|
||||
let rendered := CMark.renderHtml s
|
||||
match manyDocument rendered.mkIterator with
|
||||
| Parsec.ParseResult.success _ res =>
|
||||
res.mapM λ x => do
|
||||
pure (Html.text <| toString (← modifyElement x))
|
||||
| _ => pure #[Html.text rendered]
|
||||
res.mapM fun x => do return Html.text <| toString (← modifyElement x)
|
||||
| _ => return #[Html.text rendered]
|
||||
|
||||
end Output
|
||||
end DocGen4
|
||||
|
|
|
@ -10,8 +10,8 @@ def find : BaseHtmlM Html := do
|
|||
pure
|
||||
<html lang="en">
|
||||
<head>
|
||||
<link rel="preload" href={s!"{←getRoot}/declarations/declaration-data.bmp"} as="image"/>
|
||||
<script>{s!"const SITE_ROOT={String.quote (←getRoot)};"}</script>
|
||||
<link rel="preload" href={s!"{← getRoot}/declarations/declaration-data.bmp"} as="image"/>
|
||||
<script>{s!"const SITE_ROOT={String.quote (← getRoot)};"}</script>
|
||||
<script type="module" async="true" src="./find.js"></script>
|
||||
</head>
|
||||
<body></body>
|
||||
|
|
|
@ -28,7 +28,7 @@ def foundationalTypes : BaseHtmlM Html := templateLiftExtends (baseHtml "Foundat
|
|||
<p><code>Prop</code> is notation for <code>Sort 0</code>.</p>
|
||||
{← instancesForToHtml `_builtin_prop}
|
||||
|
||||
<h2 id="pi-types-codeπ-a--α-β-acode">Pi types, <code>{"Π a : α, β a"}</code></h2>
|
||||
<h2 id="pi-types-codeπ-a--α-β-acode">Pi types, <code>{"(a : α) → β a"}</code></h2>
|
||||
<p>The type of dependent functions is known as a pi type.
|
||||
Non-dependent functions and implications are a special case.</p>
|
||||
<p>Note that these can also be written with the alternative notations:</p>
|
||||
|
@ -39,13 +39,12 @@ def foundationalTypes : BaseHtmlM Html := templateLiftExtends (baseHtml "Foundat
|
|||
</ul>
|
||||
<p>Lean also permits ASCII-only spellings of the three variants:</p>
|
||||
<ul>
|
||||
<li><code>Pi a : A, B a</code> for <code>{"Π a : α, β a"}</code></li>
|
||||
<li><code>forall a : A, B a</code> for <code>{"∀ a : α, β a"}</code></li>
|
||||
<li><code>(a : A) -> B a</code>, for <code>(a : α) → β a</code></li>
|
||||
<li><code>A -> B</code>, for <code>α → β</code></li>
|
||||
</ul>
|
||||
<p>Note that despite not itself being a function, <code>(→)</code> is available as infix notation for
|
||||
<code>{"λ α β, α → β"}</code>.</p>
|
||||
<code>{"fun α β, α → β"}</code>.</p>
|
||||
-- TODO: instances for pi types
|
||||
</main>
|
||||
|
||||
|
|
|
@ -23,17 +23,17 @@ def ctorToHtml (c : Process.NameInfo) : HtmlM Html := do
|
|||
pure
|
||||
<li class="constructor" id={name}>
|
||||
<div class="inductive_ctor_doc">[renderedDoc]</div>
|
||||
{shortName} : [←infoFormatToHtml c.type]
|
||||
{shortName} : [← infoFormatToHtml c.type]
|
||||
</li>
|
||||
else
|
||||
pure
|
||||
<li class="constructor" id={name}>
|
||||
{shortName} : [←infoFormatToHtml c.type]
|
||||
{shortName} : [← infoFormatToHtml c.type]
|
||||
</li>
|
||||
|
||||
def inductiveToHtml (i : Process.InductiveInfo) : HtmlM (Array Html) := do
|
||||
let constructorsHtml := <ul class="constructors">[← i.ctors.toArray.mapM ctorToHtml]</ul>
|
||||
pure #[constructorsHtml]
|
||||
return #[constructorsHtml]
|
||||
|
||||
end Output
|
||||
end DocGen4
|
||||
|
|
|
@ -31,14 +31,14 @@ def argToHtml (arg : Arg) : HtmlM Html := do
|
|||
| BinderInfo.strictImplicit => ("⦃", "⦄", true)
|
||||
| BinderInfo.instImplicit => ("[", "]", true)
|
||||
let mut nodes := #[Html.text s!"{l}{arg.name.toString} : "]
|
||||
nodes := nodes.append (←infoFormatToHtml arg.type)
|
||||
nodes := nodes.append (← infoFormatToHtml arg.type)
|
||||
nodes := nodes.push r
|
||||
let inner := <span class="fn">[nodes]</span>
|
||||
let html := Html.element "span" false #[("class", "decl_args")] #[inner]
|
||||
if implicit then
|
||||
pure <span class="impl_arg">{html}</span>
|
||||
return <span class="impl_arg">{html}</span>
|
||||
else
|
||||
pure html
|
||||
return html
|
||||
|
||||
/--
|
||||
Render the structures this structure extends from as HTML so it can be
|
||||
|
@ -55,7 +55,7 @@ def structureInfoHeader (s : Process.StructureInfo) : HtmlM (Array Html) := do
|
|||
let html:= Html.element "span" false #[("class", "decl_parent")] #[inner]
|
||||
parents := parents.push html
|
||||
nodes := nodes.append (parents.toList.intersperse (Html.text ", ")).toArray
|
||||
pure nodes
|
||||
return nodes
|
||||
|
||||
/--
|
||||
Render the general header of a declaration containing its declaration type
|
||||
|
@ -66,22 +66,22 @@ def docInfoHeader (doc : DocInfo) : HtmlM Html := do
|
|||
nodes := nodes.push <| Html.element "span" false #[("class", "decl_kind")] #[doc.getKindDescription]
|
||||
nodes := nodes.push
|
||||
<span class="decl_name">
|
||||
<a class="break_within" href={←declNameToLink doc.getName}>
|
||||
<a class="break_within" href={← declNameToLink doc.getName}>
|
||||
-- TODO: HTMLify the name
|
||||
{doc.getName.toString}
|
||||
</a>
|
||||
</span>
|
||||
for arg in doc.getArgs do
|
||||
nodes := nodes.push (←argToHtml arg)
|
||||
nodes := nodes.push (← argToHtml arg)
|
||||
|
||||
match doc with
|
||||
| DocInfo.structureInfo i => nodes := nodes.append (←structureInfoHeader i)
|
||||
| DocInfo.classInfo i => nodes := nodes.append (←structureInfoHeader i)
|
||||
| DocInfo.structureInfo i => nodes := nodes.append (← structureInfoHeader i)
|
||||
| DocInfo.classInfo i => nodes := nodes.append (← structureInfoHeader i)
|
||||
| _ => nodes := nodes
|
||||
|
||||
nodes := nodes.push <| Html.element "span" true #[("class", "decl_args")] #[" :"]
|
||||
nodes := nodes.push <div class="decl_type">[←infoFormatToHtml doc.getType]</div>
|
||||
pure <div class="decl_header"> [nodes] </div>
|
||||
nodes := nodes.push <div class="decl_type">[← infoFormatToHtml doc.getType]</div>
|
||||
return <div class="decl_header"> [nodes] </div>
|
||||
|
||||
/--
|
||||
The main entry point for rendering a single declaration inside a given module.
|
||||
|
@ -100,12 +100,12 @@ def docInfoToHtml (module : Name) (doc : DocInfo) : HtmlM Html := do
|
|||
| none => pure #[]
|
||||
-- extra information like equations and instances
|
||||
let extraInfoHtml ← match doc with
|
||||
| DocInfo.classInfo i => pure #[←classInstancesToHtml i.name]
|
||||
| DocInfo.classInfo i => pure #[← classInstancesToHtml i.name]
|
||||
| DocInfo.definitionInfo i => equationsToHtml i
|
||||
| DocInfo.instanceInfo i => equationsToHtml i.toDefinitionInfo
|
||||
| DocInfo.classInductiveInfo i => pure #[←classInstancesToHtml i.name]
|
||||
| DocInfo.inductiveInfo i => pure #[←instancesForToHtml i.name]
|
||||
| DocInfo.structureInfo i => pure #[←instancesForToHtml i.name]
|
||||
| DocInfo.classInductiveInfo i => pure #[← classInstancesToHtml i.name]
|
||||
| DocInfo.inductiveInfo i => pure #[← instancesForToHtml i.name]
|
||||
| DocInfo.structureInfo i => pure #[← instancesForToHtml i.name]
|
||||
| _ => pure #[]
|
||||
let attrs := doc.getAttrs
|
||||
let attrsHtml :=
|
||||
|
@ -115,10 +115,10 @@ def docInfoToHtml (module : Name) (doc : DocInfo) : HtmlM Html := do
|
|||
else
|
||||
#[]
|
||||
let leanInkHtml :=
|
||||
if ←leanInkEnabled? then
|
||||
if ← leanInkEnabled? then
|
||||
#[
|
||||
<div class="ink_link">
|
||||
<a href={←declNameToInkLink doc.getName}>ink</a>
|
||||
<a href={← declNameToInkLink doc.getName}>ink</a>
|
||||
</div>
|
||||
]
|
||||
else
|
||||
|
@ -128,11 +128,11 @@ def docInfoToHtml (module : Name) (doc : DocInfo) : HtmlM Html := do
|
|||
<div class="decl" id={doc.getName.toString}>
|
||||
<div class={doc.getKind}>
|
||||
<div class="gh_link">
|
||||
<a href={←getSourceUrl module doc.getDeclarationRange}>source</a>
|
||||
<a href={← getSourceUrl module doc.getDeclarationRange}>source</a>
|
||||
</div>
|
||||
[leanInkHtml]
|
||||
[attrsHtml]
|
||||
{←docInfoHeader doc}
|
||||
{← docInfoHeader doc}
|
||||
[docInfoHtml]
|
||||
[docStringHtml]
|
||||
[extraInfoHtml]
|
||||
|
@ -146,7 +146,7 @@ as HTML.
|
|||
def modDocToHtml (mdoc : ModuleDoc) : HtmlM Html := do
|
||||
pure
|
||||
<div class="mod_doc">
|
||||
[←docStringToHtml mdoc.doc]
|
||||
[← docStringToHtml mdoc.doc]
|
||||
</div>
|
||||
|
||||
/--
|
||||
|
@ -168,15 +168,15 @@ Returns the list of all imports this module does.
|
|||
-/
|
||||
def getImports (module : Name) : HtmlM (Array Name) := do
|
||||
let res ← getResult
|
||||
pure <| res.moduleInfo.find! module |>.imports
|
||||
return res.moduleInfo.find! module |>.imports
|
||||
|
||||
/--
|
||||
Sort the list of all modules this one is importing, linkify it
|
||||
and return the HTML.
|
||||
-/
|
||||
def importsHtml (moduleName : Name) : HtmlM (Array Html) := do
|
||||
let imports := (←getImports moduleName) |>.qsort Name.lt
|
||||
imports.mapM (λ i => do pure <li>{←moduleToHtmlLink i}</li>)
|
||||
let imports := (← getImports moduleName).qsort Name.lt
|
||||
imports.mapM (fun i => do return <li>{← moduleToHtmlLink i}</li>)
|
||||
|
||||
/--
|
||||
Render the internal nav bar (the thing on the right on all module pages).
|
||||
|
@ -185,12 +185,12 @@ def internalNav (members : Array Name) (moduleName : Name) : HtmlM Html := do
|
|||
pure
|
||||
<nav class="internal_nav">
|
||||
<h3><a class="break_within" href="#top">{moduleName.toString}</a></h3>
|
||||
<p class="gh_nav_link"><a href={←getSourceUrl moduleName none}>source</a></p>
|
||||
<p class="gh_nav_link"><a href={← getSourceUrl moduleName none}>source</a></p>
|
||||
<div class="imports">
|
||||
<details>
|
||||
<summary>Imports</summary>
|
||||
<ul>
|
||||
[←importsHtml moduleName]
|
||||
[← importsHtml moduleName]
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
|
@ -205,10 +205,10 @@ def internalNav (members : Array Name) (moduleName : Name) : HtmlM Html := do
|
|||
The main entry point to rendering the HTML for an entire module.
|
||||
-/
|
||||
def moduleToHtml (module : Process.Module) : HtmlM Html := withTheReader SiteBaseContext (setCurrentName module.name) do
|
||||
let memberDocs ← module.members.mapM (λ i => moduleMemberToHtml module.name i)
|
||||
let memberDocs ← module.members.mapM (moduleMemberToHtml module.name ·)
|
||||
let memberNames := filterMapDocInfo module.members |>.map DocInfo.getName
|
||||
templateLiftExtends (baseHtmlGenerator module.name.toString) <| pure #[
|
||||
←internalNav memberNames module.name,
|
||||
← internalNav memberNames module.name,
|
||||
Html.element "main" false #[] memberDocs
|
||||
]
|
||||
|
||||
|
|
|
@ -14,8 +14,8 @@ open Lean
|
|||
open scoped DocGen4.Jsx
|
||||
|
||||
def moduleListFile (file : Name) : BaseHtmlM Html := do
|
||||
pure <div class={if (← getCurrentName) == file then "nav_link visible" else "nav_link"}>
|
||||
<a href={←moduleNameToLink file}>{file.getString!}</a>
|
||||
return <div class={if (← getCurrentName) == file then "nav_link visible" else "nav_link"}>
|
||||
<a href={← moduleNameToLink file}>{file.getString!}</a>
|
||||
</div>
|
||||
|
||||
/--
|
||||
|
@ -23,20 +23,20 @@ Build the HTML tree representing the module hierarchy.
|
|||
-/
|
||||
partial def moduleListDir (h : Hierarchy) : BaseHtmlM Html := do
|
||||
let children := Array.mk (h.getChildren.toList.map Prod.snd)
|
||||
let dirs := children.filter (λ c => c.getChildren.toList.length != 0)
|
||||
let files := children.filter (λ c => Hierarchy.isFile c ∧ c.getChildren.toList.length = 0)
|
||||
let dirs := children.filter (fun c => c.getChildren.toList.length != 0)
|
||||
let files := children.filter (fun c => Hierarchy.isFile c && c.getChildren.toList.length = 0)
|
||||
|>.map Hierarchy.getName
|
||||
let dirNodes ← (dirs.mapM moduleListDir)
|
||||
let fileNodes ← (files.mapM moduleListFile)
|
||||
let dirNodes ← dirs.mapM moduleListDir
|
||||
let fileNodes ← files.mapM moduleListFile
|
||||
let moduleLink ← moduleNameToLink h.getName
|
||||
let summary :=
|
||||
if h.isFile then
|
||||
<summary>{←moduleToHtmlLink h.getName}</summary>
|
||||
<summary>{← moduleToHtmlLink h.getName}</summary>
|
||||
else
|
||||
<summary>{h.getName.getString!}</summary>
|
||||
|
||||
pure
|
||||
<details class="nav_sect" "data-path"={moduleLink} [if (←getCurrentName).any (h.getName.isPrefixOf ·) then #[("open", "")] else #[]]>
|
||||
<details class="nav_sect" "data-path"={moduleLink} [if (← getCurrentName).any (h.getName.isPrefixOf ·) then #[("open", "")] else #[]]>
|
||||
{summary}
|
||||
[dirNodes]
|
||||
[fileNodes]
|
||||
|
@ -49,8 +49,8 @@ def moduleList : BaseHtmlM Html := do
|
|||
let hierarchy ← getHierarchy
|
||||
let mut list := Array.empty
|
||||
for (_, cs) in hierarchy.getChildren do
|
||||
list := list.push <| ←moduleListDir cs
|
||||
pure <div class="module_list">[list]</div>
|
||||
list := list.push <| ← moduleListDir cs
|
||||
return <div class="module_list">[list]</div>
|
||||
|
||||
/--
|
||||
The main entry point to rendering the navbar on the left hand side.
|
||||
|
@ -59,9 +59,9 @@ def navbar : BaseHtmlM Html := do
|
|||
pure
|
||||
<html lang="en">
|
||||
<head>
|
||||
[←baseHtmlHeadDeclarations]
|
||||
[← baseHtmlHeadDeclarations]
|
||||
|
||||
<script type="module" src={s!"{←getRoot}nav.js"}></script>
|
||||
<script type="module" src={s!"{← getRoot}nav.js"}></script>
|
||||
<base target="_parent" />
|
||||
</head>
|
||||
|
||||
|
@ -69,16 +69,16 @@ def navbar : BaseHtmlM Html := do
|
|||
<div class="navframe">
|
||||
<nav class="nav">
|
||||
<h3>General documentation</h3>
|
||||
<div class="nav_link"><a href={s!"{←getRoot}"}>index</a></div>
|
||||
<div class="nav_link"><a href={s!"{←getRoot}foundational_types.html"}>foundational types</a></div>
|
||||
<div class="nav_link"><a href={s!"{← getRoot}"}>index</a></div>
|
||||
<div class="nav_link"><a href={s!"{← getRoot}foundational_types.html"}>foundational types</a></div>
|
||||
/-
|
||||
TODO: Add these in later
|
||||
<div class="nav_link"><a href={s!"{←getRoot}tactics.html"}>tactics</a></div>
|
||||
<div class="nav_link"><a href={s!"{←getRoot}commands.html"}>commands</a></div>
|
||||
<div class="nav_link"><a href={s!"{←getRoot}hole_commands.html"}>hole commands</a></div>
|
||||
<div class="nav_link"><a href={s!"{←getRoot}attributes.html"}>attributes</a></div>
|
||||
<div class="nav_link"><a href={s!"{←getRoot}notes.html"}>notes</a></div>
|
||||
<div class="nav_link"><a href={s!"{←getRoot}references.html"}>references</a></div>
|
||||
<div class="nav_link"><a href={s!"{← getRoot}tactics.html"}>tactics</a></div>
|
||||
<div class="nav_link"><a href={s!"{← getRoot}commands.html"}>commands</a></div>
|
||||
<div class="nav_link"><a href={s!"{← getRoot}hole_commands.html"}>hole commands</a></div>
|
||||
<div class="nav_link"><a href={s!"{← getRoot}attributes.html"}>attributes</a></div>
|
||||
<div class="nav_link"><a href={s!"{← getRoot}notes.html"}>notes</a></div>
|
||||
<div class="nav_link"><a href={s!"{← getRoot}references.html"}>references</a></div>
|
||||
-/
|
||||
<h3>Library</h3>
|
||||
{← moduleList}
|
||||
|
|
|
@ -25,11 +25,11 @@ def getGithubBaseUrl (gitUrl : String) : String := Id.run do
|
|||
if url.startsWith "git@" then
|
||||
url := url.drop 15
|
||||
url := url.dropRight 4
|
||||
pure s!"https://github.com/{url}"
|
||||
return s!"https://github.com/{url}"
|
||||
else if url.endsWith ".git" then
|
||||
pure <| url.dropRight 4
|
||||
return url.dropRight 4
|
||||
else
|
||||
pure url
|
||||
return url
|
||||
|
||||
/--
|
||||
Obtain the Github URL of a project by parsing the origin remote.
|
||||
|
@ -38,7 +38,7 @@ def getProjectGithubUrl : IO String := do
|
|||
let out ← IO.Process.output {cmd := "git", args := #["remote", "get-url", "origin"]}
|
||||
if out.exitCode != 0 then
|
||||
throw <| IO.userError <| "git exited with code " ++ toString out.exitCode
|
||||
pure out.stdout.trimRight
|
||||
return out.stdout.trimRight
|
||||
|
||||
/--
|
||||
Obtain the git commit hash of the project that is currently getting analyzed.
|
||||
|
@ -47,7 +47,7 @@ def getProjectCommit : IO String := do
|
|||
let out ← IO.Process.output {cmd := "git", args := #["rev-parse", "HEAD"]}
|
||||
if out.exitCode != 0 then
|
||||
throw <| IO.userError <| "git exited with code " ++ toString out.exitCode
|
||||
pure out.stdout.trimRight
|
||||
return out.stdout.trimRight
|
||||
|
||||
/--
|
||||
Given a lake workspace with all the dependencies as well as the hash of the
|
||||
|
@ -58,17 +58,17 @@ def sourceLinker (ws : Lake.Workspace) : IO (Name → Option DeclarationRange
|
|||
let leanHash := ws.lakeEnv.lean.githash
|
||||
-- Compute a map from package names to source URL
|
||||
let mut gitMap := Lean.mkHashMap
|
||||
let projectBaseUrl := getGithubBaseUrl (←getProjectGithubUrl)
|
||||
let projectBaseUrl := getGithubBaseUrl (← getProjectGithubUrl)
|
||||
let projectCommit ← getProjectCommit
|
||||
gitMap := gitMap.insert ws.root.name (projectBaseUrl, projectCommit)
|
||||
let manifest ← Lake.Manifest.loadOrEmpty ws.root.manifestFile
|
||||
|>.run (Lake.MonadLog.eio .normal)
|
||||
|>.toIO (λ _ => IO.userError "Failed to load lake manifest")
|
||||
|>.toIO (fun _ => IO.userError "Failed to load lake manifest")
|
||||
for pkg in manifest.entryArray do
|
||||
if let .git _ url rev .. := pkg then
|
||||
gitMap := gitMap.insert pkg.name (getGithubBaseUrl url, rev)
|
||||
|
||||
pure λ module range =>
|
||||
return fun module range =>
|
||||
let parts := module.components.map Name.toString
|
||||
let path := (parts.intersperse "/").foldl (· ++ ·) ""
|
||||
let root := module.getRoot
|
||||
|
|
|
@ -19,12 +19,12 @@ def fieldToHtml (f : Process.NameInfo) : HtmlM Html := do
|
|||
pure
|
||||
<li id={name} class="structure_field">
|
||||
<div class="structure_field_doc">[renderedDoc]</div>
|
||||
<div class="structure_field_info">{s!"{shortName} "} : [←infoFormatToHtml f.type]</div>
|
||||
<div class="structure_field_info">{s!"{shortName} "} : [← infoFormatToHtml f.type]</div>
|
||||
</li>
|
||||
else
|
||||
pure
|
||||
<li id={name} class="structure_field">
|
||||
<div class="structure_field_info">{s!"{shortName} "} : [←infoFormatToHtml f.type]</div>
|
||||
<div class="structure_field_info">{s!"{shortName} "} : [← infoFormatToHtml f.type]</div>
|
||||
</li>
|
||||
|
||||
/--
|
||||
|
@ -34,18 +34,18 @@ def structureToHtml (i : Process.StructureInfo) : HtmlM (Array Html) := do
|
|||
let structureHtml :=
|
||||
if Name.isSuffixOf `mk i.ctor.name then
|
||||
(<ul class="structure_fields" id={i.ctor.name.toString}>
|
||||
[←i.fieldInfo.mapM fieldToHtml]
|
||||
[← i.fieldInfo.mapM fieldToHtml]
|
||||
</ul>)
|
||||
else
|
||||
let ctorShortName := i.ctor.name.componentsRev.head!.toString
|
||||
(<ul class="structure_ext">
|
||||
<li id={i.ctor.name.toString} class="structure_ext_ctor">{s!"{ctorShortName} "} :: (</li>
|
||||
<ul class="structure_ext_fields">
|
||||
[←i.fieldInfo.mapM fieldToHtml]
|
||||
[← i.fieldInfo.mapM fieldToHtml]
|
||||
</ul>
|
||||
<li class="structure_ext_ctor">)</li>
|
||||
</ul>)
|
||||
pure #[structureHtml]
|
||||
return #[structureHtml]
|
||||
|
||||
end Output
|
||||
end DocGen4
|
||||
|
|
|
@ -16,26 +16,26 @@ The HTML template used for all pages.
|
|||
-/
|
||||
def baseHtmlGenerator (title : String) (site : Array Html) : BaseHtmlM Html := do
|
||||
let moduleConstant :=
|
||||
if let some module := (←getCurrentName) then
|
||||
if let some module := ← getCurrentName then
|
||||
#[<script>{s!"const MODULE_NAME={String.quote module.toString};"}</script>]
|
||||
else
|
||||
#[]
|
||||
pure
|
||||
<html lang="en">
|
||||
<head>
|
||||
[←baseHtmlHeadDeclarations]
|
||||
[← baseHtmlHeadDeclarations]
|
||||
|
||||
<title>{title}</title>
|
||||
<script defer="true" src={s!"{←getRoot}mathjax-config.js"}></script>
|
||||
<script defer="true" src={s!"{← getRoot}mathjax-config.js"}></script>
|
||||
<script defer="true" src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
|
||||
<script defer="true" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
|
||||
|
||||
<script>{s!"const SITE_ROOT={String.quote (←getRoot)};"}</script>
|
||||
<script>{s!"const SITE_ROOT={String.quote (← getRoot)};"}</script>
|
||||
[moduleConstant]
|
||||
<script type="module" src={s!"{←getRoot}search.js"}></script>
|
||||
<script type="module" src={s!"{←getRoot}how-about.js"}></script>
|
||||
<script type="module" src={s!"{←getRoot}instances.js"}></script>
|
||||
<script type="module" src={s!"{←getRoot}importedBy.js"}></script>
|
||||
<script type="module" src={s!"{← getRoot}search.js"}></script>
|
||||
<script type="module" src={s!"{← getRoot}how-about.js"}></script>
|
||||
<script type="module" src={s!"{← getRoot}instances.js"}></script>
|
||||
<script type="module" src={s!"{← getRoot}importedBy.js"}></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@ -56,7 +56,7 @@ def baseHtmlGenerator (title : String) (site : Array Html) : BaseHtmlM Html := d
|
|||
[site]
|
||||
|
||||
<nav class="nav">
|
||||
<iframe src={s!"{←getRoot}navbar.html"} class="navframe" frameBorder="0"></iframe>
|
||||
<iframe src={s!"{← getRoot}navbar.html"} class="navframe" frameBorder="0"></iframe>
|
||||
</nav>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -29,7 +29,7 @@ instance : Coe String Html :=
|
|||
namespace Html
|
||||
|
||||
def attributesToString (attrs : Array (String × String)) :String :=
|
||||
attrs.foldl (λ acc (k, v) => acc ++ " " ++ k ++ "=\"" ++ v ++ "\"") ""
|
||||
attrs.foldl (fun acc (k, v) => acc ++ " " ++ k ++ "=\"" ++ v ++ "\"") ""
|
||||
|
||||
-- TODO: Termination proof
|
||||
partial def toStringAux : Html → String
|
||||
|
@ -60,7 +60,7 @@ def escapePairs : Array (String × String) :=
|
|||
]
|
||||
|
||||
def escape (s : String) : String :=
|
||||
escapePairs.foldl (λ acc (o, r) => acc.replace o r) s
|
||||
escapePairs.foldl (fun acc (o, r) => acc.replace o r) s
|
||||
|
||||
end Html
|
||||
|
||||
|
|
|
@ -36,11 +36,11 @@ structure JsonIndex where
|
|||
|
||||
instance : ToJson JsonIndex where
|
||||
toJson idx := Id.run do
|
||||
let jsonDecls := Json.mkObj <| idx.declarations.map (λ (k, v) => (k, toJson v))
|
||||
let jsonInstances := Json.mkObj <| idx.instances.toList.map (λ (k, v) => (k, toJson v))
|
||||
let jsonImportedBy := Json.mkObj <| idx.importedBy.toList.map (λ (k, v) => (k, toJson v))
|
||||
let jsonModules := Json.mkObj <| idx.modules.map (λ (k, v) => (k, toJson v))
|
||||
let jsonInstancesFor := Json.mkObj <| idx.instancesFor.toList.map (λ (k, v) => (k, toJson v))
|
||||
let jsonDecls := Json.mkObj <| idx.declarations.map (fun (k, v) => (k, toJson v))
|
||||
let jsonInstances := Json.mkObj <| idx.instances.toList.map (fun (k, v) => (k, toJson v))
|
||||
let jsonImportedBy := Json.mkObj <| idx.importedBy.toList.map (fun (k, v) => (k, toJson v))
|
||||
let jsonModules := Json.mkObj <| idx.modules.map (fun (k, v) => (k, toJson v))
|
||||
let jsonInstancesFor := Json.mkObj <| idx.instancesFor.toList.map (fun (k, v) => (k, toJson v))
|
||||
let finalJson := Json.mkObj [
|
||||
("declarations", jsonDecls),
|
||||
("instances", jsonInstances),
|
||||
|
@ -48,12 +48,12 @@ instance : ToJson JsonIndex where
|
|||
("modules", jsonModules),
|
||||
("instancesFor", jsonInstancesFor)
|
||||
]
|
||||
pure finalJson
|
||||
return finalJson
|
||||
|
||||
def JsonIndex.addModule (index : JsonIndex) (module : JsonModule) : BaseHtmlM JsonIndex := do
|
||||
let mut index := index
|
||||
let newModule := (module.name, ←moduleNameToLink (String.toName module.name))
|
||||
let newDecls := module.declarations.map (λ d => (d.name, d))
|
||||
let newModule := (module.name, ← moduleNameToLink (String.toName module.name))
|
||||
let newDecls := module.declarations.map (fun d => (d.name, d))
|
||||
index := { index with
|
||||
modules := newModule :: index.modules
|
||||
declarations := newDecls ++ index.declarations
|
||||
|
@ -72,21 +72,21 @@ def JsonIndex.addModule (index : JsonIndex) (module : JsonModule) : BaseHtmlM Js
|
|||
let mut impBy := index.importedBy.findD imp #[]
|
||||
impBy := impBy.push module.name
|
||||
index := { index with importedBy := index.importedBy.insert imp impBy }
|
||||
pure index
|
||||
return index
|
||||
|
||||
def DocInfo.toJson (module : Name) (info : Process.DocInfo) : HtmlM JsonDeclaration := do
|
||||
let name := info.getName.toString
|
||||
let doc := info.getDocString.getD ""
|
||||
let docLink ← declNameToLink info.getName
|
||||
let sourceLink ← getSourceUrl module info.getDeclarationRange
|
||||
pure { name, doc, docLink, sourceLink }
|
||||
return { name, doc, docLink, sourceLink }
|
||||
|
||||
def Process.Module.toJson (module : Process.Module) : HtmlM Json := do
|
||||
let mut jsonDecls := []
|
||||
let mut instances := #[]
|
||||
let declInfo := Process.filterMapDocInfo module.members
|
||||
for decl in declInfo do
|
||||
jsonDecls := (←DocInfo.toJson module.name decl) :: jsonDecls
|
||||
jsonDecls := (← DocInfo.toJson module.name decl) :: jsonDecls
|
||||
if let .instanceInfo i := decl then
|
||||
instances := instances.push {
|
||||
name := i.name.toString,
|
||||
|
@ -99,6 +99,6 @@ def Process.Module.toJson (module : Process.Module) : HtmlM Json := do
|
|||
instances,
|
||||
imports := module.imports.map Name.toString
|
||||
}
|
||||
pure <| ToJson.toJson jsonMod
|
||||
return ToJson.toJson jsonMod
|
||||
|
||||
end DocGen4.Output
|
||||
|
|
Loading…
Reference in New Issue