Add PDF generation to absorbed doc-gen4 project.
parent
dac45de7f2
commit
fe53025817
|
@ -107,18 +107,25 @@ def templateExtends {α β} {m} [Bind m] (base : α → m β) (new : m α) : m
|
||||||
|
|
||||||
def templateLiftExtends {α β} {m n} [Bind m] [MonadLift n m] (base : α → n β) (new : m α) : m β :=
|
def templateLiftExtends {α β} {m n} [Bind m] [MonadLift n m] (base : α → n β) (new : m α) : m β :=
|
||||||
new >>= (monadLift ∘ base)
|
new >>= (monadLift ∘ base)
|
||||||
|
|
||||||
|
/-
|
||||||
|
Returns the doc-gen4 link to a module `NameExt`.
|
||||||
|
-/
|
||||||
|
def moduleNameExtToLink (n : NameExt) : BaseHtmlM String := do
|
||||||
|
let parts := n.name.components.map Name.toString
|
||||||
|
return (← getRoot) ++ (parts.intersperse "/").foldl (· ++ ·) "" ++ "." ++ n.ext.toString
|
||||||
|
|
||||||
/--
|
/--
|
||||||
Returns the doc-gen4 link to a module name.
|
Returns the doc-gen4 link to a module name.
|
||||||
-/
|
-/
|
||||||
def moduleNameToLink (n : Name) : BaseHtmlM String := do
|
def moduleNameToHtmlLink (n : Name) : BaseHtmlM String :=
|
||||||
let parts := n.components.map Name.toString
|
moduleNameExtToLink ⟨n, .html⟩
|
||||||
return (← getRoot) ++ (parts.intersperse "/").foldl (· ++ ·) "" ++ ".html"
|
|
||||||
|
|
||||||
/--
|
/--
|
||||||
Returns the HTML doc-gen4 link to a module name.
|
Returns the HTML doc-gen4 link to a module name.
|
||||||
-/
|
-/
|
||||||
def moduleToHtmlLink (module : Name) : BaseHtmlM Html := do
|
def moduleToHtmlLink (module : Name) : BaseHtmlM Html := do
|
||||||
return <a href={← moduleNameToLink module}>{module.toString}</a>
|
return <a href={← moduleNameToHtmlLink module}>{module.toString}</a>
|
||||||
|
|
||||||
/--
|
/--
|
||||||
Returns the LeanInk link to a module name.
|
Returns the LeanInk link to a module name.
|
||||||
|
@ -168,7 +175,7 @@ Returns the doc-gen4 link to a declaration name.
|
||||||
def declNameToLink (name : Name) : HtmlM String := do
|
def declNameToLink (name : Name) : HtmlM String := do
|
||||||
let res ← getResult
|
let res ← getResult
|
||||||
let module := res.moduleNames[res.name2ModIdx.find! name |>.toNat]!
|
let module := res.moduleNames[res.name2ModIdx.find! name |>.toNat]!
|
||||||
return (← moduleNameToLink module) ++ "#" ++ name.toString
|
return (← moduleNameToHtmlLink module) ++ "#" ++ name.toString
|
||||||
|
|
||||||
/--
|
/--
|
||||||
Returns the HTML doc-gen4 link to a declaration name.
|
Returns the HTML doc-gen4 link to a declaration name.
|
||||||
|
|
|
@ -76,7 +76,7 @@ def nameToLink? (s : String) : HtmlM (Option String) := do
|
||||||
declNameToLink name
|
declNameToLink name
|
||||||
-- module name
|
-- module name
|
||||||
else if res.moduleNames.contains name then
|
else if res.moduleNames.contains name then
|
||||||
moduleNameToLink name
|
moduleNameToHtmlLink name
|
||||||
-- find similar name in the same module
|
-- find similar name in the same module
|
||||||
else
|
else
|
||||||
match (← getCurrentName) with
|
match (← getCurrentName) with
|
||||||
|
|
|
@ -15,9 +15,48 @@ def index : BaseHtmlM Html := do templateExtends (baseHtml "Index") <|
|
||||||
pure <|
|
pure <|
|
||||||
<main>
|
<main>
|
||||||
<a id="top"></a>
|
<a id="top"></a>
|
||||||
<h1> Welcome to the documentation page </h1>
|
<h1>Bookshelf</h1>
|
||||||
-- Temporary comment until the lake issue is resolved
|
<p>
|
||||||
-- for commit <a href={s!"{← getProjectGithubUrl}/tree/{← getProjectCommit}"}>{s!"{← getProjectCommit} "}</a>
|
A study of the books listed below. Most proofs are conducted in LaTeX.
|
||||||
|
Where feasible, theorems are also formally proven in
|
||||||
|
<a target="_blank" href="https://leanprover.github.io/">Lean</a>.
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>Apostol, Tom M. Calculus, Vol. 1: One-Variable Calculus, with an Introduction to Linear Algebra. 2nd ed. Vol. 1. 2 vols. Wiley, 1991.</li>
|
||||||
|
<li>Avigad, Jeremy. ‘Theorem Proving in Lean’, n.d.</li>
|
||||||
|
<li>Axler, Sheldon. Linear Algebra Done Right. Undergraduate Texts in Mathematics. Cham: Springer International Publishing, 2015.</li>
|
||||||
|
<li>Cormen, Thomas H., Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. Introduction to Algorithms. 3rd ed. Cambridge, Mass: MIT Press, 2009.</li>
|
||||||
|
<li>Enderton, Herbert B. A Mathematical Introduction to Logic. 2nd ed. San Diego: Harcourt/Academic Press, 2001.</li>
|
||||||
|
<li>Gries, David. The Science of Programming. Texts and Monographs in Computer Science. New York: Springer-Verlag, 1981.</li>
|
||||||
|
<li>Gustedt, Jens. Modern C. Shelter Island, NY: Manning Publications Co, 2020.</li>
|
||||||
|
<li>Ross, Sheldon. A First Course in Probability Theory. 8th ed. Pearson Prentice Hall, n.d.</li>
|
||||||
|
<li>Smullyan, Raymond M. To Mock a Mockingbird: And Other Logic Puzzles Including an Amazing Adventure in Combinatory Logic. Oxford: Oxford university press, 2000.</li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
A color/symbol code is used on generated PDF headers to indicate their
|
||||||
|
status:
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<span style="color:cyan">Cyan statements </span> indicate axioms and
|
||||||
|
definitions. There must exist a corresponding <code>axiom</code> or
|
||||||
|
<code>def</code> in Lean.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<span style="color:teal">Teal statements </span> indicate those
|
||||||
|
with complete proofs in both LaTeX <i>and </i> Lean.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<span style="color:magenta">Magenta statements </span> indicate
|
||||||
|
those that have not been completely proven in either LaTeX or Lean
|
||||||
|
(or both). Progress is currently being made to correct this though.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<span style="color:red">Red coloring </span> is a catch-all for all
|
||||||
|
statements that don't fit the above categorizations. Incomplete
|
||||||
|
definitions, proofs only conducted in LaTeX, etc. belong here.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</p>
|
||||||
<p>This was built using Lean 4 at commit <a href={s!"https://github.com/leanprover/lean4/tree/{Lean.githash}"}>{Lean.githash}</a></p>
|
<p>This was built using Lean 4 at commit <a href={s!"https://github.com/leanprover/lean4/tree/{Lean.githash}"}>{Lean.githash}</a></p>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
|
|
@ -13,9 +13,9 @@ namespace Output
|
||||||
open Lean
|
open Lean
|
||||||
open scoped DocGen4.Jsx
|
open scoped DocGen4.Jsx
|
||||||
|
|
||||||
def moduleListFile (file : Name) : BaseHtmlM Html := do
|
def moduleListFile (file : NameExt) : BaseHtmlM Html := do
|
||||||
return <div class={if (← getCurrentName) == file then "nav_link visible" else "nav_link"}>
|
return <div class={if (← getCurrentName) == file.name then "nav_link visible" else "nav_link"}>
|
||||||
<a href={← moduleNameToLink file}>{file.getString!}</a>
|
<a href={← moduleNameExtToLink file}>{file.getString!}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
/--
|
/--
|
||||||
|
@ -25,13 +25,13 @@ partial def moduleListDir (h : Hierarchy) : BaseHtmlM Html := do
|
||||||
let children := Array.mk (h.getChildren.toList.map Prod.snd)
|
let children := Array.mk (h.getChildren.toList.map Prod.snd)
|
||||||
let dirs := children.filter (fun 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)
|
let files := children.filter (fun c => Hierarchy.isFile c && c.getChildren.toList.length = 0)
|
||||||
|>.map Hierarchy.getName
|
|>.map Hierarchy.getNameExt
|
||||||
let dirNodes ← dirs.mapM moduleListDir
|
let dirNodes ← dirs.mapM moduleListDir
|
||||||
let fileNodes ← files.mapM moduleListFile
|
let fileNodes ← files.mapM moduleListFile
|
||||||
let moduleLink ← moduleNameToLink h.getName
|
let moduleLink ← moduleNameToHtmlLink h.getName
|
||||||
let summary :=
|
let summary :=
|
||||||
if h.isFile then
|
if h.isFile then
|
||||||
<summary>{s!"{h.getName.getString!} ({<a href={← moduleNameToLink h.getName}>file</a>})"} </summary>
|
<summary>{s!"{h.getName.getString!} ({<a href={← moduleNameToHtmlLink h.getName}>file</a>})"} </summary>
|
||||||
else
|
else
|
||||||
<summary>{h.getName.getString!}</summary>
|
<summary>{h.getName.getString!}</summary>
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ instance : ToJson JsonIndex where
|
||||||
|
|
||||||
def JsonIndex.addModule (index : JsonIndex) (module : JsonModule) : BaseHtmlM JsonIndex := do
|
def JsonIndex.addModule (index : JsonIndex) (module : JsonModule) : BaseHtmlM JsonIndex := do
|
||||||
let mut index := index
|
let mut index := index
|
||||||
let newModule := (module.name, ← moduleNameToLink (String.toName module.name))
|
let newModule := (module.name, ← moduleNameToHtmlLink (String.toName module.name))
|
||||||
let newDecls := module.declarations.map (fun d => (d.name, d))
|
let newDecls := module.declarations.map (fun d => (d.name, d))
|
||||||
index := { index with
|
index := { index with
|
||||||
modules := newModule :: index.modules
|
modules := newModule :: index.modules
|
||||||
|
|
|
@ -14,6 +14,7 @@ import DocGen4.Process.DocInfo
|
||||||
import DocGen4.Process.Hierarchy
|
import DocGen4.Process.Hierarchy
|
||||||
import DocGen4.Process.InductiveInfo
|
import DocGen4.Process.InductiveInfo
|
||||||
import DocGen4.Process.InstanceInfo
|
import DocGen4.Process.InstanceInfo
|
||||||
|
import DocGen4.Process.NameExt
|
||||||
import DocGen4.Process.NameInfo
|
import DocGen4.Process.NameInfo
|
||||||
import DocGen4.Process.OpaqueInfo
|
import DocGen4.Process.OpaqueInfo
|
||||||
import DocGen4.Process.StructureInfo
|
import DocGen4.Process.StructureInfo
|
||||||
|
|
|
@ -6,6 +6,8 @@ Authors: Henrik Böving
|
||||||
import Lean
|
import Lean
|
||||||
import Lean.Data.HashMap
|
import Lean.Data.HashMap
|
||||||
|
|
||||||
|
import DocGen4.Process.NameExt
|
||||||
|
|
||||||
def Lean.HashSet.fromArray [BEq α] [Hashable α] (xs : Array α) : Lean.HashSet α :=
|
def Lean.HashSet.fromArray [BEq α] [Hashable α] (xs : Array α) : Lean.HashSet α :=
|
||||||
xs.foldr (flip .insert) .empty
|
xs.foldr (flip .insert) .empty
|
||||||
|
|
||||||
|
@ -18,35 +20,38 @@ def getNLevels (name : Name) (levels: Nat) : Name :=
|
||||||
(components.drop (components.length - levels)).reverse.foldl (· ++ ·) Name.anonymous
|
(components.drop (components.length - levels)).reverse.foldl (· ++ ·) Name.anonymous
|
||||||
|
|
||||||
inductive Hierarchy where
|
inductive Hierarchy where
|
||||||
| node (name : Name) (isFile : Bool) (children : RBNode Name (fun _ => Hierarchy)) : Hierarchy
|
| node (name : NameExt) (isFile : Bool) (children : RBNode NameExt (fun _ => Hierarchy)) : Hierarchy
|
||||||
|
|
||||||
instance : Inhabited Hierarchy := ⟨Hierarchy.node Name.anonymous false RBNode.leaf⟩
|
instance : Inhabited Hierarchy := ⟨Hierarchy.node ⟨.anonymous, .html⟩ false RBNode.leaf⟩
|
||||||
|
|
||||||
abbrev HierarchyMap := RBNode Name (fun _ => Hierarchy)
|
abbrev HierarchyMap := RBNode NameExt (fun _ => Hierarchy)
|
||||||
|
|
||||||
-- Everything in this namespace is adapted from stdlib's RBNode
|
-- Everything in this namespace is adapted from stdlib's RBNode
|
||||||
namespace HierarchyMap
|
namespace HierarchyMap
|
||||||
|
|
||||||
def toList : HierarchyMap → List (Name × Hierarchy)
|
def toList : HierarchyMap → List (NameExt × Hierarchy)
|
||||||
| t => t.revFold (fun ps k v => (k, v)::ps) []
|
| t => t.revFold (fun ps k v => (k, v)::ps) []
|
||||||
|
|
||||||
def toArray : HierarchyMap → Array (Name × Hierarchy)
|
def toArray : HierarchyMap → Array (NameExt × Hierarchy)
|
||||||
| t => t.fold (fun ps k v => ps ++ #[(k, v)] ) #[]
|
| t => t.fold (fun ps k v => ps ++ #[(k, v)] ) #[]
|
||||||
|
|
||||||
def hForIn [Monad m] (t : HierarchyMap) (init : σ) (f : (Name × Hierarchy) → σ → m (ForInStep σ)) : m σ :=
|
def hForIn [Monad m] (t : HierarchyMap) (init : σ) (f : (NameExt × Hierarchy) → σ → m (ForInStep σ)) : m σ :=
|
||||||
t.forIn init (fun a b acc => f (a, b) acc)
|
t.forIn init (fun a b acc => f (a, b) acc)
|
||||||
|
|
||||||
instance : ForIn m HierarchyMap (Name × Hierarchy) where
|
instance : ForIn m HierarchyMap (NameExt × Hierarchy) where
|
||||||
forIn := HierarchyMap.hForIn
|
forIn := HierarchyMap.hForIn
|
||||||
|
|
||||||
end HierarchyMap
|
end HierarchyMap
|
||||||
|
|
||||||
namespace Hierarchy
|
namespace Hierarchy
|
||||||
|
|
||||||
def empty (n : Name) (isFile : Bool) : Hierarchy :=
|
def empty (n : NameExt) (isFile : Bool) : Hierarchy :=
|
||||||
node n isFile RBNode.leaf
|
node n isFile RBNode.leaf
|
||||||
|
|
||||||
def getName : Hierarchy → Name
|
def getName : Hierarchy → Name
|
||||||
|
| node n _ _ => n.name
|
||||||
|
|
||||||
|
def getNameExt : Hierarchy → NameExt
|
||||||
| node n _ _ => n
|
| node n _ _ => n
|
||||||
|
|
||||||
def getChildren : Hierarchy → HierarchyMap
|
def getChildren : Hierarchy → HierarchyMap
|
||||||
|
@ -55,31 +60,34 @@ def getChildren : Hierarchy → HierarchyMap
|
||||||
def isFile : Hierarchy → Bool
|
def isFile : Hierarchy → Bool
|
||||||
| node _ f _ => f
|
| node _ f _ => f
|
||||||
|
|
||||||
partial def insert! (h : Hierarchy) (n : Name) : Hierarchy := Id.run do
|
partial def insert! (h : Hierarchy) (n : NameExt) : Hierarchy := Id.run do
|
||||||
let hn := h.getName
|
let hn := h.getNameExt
|
||||||
let mut cs := h.getChildren
|
let mut cs := h.getChildren
|
||||||
|
|
||||||
if getNumParts hn + 1 == getNumParts n then
|
if getNumParts hn.name + 1 == getNumParts n.name then
|
||||||
match cs.find Name.cmp n with
|
match cs.find NameExt.cmp n with
|
||||||
| none =>
|
| none =>
|
||||||
node hn h.isFile (cs.insert Name.cmp n <| empty n true)
|
node hn h.isFile (cs.insert NameExt.cmp n <| empty n true)
|
||||||
| some (node _ true _) => h
|
| some (node _ true _) => h
|
||||||
| some (node _ false ccs) =>
|
| some (node _ false ccs) =>
|
||||||
cs := cs.erase Name.cmp n
|
cs := cs.erase NameExt.cmp n
|
||||||
node hn h.isFile (cs.insert Name.cmp n <| node n true ccs)
|
node hn h.isFile (cs.insert NameExt.cmp n <| node n true ccs)
|
||||||
else
|
else
|
||||||
let leveledName := getNLevels n (getNumParts hn + 1)
|
let leveled := ⟨getNLevels n.name (getNumParts hn.name + 1), .html⟩
|
||||||
match cs.find Name.cmp leveledName with
|
match cs.find NameExt.cmp leveled with
|
||||||
| some nextLevel =>
|
| some nextLevel =>
|
||||||
cs := cs.erase Name.cmp leveledName
|
cs := cs.erase NameExt.cmp leveled
|
||||||
-- BUG?
|
-- BUG?
|
||||||
node hn h.isFile <| cs.insert Name.cmp leveledName (nextLevel.insert! n)
|
node hn h.isFile <| cs.insert NameExt.cmp leveled (nextLevel.insert! n)
|
||||||
| none =>
|
| none =>
|
||||||
let child := (insert! (empty leveledName false) n)
|
let child := (insert! (empty leveled false) n)
|
||||||
node hn h.isFile <| cs.insert Name.cmp leveledName child
|
node hn h.isFile <| cs.insert NameExt.cmp leveled child
|
||||||
|
|
||||||
partial def fromArray (names : Array Name) : Hierarchy :=
|
partial def fromArray (names : Array Name) : Hierarchy :=
|
||||||
names.foldl insert! (empty anonymous false)
|
(names.map (fun n => NameExt.mk n .html)).foldl insert! (empty ⟨anonymous, .html⟩ false)
|
||||||
|
|
||||||
|
partial def fromArrayExt (names : Array NameExt) : Hierarchy :=
|
||||||
|
names.foldl insert! (empty ⟨anonymous, .html⟩ false)
|
||||||
|
|
||||||
def baseDirBlackList : HashSet String :=
|
def baseDirBlackList : HashSet String :=
|
||||||
HashSet.fromArray #[
|
HashSet.fromArray #[
|
||||||
|
@ -99,13 +107,15 @@ def baseDirBlackList : HashSet String :=
|
||||||
"style.css"
|
"style.css"
|
||||||
]
|
]
|
||||||
|
|
||||||
partial def fromDirectoryAux (dir : System.FilePath) (previous : Name) : IO (Array Name) := do
|
partial def fromDirectoryAux (dir : System.FilePath) (previous : Name) : IO (Array NameExt) := do
|
||||||
let mut children := #[]
|
let mut children := #[]
|
||||||
for entry in ← System.FilePath.readDir dir do
|
for entry in ← System.FilePath.readDir dir do
|
||||||
if ← entry.path.isDir then
|
if ← entry.path.isDir then
|
||||||
children := children ++ (← fromDirectoryAux entry.path (.str previous entry.fileName))
|
children := children ++ (← fromDirectoryAux entry.path (.str previous entry.fileName))
|
||||||
else if entry.path.extension = some "html" then
|
else if entry.path.extension = some "html" then
|
||||||
children := children.push <| .str previous (entry.fileName.dropRight ".html".length)
|
children := children.push <| ⟨.str previous (entry.fileName.dropRight ".html".length), .html⟩
|
||||||
|
else if entry.path.extension = some "pdf" then
|
||||||
|
children := children.push <| ⟨.str previous (entry.fileName.dropRight ".pdf".length), .pdf⟩
|
||||||
return children
|
return children
|
||||||
|
|
||||||
def fromDirectory (dir : System.FilePath) : IO Hierarchy := do
|
def fromDirectory (dir : System.FilePath) : IO Hierarchy := do
|
||||||
|
@ -116,8 +126,10 @@ def fromDirectory (dir : System.FilePath) : IO Hierarchy := do
|
||||||
else if ← entry.path.isDir then
|
else if ← entry.path.isDir then
|
||||||
children := children ++ (← fromDirectoryAux entry.path (.mkSimple entry.fileName))
|
children := children ++ (← fromDirectoryAux entry.path (.mkSimple entry.fileName))
|
||||||
else if entry.path.extension = some "html" then
|
else if entry.path.extension = some "html" then
|
||||||
children := children.push <| .mkSimple (entry.fileName.dropRight ".html".length)
|
children := children.push <| ⟨.mkSimple (entry.fileName.dropRight ".html".length), .html⟩
|
||||||
return Hierarchy.fromArray children
|
else if entry.path.extension = some "pdf" then
|
||||||
|
children := children.push <| ⟨.mkSimple (entry.fileName.dropRight ".pdf".length), .pdf⟩
|
||||||
|
return Hierarchy.fromArrayExt children
|
||||||
|
|
||||||
end Hierarchy
|
end Hierarchy
|
||||||
end DocGen4
|
end DocGen4
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
/-
|
||||||
|
A generalization of `Lean.Name` that includes a file extension.
|
||||||
|
-/
|
||||||
|
import Lean
|
||||||
|
|
||||||
|
open Lean Name
|
||||||
|
|
||||||
|
inductive Extension where
|
||||||
|
| html
|
||||||
|
| pdf
|
||||||
|
deriving Repr
|
||||||
|
|
||||||
|
namespace Extension
|
||||||
|
|
||||||
|
def cmp : Extension → Extension → Ordering
|
||||||
|
| html, html => Ordering.eq
|
||||||
|
| html, _ => Ordering.lt
|
||||||
|
| pdf, pdf => Ordering.eq
|
||||||
|
| pdf, _ => Ordering.gt
|
||||||
|
|
||||||
|
def toString : Extension → String
|
||||||
|
| html => "html"
|
||||||
|
| pdf => "pdf"
|
||||||
|
|
||||||
|
end Extension
|
||||||
|
|
||||||
|
structure NameExt where
|
||||||
|
name : Name
|
||||||
|
ext : Extension
|
||||||
|
|
||||||
|
namespace NameExt
|
||||||
|
|
||||||
|
def cmp (n₁ n₂ : NameExt) : Ordering :=
|
||||||
|
match Name.cmp n₁.name n₂.name with
|
||||||
|
| Ordering.eq => Extension.cmp n₁.ext n₂.ext
|
||||||
|
| ord => ord
|
||||||
|
|
||||||
|
def getString! : NameExt → String
|
||||||
|
| ⟨str _ s, .html⟩ => s
|
||||||
|
| ⟨str _ s, .pdf⟩ => s ++ "_pdf"
|
||||||
|
| _ => unreachable!
|
||||||
|
|
||||||
|
end NameExt
|
25
README.md
25
README.md
|
@ -15,27 +15,16 @@ feasible, theorems are also formally proven in [Lean](https://leanprover.github.
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
To generate documentation, we use [bookshelf-docgen](https://github.com/jrpotter/bookshelf-docgen).
|
This project has absorbed [doc-gen4](https://github.com/leanprover/doc-gen4) to
|
||||||
Refer to this project on prerequisites and then run the following to build and
|
ease customization. In particular, the `DocGen4` module found in this project
|
||||||
serve files locally:
|
allows generating PDFs and including them into the navbar. To generate
|
||||||
|
documentation and serve files locally, run the following:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
> lake build Bookshelf:docs
|
> lake build Bookshelf:docs
|
||||||
> lake run server
|
> lake run server
|
||||||
```
|
```
|
||||||
|
|
||||||
This assumes you have `python3` available in your `$PATH`. To change how the
|
This assumes you have `pdflatex` and `python3` available in your `$PATH`. To
|
||||||
server behaves, refer to the `.env` file located in the root directory of this
|
change how the server behaves, refer to the `.env` file located in the root
|
||||||
project.
|
directory of this project.
|
||||||
|
|
||||||
A color code is used on generated PDF headers to indicate their status:
|
|
||||||
|
|
||||||
* Cyan statements indicate axioms and definitions. There must exist a
|
|
||||||
corresponding `axiom` or `def` in Lean.
|
|
||||||
* Teal statements indicate those with complete proofs in both LaTeX *and* Lean.
|
|
||||||
* Magenta statements indicate those that have not been completely proven in
|
|
||||||
either LaTeX or Lean (or both). Progress is currently being made to correct
|
|
||||||
this though.
|
|
||||||
* Red coloring is a catch-all for all statements that don't fit the above
|
|
||||||
categorizations. Incomplete definitions, proofs only conducted in LaTeX, etc.
|
|
||||||
belong here.
|
|
||||||
|
|
|
@ -77,7 +77,28 @@ target coreDocs : FilePath := do
|
||||||
}
|
}
|
||||||
return (dataFile, trace)
|
return (dataFile, trace)
|
||||||
|
|
||||||
|
/--
|
||||||
|
Wrapper for running scripts found in the `script` directory.
|
||||||
|
-/
|
||||||
|
def run_sh (name : String) : IndexBuildM Unit := do
|
||||||
|
let some bookshelfPkg ← findPackage? `«bookshelf»
|
||||||
|
| error "no bookshelf package found in workspace"
|
||||||
|
let proc <- IO.Process.output {
|
||||||
|
cmd := bookshelfPkg.dir.toString ++ s!"/scripts/{name}.sh",
|
||||||
|
args := #[(← getWorkspace).root.buildDir.toString]
|
||||||
|
}
|
||||||
|
if proc.exitCode == 0 then
|
||||||
|
let out := proc.stdout.trim
|
||||||
|
if out.length > 0 then IO.println out
|
||||||
|
else
|
||||||
|
let err := proc.stderr.trim
|
||||||
|
if err.length > 0 then IO.eprintln err
|
||||||
|
|
||||||
library_facet docs (lib) : FilePath := do
|
library_facet docs (lib) : FilePath := do
|
||||||
|
run_sh "run_pdflatex"
|
||||||
|
-- Ordering is important. The index file is generated by walking through the
|
||||||
|
-- filesystem directory. Files copied from the shell scripts need to exist
|
||||||
|
-- prior to this.
|
||||||
let some bookshelfPkg ← findPackage? `«bookshelf»
|
let some bookshelfPkg ← findPackage? `«bookshelf»
|
||||||
| error "no bookshelf package found in workspace"
|
| error "no bookshelf package found in workspace"
|
||||||
let some docGen4 := bookshelfPkg.findLeanExe? `«doc-gen4»
|
let some docGen4 := bookshelfPkg.findLeanExe? `«doc-gen4»
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
if ! command -v pdflatex > /dev/null; then
|
||||||
|
>&2 echo 'pdflatex was not found in the current $PATH.'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
BUILD_DIR="$1"
|
||||||
|
|
||||||
|
function process_file () {
|
||||||
|
REL_DIR=$(dirname "$1")
|
||||||
|
REL_BASE=$(basename -s ".tex" "$1")
|
||||||
|
mkdir -p "$BUILD_DIR/doc/$REL_DIR"
|
||||||
|
(cd "$REL_DIR" && pdflatex "$REL_BASE.tex")
|
||||||
|
cp "$REL_DIR/$REL_BASE.pdf" "$BUILD_DIR/doc/$REL_DIR/"
|
||||||
|
}
|
||||||
|
|
||||||
|
export BUILD_DIR
|
||||||
|
export -f process_file
|
||||||
|
|
||||||
|
# We run this command twice to allow any cross-references to resolve correctly.
|
||||||
|
# https://tex.stackexchange.com/questions/41539/does-hyperref-work-between-two-files
|
||||||
|
for _ in {1..2}; do
|
||||||
|
find ./* \( -path build -o -path lake-packages \) -prune -o -name "*.tex" -print0 \
|
||||||
|
| xargs -0 -I{} bash -c "process_file {}"
|
||||||
|
done
|
Loading…
Reference in New Issue