package odoc
Source file odoc_html_frontend.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136module Html : sig type t val string_of_list : t list -> string type attr val a_class : string list -> attr val code : a:attr list -> t list -> t val span : a:attr list -> t list -> t val div : a:attr list -> t list -> t val txt : string -> t module Unsafe : sig val data : string -> t end end = struct type t = Raw of string | Txt of string | Concat of t list let add_escape_string buf s = (* https://discuss.ocaml.org/t/html-encoding-of-string/4289/4 *) let add = Buffer.add_string buf in let len = String.length s in let max_idx = len - 1 in let flush start i = if start < len then Buffer.add_substring buf s start (i - start) in let rec loop start i = if i > max_idx then flush start i else match String.get s i with | '&' -> escape "&" start i | '<' -> escape "<" start i | '>' -> escape ">" start i | '\'' -> escape "'" start i | '"' -> escape """ start i | '@' -> escape "@" start i | _ -> loop start (i + 1) and escape amperstr start i = flush start i; add amperstr; let next = i + 1 in loop next next in loop 0 0 let to_string t = let buf = Buffer.create 16 in let rec go = function | Raw s -> Buffer.add_string buf s | Txt s -> add_escape_string buf s | Concat xs -> List.iter go xs in go t; Buffer.contents buf let string_of_list lst = to_string (Concat lst) type attr = t let a_class lst = Concat [ Raw "class=\""; Txt (String.concat " " lst); Raw "\"" ] let attrs = function [] -> Concat [] | xs -> Concat (Raw " " :: xs) let block name ~a body = let name = Raw name in Concat [ Raw "<"; name; attrs a; Raw ">"; Concat body; Raw "</"; name; Raw ">" ] let code = block "code" let span = block "span" let div = block "div" let txt s = Txt s module Unsafe = struct let data s = Raw s end end let of_strings ~kind ~prefix_name ~name ~rhs ~typedecl_params ~doc = let open Html in let kind = code ~a:[ a_class [ "entry-kind" ] ] [ txt kind ] and typedecl_params = match typedecl_params with | None -> [] | Some p -> [ span ~a: [ a_class [ (* the parameter of the typedecl are highlighted as if part of main entry name. *) "entry-name"; ]; ] [ txt (p ^ " ") ]; ] and prefix_name = match prefix_name with | None -> [] | Some "" -> [] | Some prefix_name -> [ span ~a:[ a_class [ "prefix-name" ] ] [ txt prefix_name ] ] and name = match name with | Some name -> [ span ~a:[ a_class [ "entry-name" ] ] [ txt name ] ] | None -> [] and rhs = match rhs with | None -> [] | Some rhs -> [ code ~a:[ a_class [ "entry-rhs" ] ] [ txt rhs ] ] in Html.string_of_list [ kind; code ~a:[ a_class [ "entry-title" ] ] (typedecl_params @ prefix_name @ name @ rhs); div ~a:[ a_class [ "entry-comment" ] ] [ Unsafe.data doc ]; ] let kind_doc = "doc" let kind_typedecl = "type" let kind_module = "mod" let kind_exception = "exn" let kind_class_type = "class" let kind_class = "class" let kind_method = "meth" let kind_extension_constructor = "cons" let kind_module_type = "sig" let kind_constructor = "cons" let kind_field = "field" let kind_value = "val" let kind_extension = "ext"