@.";
Fmt.pf fmt "
Summary
@.";
Fmt.pf fmt "
Total symbols: %d
@." total_symbols;
Fmt.pf fmt "
Used symbols: %d
@." (List.length used_symbols);
Fmt.pf fmt "
Unused symbols: %d
@." (List.length unused_symbols);
Fmt.pf fmt "
Used only in excluded directories: %d
@."
(List.length excluded_only);
Fmt.pf fmt "
@."
(* Write tab buttons *)
let write_tab_buttons fmt =
Fmt.pf fmt "@." class_name;
Fmt.pf fmt "
%s "
(escape_html (string_of_symbol_kind occ.symbol.kind));
Fmt.pf fmt "
%s "
(escape_html occ.symbol.name);
Fmt.pf fmt "
(%d occurrences)@."
occ.occurrences;
if occ.occurrences > 0 then (
let usage_locations = filter_usage_locations occ in
if usage_locations <> [] then (
Fmt.pf fmt "
Used in:
@.";
List.iter
(fun loc ->
Fmt.pf fmt "
%s:%d:%d
@."
(escape_html loc.file) loc.start_line loc.start_col)
usage_locations);
Fmt.pf fmt "
@.")
(* Write By File view *)
let write_by_file_view fmt by_file =
Fmt.pf fmt "@.";
Fmt.pf fmt "
Symbols by File
@.";
List.iter
(fun (file, occs) ->
Fmt.pf fmt "
@.";
Fmt.pf fmt "
%s
@." (escape_html file);
List.iter (write_symbol fmt) occs;
Fmt.pf fmt " @.")
(List.sort (fun (f1, _) (f2, _) -> String.compare f1 f2) by_file);
Fmt.pf fmt "
@."
(* Write By Symbol view *)
let write_by_symbol_view fmt by_symbol =
Fmt.pf fmt "@.";
Fmt.pf fmt "
All Symbols
@.";
List.iter
(fun ((name, kind), occs) ->
let first_occ = List.hd occs in
let total_occurrences =
List.fold_left (fun acc o -> acc + o.occurrences) 0 occs
in
let class_name = class_of_usage first_occ.usage_class in
Fmt.pf fmt "
@." class_name;
Fmt.pf fmt "
%s "
(escape_html (string_of_symbol_kind kind));
Fmt.pf fmt "
%s " (escape_html name);
Fmt.pf fmt "
(%d total occurrences)@."
total_occurrences;
(* Show where it's defined *)
Fmt.pf fmt "
Defined in:
@.";
List.iter
(fun occ ->
Fmt.pf fmt "
%s:%d:%d
@."
(escape_html occ.symbol.location.file)
occ.symbol.location.start_line occ.symbol.location.start_col)
occs;
(* Show all usage locations *)
let usage_locations =
List.concat_map (fun occ -> filter_usage_locations occ) occs
in
if usage_locations <> [] then (
Fmt.pf fmt "
Used in:
@.";
List.iter
(fun loc ->
Fmt.pf fmt "
%s:%d:%d
@."
(escape_html loc.file) loc.start_line loc.start_col)
usage_locations);
Fmt.pf fmt "
@.")
(List.sort
(fun ((n1, k1), _) ((n2, k2), _) ->
match String.compare n1 n2 with 0 -> compare k1 k2 | n -> n)
by_symbol);
Fmt.pf fmt "
@."
(* Write JavaScript for tab switching *)
let write_javascript fmt =
Fmt.pf fmt "@."
let render_html output_dir occurrences =
let html_file = Filename.concat output_dir "index.html" in
let oc = open_out html_file in
let fmt = Format.formatter_of_out_channel oc in
let by_file = group_by_file occurrences in
let by_symbol = group_by_symbol occurrences in
(* HTML header *)
write_html_header fmt;
Fmt.pf fmt "@.";
Fmt.pf fmt "