package odoc
Source file html.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 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232type html = Html_types.div_content Tyxml.Html.elt open Odoc_model open Lang open Odoc_index let url { Entry.id; kind; doc = _ } = let open Entry in let stop_before = (* Some module/module types/... might not have an expansion, so we need to be careful and set [stop_before] to [true] for those kind of search entries, to avoid linking to an inexistant page. Docstring do not have an ID in the model, and use the ID from the parent signature in search entries. Therefore, links to doc comments need [stop_before] to be [false] to point to the page where they are present. Values, types, ... are not sensitive to [stop_before], allowing us to shorten the match. *) match kind with | Doc -> false | _ -> true in let url = Odoc_document.Url.from_identifier ~stop_before id in let config = Odoc_html.Config.v ~search_result:true ~semantic_uris:false ~indent:false ~flat:false ~open_details:false ~as_json:false ~remap:[] () in Odoc_html.Link.href ~config ~resolve:(Base "") url let map_option f = function Some x -> Some (f x) | None -> None let display_constructor_args args = let open Odoc_model.Lang in match args with | TypeDecl.Constructor.Tuple args -> (match args with | _ :: _ :: _ -> Some TypeExpr.(Tuple (List.map (fun x -> (None, x)) args)) | [ arg ] -> Some arg | _ -> None) |> map_option Text.of_type | TypeDecl.Constructor.Record fields -> Some (Text.of_record fields) let constructor_rhs ~args ~res = let args = display_constructor_args args in let res = map_option Text.of_type res in match (args, res) with | None, None -> "" | None, Some res -> " : " ^ res | Some args, None -> " of " ^ args | Some args, Some res -> " : " ^ args ^ " -> " ^ res let field_rhs ({ mutable_ = _; type_; parent_type = _ } : Entry.field_entry) = " : " ^ Text.of_type type_ let typedecl_params ?(delim = `parens) params = let format_param { TypeDecl.desc; variance; injectivity } = let desc = match desc with TypeDecl.Any -> [ "_" ] | Var s -> [ "'"; s ] in let var_desc = match variance with | None -> desc | Some TypeDecl.Pos -> "+" :: desc | Some TypeDecl.Neg -> "-" :: desc | Some TypeDecl.Bivariant -> "+" :: "-" :: desc in let final = if injectivity then "!" :: var_desc else var_desc in String.concat "" final in match params with | [] -> None | [ x ] -> Some (format_param x) | lst -> let params = String.concat ", " (List.map format_param lst) in Some ((match delim with `parens -> "(" | `brackets -> "[") ^ params ^ match delim with `parens -> ")" | `brackets -> "]") let type_decl_constraint (typ, typ') = "constraint" ^ " " ^ Text.of_type typ ^ " = " ^ Text.of_type typ' let typedecl_params_of_entry ({ kind; _ } : Entry.t) = match kind with | Entry.TypeDecl { canonical = _; equation; representation = _ } -> typedecl_params equation.params | _ -> None let typedecl_repr ~private_ (repr : TypeDecl.Representation.t) = let constructor ~id ~args ~res = let name = Comment.Identifier.name id in name ^ constructor_rhs ~args ~res in let private_ = if private_ then "private " else "" in " = " ^ private_ ^ match repr with | Extensible -> ".." | Variant constructors -> constructors |> List.map (fun ({ id; args; res; _ } : TypeDecl.Constructor.t) -> constructor ~id ~args ~res) |> String.concat " | " | Record record -> Text.of_record record let typedecl_rhs ({ equation; representation; _ } : Entry.type_decl_entry) = let ({ private_; manifest; constraints; _ } : TypeDecl.Equation.t) = equation in let repr = match representation with Some r -> typedecl_repr ~private_ r | None -> "" in let manifest = match manifest with None -> "" | Some typ -> " = " ^ Text.of_type typ in let constraints = match constraints with | [] -> "" | _ :: _ -> " " ^ (constraints |> List.map type_decl_constraint |> String.concat " ") in match repr ^ manifest ^ constraints with "" -> None | r -> Some r let constructor_rhs ({ args; res } : Entry.constructor_entry) = constructor_rhs ~args ~res:(Some res) (** Kinds *) let kind_doc = "doc" let kind_page = "page" let kind_dir = "dir" let kind_impl = "impl" 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" let string_of_kind = let open Entry in function | Constructor _ -> kind_constructor | Field _ -> kind_field | ExtensionConstructor _ -> kind_extension_constructor | TypeDecl _ -> kind_typedecl | Module _ -> kind_module | Value _ -> kind_value | Exception _ -> kind_exception | Class_type _ -> kind_class_type | Method _ -> kind_method | Class _ -> kind_class | TypeExtension _ -> kind_extension | ModuleType _ -> kind_module_type | Doc -> kind_doc | Page _ -> kind_page | Impl -> kind_impl | Dir -> kind_dir let value_rhs (t : Entry.value_entry) = " : " ^ Text.of_type t.type_ let of_strings ~kind ~prefix_name ~name ~rhs ~typedecl_params ~doc = [ Tyxml.Html.Unsafe.data (Odoc_html_frontend.of_strings ~kind ~prefix_name ~name ~rhs ~typedecl_params ~doc); ] let rhs_of_kind (entry : Entry.kind) = match entry with | TypeDecl td -> typedecl_rhs td | Value t -> Some (value_rhs t) | Constructor t | ExtensionConstructor t | Exception t -> Some (constructor_rhs t) | Field f -> Some (field_rhs f) | Module _ | Class_type _ | Method _ | Class _ | TypeExtension _ | ModuleType _ | Doc | Page _ | Impl | Dir -> None let names_of_id id = let fullname = Paths.Identifier.fullname id in let prefix_name, name = let rev_fullname = List.rev fullname in ( rev_fullname |> List.tl |> List.rev |> List.map (fun str -> str ^ ".") |> String.concat "", List.hd rev_fullname ) in (prefix_name, name) let of_doc doc = let config = Odoc_html.Config.v ~search_result:true ~semantic_uris:false ~indent:false ~flat:false ~open_details:false ~as_json:false ~remap:[] () in Tyxml.Html.div ~a:[] @@ Odoc_html.Generator.doc ~config ~xref_base_uri:"" @@ Odoc_document.Comment.to_ir doc let html_string_of_doc doc = doc |> of_doc |> Format.asprintf "%a" (Tyxml.Html.pp_elt ()) let of_entry (entry : Entry.t) = let ({ id; doc; kind } : Entry.t) = entry in let rhs = rhs_of_kind kind in let prefix_name, name = names_of_id id in let prefix_name = Some prefix_name and name = Some name in let doc = html_string_of_doc doc in let kind = string_of_kind kind in let typedecl_params = typedecl_params_of_entry entry in of_strings ~kind ~prefix_name ~name ~rhs ~doc ~typedecl_params