Skip to content

Index pages #1221

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
157 changes: 106 additions & 51 deletions src/driver/landing_pages.ml
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
open Packages
open Odoc_unit

type unit_of_html =
| Html of { path : Fpath.t; content : string }
| Unit of [ `Mld ] Odoc_unit.unit

let split_units_and_html li :
(Fpath.t * string) list * [> `Mld ] Odoc_unit.unit list =
List.partition_map
(function
| Html { path; content } -> Left (path, content)
| Unit unit -> Right (unit :> [< `Mld ] Odoc_unit.unit))
li
let fpf = Format.fprintf

let make_unit ~odoc_dir ~odocl_dir ~mld_dir ~output_dir rel_path ~content
Expand All @@ -12,39 +23,99 @@ let make_unit ~odoc_dir ~odocl_dir ~mld_dir ~output_dir rel_path ~content
fpf (Format.formatter_of_out_channel oc) "%t@?" content)
|> Result.get_ok;
let parent_id = rel_path |> Odoc.Id.of_fpath in
{
parent_id;
odoc_dir;
input_file;
output_dir;
odoc_file;
odocl_file;
pkg_args;
pkgname;
include_dirs;
index = None;
kind = `Mld;
}
Unit
{
parent_id;
odoc_dir;
input_file;
output_dir;
odoc_file;
odocl_file;
pkg_args;
pkgname;
include_dirs;
index = None;
kind = `Mld;
}

module PackageLibLanding = struct
let page ~pkg =
let package_index = Fpath.(v ".." / "index.html") in
let path = Fpath.(v pkg.name / "lib" / "index.html") in
let content =
Format.asprintf
{|<head><meta http-equiv="refresh" content="1; URL=%a"></head>|}
Fpath.pp package_index
in
Html { path; content }
end

module PackageLanding = struct
let module_list ppf lib =
let modules = List.filter (fun m -> not m.m_hidden) lib.modules in
match modules with
| [] -> fpf ppf " with no toplevel module."
| _ :: _ ->
let modules =
List.sort (fun m m' -> String.compare m.m_name m'.m_name) modules
in
fpf ppf " {!modules:";
List.iter (fun m -> fpf ppf " %s" m.m_name) modules;
fpf ppf " }@\n"

let library_list ppf pkg =
let print_lib (lib : Packages.libty) =
fpf ppf "{2 Library %s}@\n%a@\n" lib.lib_name module_list lib
in
let libraries =
List.sort
(fun lib lib' -> String.compare lib.lib_name lib'.lib_name)
pkg.libraries
in
List.iter print_lib libraries

let content pkg ppf =
fpf ppf "{0 %s}\n" pkg.name;
if not (List.is_empty pkg.mlds) then
fpf ppf
"{1 Documentation pages}@\n@\n{{!/%s/doc/index}Documentation for %s}@\n"
pkg.name pkg.name;
List.iter
(fun { mld_rel_path; _ } ->
let page = mld_rel_path |> Fpath.rem_ext |> Fpath.to_string in
fpf ppf "@\n{!/%s/doc/%s}@\n" pkg.name page)
pkg.mlds;
if not (List.is_empty pkg.libraries) then
fpf ppf "{1 Libraries}@\n@\n{{!/%s/lib/index}Libraries for %s}@\n"
pkg.name pkg.name
fpf ppf "{1 API}@\n@\n%a@\n" library_list pkg

let page ~odoc_dir ~odocl_dir ~mld_dir ~output_dir ~pkg =
let content = content pkg in
let rel_path = Fpath.v pkg.name in
let pkg_args =
{ pages = [ (pkg.name, Fpath.( // ) odoc_dir rel_path) ]; libs = [] }
let include_dirs ~odoc_dir pkg =
List.map
(fun lib -> Fpath.(odoc_dir // pkg.pkg_dir / "lib" / lib.lib_name))
pkg.Packages.libraries

let page_exists pkg page =
List.exists
(fun Packages.{ mld_path = _; mld_rel_path } -> page = mld_rel_path)
pkg.mlds

let pkg_has_index pkg = page_exists pkg Fpath.(v "index.mld")

let pkg_redirect pkg =
let package_index = Fpath.(v "doc" / "index.html") in
let path = Fpath.(v pkg.name / "index.html") in
let content =
Format.asprintf
{|<head><meta http-equiv="refresh" content="1; URL=%a"></head>|}
Fpath.pp package_index
in
make_unit ~odoc_dir ~odocl_dir ~mld_dir ~output_dir rel_path ~content
~pkgname:pkg.name ~pkg_args ()
Html { path; content }

let page ~odoc_dir ~odocl_dir ~mld_dir ~output_dir ~pkg =
if pkg_has_index pkg then pkg_redirect pkg
else
let content = content pkg in
let rel_path = Fpath.v pkg.name in
let pkg_args =
{ pages = [ (pkg.name, Fpath.( // ) odoc_dir rel_path) ]; libs = [] }
in
let include_dirs = include_dirs ~odoc_dir pkg in
make_unit ~odoc_dir ~odocl_dir ~mld_dir ~output_dir rel_path ~content
~pkgname:pkg.name ~pkg_args ~include_dirs ()
end

module PackageList = struct
Expand Down Expand Up @@ -88,24 +159,6 @@ module LibraryLanding = struct
~pkgname:pkg.name ~include_dirs ~pkg_args ()
end

module PackageLibLanding = struct
let content pkg ppf =
fpf ppf "{0 %s}@\n" pkg.name;
let print_lib (lib : Packages.libty) =
fpf ppf "- {{!/%s/%s/index}%s}@\n" pkg.name lib.lib_name lib.lib_name
in
List.iter print_lib pkg.libraries

let page ~pkg ~odoc_dir ~odocl_dir ~mld_dir ~output_dir =
let content = content pkg in
let rel_path = Fpath.(v pkg.name / "lib") in
let pkg_args =
{ pages = [ (pkg.name, Fpath.( // ) odoc_dir rel_path) ]; libs = [] }
in
make_unit ~odoc_dir ~odocl_dir ~mld_dir ~output_dir rel_path ~content
~pkgname:pkg.name ~pkg_args ()
end

let of_package ~mld_dir ~odoc_dir ~odocl_dir ~output_dir pkg =
let library_pages =
List.map
Expand All @@ -115,11 +168,13 @@ let of_package ~mld_dir ~odoc_dir ~odocl_dir ~output_dir pkg =
let package_landing_page =
PackageLanding.page ~odoc_dir ~odocl_dir ~mld_dir ~output_dir ~pkg
in
let library_list_page =
PackageLibLanding.page ~odoc_dir ~odocl_dir ~mld_dir ~output_dir ~pkg
in
let library_list_page = PackageLibLanding.page ~pkg in
package_landing_page :: library_list_page :: library_pages

let of_packages ~mld_dir ~odoc_dir ~odocl_dir ~output_dir all =
PackageList.page ~mld_dir ~odoc_dir ~odocl_dir ~output_dir all
:: List.concat_map (of_package ~mld_dir ~odoc_dir ~odocl_dir ~output_dir) all
let of_packages ~mld_dir ~odoc_dir ~odocl_dir ~output_dir all :
(Fpath.t * string) list * [> `Mld ] Odoc_unit.unit list =
split_units_and_html
(PackageList.page ~mld_dir ~odoc_dir ~odocl_dir ~output_dir all
:: List.concat_map
(of_package ~mld_dir ~odoc_dir ~odocl_dir ~output_dir)
all)
2 changes: 1 addition & 1 deletion src/driver/landing_pages.mli
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ val of_packages :
odocl_dir:Fpath.t ->
output_dir:Fpath.t ->
Packages.t list ->
[> `Mld ] Odoc_unit.unit list
(Fpath.t * string) list * [ `Mld ] Odoc_unit.unit list
13 changes: 10 additions & 3 deletions src/driver/odoc_driver.ml
Original file line number Diff line number Diff line change
Expand Up @@ -557,20 +557,27 @@ let run libs verbose packages_dir odoc_dir odocl_dir html_dir stats nb_workers
let () =
Eio.Fiber.both
(fun () ->
let all =
let htmls, all =
let all = Util.StringMap.bindings all |> List.map snd in
let internal =
Odoc_unit.of_packages ~output_dir:odoc_dir ~linked_dir:odocl_dir
~index_dir:None all
in
let external_ =
let htmls, external_ =
let mld_dir = odoc_dir in
let odocl_dir = Option.value odocl_dir ~default:odoc_dir in
Landing_pages.of_packages ~mld_dir ~odoc_dir ~odocl_dir
~output_dir:odoc_dir all
in
internal @ external_
(htmls, internal @ (external_ :> Odoc_unit.t list))
in
List.iter
(fun (path, content) ->
Logs.debug (fun m -> m "writing raw html to %a" Fpath.pp path);
let path = Fpath.(v "_html" // path) in
Out_channel.with_open_text (Fpath.to_string path) (fun ch ->
output_string ch content))
htmls;
Compile.init_stats all;
let compiled =
Compile.compile ?partial ~partial_dir:odoc_dir ?linked_dir:odocl_dir
Expand Down
Loading