Skip to content

Commit 06f21a4

Browse files
committed
Add a source-root arg to html-generate
The relative path has already been given when the .cmt was originally compiled, so to avoid having to pass it again this argument allows the root directory of the source tree to be passed, and then odoc finds the actual source file by looking up that relative file within the tree.
1 parent 86f33b1 commit 06f21a4

File tree

9 files changed

+160
-13
lines changed

9 files changed

+160
-13
lines changed

src/compat/compatcmdliner.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ module Arg = struct
6060

6161
let file = file
6262

63+
let dir = dir
64+
6365
let bool = bool
6466

6567
let ( & ) = ( & )

src/odoc/bin/main.ml

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,22 @@ let convert_fpath =
3838
and print = Fpath.pp in
3939
Arg.conv (parse, print)
4040

41+
let convert_src_fpath =
42+
let parse inp =
43+
match Arg.(conv_parser file) inp with
44+
| Ok s -> Result.Ok (Html_page.File (Fs.File.of_string s))
45+
| Error _ as e -> e
46+
and print = Html_page.pp in
47+
Arg.conv (parse, print)
48+
49+
let convert_src_dir =
50+
let parse inp =
51+
match Arg.(conv_parser dir) inp with
52+
| Ok s -> Result.Ok (Html_page.Root (Fs.File.of_string s))
53+
| Error _ as e -> e
54+
and print = Html_page.pp in
55+
Arg.conv (parse, print)
56+
4157
(** On top of the conversion 'string', split into segs. *)
4258
let convert_source_name =
4359
let parse inp =
@@ -714,7 +730,7 @@ module Odoc_html_args = struct
714730
in
715731
Arg.(
716732
value
717-
& opt (some convert_fpath) None
733+
& opt (some convert_src_fpath) None
718734
& info [ "source" ] ~doc ~docv:"file.ml")
719735

720736
let assets =
@@ -725,19 +741,38 @@ module Odoc_html_args = struct
725741
Arg.(
726742
value & opt_all convert_fpath [] & info [ "asset" ] ~doc ~docv:"file.ext")
727743

744+
let source_root =
745+
let doc =
746+
"Source code root for the compilation unit. It must have been compiled \
747+
with --source-parent passed."
748+
in
749+
Arg.(
750+
value
751+
& opt (some convert_src_dir) None
752+
& info [ "source-root" ] ~doc ~docv:"dir")
753+
728754
let extra_args =
729755
let config semantic_uris closed_details indent theme_uri support_uri flat
730-
as_json source_file assets =
756+
as_json source_file assets source_root =
731757
let open_details = not closed_details in
758+
let source =
759+
match (source_root, source_file) with
760+
| Some x, None -> Some x
761+
| None, Some x -> Some x
762+
| None, None -> None
763+
| Some _, Some _ ->
764+
Printf.eprintf "ERROR: Can't use both source and source-root\n%!";
765+
exit 1
766+
in
732767
let html_config =
733768
Odoc_html.Config.v ~theme_uri ~support_uri ~semantic_uris ~indent ~flat
734769
~open_details ~as_json ()
735770
in
736-
{ Html_page.html_config; source_file; assets }
771+
{ Html_page.html_config; source; assets }
737772
in
738773
Term.(
739774
const config $ semantic_uris $ closed_details $ indent $ theme_uri
740-
$ support_uri $ flat $ as_json $ source_file $ assets)
775+
$ support_uri $ flat $ as_json $ source_file $ assets $ source_root)
741776
end
742777

743778
module Odoc_html = Make_renderer (Odoc_html_args)

src/odoc/html_page.ml

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,45 @@
1616

1717
open Odoc_model
1818

19+
type source = File of Fpath.t | Root of Fpath.t
20+
21+
let pp fmt = function
22+
| File f -> Format.fprintf fmt "File: %a" Fpath.pp f
23+
| Root f -> Format.fprintf fmt "File: %a" Fpath.pp f
24+
25+
let to_string f = Format.asprintf "%a" pp f
26+
1927
type args = {
2028
html_config : Odoc_html.Config.t;
21-
source_file : Fpath.t option;
29+
source : source option;
2230
assets : Fpath.t list;
2331
}
2432

25-
let render { html_config; source_file = _; assets = _ } page =
33+
let render { html_config; source = _; assets = _ } page =
2634
Odoc_html.Generator.render ~config:html_config page
2735

28-
let source_documents source_info source_file ~syntax =
29-
match (source_info, source_file) with
36+
let source_documents source_info source ~syntax =
37+
match (source_info, source) with
3038
| Some { Lang.Source_info.id; infos }, Some src -> (
31-
match Fs.File.read src with
39+
let file =
40+
match src with
41+
| File f -> f
42+
| Root f ->
43+
let open Odoc_model.Paths.Identifier in
44+
let rec get_path_dir : SourceDir.t -> Fpath.t = function
45+
| { iv = `SourceDir (d, f); _ } -> Fpath.(get_path_dir d / f)
46+
| { iv = `Page _; _ } -> f
47+
in
48+
let get_path : SourcePage.t -> Fpath.t = function
49+
| { iv = `SourcePage (d, f); _ } -> Fpath.(get_path_dir d / f)
50+
in
51+
get_path id
52+
in
53+
match Fs.File.read file with
3254
| Error (`Msg msg) ->
3355
Error.raise_warning
3456
(Error.filename_only "Couldn't load source file: %s" msg
35-
(Fs.File.to_string src));
57+
(Fs.File.to_string file));
3658
[]
3759
| Ok source_code ->
3860
let syntax_info =
@@ -56,7 +78,7 @@ let source_documents source_info source_file ~syntax =
5678
(Error.filename_only
5779
"--source argument is invalid on compilation unit that were not \
5880
compiled with --source-parent and --source-name"
59-
(Fs.File.to_string src));
81+
(to_string src));
6082
[]
6183
| None, None -> []
6284

