Skip to content

Handle Math_span and Math_block constructs #886

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,6 @@ ocaml-re/
result/
tyxml/
uutf/

# Mac things
.DS_Store
2 changes: 1 addition & 1 deletion .ocamlformat
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
module-item-spacing=preserve
version=0.21.0
version=0.24.1
2 changes: 1 addition & 1 deletion odoc.opam
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ delimited with `(** ... *)`, and outputs HTML.
"""

depends: [
"odoc-parser" {>= "1.0.0"}
"odoc-parser" {>= "2.0.0"}
"astring"
"cmdliner" {>= "1.0.0"}
"cppo" {build & >= "1.1.0"}
Expand Down
2 changes: 2 additions & 0 deletions src/document/comment.ml
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ let leaf_inline_element : Comment.leaf_inline_element -> Inline.one = function
| `Space -> inline @@ Text " "
| `Word s -> inline @@ Text s
| `Code_span s -> inline @@ Source (source_of_code s)
| `Math_span s -> inline @@ Math s
| `Raw_markup (target, s) -> inline @@ Raw_markup (target, s)

let rec non_link_inline_element : Comment.non_link_inline_element -> Inline.one
Expand Down Expand Up @@ -202,6 +203,7 @@ let rec nestable_block_element : Comment.nestable_block_element -> Block.one =
in
block
@@ Source (lang_tag, source_of_code (Odoc_model.Location_.value code))
| `Math_block s -> block @@ Math s
| `Verbatim s -> block @@ Verbatim s
| `Modules ms -> module_references ms
| `List (kind, items) ->
Expand Down
74 changes: 74 additions & 0 deletions src/document/doctree.ml
Original file line number Diff line number Diff line change
Expand Up @@ -282,3 +282,77 @@ end = struct
labels page
|> snd
end

module Math : sig
val has_math_elements : Page.t -> bool
end = struct
let rec items x = List.exists item x

and item : Item.t -> bool = function
| Text x -> block x
| Heading x -> heading x
| Declaration { content = x; doc; _ } -> documentedsrc x || block doc
| Include { content = x; doc; _ } -> include_ x || block doc

and documentedsrc : DocumentedSrc.t -> bool =
fun x ->
let documentedsrc_ : DocumentedSrc.one -> bool = function
| Code _ -> false
| Documented { code = x; doc; _ } -> inline x || block doc
| Nested { code = x; doc; _ } -> documentedsrc x || block doc
| Subpage x -> subpage x
| Alternative x -> alternative x
in
List.exists documentedsrc_ x

and subpage : Subpage.t -> bool = fun x -> page x.content

and page : Page.t -> bool = fun x -> items x.items

and alternative : Alternative.t -> bool = function
| Expansion x -> documentedsrc x.expansion

and include_ : Include.t -> bool = fun x -> items x.content

and block : Block.t -> bool =
fun x ->
let block_ : Block.one -> bool =
fun x ->
match x.desc with
| Inline x -> inline x
| Paragraph x -> inline x
| List (_, x) -> List.exists block x
| Description x -> description x
| Math _ -> true
| Source _ | Verbatim _ | Raw_markup _ -> false
in
List.exists block_ x

and heading : Heading.t -> bool = fun x -> inline x.title

and inline : Inline.t -> bool =
fun x ->
let inline_ : Inline.one -> bool =
fun x ->
match x.desc with
| Styled (_, x) -> inline x
| Link (_, x) -> inline x
| InternalLink x -> internallink x
| Math _ -> true
| Text _ | Entity _ | Linebreak | Source _ | Raw_markup _ -> false
in
List.exists inline_ x

and internallink : InternalLink.t -> bool = function
| Resolved (_, x) -> inline x
| Unresolved x -> inline x

and description : Description.t -> bool =
fun x ->
let description_ : Description.one -> bool =
fun x -> inline x.key || block x.definition
in
List.exists description_ x

let has_math_elements = page
end
7 changes: 7 additions & 0 deletions src/document/types.ml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ and Source : sig
end =
Source

and Math : sig
type t = string
end =
Math

and Inline : sig
type entity = string

Expand All @@ -47,6 +52,7 @@ and Inline : sig
| Link of href * t
| InternalLink of InternalLink.t
| Source of Source.t
| Math of Math.t
| Raw_markup of Raw_markup.t
end =
Inline
Expand Down Expand Up @@ -76,6 +82,7 @@ and Block : sig
| List of list_type * t list
| Description of Description.t
| Source of lang_tag * Source.t
| Math of Math.t
| Verbatim of string
| Raw_markup of Raw_markup.t

Expand Down
1 change: 1 addition & 0 deletions src/document/utils.ml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ and compute_length_inline (t : Types.Inline.t) : int =
| InternalLink (Unresolved t) ->
acc + compute_length_inline t
| Source s -> acc + compute_length_source s
| Math _ -> assert false
| Raw_markup _ -> assert false
(* TODO *)
in
Expand Down
12 changes: 11 additions & 1 deletion src/html/generator.ml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ let mk_anchor anchor =

let class_ (l : Class.t) = if l = [] then [] else [ Html.a_class l ]

let inline_math (s : Math.t) =
Html.code ~a:[ Html.a_class [ "odoc-katex-math" ] ] [ Html.txt s ]

let block_math (s : Math.t) =
Html.pre ~a:[ Html.a_class [ "odoc-katex-math"; "display" ] ] [ Html.txt s ]

and raw_markup (t : Raw_markup.t) =
let target, content = t in
match Astring.String.Ascii.lowercase target with
Expand Down Expand Up @@ -121,6 +127,7 @@ and inline ~config ?(emph_level = 0) ~resolve (l : Inline.t) :
[ Html.a ~a:(Html.a_href href :: a) content ]
| InternalLink c -> internallink ~config ~emph_level ~resolve ~a c
| Source c -> source (inline ~config ~emph_level ~resolve) ~a c
| Math s -> [ inline_math s ]
| Raw_markup r -> raw_markup r
in
Utils.list_concat_map ~f:one l
Expand All @@ -142,6 +149,7 @@ and inline_nolink ?(emph_level = 0) (l : Inline.t) :
| Link (_, c) -> inline_nolink ~emph_level c
| InternalLink c -> internallink_nolink ~emph_level ~a c
| Source c -> source (inline_nolink ~emph_level) ~a c
| Math s -> [ inline_math s ]
| Raw_markup r -> raw_markup r
in
Utils.list_concat_map ~f:one l
Expand Down Expand Up @@ -196,6 +204,7 @@ let rec block ~config ~resolve (l : Block.t) : flow Html.elt list =
| Source (lang_tag, c) ->
let extra_class = [ "language-" ^ lang_tag ] in
mk_block ~extra_class Html.pre (source (inline ~config ~resolve) c)
| Math s -> mk_block Html.div [ block_math s ]
in
Utils.list_concat_map l ~f:one

Expand Down Expand Up @@ -389,10 +398,11 @@ module Page = struct
in
let resolve = Link.Current url in
let i = Doctree.Shift.compute ~on_sub i in
let uses_katex = Doctree.Math.has_math_elements p in
let toc = Toc.gen_toc ~config ~resolve ~path:url i in
let header = items ~config ~resolve header in
let content = (items ~config ~resolve i :> any Html.elt list) in
Tree.make ~config ~header ~toc ~url title content subpages
Tree.make ~config ~header ~toc ~url ~uses_katex title content subpages
end

let render ~config page = Page.page ~config page
Expand Down
41 changes: 35 additions & 6 deletions src/html/tree.ml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ let html_of_toc toc =
| [] -> []
| _ -> [ Html.nav ~a:[ Html.a_class [ "odoc-toc" ] ] [ sections toc ] ]

let page_creator ~config ~url name header toc content =
let page_creator ~config ~url ~uses_katex name header toc content =
let theme_uri = Config.theme_uri config in
let support_uri = Config.support_uri config in
let path = Link.Path.for_printing url in
Expand All @@ -51,9 +51,7 @@ let page_creator ~config ~url name header toc content =

let odoc_css_uri = file_uri theme_uri "odoc.css" in
let highlight_js_uri = file_uri support_uri "highlight.pack.js" in

Html.head
(Html.title (Html.txt title_string))
let default_meta_elements =
[
Html.link ~rel:[ `Stylesheet ] ~href:odoc_css_uri ();
Html.meta ~a:[ Html.a_charset "utf-8" ] ();
Expand All @@ -70,6 +68,35 @@ let page_creator ~config ~url name header toc content =
Html.script ~a:[ Html.a_src highlight_js_uri ] (Html.txt "");
Html.script (Html.txt "hljs.initHighlightingOnLoad();");
]
in
let meta_elements =
if uses_katex then
let katex_css_uri = file_uri theme_uri "katex.min.css" in
let katex_js_uri = file_uri support_uri "katex.min.js" in
default_meta_elements
@ [
Html.link ~rel:[ `Stylesheet ] ~href:katex_css_uri ();
Html.script ~a:[ Html.a_src katex_js_uri ] (Html.txt "");
Html.script
(Html.cdata_script
{|
document.addEventListener("DOMContentLoaded", function () {
var elements = Array.from(document.getElementsByClassName("odoc-katex-math"));
for (var i = 0; i < elements.length; i++) {
var el = elements[i];
var content = el.textContent;
var new_el = document.createElement("span");
new_el.setAttribute("class", "odoc-katex-math-rendered");
var display = el.classList.contains("display");
katex.render(content, new_el, { throwOnError: false, displayMode: display });
el.replaceWith(new_el);
}
});
|});
]
else default_meta_elements
in
Html.head (Html.title (Html.txt title_string)) meta_elements
in

let gen_breadcrumbs () =
Expand Down Expand Up @@ -152,7 +179,9 @@ let page_creator ~config ~url name header toc content =
let content ppf = htmlpp ppf html in
content

let make ~config ~url ~header ~toc title content children =
let make ~config ~url ~header ~toc ~uses_katex title content children =
let filename = Link.Path.as_filename ~is_flat:(Config.flat config) url in
let content = page_creator ~config ~url title header toc content in
let content =
page_creator ~config ~url ~uses_katex title header toc content
in
[ { Odoc_document.Renderer.filename; content; children } ]
1 change: 1 addition & 0 deletions src/html/tree.mli
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ val make :
url:Odoc_document.Url.Path.t ->
header:Html_types.flow5_without_header_footer Html.elt list ->
toc:Types.toc list ->
uses_katex:bool ->
string ->
Html_types.div_content Html.elt list ->
Odoc_document.Renderer.page list ->
Expand Down
7 changes: 7 additions & 0 deletions src/latex/generator.ml
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ and inline ~in_source ~verbatim (l : Inline.t) =
| InternalLink c -> [ internalref ~in_source ~verbatim c ]
| Source c ->
[ Inlined_code (source (inline ~verbatim:false ~in_source:true) c) ]
| Math s -> [ Raw (Format.asprintf "%a" Raw.math s) ]
| Raw_markup r -> raw_markup r
| Entity s -> [ entity ~in_source ~verbatim s ]
in
Expand Down Expand Up @@ -309,6 +310,12 @@ let rec block ~in_source (l : Block.t) =
| Raw_markup r -> raw_markup r
| Verbatim s -> [ Verbatim s ]
| Source (_, c) -> non_empty_block_code c
| Math s ->
[
Break Paragraph;
Raw (Format.asprintf "%a" Raw.equation s);
Break Paragraph;
]
in
list_concat_map l ~f:one

Expand Down
10 changes: 10 additions & 0 deletions src/latex/raw.ml
Original file line number Diff line number Diff line change
Expand Up @@ -206,3 +206,13 @@ let small_table pp ppf tbl =
break ppf Line

let ocamltag tag pp ppf x = create2 "ocamltag" Fmt.string pp ppf tag x

let math ppf x = Fmt.pf ppf {|$%s$|} x

let equation ppf x =
let name = "equation*" in
mbegin ppf name;
Fmt.cut ppf ();
Fmt.string ppf x;
Fmt.cut ppf ();
mend ppf name
6 changes: 6 additions & 0 deletions src/latex/raw.mli
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,9 @@ val ocamltag : string -> 'a t
(** tag (e.g keyword, type-var, ...) are rendered to
{v \ocamltag{tagname}{content} v}
*)

(** {2 Math mode} *)

val math : string Fmt.t

val equation : string Fmt.t
6 changes: 5 additions & 1 deletion src/manpage/generator.ml
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ let strip l =
| [] -> acc
| h :: t -> (
match h.Inline.desc with
| Text _ | Entity _ | Raw_markup _ -> loop (h :: acc) t
| Text _ | Entity _ | Raw_markup _ | Math _ -> loop (h :: acc) t
| Linebreak -> loop acc t
| Styled (sty, content) ->
let h =
Expand Down Expand Up @@ -267,6 +267,8 @@ let raw_markup (t : Raw_markup.t) =
| "manpage" | "troff" | "roff" -> String content
| _ -> noop

let math (s : Types.Math.t) = String s

let rec source_code (s : Source.t) =
match s with
| [] -> noop
Expand Down Expand Up @@ -299,6 +301,7 @@ and inline (l : Inline.t) =
| InternalLink (Resolved (_, content) | Unresolved content) ->
font "CI" (inline @@ strip content) ++ inline rest
| Source content -> source_code content ++ inline rest
| Math s -> math s ++ inline rest
| Raw_markup t -> raw_markup t ++ inline rest)

let rec block (l : Block.t) =
Expand Down Expand Up @@ -333,6 +336,7 @@ let rec block (l : Block.t) =
list ~sep:break (List.map f descrs) ++ continue rest
| Source (_, content) ->
env "EX" "EE" "" (source_code content) ++ continue rest
| Math s -> math s ++ continue rest
| Verbatim content -> env "EX" "EE" "" (str "%s" content) ++ continue rest
| Raw_markup t -> raw_markup t ++ continue rest)

Expand Down
2 changes: 2 additions & 0 deletions src/model/comment.ml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type leaf_inline_element =
[ `Space
| `Word of string
| `Code_span of string
| `Math_span of string
| `Raw_markup of raw_markup_target * string ]

type non_link_inline_element =
Expand Down Expand Up @@ -41,6 +42,7 @@ type module_reference = {
type nestable_block_element =
[ `Paragraph of paragraph
| `Code_block of string option * string with_location
| `Math_block of string
| `Verbatim of string
| `Modules of module_reference list
| `List of
Expand Down
Loading