Skip to content

Render modules synopsis for {!modules:...} #597

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

Merged
merged 6 commits into from
Feb 25, 2021
Merged
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
27 changes: 20 additions & 7 deletions src/document/comment.ml
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,25 @@ and inline_element_list elements =
(fun elt -> inline_element elt.Odoc_model.Location_.value)
elements

let module_references ms =
let module_reference (m : Comment.module_reference) =
let reference =
Reference.to_ir ~stop_before:false
(m.module_reference :> Odoc_model.Paths.Reference.t)
and synopsis =
match m.module_synopsis with
| Some synopsis ->
[
block ~attr:[ "synopsis" ]
@@ Paragraph (inline_element_list synopsis);
]
| None -> []
in
(reference, synopsis)
in
let items = List.map module_reference ms in
block ~attr:[ "modules" ] @@ Description items

let rec nestable_block_element : Comment.nestable_block_element -> Block.one =
fun content ->
match content with
Expand All @@ -214,13 +233,7 @@ let rec nestable_block_element : Comment.nestable_block_element -> Block.one =
| `Paragraph content -> block @@ Block.Paragraph (inline_element_list content)
| `Code_block code -> block @@ Source (source_of_code code)
| `Verbatim s -> block @@ Verbatim s
| `Modules ms ->
let items =
List.map
(fun r -> [ block @@ Inline (Reference.to_ir ~stop_before:false r) ])
(ms :> Odoc_model.Paths.Reference.t list)
in
block ~attr:[ "modules" ] @@ Block.List (Unordered, items)
| `Modules ms -> module_references ms
| `List (kind, items) ->
let kind =
match kind with
Expand Down
13 changes: 11 additions & 2 deletions src/model/comment.ml
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,20 @@ type inline_element =
| `Reference of Reference.t * link_content
| `Link of string * link_content ]

type paragraph = inline_element with_location list

type module_reference = {
module_reference : Reference.Module.t;
module_synopsis : paragraph option;
}
(** The [{!modules: ...}] markup. [module_synopsis] is initially [None], it is
resolved during linking. *)

