bookshelf-doc/DocGen4/Output/DocString.lean

64 lines
2.0 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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