Skip to content

feat: use output from new doc-ci with odoc 3 features in the package documentation area #3124

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

Draft
wants to merge 16 commits into
base: main
Choose a base branch
from
Draft
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
15 changes: 14 additions & 1 deletion asset/css/doc.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
[x-cloak] { display: none !important; }

div.odoc {
max-width: 56rem /* 896px */;
position: relative;
Expand Down Expand Up @@ -314,6 +316,15 @@ div.odoc .comment-delim {
border-color: rgb(32, 68, 165);
}

.navmap-tag.page-tag::after {
content: "P";
}
.page-tag{
color: rgb(32, 68, 165);
background-color: rgb(32, 68, 165);
border-color: rgb(32, 68, 165);
}

span.icon-expand > .navmap-tag,
span.no-expand > .navmap-tag {
color: white;
Expand Down Expand Up @@ -344,10 +355,12 @@ span.arrow-expand.open {
}

span.sign-expand::before {
content: " \002B";
content: "\002B";
display: flex;
justify-content: center;
align-items: center;
font-size: 1.25rem;
width: 1.25rem;
margin-top: -0.25rem;
}

Expand Down
1 change: 1 addition & 0 deletions dune-project
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
ezjsonm
lambdasoup
ptime
ppx_deriving_yojson
(cmdliner
(>= 1.1.0))
xmlm
Expand Down
1 change: 1 addition & 0 deletions ocamlorg.opam
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ depends: [
"ezjsonm"
"lambdasoup"
"ptime"
"ppx_deriving_yojson"
"cmdliner" {>= "1.1.0"}
"xmlm"
"uri"
Expand Down
11 changes: 6 additions & 5 deletions src/ocamlorg_frontend/components/navmap.eml
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@ let kind_title = function
| Class_type -> "Class type"
| _ -> "?"

let title_style = "flex-1 flex-nowrap py-1 md:py-0.5 pr-1 text-title dark:text-dark-title"
let title_style = "flex-1 flex-nowrap py-1 md:py-0.5 pr-1 text-title dark:text-dark-title truncate"

let htmx_attributes = "hx-boost=\"true\" hx-ext=\"multi-swap\" hx-swap=\"multi:#htmx-head,#htmx-sidebar,#htmx-content,#htmx-right-sidebar,#htmx-breadcrumbs\" hx-push-url=\"true\""
let htmx_attributes = "hx-boost=\"true\" hx-ext=\"multi-swap\" hx-swap=\"multi:#htmx-head,#htmx-content,#htmx-right-sidebar,#htmx-breadcrumbs\" hx-push-url=\"true\""

let icon_style = function
| Page -> "navmap-tag page-tag"
| Library -> "navmap-tag library-tag"
| Module -> "navmap-tag module-tag"
| Module_type -> "navmap-tag module-type-tag"
Expand Down Expand Up @@ -75,20 +76,20 @@ let rec nested_render ~path (item : toc) =
let active_style = if item.title = fragment then (if List.length path = 0 then "bg-gray-200 dark:bg-dark-tertiary_bt_hover font-medium dark:font-semibold" else "border-transparent bg-gray-100 dark:bg-dark-tertiary_bt_hover font-medium dark:font-semibold") else "border-transparent" in
<div x-data="{ open: <%s if default_open then "true" else "false" %> }">
<div class="box-border border <%s active_style %> cursor-pointer pl-1 ml-1" :class="open ? 'nav-expand' : ''">
<div class="flex flex-nowrap" title="<%s kind_title item.kind ^ " " ^ item.title %>">
<div class="flex flex-nowrap items-center" title="<%s kind_title item.kind ^ " " ^ item.title %>">
<span class="icon-expand" x-on:click="open = ! open" :class="open ? 'open' : ''" >
<span class="<%s if item.title = fragment then "" else "opacity-80" %> <%s icon_style item.kind %>"></span>
</span>
<% (match item.href with | None -> %>
<span x-on:click="open = ! open" class="<%s title_style %> <%s if item.title = fragment then "white-200" else "gray-900" %>">
<%s! item.title %>
<span class="arrow-expand absolute right-0.5 px-3" :class="open ? 'open' : ''"><%s! Icons.chevron_down "h-5 w-5" %></span>
</span>
<span x-on:click="open = ! open" class="arrow-expand mr-2" :class="open ? 'open' : ''"><%s! Icons.chevron_down "h-5 w-5" %></span>
<% | Some href -> %>
<a href="<%s href %>" <%s! htmx_attributes %> class="<%s title_style %> overflow-hidden truncate text-title dark:text-dark-title transition-colors hover:text-primary">
<%s! item.title %>
</a>
<span x-on:click="open = ! open" class="sign-expand mr-2 px-2" :class="open ? 'open' : ''"></span>
<span x-on:click="open = ! open" class="sign-expand mr-2" :class="open ? 'open' : ''"></span>
<% ); %>
</div>
</div>
Expand Down
107 changes: 52 additions & 55 deletions src/ocamlorg_frontend/components/package_breadcrumbs.eml
Original file line number Diff line number Diff line change
@@ -1,30 +1,33 @@
type library_path_item =
| Module of { name: string; href: string; }
| ModuleType of { name: string; href: string; }
| Parameter of { name: string; href: string; number: int; }
| Class of { name: string; href: string; }
| ClassType of { name: string; href: string; }
type breadcrumb = {
name: string;
href: string option;
}

type docs_path =
| Index
| Page of string
| Library of string * library_path_item list
type path_item =
| Module of breadcrumb
| ModuleType of breadcrumb
| Parameter of breadcrumb * int
| Class of breadcrumb
| ClassType of breadcrumb
| Page of breadcrumb

let kind_tag (m : library_path_item) = match m with
let kind_tag (m : path_item) = match m with
| Module _ ->
<span tabindex="0" aria-label="module" class="breadcrumbs-tag module-tag">Module</span>
| ModuleType _ ->
<span tabindex="0" aria-label="module type" class="breadcrumbs-tag module-type-tag">Module type</span>
| Parameter { number; _ } ->
| Parameter (_, number) ->
<span tabindex="0" aria-label="<%s "Parameter #" ^ (Int.to_string number) %>" class="breadcrumbs-tag parameter-tag"><%s "Parameter #" ^ (Int.to_string number) %></span>
| Class _ ->
<span tabindex="0" aria-label="class" class="breadcrumbs-tag class-tag">Class</span>
| ClassType _ ->
<span tabindex="0" aria-label="class type" class="breadcrumbs-tag class-type-tag">Class type</span>
| Page _ ->
<span tabindex="0" aria-label="page" class="breadcrumbs-tag page-tag">Page</span>

type path =
| Overview of string option
| Documentation of (docs_path)
| Documentation of path_item list

let render_package_and_version
~path
Expand Down Expand Up @@ -57,54 +60,49 @@ let render_package_and_version
</select>
</div>

type breadcrumb = {
name: string;
href: string;
}
let path_item_to_breadcrumb = function
| Module x | ModuleType x | Class x | ClassType x | Parameter (x, _) | Page x
->
x

let library_path_item_to_breadcrumb = function
| Module x -> { name = x.name; href = x.href }
| ModuleType x -> { name = x.name; href = x.href }
| Class x -> { name = x.name; href = x.href }
| ClassType x -> { name = x.name; href = x.href }
| Parameter x -> { name = x.name; href = x.href }
let is_page : path_item -> bool = function Page _ -> true | _ -> false

let render_library_path_breadcrumbs
~library_name
~(path: library_path_item list) =
let render_breadcrumb i b =
if i < List.length path - 1 then
<a href="<%s! b.href %>" class="font-semibold underline text-content dark:text-dark-title"><%s b.name %></a>
else
<a href="<%s! b.href %>" aria-current="page" class="text-content dark:text-dark-title mr-2"><%s b.name %></a>
let render_path_breadcrumbs
~(path: path_item list) =
let pages, modules = List.partition is_page path in
let render_breadcrumb max i b =
match b.href with
| None when i < max ->
<span class="font-semibold underline text-content dark:text-dark-title"><%s b.name %></span>
| None ->
<span aria-current="page" class="text-content dark:text-dark-title mr-2"><%s b.name %></span>
| Some href when i < max ->
<a href="<%s! href %>" class="font-semibold underline text-content dark:text-dark-title"><%s b.name %></a>
| Some href ->
<a href="<%s! href %>" aria-current="page" class="text-content dark:text-dark-title mr-2"><%s b.name %></a>
in
<li>
<span tabindex="0" class="text-content dark:text-dark-content"><%s library_name %> lib</span>
</li>
<li class="flex flex-wrap items-center">
<%s! String.concat "<span>.</span>" (path |> List.map library_path_item_to_breadcrumb |> List.mapi render_breadcrumb); %>
<%s! kind_tag (List.hd (List.rev path)) %>
</li>
let li content =
<li class="flex flex-wrap items-center">
<%s! content %>
</li>
in
let page_items = List.fold_left (fun (i, acc) item ->
(i+1, acc ^ li (render_breadcrumb (List.length pages - 1) i (path_item_to_breadcrumb item)))) (0,"") pages |> snd in
let ms =
<%s! String.concat "<span>.</span>" (List.mapi (render_breadcrumb (List.length modules - 1)) (List.map path_item_to_breadcrumb modules)) %>
in
let last = kind_tag (List.hd (List.rev path)) in
if List.length modules > 0 then
page_items ^ li (ms ^ last)
else
page_items

let render_docs_path_breadcrumbs
~(path: docs_path)
(package: Package.package)
~(path: path_item list)
=
let version = Package.url_version package in
<nav aria-label="breadcrumb" class="flex mb-6 border-b pb-6">
<ul class="flex flex-wrap gap-x-2 text-base leading-7 package-breadcrumbs">
<li>
<a class="underline font-semibold text-content dark:text-dark-title hover:text-primary dark:hover:text-dark-primary" href="<%s! Url.Package.documentation package.name ?version %>">Documentation</a>
</li>
<% (match path with
| Index -> %>
<% | Library (library_name, library_path) -> %>
<%s! if library_path != [] then render_library_path_breadcrumbs ~library_name ~path:library_path else "ERROR: library path is []" %>
<% | Page page_name -> %>
<li>
<span><%s page_name %></span>
</li>
<% ); %>
<%s! if path != [] then render_path_breadcrumbs ~path else "ERROR: library path is []" %>
</ul>
</nav>

Expand All @@ -122,8 +120,7 @@ let render_overview_breadcrumbs

let render
~(path: path)
(package: Package.package)
=
match path with
| Overview page -> render_overview_breadcrumbs page
| Documentation (docs_path) -> render_docs_path_breadcrumbs ~path:docs_path package
| Documentation (docs_path) -> render_docs_path_breadcrumbs ~path:docs_path
2 changes: 1 addition & 1 deletion src/ocamlorg_frontend/layouts/package_layout.eml
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ Layout.base

let list_item = document.createElement("li");
let a = document.createElement("a");
let href = "/" + entry.url;
let href = entry.url;
a.href = href;
a.id = "search-result-"+entry.id;
a.classList.add("search-entry", kind.innerText.slice(0,3));
Expand Down
43 changes: 21 additions & 22 deletions src/ocamlorg_frontend/pages/package_documentation.eml
Original file line number Diff line number Diff line change
@@ -1,49 +1,48 @@
let sidebar
~str_path
~toc
~maptoc
~local_toc
~global_toc
(package : Package.package)
=
<div class="flex flex-col font-normal text-content dark:text-dark-content" id="htmx-sidebar">
<% if (toc != []) then ( %>
<% if (local_toc != []) then ( %>
<div class="xl:hidden mb-6 xl:mb-0">
<%s! Toc.render toc %>
<%s! Toc.render local_toc %>
</div><% ); %>
<div class="space-y-6 flex flex-col overflow-x:scroll">
<div>
<%s! Navmap.render ~package ~path:str_path maptoc %>
<%s! Navmap.render ~package ~path:str_path global_toc %>
</div>
</div>
</div>

let right_sidebar
~toc
~local_toc
=
<div class="pt-6" id="htmx-right-sidebar">
<%s! Toc.render toc %>
<%s! Toc.render local_toc %>
</div>

let render
~(path: Package_breadcrumbs.path)
~page
~toc
~maptoc
~local_toc
~global_toc
~content
(package : Package.package)
=
let str_path =
match path with
| Overview _ -> []
| Documentation (docs_path) -> (match docs_path with
| Package_breadcrumbs.Index -> []
| Library (s, p) -> s :: List.map (function
| Package_breadcrumbs.Module { name ; _ } -> name
| ModuleType { name ; _ } -> name
| Parameter { name ; _ } -> name
| Class { name ; _ } -> name
| ClassType { name ; _ } -> name
) p
| Page s -> [""; s])
| Documentation (docs_path) ->
List.map (function
| Package_breadcrumbs.Module { name ; _ }
| ModuleType { name ; _ }
| Parameter ({ name ; _ }, _)
| Class { name ; _ }
| ClassType { name ; _ }
| Page { name; _ } -> name
) docs_path |> List.tl
in
Package_layout.render
~title:(Printf.sprintf "%s %s · OCaml Package" package.name (Package.render_version package))
Expand All @@ -54,10 +53,10 @@ Package_layout.render
~documentation_status:Success
~canonical:(Url.Package.documentation package.name ~version:(Package.specific_version package) ~page:(Url.Package.documentation ?version:(Some (Package.specific_version package)) package.name))
~styles:["css/main.css"; "css/doc.css"]
~left_sidebar_html:(sidebar ~str_path ~toc ~maptoc package)
~right_sidebar_html:(right_sidebar ~toc) @@
~left_sidebar_html:(sidebar ~str_path ~local_toc ~global_toc package)
~right_sidebar_html:(right_sidebar ~local_toc) @@
<div id="htmx-content">
<%s! Package_breadcrumbs.render ~path package %>
<%s! Package_breadcrumbs.render ~path %>
<div class="odoc prose dark:prose-invert prose-orange">
<%s! content %>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/ocamlorg_package/lib/config.ml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ let opam_polling =

let documentation_url =
Sys.getenv_opt "OCAMLORG_DOC_URL"
|> Option.value ~default:"https://docs-data.ocaml.org/live/"
|> Option.value ~default:"https://sage.ci.dev/current/"

let package_caches_ttl =
env_with_default "OCAMLORG_PACKAGE_CACHES_TTL" "3600" |> float_of_string
Expand Down
53 changes: 23 additions & 30 deletions src/ocamlorg_package/lib/documentation_status.ml
Original file line number Diff line number Diff line change
@@ -1,34 +1,27 @@
type otherdocs = {
readme : string option;
license : string option;
changes : string option;
}
type redirection = { old_path : string; new_path : string } [@@deriving yojson]

type t = { failed : bool; otherdocs : otherdocs }
type t = {
name : string;
version : string;
failed : bool;
files : string list;
redirections : redirection list;
}
[@@deriving yojson]

let first_opt = function x :: _ -> Some x | [] -> None
let has_file (v : t) (options : string list) : string option =
let children = v.files in
try
List.find_map
(fun x ->
let fname = Fpath.(v x |> rem_ext |> filename) in
if List.mem fname options then Some fname else None)
children
with Not_found -> None

let strip_prefix (p : string option) =
let v : string list option = Option.map (String.split_on_char '/') p in
match v with
| None -> None
| Some (_ :: _ :: _ :: _ :: _ :: xs) -> Some (String.concat "/" xs)
| _ -> None
let license (v : t) = has_file v [ "LICENSE"; "LICENCE" ]
let readme (v : t) = has_file v [ "README"; "Readme"; "readme" ]

let of_yojson (v : Yojson.Safe.t) : t =
let status = Voodoo_serialize.Status.of_yojson v in
{
failed = status.failed;
otherdocs =
{
readme =
status.otherdocs.readme |> first_opt |> Option.map Fpath.to_string
|> strip_prefix;
license =
status.otherdocs.license |> first_opt |> Option.map Fpath.to_string
|> strip_prefix;
changes =
status.otherdocs.changes |> first_opt |> Option.map Fpath.to_string
|> strip_prefix;
};
}
let changelog (v : t) =
has_file v
[ "CHANGELOG"; "Changelog"; "changelog"; "CHANGES"; "Changes"; "changes" ]
Loading
Loading