---
lib/forest/Forest_graph.mli | 3 ++-lib/forest/Forester_forest.ml | 1 +lib/forest/Graphviz_client.ml | 21 +++++++++++++++++++++lib/frontend/Forester.ml | 11 ++++++++++-
4 files changed, 34 insertions(+), 2 deletions(-)
create mode 100644 lib/forest/Graphviz_client.ml
diff --git a/lib/forest/Forest_graph.mli b/lib/forest/Forest_graph.mli
index 33f50f3..75a26ab 100644
--- a/lib/forest/Forest_graph.mli+++ b/lib/forest/Forest_graph.mli
@@ -1,6 +1,7 @@
open Forester_core
-type t+include module type of Graph.Imperative.Digraph.ConcreteBidirectional(Vertex)+type t = Graph.Imperative.Digraph.ConcreteBidirectional(Forester_core.Vertex).tval create : ?size: int -> unit -> t
val add_vertex : t -> Vertex.t -> unit
diff --git a/lib/forest/Forester_forest.ml b/lib/forest/Forester_forest.ml
index af54007..22831fb 100644
--- a/lib/forest/Forester_forest.ml+++ b/lib/forest/Forester_forest.ml
@@ -3,5 +3,6 @@ module Forest = Forest
module Forest_util = Forest_util
module Legacy_xml_client = Legacy_xml_client
module Plain_text_client = Plain_text_client
+module Graphviz_client = Graphviz_clientmodule Render_json = Render_json
diff --git a/lib/forest/Graphviz_client.ml b/lib/forest/Graphviz_client.ml
new file mode 100644
index 0000000..19daf4c
--- /dev/null+++ b/lib/forest/Graphviz_client.ml
@@ -0,0 +1,21 @@
+open Forester_core++module G = struct+ include Forest_graph++ let vertex_name v =+ match Vertex.iri_of_vertex v with+ | Some iri -> "\"" ^ Iri.to_string iri ^ "\""+ | None -> ""++ let graph_attributes _ = []+ let default_vertex_attributes _ = []+ let vertex_attributes _ = []+ let default_edge_attributes _ = []+ let edge_attributes e = [ `Label "" ]+ let get_subgraph _ = None+end++module Make (F: Forest.S) () = struct+ module Dot = Graph.Graphviz.Dot(G)+end
diff --git a/lib/frontend/Forester.ml b/lib/frontend/Forester.ml
index 4fde55b..fcfd591 100644
--- a/lib/frontend/Forester.ml+++ b/lib/frontend/Forester.ml
@@ -5,7 +5,8 @@ open Forester_compiler
module M = Iri_map
module T = Xml_tree
-module F = Forest.Make(Forest_graphs.Make ())+module FG = Forest_graphs.Make ()+module F = Forest.Make(FG)module FU = Forest_util.Make(F)
module PT = Plain_text_client.Make(F)
module C = T.Comparators(PT)
@@ -144,10 +145,18 @@ let json_manifest ~host ~home ~dev : string =
let render_forest ~env ~dev ~host ~home ~stylesheet : unit =
let module P = struct let host = host let home = home end in
let module Client = Legacy_xml_client.Make(P)(F)() in
+ let module Graph_client = Graphviz_client.Make(F)() in let module R = Render_json.Make(Client)(F) in
let@ () = Reporter.profile "Render forest" in
let cwd = Eio.Stdenv.cwd env in
let all_articles = FU.get_all_articles () in
+ begin+ let@ () = Reporter.profile "Render graph" in+ let transclusion_graph = FG.get_rel Edges Query.Rel.transclusion in+ (* TODO: Use Eio for this *)+ let out = open_out "output/graph.dot" in+ Graph_client.Dot.output_graph out transclusion_graph+ end; begin
let json_string = Yojson.Basic.to_string @@ R.render_trees ~dev ~host all_articles in
let json_path = EP.(cwd / output_dir_name / "forest.json") in
--
2.46.0
Hi Kento,
This is pretty cool, and it seems like a good feature to add.
On 1 Oct 2024, at 10:28, Kento Okura wrote:
> ---> lib/forest/Forest_graph.mli | 3 ++-> lib/forest/Forester_forest.ml | 1 +> lib/forest/Graphviz_client.ml | 21 +++++++++++++++++++++> lib/frontend/Forester.ml | 11 ++++++++++-> 4 files changed, 34 insertions(+), 2 deletions(-)> create mode 100644 lib/forest/Graphviz_client.ml>> diff --git a/lib/forest/Forest_graph.mli b/lib/forest/Forest_graph.mli> index 33f50f3..75a26ab 100644> --- a/lib/forest/Forest_graph.mli> +++ b/lib/forest/Forest_graph.mli> @@ -1,6 +1,7 @@> open Forester_core>> -type t> +include module type of > Graph.Imperative.Digraph.ConcreteBidirectional(Vertex)> +type t = > Graph.Imperative.Digraph.ConcreteBidirectional(Forester_core.Vertex).t
I wonder if for now, it would be possible to just hide whatever things
we need inside this module rather than exposing the type. The reason is
that, although the ocamlgraph library is really good, I want to limit
the dependency on it to some key features that we use.
>> val create : ?size: int -> unit -> t> val add_vertex : t -> Vertex.t -> unit> diff --git a/lib/forest/Forester_forest.ml > b/lib/forest/Forester_forest.ml> index af54007..22831fb 100644> --- a/lib/forest/Forester_forest.ml> +++ b/lib/forest/Forester_forest.ml> @@ -3,5 +3,6 @@ module Forest = Forest> module Forest_util = Forest_util> module Legacy_xml_client = Legacy_xml_client> module Plain_text_client = Plain_text_client> +module Graphviz_client = Graphviz_client>> module Render_json = Render_json> diff --git a/lib/forest/Graphviz_client.ml > b/lib/forest/Graphviz_client.ml> new file mode 100644> index 0000000..19daf4c> --- /dev/null> +++ b/lib/forest/Graphviz_client.ml> @@ -0,0 +1,21 @@> +open Forester_core> +> +module G = struct> + include Forest_graph> +> + let vertex_name v => + match Vertex.iri_of_vertex v with> + | Some iri -> "\"" ^ Iri.to_string iri ^ "\""> + | None -> ""> +> + let graph_attributes _ = []> + let default_vertex_attributes _ = []> + let vertex_attributes _ = []> + let default_edge_attributes _ = []> + let edge_attributes e = [ `Label "" ]> + let get_subgraph _ = None> +end> +> +module Make (F: Forest.S) () = struct> + module Dot = Graph.Graphviz.Dot(G)> +end> diff --git a/lib/frontend/Forester.ml b/lib/frontend/Forester.ml> index 4fde55b..fcfd591 100644> --- a/lib/frontend/Forester.ml> +++ b/lib/frontend/Forester.ml> @@ -5,7 +5,8 @@ open Forester_compiler>> module M = Iri_map> module T = Xml_tree> -module F = Forest.Make(Forest_graphs.Make ())> +module FG = Forest_graphs.Make ()> +module F = Forest.Make(FG)> module FU = Forest_util.Make(F)> module PT = Plain_text_client.Make(F)> module C = T.Comparators(PT)> @@ -144,10 +145,18 @@ let json_manifest ~host ~home ~dev : string => let render_forest ~env ~dev ~host ~home ~stylesheet : unit => let module P = struct let host = host let home = home end in> let module Client = Legacy_xml_client.Make(P)(F)() in> + let module Graph_client = Graphviz_client.Make(F)() in> let module R = Render_json.Make(Client)(F) in> let@ () = Reporter.profile "Render forest" in> let cwd = Eio.Stdenv.cwd env in> let all_articles = FU.get_all_articles () in> + begin> + let@ () = Reporter.profile "Render graph" in> + let transclusion_graph = FG.get_rel Edges Query.Rel.transclusion > in> + (* TODO: Use Eio for this *)> + let out = open_out "output/graph.dot" in> + Graph_client.Dot.output_graph out transclusion_graph> + end;> begin> let json_string = Yojson.Basic.to_string @@ R.render_trees ~dev > ~host all_articles in> let json_path = EP.(cwd / output_dir_name / "forest.json") in> -- > 2.46.0