type nestable_block_element =
[ `Paragraph of inline_element with_location list
[ `Paragraph of paragraph
| `Code_block of string
| `Verbatim of string
| `Modules of Reference.Module.t list
| `Modules of module_reference list
| `List of
[ `Unordered | `Ordered ] * nestable_block_element with_location list list
]
Expand Down
11 changes: 9 additions & 2 deletions src/model_desc/comment_desc.ml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type general_block_element =
[ `Paragraph of general_link_content
| `Code_block of string
| `Verbatim of string
| `Modules of Paths.Reference.t list
| `Modules of Comment.module_reference list
| `List of
[ `Unordered | `Ordered ] * general_block_element with_location list list
| `Heading of heading_level * Paths.Identifier.Label.t * general_link_content
Expand Down Expand Up @@ -67,6 +67,13 @@ let rec inline_element : general_inline_element t =
and link_content : general_link_content t =
List (Indirect (ignore_loc, inline_element))

let module_reference =
let simplify m =
( (m.module_reference :> Paths.Reference.t),
(m.module_synopsis :> general_link_content option) )
in
Indirect (simplify, Pair (reference, Option link_content))

let rec block_element : general_block_element t =
let heading_level =
Variant
Expand All @@ -87,7 +94,7 @@ let rec block_element : general_block_element t =
| `Paragraph x -> C ("`Paragraph", x, link_content)
| `Code_block x -> C ("`Code_block", x, string)
| `Verbatim x -> C ("`Verbatim", x, string)
| `Modules x -> C ("`Modules", x, List reference)
| `Modules x -> C ("`Modules", x, List module_reference)
| `List (x1, x2) ->
C ("`List", (x1, (x2 :> general_docs list)), Pair (list_kind, List docs))
| `Heading (x1, x2, x3) ->
Expand Down
3 changes: 2 additions & 1 deletion src/parser/semantics.ml
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ let rec nestable_block_element :
match
Reference.read_mod_longident status.warnings location value
with
| Result.Ok r -> r :: acc
| Result.Ok r ->
{ Comment.module_reference = r; module_synopsis = None } :: acc
| Result.Error error ->
Error.warning status.warnings error;
acc)
Expand Down
33 changes: 30 additions & 3 deletions src/xref2/link.ml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,29 @@ module Opt = struct
let map f = function Some x -> Some (f x) | None -> None
end

let rec list_find_map f = function
| hd :: tl -> (
match f hd with Some _ as x -> x | None -> list_find_map f tl )
| [] -> None

(** The synopsis is the first paragraph of a comment. Headings, tags and other
{!Comment.block_element} that are not [`Paragraph] or [`List] are skipped.
*)
let synopsis_from_comment docs =
let open Location_ in
let rec from_element elem =
match elem.value with
| `Paragraph p -> Some p
| `List (_, items) -> list_find_map (list_find_map from_element) items
| _ -> None
in
list_find_map
(function
| { value = #Comment.nestable_block_element; _ } as elem ->
from_element elem
| _ -> None)
docs

exception Loop

let rec is_forward : Paths.Path.Module.t -> bool = function
Expand Down Expand Up @@ -175,9 +198,13 @@ and comment_nestable_block_element env (x : Comment.nestable_block_element) =
| `Modules refs ->
let refs =
List.map
(fun r ->
match Ref_tools.resolve_module_reference env r with
| Some (r, _, _) -> `Resolved r
(fun (r : Comment.module_reference) ->
match Ref_tools.resolve_module_reference env r.module_reference with
| Some (r, _, m) ->
{
Comment.module_reference = `Resolved r;
module_synopsis = synopsis_from_comment m.doc;
}
| None -> r)
refs
in
Expand Down
30 changes: 17 additions & 13 deletions test/html/expect/test_package+ml/Markup/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -286,23 +286,27 @@ <h2 id="modules">
<a href="#modules" class="anchor"></a>Modules
</h2>
<aside>
<ul class="modules"></ul>
<ul class="modules">
<li>
<dl class="modules"></dl>
<dl class="modules">
<dt>
<code>X</code>
</li>
</ul>
<ul class="modules">
<li>
</dt>
<dd></dd>
</dl>
<dl class="modules">
<dt>
<code>X</code>
</li>
<li>
</dt>
<dd></dd>
<dt>
<code>Y</code>
</li>
<li>
</dt>
<dd></dd>
<dt>
<code>Z</code>
</li>
</ul>
</dt>
<dd></dd>
</dl>
</aside>
<h2 id="tags">
<a href="#tags" class="anchor"></a>Tags
Expand Down
69 changes: 45 additions & 24 deletions test/html/expect/test_package+ml/Ocamlary/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -173,14 +173,24 @@ <h1>
<p>
Here is an index table of <code>Empty</code> modules:
</p>
<ul class="modules">
<li>
<dl class="modules">
<dt>
<a href="Empty/index.html"><code>Empty</code></a>
</li>
<li>
</dt>
<dd>
<p class="synopsis">
A plain, empty module
</p>
</dd>
<dt>
<a href="Empty/index.html"><code>EmptyAlias</code></a>
</li>
</ul>
</dt>
<dd>
<p class="synopsis">
A plain module alias of <code>Empty</code>
</p>
</dd>
</dl>
<p>
Here is a table of links to indexes: <code>indexlist</code>
</p>
Expand Down Expand Up @@ -1677,36 +1687,47 @@ <h2 id="indexmodules">
<p>
With odoc, everything should be resolved (and linked) but only toplevel units will be documented.
</p>
<ul class="modules">
<li>
<dl class="modules">
<dt>
<a href="Dep1/X/index.html"><code>Dep1.X</code></a>
</li>
<li>
</dt>
<dd></dd>
<dt>
<code>DocOckTypes</code>
</li>
<li>
</dt>
<dd></dd>
<dt>
<a href="IncludeInclude1/index.html"><code>Ocamlary.IncludeInclude1</code></a>
</li>
<li>
</dt>
<dd></dd>
<dt>
<a href="#"><code>Ocamlary</code></a>
</li>
</ul>
</dt>
<dd>
<p class="synopsis">
This is an <i>interface</i> with <b>all</b> of the <em>module system</em> features. <code>C This text is centered. </code> <code>L This text is left-aligned. </code> <code>R This text is right-aligned. </code> This documentation demonstrates:
</p>
</dd>
</dl>
</aside>
<h4 id="weirder-usages-involving-module-types">
<a href="#weirder-usages-involving-module-types" class="anchor"></a>Weirder usages involving module types
</h4>
<aside>
<ul class="modules">
<li>
<dl class="modules">
<dt>
<code>IncludeInclude1</code>.IncludeInclude2
</li>
<li>
</dt>
<dd></dd>
<dt>
<code>Dep4</code>.T
</li>
<li>
</dt>
<dd></dd>
<dt>
<a href="module-type-A/Q/index.html"><code>A.Q</code></a>
</li>
</ul>
</dt>
<dd></dd>
</dl>
</aside>
<h2 id="playing-with-@canonical-paths">
<a href="#playing-with-@canonical-paths" class="anchor"></a>Playing with @canonical paths
Expand Down
30 changes: 17 additions & 13 deletions test/html/expect/test_package+re/Markup/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -286,23 +286,27 @@ <h2 id="modules">
<a href="#modules" class="anchor"></a>Modules
</h2>
<aside>
<ul class="modules"></ul>
<ul class="modules">
<li>
<dl class="modules"></dl>
<dl class="modules">
<dt>
<code>X</code>
</li>
</ul>
<ul class="modules">
<li>
</dt>
<dd></dd>
</dl>
<dl class="modules">
<dt>
<code>X</code>
</li>
<li>
</dt>
<dd></dd>
<dt>
<code>Y</code>
</li>
<li>
</dt>
<dd></dd>
<dt>
<code>Z</code>
</li>
</ul>
</dt>
<dd></dd>
</dl>
</aside>
<h2 id="tags">
<a href="#tags" class="anchor"></a>Tags
Expand Down
Loading