@@ -111,7 +133,7 @@ let asset_documents parent_id children asset_paths =
111133
let extra_documents args input ~syntax =
112134
match input with
113135
| Odoc_document.Renderer.CU unit ->
114-
source_documents unit.Lang.Compilation_unit.source_info args.source_file
136+
source_documents unit.Lang.Compilation_unit.source_info args.source
115137
~syntax
116138
| Page page -> asset_documents page.Lang.Page.name page.children args.assets
117139

src/odoc/html_page.mli

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,13 @@
1616

1717
open Odoc_document
1818

19+
type source = File of Fpath.t | Root of Fpath.t
20+
21+
val pp : Format.formatter -> source -> unit
22+
1923
type args = {
2024
html_config : Odoc_html.Config.t;
21-
source_file : Fpath.t option;
25+
source : source option;
2226
assets : Fpath.t list;
2327
}
2428

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
let y = 1
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
let x = 0
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
let w = 5
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{0 Root}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
A page can have source children.
2+
3+
$ odoc compile -c module-a -c module-b -c src-source root.mld
4+
5+
$ printf "lib/main.ml\nlib/b/b.ml\nlib/a/a.ml\n" > source.map
6+
$ odoc source-tree -I . --parent page-root source.map
7+
8+
Compile the modules:
9+
10+
$ ocamlc -c lib/a/a.ml -bin-annot
11+
$ ocamlc -c lib/b/b.ml -bin-annot
12+
$ ocamlc -c lib/main.ml -bin-annot
13+
14+
Now, compile the pages with the --source option. The source-name must be included in the source-children of the source-parent:
15+
16+
$ odoc compile -I . --source-name lib/a/a.ml --source-parent-file src-source.odoc lib/a/a.cmt
17+
$ odoc compile -I . --source-name lib/b/b.ml --source-parent-file src-source.odoc lib/b/b.cmt
18+
$ odoc compile -I . --source-name lib/main.ml --source-parent-file src-source.odoc lib/main.cmt
19+
$ odoc link -I . -I lib/a -I lib/b -I lib page-root.odoc
20+
$ odoc link -I . lib/a/a.odoc
21+
$ odoc link -I . lib/b/b.odoc
22+
$ odoc link -I . lib/main.odoc
23+
$ odoc link -I . src-source.odoc
24+
$ odoc html-generate --indent -o html page-root.odocl
25+
$ odoc html-generate --indent -o html src-source.odocl
26+
$ odoc html-generate --source-root . --indent -o html lib/a/a.odocl
27+
$ odoc html-generate --source-root . --indent -o html lib/b/b.odocl
28+
$ odoc html-generate --source-root . --indent -o html lib/main.odocl
29+
30+
Source pages and source directory pages are generated:
31+
32+
$ find html | sort
33+
html
34+
html/A
35+
html/A/index.html
36+
html/B
37+
html/B/index.html
38+
html/Main
39+
html/Main/index.html
40+
html/root
41+
html/root/index.html
42+
html/root/source
43+
html/root/source/index.html
44+
html/root/source/lib
45+
html/root/source/lib/a
46+
html/root/source/lib/a/a.ml.html
47+
html/root/source/lib/a/index.html
48+
html/root/source/lib/b
49+
html/root/source/lib/b/b.ml.html
50+
html/root/source/lib/b/index.html
51+
html/root/source/lib/index.html
52+
html/root/source/lib/main.ml.html
53+
54+
A directory simply list its children:
55+
56+
$ cat html/root/source/lib/index.html
57+
<!DOCTYPE html>
58+
<html xmlns="http://www.w3.org/1999/xhtml">
59+
<head><title>lib (root.source.lib)</title>
60+
<link rel="stylesheet" href="../../../odoc.css"/><meta charset="utf-8"/>
61+
<meta name="generator" content="odoc %%VERSION%%"/>
62+
<meta name="viewport" content="width=device-width,initial-scale=1.0"/>
63+
<script src="../../../highlight.pack.js"></script>
64+
<script>hljs.initHighlightingOnLoad();</script>
65+
</head>
66+
<body class="odoc">
67+
<nav class="odoc-nav"><a href="../index.html">Up</a> –
68+
<a href="../../index.html">root</a> &#x00BB;
69+
<a href="../index.html">source</a> &#x00BB; lib
70+
</nav><header class="odoc-preamble"></header>
71+
<div class="odoc-content"><h1>./lib/</h1>
72+
<ul class="odoc-folder-list">
73+
<li><span class="odoc-directory"><a href="a/index.html">a</a></span></li>
74+
<li><span class="odoc-directory"><a href="b/index.html">b</a></span></li>
75+
<li><span class="odoc-file"><a href="main.ml.html">main.ml</a></span>
76+
</li>
77+
</ul>
78+
</div>
79+
</body>
80+
</html>

0 commit comments

Comments
 (0)