~jonsterling/forester-devel

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
2 2

[PATCH v2] DRAFT: Emit graphviz file for visualization

Details
Message ID
<20241001092904.45201-1-kentookura@gmail.com>
DKIM signature
pass
Download raw message
Patch: +34 -2
---
 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

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
Details
Message ID
<D4KEG45VV7O1.19WQX5LJU1Z6R@gmail.com>
In-Reply-To
<20241001092904.45201-1-kentookura@gmail.com> (view parent)
DKIM signature
pass
Download raw message
You can paste the output into here

https://dreampuf.github.io/GraphvizOnline/#

and select the "fdp" layout engine to get an obsidian-like graph view of
your forest!

On Tue Oct 1, 2024 at 11:28 AM CEST, 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
>  
>  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
Details
Message ID
<3BF3681D-048A-4899-A06D-AFF54E9F17D7@jonmsterling.com>
In-Reply-To
<20241001092904.45201-1-kentookura@gmail.com> (view parent)
DKIM signature
pass
Download raw message
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
Reply to thread Export thread (mbox)