this repo has no description
at main 290 lines 9.0 kB view raw
1open Odoc_unit 2open Packages 3 4let fpf = Format.fprintf 5 6let make_index ~dirs ~rel_dir ~libs ~pkgs ~index ~enable_warnings ~content : 7 Odoc_unit.mld Odoc_unit.t = 8 let { odoc_dir; odocl_dir; mld_dir; _ } = dirs in 9 let input_file = Fpath.(mld_dir // rel_dir / "index.mld") in 10 let odoc_file = Fpath.(odoc_dir // rel_dir / "page-index.odoc") in 11 let odocl_file = Fpath.(odocl_dir // rel_dir / "page-index.odocl") in 12 let parent_id = rel_dir |> Odoc.Id.of_fpath in 13 let pages = 14 List.map (fun pkg -> (pkg.Packages.name, Odoc_unit.doc_dir pkg)) pkgs 15 in 16 let libs = 17 List.map 18 (fun (pkg, lib) -> (lib.Packages.lib_name, Odoc_unit.lib_dir pkg lib)) 19 libs 20 in 21 let pkg_args = Pkg_args.v ~pages ~libs ~includes:[] ~odoc_dir ~odocl_dir in 22 Util.with_out_to input_file (fun oc -> 23 fpf (Format.formatter_of_out_channel oc) "%t@?" content) 24 |> Result.get_ok; 25 { 26 output_dir = dirs.odoc_dir; 27 pkgname = None; 28 pkg_args; 29 parent_id; 30 input_file; 31 input_copy = None; 32 odoc_file; 33 odocl_file; 34 enable_warnings; 35 to_output = true; 36 kind = `Mld; 37 index; 38 } 39 40let module_list ppf lib = 41 let modules = List.filter (fun m -> not m.m_hidden) lib.modules in 42 match modules with 43 | [] -> fpf ppf "No module." 44 | _ :: _ -> 45 let modules = 46 List.sort (fun m m' -> String.compare m.m_name m'.m_name) modules 47 in 48 fpf ppf "{!modules:"; 49 List.iter (fun m -> fpf ppf " %s" m.m_name) modules; 50 fpf ppf "}@\n" 51 52let library ~dirs ~pkg ~index lib = 53 let content ppf = 54 fpf ppf "%@toc_status hidden\n"; 55 fpf ppf "%@order_category libraries\n"; 56 fpf ppf "{0 Library [%s]}@\n" lib.lib_name; 57 fpf ppf "%a@\n" module_list lib 58 in 59 let rel_dir = lib_dir pkg lib in 60 let libs = [ (pkg, lib) ] in 61 make_index ~dirs ~rel_dir ~libs ~pkgs:[] ~index:(Some index) ~content 62 ~enable_warnings:false 63 64let package ~dirs ~pkg ~index = 65 let library_list ppf pkg = 66 let print_lib lib = 67 fpf ppf "{2 Library %s}@\n%a@\n" lib.lib_name module_list lib 68 in 69 let libraries = 70 List.sort 71 (fun lib lib' -> String.compare lib.lib_name lib'.lib_name) 72 pkg.libraries 73 in 74 List.iter print_lib libraries 75 in 76 let content pkg ppf = 77 fpf ppf "{0 %s}@\n@\n@\n" pkg.name; 78 List.iter 79 (fun { mld_rel_path; _ } -> 80 let page = mld_rel_path |> Fpath.rem_ext |> Fpath.to_string in 81 fpf ppf "@\n{!/%s/%s}@\n" pkg.name page) 82 pkg.mlds; 83 if not (List.is_empty pkg.libraries) then 84 fpf ppf "{1 API}@\n@\n%a@\n" library_list pkg 85 in 86 let content = content pkg in 87 let rel_dir = doc_dir pkg in 88 let libs = List.map (fun lib -> (pkg, lib)) pkg.libraries in 89 make_index ~dirs ~rel_dir ~index:(Some index) ~content ~pkgs:[ pkg ] ~libs 90 ~enable_warnings:false 91 92let src ~dirs ~pkg ~index = 93 let content ppf = 94 fpf ppf "%@order_category source\n"; 95 fpf ppf 96 "{0 Sources}@\n\ 97 This contains the rendered source for [%s]. Use the sidebar to navigate \ 98 them." 99 pkg.name 100 in 101 let rel_dir = src_dir pkg in 102 make_index ~dirs ~pkgs:[] ~libs:[] ~rel_dir ~index:(Some index) ~content 103 ~enable_warnings:true 104 105let package_list ~dirs ~remap all = 106 let content all ppf = 107 let sorted_packages = 108 all |> List.sort (fun n1 n2 -> String.compare n1.name n2.name) 109 in 110 fpf ppf "{0 List of all packages}@\n"; 111 let print_pkg pkg = 112 if pkg.selected || not remap then 113 fpf ppf "- {{!/%s/page-index}%s}@\n" pkg.name pkg.name 114 in 115 List.iter print_pkg sorted_packages 116 in 117 let content = content all in 118 let rel_dir = Fpath.v "./" in 119 make_index ~dirs ~rel_dir ~pkgs:all ~libs:[] ~index:None ~content 120 ~enable_warnings:true 121 122let content dir _pkg libs _src subdirs all_libs pfp = 123 let is_root = Fpath.to_string dir = "./" in 124 fpf pfp "{0 Directory: %a}\n\n" Fpath.pp dir; 125 126 if is_root then ( 127 fpf pfp "@short_title /\n"; 128 fpf pfp "@children_order "; 129 Fpath.Set.iter 130 (fun x -> 131 if Fpath.basename x <> "opam_switch" then 132 fpf pfp "%s/ " (Fpath.basename x)) 133 subdirs; 134 fpf pfp "opam_switch\n%!") 135 else fpf pfp "@short_title %s\n" (Fpath.basename dir); 136 137 if Fpath.Set.cardinal subdirs > 0 then ( 138 fpf pfp "{1 Subdirectories}\n"; 139 Fpath.Set.iter 140 (fun subdir -> 141 fpf pfp "- {{!/%s/%apage-index}%s}\n%!" Monorepo_style.monorepo_pkg_name 142 Fpath.pp subdir (Fpath.basename subdir)) 143 subdirs); 144 145 if (not is_root) && List.length libs > 0 then 146 List.iter 147 (fun (_, lib) -> 148 fpf pfp "{1 Library %s}" lib.Packages.lib_name; 149 fpf pfp "%a@\n" module_list lib) 150 libs; 151 152 if is_root then ( 153 fpf pfp "{1 Libraries index}\n"; 154 List.iter 155 (fun lib -> 156 fpf pfp "- Library [%s]\n" lib.Packages.lib_name; 157 fpf pfp " %a@\n" module_list lib) 158 all_libs) 159 160let make_custom dirs index_of (pkg : Packages.t) : 161 Odoc_unit.mld Odoc_unit.t list = 162 let pkgs = [ pkg ] in 163 let pkg_dirs = 164 List.fold_right 165 (fun pkg dirs -> 166 Fpath.Map.add (Fpath.to_dir_path pkg.Packages.pkg_dir) pkg dirs) 167 pkgs Fpath.Map.empty 168 in 169 let lib_dirs = 170 List.fold_right 171 (fun pkg dirs -> 172 let libs = pkg.libraries in 173 List.fold_left 174 (fun dirs lib -> 175 Fpath.Map.add 176 (Fpath.to_dir_path (Odoc_unit.lib_dir pkg lib)) 177 (pkg, lib) dirs) 178 dirs libs) 179 pkgs Fpath.Map.empty 180 in 181 let src_dirs = 182 List.fold_right 183 (fun pkg dirs -> 184 let libs = pkg.libraries in 185 let x = 186 List.fold_right 187 (fun lib dirs -> 188 if 189 List.exists 190 (fun m -> 191 match m.Packages.m_impl with 192 | Some { mip_src_info = Some _; _ } -> true 193 | _ -> false) 194 lib.modules 195 then 196 Fpath.Map.add 197 (Fpath.to_dir_path (Odoc_unit.src_lib_dir pkg lib)) 198 (pkg, lib) dirs 199 else dirs) 200 libs dirs 201 in 202 x) 203 pkgs Fpath.Map.empty 204 in 205 let pkg_src_dirs = 206 List.fold_left 207 (fun acc pkg -> 208 Fpath.Map.add (Odoc_unit.src_dir pkg |> Fpath.to_dir_path) pkg acc) 209 Fpath.Map.empty pkgs 210 in 211 let all_dirs = 212 Fpath.Set.union (Fpath.Map.dom pkg_dirs) 213 (Fpath.Set.union (Fpath.Map.dom lib_dirs) (Fpath.Map.dom src_dirs)) 214 in 215 let rec all_parents path = 216 let parent, _ = Fpath.split_base path in 217 if 218 Fpath.compare parent (Fpath.v "./") = 0 219 || Fpath.compare parent (Fpath.v "/") = 0 220 then [ path ] 221 else path :: all_parents parent 222 in 223 let all_dirs = 224 Fpath.Set.fold 225 (fun p acc -> 226 let parents = all_parents p in 227 List.fold_right Fpath.Set.add parents acc) 228 all_dirs all_dirs 229 in 230 231 let all_indexes = 232 List.fold_right 233 (fun pkg acc -> 234 let mlds = pkg.Packages.mlds in 235 let indexes = 236 List.filter 237 (fun mld -> Fpath.basename mld.mld_rel_path = "index.mld") 238 mlds 239 in 240 let index_paths = 241 List.map 242 (fun mld -> Fpath.(pkg.pkg_dir // mld.mld_rel_path |> parent)) 243 indexes 244 |> Fpath.Set.of_list 245 in 246 Fpath.Set.union acc index_paths) 247 pkgs Fpath.Set.empty 248 in 249 250 Fpath.Set.fold 251 (fun p acc -> 252 if Fpath.Set.mem p all_indexes then ( 253 Logs.debug (fun m -> m "Skipping predefined index.mld: %a" Fpath.pp p); 254 acc) 255 else 256 let libs = 257 let is_root = Fpath.to_string p = "./" in 258 Fpath.Map.fold 259 (fun p' lib libs -> if p = p' || is_root then lib :: libs else libs) 260 lib_dirs [] 261 in 262 let src = Fpath.Map.find_opt p src_dirs in 263 let pkg_src = Fpath.Map.find_opt p pkg_src_dirs in 264 let subdirs = 265 Fpath.Set.filter (fun p' -> Fpath.parent p' = p) all_dirs 266 in 267 Logs.debug (fun x -> 268 x "dir: %a pkg: %a lib: %a src: %a pkg_src: %a subdirs: %a" Fpath.pp 269 p Fmt.string pkg.Packages.name (Fmt.Dump.list Fmt.string) 270 (List.map (fun (_, p) -> p.Packages.lib_name) libs) 271 (Fmt.Dump.option Fmt.string) 272 (Option.map (fun (_, p) -> p.Packages.lib_name) src) 273 (Fmt.Dump.option Fmt.string) 274 (Option.map (fun p -> p.Packages.name) pkg_src) 275 (Fmt.Dump.list Fpath.pp) 276 (Fpath.Set.elements subdirs)); 277 let index = Some (index_of pkg) in 278 let pkgs = pkgs in 279 let all_libs = pkg.libraries in 280 Logs.debug (fun m -> 281 m "pkgs: %a" 282 Fmt.Dump.(list string) 283 (List.map (fun p -> p.Packages.name) pkgs)); 284 let idx = 285 make_index ~dirs ~rel_dir:p ~libs ~pkgs 286 ~content:(content p pkg libs src subdirs all_libs) 287 ~index ~enable_warnings:false 288 in 289 idx :: acc) 290 all_dirs []