···524 | None, `Marshall -> Ok (Fs.File.of_string "index.odoc-index")
525526 let index dst json warnings_options page_roots lib_roots inputs_in_file inputs
527- =
528 let marshall = if json then `JSON else `Marshall in
529 output_file ~dst marshall >>= fun output ->
530 (if
···534 then Error (`Msg "Paths given to all -P and -L options must be disjoint")
535 else Ok ())
536 >>= fun () ->
537- Indexing.compile marshall ~output ~warnings_options ~lib_roots ~page_roots
538- ~inputs_in_file ~odocls:inputs
539 let cmd =
540 let dst =
541 let doc =
···545 in
546 Arg.(
547 value & opt (some string) None & info ~docs ~docv:"PATH" ~doc [ "o" ])
0000000548 in
549 let inputs_in_file =
550 let doc =
···587 Term.(
588 const handle_error
589 $ (const index $ dst $ json $ warnings_options $ page_roots $ lib_roots
590- $ inputs_in_file $ inputs))
591592 let info ~docs =
593 let doc =
···524 | None, `Marshall -> Ok (Fs.File.of_string "index.odoc-index")
525526 let index dst json warnings_options page_roots lib_roots inputs_in_file inputs
527+ occurrences =
528 let marshall = if json then `JSON else `Marshall in
529 output_file ~dst marshall >>= fun output ->
530 (if
···534 then Error (`Msg "Paths given to all -P and -L options must be disjoint")
535 else Ok ())
536 >>= fun () ->
537+ Indexing.compile marshall ~output ~warnings_options ~occurrences ~lib_roots
538+ ~page_roots ~inputs_in_file ~odocls:inputs
539 let cmd =
540 let dst =
541 let doc =
···545 in
546 Arg.(
547 value & opt (some string) None & info ~docs ~docv:"PATH" ~doc [ "o" ])
548+ in
549+ let occurrences =
550+ let doc = "Occurrence file." in
551+ Arg.(
552+ value
553+ & opt (some convert_fpath) None
554+ & info ~docs ~docv:"PATH" ~doc [ "occurrences" ])
555 in
556 let inputs_in_file =
557 let doc =
···594 Term.(
595 const handle_error
596 $ (const index $ dst $ json $ warnings_options $ page_roots $ lib_roots
597+ $ inputs_in_file $ inputs $ occurrences))
598599 let info ~docs =
600 let doc =
+15-5
src/odoc/indexing.ml
···40 (Ok []) input
41 >>= fun files -> Ok (List.concat files)
4243-let compile_to_json ~output ~warnings_options files =
44 let output_channel =
45 Fs.Directory.mkdir_p (Fs.File.dirname output);
46 open_out_bin (Fs.File.to_string output)
···57 (fun acc file ->
58 match
59 handle_file
60- ~unit:(print Json_search.unit acc)
61 ~page:(print Json_search.page acc)
62 ~occ:(print Json_search.index acc)
63 file
···110 result |> Error.handle_warnings ~warnings_options >>= fun () ->
111 Ok (Odoc_file.save_index output (sidebar, final_index))
11200000113open Odoc_model.Lang.Sidebar
114115-let compile out_format ~output ~warnings_options ~lib_roots ~page_roots
116- ~inputs_in_file ~odocls =
117 let current_dir = Fs.File.dirname output in
118 parse_input_files inputs_in_file >>= fun files ->
119 let files = List.rev_append odocls files in
00000120 let resolver =
121 Resolver.create ~important_digests:false ~directories:[]
122 ~roots:
···175 in
176 let content = { pages; libraries } in
177 match out_format with
178- | `JSON -> compile_to_json ~output ~warnings_options files
179 | `Marshall -> compile_to_marshall ~output ~warnings_options content files
···40 (Ok []) input
41 >>= fun files -> Ok (List.concat files)
4243+let compile_to_json ~output ~warnings_options ~occurrences files =
44 let output_channel =
45 Fs.Directory.mkdir_p (Fs.File.dirname output);
46 open_out_bin (Fs.File.to_string output)
···57 (fun acc file ->
58 match
59 handle_file
60+ ~unit:(print (Json_search.unit ?occurrences) acc)
61 ~page:(print Json_search.page acc)
62 ~occ:(print Json_search.index acc)
63 file
···110 result |> Error.handle_warnings ~warnings_options >>= fun () ->
111 Ok (Odoc_file.save_index output (sidebar, final_index))
112113+let read_occurrences file =
114+ let ic = open_in_bin file in
115+ let htbl : Odoc_occurrences.Table.t = Marshal.from_channel ic in
116+ htbl
117+118open Odoc_model.Lang.Sidebar
119120+let compile out_format ~output ~warnings_options ~occurrences ~lib_roots
121+ ~page_roots ~inputs_in_file ~odocls =
122 let current_dir = Fs.File.dirname output in
123 parse_input_files inputs_in_file >>= fun files ->
124 let files = List.rev_append odocls files in
125+ let occurrences =
126+ match occurrences with
127+ | None -> None
128+ | Some occurrences -> Some (read_occurrences (Fpath.to_string occurrences))
129+ in
130 let resolver =
131 Resolver.create ~important_digests:false ~directories:[]
132 ~roots:
···185 in
186 let content = { pages; libraries } in
187 match out_format with
188+ | `JSON -> compile_to_json ~output ~warnings_options ~occurrences files
189 | `Marshall -> compile_to_marshall ~output ~warnings_options content files
+1
src/odoc/indexing.mli
···13 [ `JSON | `Marshall ] ->
14 output:Fs.file ->
15 warnings_options:Odoc_model.Error.warnings_options ->
016 lib_roots:(string * Fs.directory) list ->
17 page_roots:(string * Fs.directory) list ->
18 inputs_in_file:Fs.file list ->
···86 let txt = Text.of_doc doc in
87 `String txt
8889-let of_entry ({ Entry.id; doc; kind } as entry) html =
90 let j_id = of_id id in
91 let doc = of_doc doc in
92 let kind =
···167 ("parent_type", `String (Text.of_type parent_type));
168 ]
169 in
0000000000170 match Json_display.of_entry entry html with
171 | Result.Ok display ->
172 Result.Ok
173 (`Object
174- [ ("id", j_id); ("doc", doc); ("kind", kind); ("display", display) ])
000000175 | Error _ as e -> e
176177let output_json ppf first entries =
···180 Format.fprintf ppf "%s\n" str
181 in
182 List.fold_left
183- (fun first (entry, html) ->
184- let json = of_entry entry html in
185 if not first then Format.fprintf ppf ",";
186 match json with
187 | Ok json ->
···192 true)
193 first entries
194195-let unit ppf u =
00000196 let f first i =
197 let entries = Entry.entries_of_item i in
198 let entries =
199- List.map (fun entry -> (entry, Html.of_entry entry)) entries
0000200 in
201 let first = output_json ppf first entries in
202 first
···208 let f first i =
209 let entries = Entry.entries_of_item i in
210 let entries =
211- List.map (fun entry -> (entry, Html.of_entry entry)) entries
212 in
213 output_json ppf first entries
214 in
···219 let _first =
220 Odoc_model.Paths.Identifier.Hashtbl.Any.fold
221 (fun _id entry first ->
222- let entry = (entry, Html.of_entry entry) in
223 output_json ppf first [ entry ])
224 index true
225 in
···86 let txt = Text.of_doc doc in
87 `String txt
8889+let of_entry ({ Entry.id; doc; kind } as entry) html occurrences =
90 let j_id = of_id id in
91 let doc = of_doc doc in
92 let kind =
···167 ("parent_type", `String (Text.of_type parent_type));
168 ]
169 in
170+ let occurrences =
171+ match occurrences with
172+ | Some occ ->
173+ `Object
174+ [
175+ ("direct", `Float (float_of_int occ.Odoc_occurrences.Table.direct));
176+ ("indirect", `Float (float_of_int occ.indirect));
177+ ]
178+ | None -> `Null
179+ in
180 match Json_display.of_entry entry html with
181 | Result.Ok display ->
182 Result.Ok
183 (`Object
184+ [
185+ ("id", j_id);
186+ ("doc", doc);
187+ ("kind", kind);
188+ ("display", display);
189+ ("occurrences", occurrences);
190+ ])
191 | Error _ as e -> e
192193let output_json ppf first entries =
···196 Format.fprintf ppf "%s\n" str
197 in
198 List.fold_left
199+ (fun first (entry, html, occurrences) ->
200+ let json = of_entry entry html occurrences in
201 if not first then Format.fprintf ppf ",";
202 match json with
203 | Ok json ->
···208 true)
209 first entries
210211+let unit ?occurrences ppf u =
212+ let get_occ id =
213+ match occurrences with
214+ | None -> None
215+ | Some occurrences -> Odoc_occurrences.Table.get occurrences id
216+ in
217 let f first i =
218 let entries = Entry.entries_of_item i in
219 let entries =
220+ List.map
221+ (fun entry ->
222+ let occ = get_occ entry.Entry.id in
223+ (entry, Html.of_entry entry, occ))
224+ entries
225 in
226 let first = output_json ppf first entries in
227 first
···233 let f first i =
234 let entries = Entry.entries_of_item i in
235 let entries =
236+ List.map (fun entry -> (entry, Html.of_entry entry, None)) entries
237 in
238 output_json ppf first entries
239 in
···244 let _first =
245 Odoc_model.Paths.Identifier.Hashtbl.Any.fold
246 (fun _id entry first ->
247+ let entry = (entry, Html.of_entry entry, None) in
248 output_json ppf first [ entry ])
249 index true
250 in
+5-1
src/search/json_index/json_search.mli
···1(** This module generates json intended to be consumed by search engines. *)
23-val unit : Format.formatter -> Odoc_model.Lang.Compilation_unit.t -> unit
00004val page : Format.formatter -> Odoc_model.Lang.Page.t -> unit
5val index :
6 Format.formatter ->
···1(** This module generates json intended to be consumed by search engines. *)
23+val unit :
4+ ?occurrences:Odoc_occurrences.Table.t ->
5+ Format.formatter ->
6+ Odoc_model.Lang.Compilation_unit.t ->
7+ unit
8val page : Format.formatter -> Odoc_model.Lang.Page.t -> unit
9val index :
10 Format.formatter ->
+73
test/occurrences/double_wrapped.t/run.t
···144 Main__A was used directly 1 times and indirectly 0 times
145 Main__B was used directly 1 times and indirectly 0 times
146 Main__C was used directly 1 times and indirectly 0 times
0000000000000000000000000000000000000000000000000000000000000000000000000