Skip to content

Commit ede2bf3

Browse files
panglesdjonludlam
authored andcommitted
Update driver to use the new source-tree command
Mld-based generation of source tree is no longer needed. Fixes a retro-compatibility issue, by accepting `page-"foo"` as if it were `page-foo`. Adds the `html_support_files` library which was no forgotten in the list of `odoc` libraries. Signed-off-by: Paul-Elliot <[email protected]>
1 parent 9007df2 commit ede2bf3

File tree

3 files changed

+56
-130
lines changed

3 files changed

+56
-130
lines changed

doc/driver.md

Lines changed: 40 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ let compile file ?parent ?(output_dir = Fpath.v "./") ?(search_path = [])
173173
| None -> Cmd.empty
174174
| Some (source_name, source_parent_file) ->
175175
Cmd.(
176-
v "--source-name" % source_name % "--source-parent-file"
176+
v "--source-name" % p source_name % "--source-parent-file"
177177
% p source_parent_file)
178178
in
179179
let cmd =
@@ -195,7 +195,6 @@ let link ?(ignore_output = false) file =
195195
let open Cmd in
196196
let cmd = odoc % "link" % p file % "-I" % "." in
197197
let cmd = if Fpath.to_string file = "stdlib.odoc" then cmd % "--open=\"\"" else cmd in
198-
Format.printf "%a" pp cmd;
199198
let lines = OS.Cmd.(run_out ~err:err_run_out cmd |> to_lines) |> get_ok in
200199
if not ignore_output then
201200
add_prefixed_output cmd link_output (Fpath.to_string file) lines
@@ -257,7 +256,7 @@ let dep_libraries =
257256
| _ -> dep_libraries_core
258257
259258
let odoc_libraries = [
260-
"odoc_xref_test"; "odoc_xref2"; "odoc_odoc";
259+
"odoc_xref_test"; "odoc_xref2"; "odoc_odoc"; "odoc_html_support_files";
261260
"odoc_model_desc"; "odoc_model"; "odoc_manpage"; "odoc_loader";
262261
"odoc_latex"; "odoc_html"; "odoc_document"; "odoc_examples" ];;
263262
@@ -361,23 +360,31 @@ let compile_deps f =
361360
```
362361

363362
For `odoc` libraries, we infer the implementation and interface source file path
364-
from the library name. For each directory in the hierarchy, we generate an `mld`
365-
file with links, to the contents of the directory (using html specific backend
366-
as there are no syntax to reference sources).
363+
from the library name. We list them in a file, passed to `odoc source-tree`, to
364+
generate `src-source.odoc`. This file contains the source hierarchy, and will be
365+
linked and passed to `html-generate` just as other pages and compilation units.
367366

368-
The `.mld` files are stored in a specific folder, to avoid conflicts between
369-
folder names and other page's names. For instance, `page-odoc.odoc` exists both
370-
because there is a page named after the `odoc` folder and a page named after the
371-
`odoc` library. Moreover, the original hierarchy is preserved to avoid conflicts
372-
between different folders name, such as `lib` in `src/foo/lib/` and
373-
`src/bar/lib/`.
374-
375-
Mld files are compiled, with parents and children that correspond to the
376-
hierarchy. If a page has no children, we artificially add one to make it render
377-
as `name/index.html`.
367+
It is used as the `source-parent` for all units for which we could provide
368+
sources.
378369

379370
```ocaml env=e1
380-
let source_folder = Fpath.v "source_mlds"
371+
let source_tree_output = ref [ "" ]
372+
373+
let source_tree ?(ignore_output = false) ?(search_path = []) ~parent ~output file =
374+
let open Cmd in
375+
let search_path =
376+
search_path
377+
|> List.fold_left
378+
(fun acc s_path -> Cmd.(v "-I" % p s_path %% acc))
379+
Cmd.empty
380+
in
381+
let parent = v "--parent" % ("page-\"" ^ parent ^ "\"") in
382+
let cmd = odoc % "source-tree" % "-I" % "." %% search_path %% parent % "-o" % p output % p file in
383+
let lines = OS.Cmd.(run_out ~err:err_run_out cmd |> to_lines) |> get_ok in
384+
if not ignore_output then
385+
add_prefixed_output cmd source_tree_output (Fpath.to_string file) lines
386+
387+
let odoc_source_tree = Fpath.v "src-source.odoc"
381388
382389
let source_dir_of_odoc_lib lib =
383390
match String.split_on_char '_' lib with
@@ -412,101 +419,15 @@ let source_files_of_odoc_module lib module_ =
412419
in
413420
find_by_extension relpath [ "pp.ml"; "ml" ]
414421
415-
let source_mld title filenames =
416-
let title = Format.asprintf "{0 %s}" title in
417-
let filenames =
418-
Fpath.Set.fold
419-
(fun filename acc ->
420-
if Fpath.is_dir_path filename then
421-
let name = Fpath.basename filename ^ "/index.html" in
422-
Format.asprintf
423-
{html|- {%%html: <svg aria-label="Directory" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true"><path d="M1.75 1A1.75 1.75 0 000 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0016 13.25v-8.5A1.75 1.75 0 0014.25 3H7.5a.25.25 0 01-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75z"></path></svg> <a href="%s">%s</a>%%}|html}
424-
name (Fpath.basename filename)
425-
:: acc
426-
else
427-
let name = Fpath.basename filename ^ ".html" in
428-
Format.asprintf
429-
{html|- {%%html: <svg height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true"><path fill-rule="evenodd" d="M3.75 1.5a.25.25 0 00-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 00.25-.25V6h-2.75A1.75 1.75 0 019 4.25V1.5H3.75zm6.75.062V4.25c0 .138.112.25.25.25h2.688a.252.252 0 00-.011-.013l-2.914-2.914a.272.272 0 00-.013-.011zM2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0113.25 16h-9.5A1.75 1.75 0 012 14.25V1.75z"></path></svg> <a href="%s">%s</a>%%}|html}
430-
name (Fpath.basename filename)
431-
:: acc)
432-
filenames []
422+
let compile_source_tree units =
423+
let sources =
424+
List.filter_map (fun (_, _, _, file) -> Option.map Fpath.to_string file) units
433425
in
434-
Format.sprintf "%s\n\n%s\n" title (String.concat "\n" filenames)
435-
436-
let source_mlds_of_units units =
437-
let module M = Map.Make (Fpath) in
438-
let multi_map_add key v map =
439-
M.update key
440-
(fun set ->
441-
let set = match set with None -> Fpath.Set.empty | Some set -> set in
442-
Some (Fpath.Set.add v set))
443-
map
444-
in
445-
let rec add_path map path =
446-
if Fpath.is_current_dir path then map
447-
else
448-
let parent, _ = Fpath.split_base path in
449-
let map = multi_map_add parent path map in
450-
add_path map parent
451-
in
452-
List.fold_left
453-
(fun map (_, _, _, file) ->
454-
match file with None -> map | Some file -> add_path map file)
455-
M.empty units
456-
457-
let compile_src_mlds units =
458-
let mlds = source_mlds_of_units units in
459-
let module M = Map.Make (Fpath) in
460-
let mld_name lib =
461-
if Fpath.is_current_dir lib then "source" else Fpath.basename lib
462-
in
463-
let title lib =
464-
if Fpath.is_current_dir lib then "source" else Fpath.to_string lib
465-
in
466-
let parent_search_path lib =
467-
if Fpath.is_current_dir lib then [ source_folder ]
468-
else [ Fpath.( // ) source_folder (Fpath.parent lib) ]
469-
in
470-
let rec traverse_parent parent lib acc =
471-
if Fpath.is_dir_path lib then
472-
match M.find_opt lib mlds with
473-
| None -> []
474-
| Some set ->
475-
let path = Fpath.(source_folder // lib / (mld_name lib ^ ".mld")) in
476-
let mld_content = source_mld (title lib) set in
477-
let _was_created = Bos.OS.Dir.create (Fpath.parent path) |> get_ok in
478-
let () = Bos.OS.File.write path mld_content |> get_ok in
479-
let () =
480-
let children =
481-
match
482-
set |> Fpath.Set.to_seq |> List.of_seq
483-
|> List.filter_map (fun p ->
484-
if Fpath.is_dir_path p then Some (mld_name p) else None)
485-
with
486-
| [] ->
487-
[ "dummy" ]
488-
(* Needed to have the mld rendered as [name/index.html] *)
489-
| a -> a
490-
in
491-
compile ?parent ~search_path:(parent_search_path lib)
492-
~output_dir:(Fpath.parent path) path children
493-
in
494-
let acc =
495-
[
496-
( Fpath.(source_folder // lib / ("page-" ^ mld_name lib ^ ".odoc")),
497-
false,
498-
None );
499-
]
500-
:: acc
501-
in
502-
Fpath.Set.fold
503-
(fun path acc ->
504-
traverse_parent (Some (mld_name lib)) path [] :: acc)
505-
set acc
506-
|> List.flatten
507-
else []
508-
in
509-
traverse_parent (Some "odoc") (Fpath.v "./") []
426+
let source_map = Fpath.v "source_tree.map" in
427+
let () = Bos.OS.File.write_lines source_map sources |> get_ok in
428+
let () = source_tree ~parent:"odoc" ~output:odoc_source_tree source_map in
429+
(odoc_source_tree, false, None)
430+
510431
```
511432

512433
Let's now put together a list of all possible modules. We'll keep track of
@@ -554,7 +475,7 @@ let compile_mlds () =
554475
let mkmld x = Fpath.(add_ext "mld" (v x)) in
555476
ignore
556477
(compile (mkmld "odoc")
557-
("page-source" :: "page-deps" :: List.map mkpage (odoc_libraries @ extra_docs)));
478+
("src-source" :: "page-deps" :: List.map mkpage (odoc_libraries @ extra_docs)));
558479
ignore (compile (mkmld "deps") ~parent:"odoc" (List.map mkpage dep_libraries));
559480
let extra_odocs =
560481
List.map
@@ -588,18 +509,9 @@ Now we get to the compilation phase. For each unit, we query its dependencies, t
588509
```ocaml env=e1
589510
let compile_all () =
590511
let mld_odocs = compile_mlds () in
591-
let src_mlds = compile_src_mlds all_units in
592-
let source_args = function
593-
| None -> None
594-
| Some source_relpath ->
595-
let source_parent_name =
596-
Format.sprintf "page-%s.odoc"
597-
(source_relpath |> Fpath.parent |> Fpath.basename)
598-
in
599-
let source_parent_file =
600-
Fpath.(v "source_mlds" // parent source_relpath / source_parent_name)
601-
and source_name = Fpath.basename source_relpath in
602-
Some (source_name, source_parent_file)
512+
let source_tree = compile_source_tree all_units in
513+
let source_args =
514+
Option.map (fun source_relpath -> (source_relpath, odoc_source_tree))
603515
in
604516
let rec rec_compile ?impl parent lib file =
605517
let output = Fpath.(base (set_ext "odoc" file)) in
@@ -626,11 +538,12 @@ let compile_all () =
626538
compile file ~parent:lib ?source_args ~ignore_output [];
627539
(output, ignore_output, impl) :: files
628540
in
629-
List.fold_left
541+
source_tree
542+
:: List.fold_left
630543
(fun acc (parent, lib, dep, impl) ->
631544
acc @ rec_compile ?impl parent lib (best_file dep))
632545
[] all_units
633-
@ mld_odocs @ src_mlds
546+
@ mld_odocs
634547
```
635548

636549
Linking is now straightforward. We link all `odoc` files.
@@ -699,6 +612,7 @@ Let's see if there was any output from the `odoc` invocations:
699612
"page-stdlib.odoc: Warning: Failed to resolve reference unresolvedroot(Available_regs) Parent_module: Lookup failure (root module): Available_regs";
700613
"page-stdlib.odoc: File \"library_mlds/stdlib.mld\", line 9, characters 0-22:";
701614
"page-stdlib.odoc: Warning: Failed to resolve reference unresolvedroot(Arith_status) Parent_module: Lookup failure (root module): Arith_status"]
615+
# !source_tree_output;;
702616
# !generate_output;;
703617
- : string list =
704618
["";
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{0 odoc_html_support_files}
2+
3+
{!childmodule-Odoc_html_support_files}

src/odoc/compile.ml

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,21 @@ let is_module_name n = String.length n > 0 && Char.Ascii.is_upper n.[0]
5252
5353
- [page-foo] child is a container or leaf page.
5454
- [module-Foo] child is a module.
55-
- [module-foo], [Foo] child is a module, for backward compatibility. *)
55+
- [module-foo], [Foo] child is a module, for backward compatibility.
56+
57+
Parses [...-"foo"] as [...-foo] for backward compatibility. *)
5658
let parse_parent_child_reference s =
59+
let unquote s =
60+
let len = String.length s in
61+
if String.head s = Some '"' && String.head ~rev:true s = Some '"' && len > 1
62+
then String.with_range ~first:1 ~len:(len - 2) s
63+
else s
64+
in
5765
match String.cut ~sep:"-" s with
58-
| Some ("page", n) -> Ok (Lang.Page.Page_child n)
59-
| Some ("src", n) -> Ok (Source_tree_child n)
60-
| Some ("module", n) -> Ok (Module_child (String.Ascii.capitalize n))
66+
| Some ("page", n) -> Ok (Lang.Page.Page_child (unquote n))
67+
| Some ("src", n) -> Ok (Source_tree_child (unquote n))
68+
| Some ("module", n) ->
69+
Ok (Module_child (unquote (String.Ascii.capitalize n)))
6170
| Some (k, _) -> Error (`Msg ("Unrecognized kind: " ^ k))
6271
| None -> if is_module_name s then Ok (Module_child s) else Ok (Page_child s)
6372

0 commit comments

Comments
 (0)