64 lines
2.0 KiB
Plaintext
64 lines
2.0 KiB
Plaintext
import CMark
|
||
import DocGen4.Output.Template
|
||
import Lean.Data.Parsec
|
||
|
||
open Lean
|
||
|
||
namespace DocGen4
|
||
namespace Output
|
||
|
||
open Xml Parser Lean Parsec
|
||
|
||
def manyDocument : Parsec (Array Element) := many (prolog *> element <* many Misc) <* eof
|
||
|
||
partial def elementToPlainText : Xml.Element → String
|
||
| (Element.Element name attrs contents) =>
|
||
"".intercalate (contents.toList.map contentToPlainText)
|
||
where
|
||
contentToPlainText c := match c with
|
||
| Content.Element el => elementToPlainText el
|
||
| Content.Comment _ => ""
|
||
| Content.Character s => s
|
||
|
||
def dropAllCharWhile (s : String) (p : Char → Bool) : String :=
|
||
⟨ s.data.filter p ⟩
|
||
|
||
def textToIdAttribute (s : String) : String :=
|
||
dropAllCharWhile s (λ c => (c.isAlphanum ∨ c = '-' ∨ c = ' '))
|
||
|>.toLower
|
||
|>.replace " " "-"
|
||
|
||
partial def addAttributes : Element → Element
|
||
| el@(Element.Element name attrs contents) =>
|
||
-- heading only
|
||
if name = "h1" ∨ name = "h2" ∨ name = "h3" ∨ name = "h4" ∨ name = "h5" ∨ name = "h6" then
|
||
let id := textToIdAttribute (elementToPlainText el)
|
||
let anchorAttributes := Std.RBMap.empty
|
||
|>.insert "class" "hover-link"
|
||
|>.insert "href" s!"#{id}"
|
||
let anchor := Element.Element "a" anchorAttributes #[Content.Character "#"]
|
||
let newAttrs := attrs
|
||
|>.insert "id" id
|
||
|>.insert "class" "markdown-heading"
|
||
let newContents :=
|
||
contents.map (λ c => match c with
|
||
| Content.Element e => Content.Element (addAttributes e)
|
||
| _ => c)
|
||
|>.push (Content.Element anchor)
|
||
⟨ name, newAttrs, newContents⟩
|
||
else
|
||
let newContents := contents.map λ c => match c with
|
||
| Content.Element e => Content.Element (addAttributes e)
|
||
| _ => c
|
||
⟨ name, attrs, newContents ⟩
|
||
|
||
def docStringToHtml (s : String) : Html :=
|
||
let rendered := CMark.renderHtml s
|
||
let attributed := match manyDocument rendered.mkIterator with
|
||
| Parsec.ParseResult.success _ res => "".intercalate (res.map addAttributes |>.map toString).toList
|
||
| _ => rendered
|
||
Html.text attributed
|
||
|
||
end Output
|
||
end DocGen4
|