package ocamlgraph
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
A generic graph library for OCaml
Install
dune-project
Dependency
Authors
Maintainers
Sources
ocamlgraph-2.2.0.tbz
sha256=b0956210863cc24f480203ba3c2ef06dfae5579536a05744364e7de58822b230
sha512=257cdd5fb90337b3e3682cade1269c1d181f3124e569a731909f49bbfbe581ab529ac401472fb9ef57166ac34d8ebadfa6a32c93665f38f5a335982d5e5dc0e1
doc/src/ocamlgraph/dot.ml.html
Source file dot.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215(**************************************************************************) (* *) (* Ocamlgraph: a generic graph library for OCaml *) (* Copyright (C) 2004-2010 *) (* Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles *) (* *) (* This software is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Library General Public *) (* License version 2.1, with the special exception on linking *) (* described in file LICENSE. *) (* *) (* This software is distributed in the hope that it will be useful, *) (* but WITHOUT ANY WARRANTY; without even the implied warranty of *) (* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *) (* *) (**************************************************************************) (** Parser for DOT file format *) open Dot_ast let parse_dot_ast_from_chan c = let lb = Lexing.from_channel c in let dot = try Dot_parser.file Dot_lexer.token lb with Parsing.Parse_error -> let n = Lexing.lexeme_start lb in failwith (Printf.sprintf "Dot.parse: parse error character %d" n) in close_in c; dot let parse_dot_ast f = let c = open_in f in parse_dot_ast_from_chan c type clusters_hash = (string, attr list) Hashtbl.t let get_string = function | String s -> s | Ident s -> s | Number s -> s | Html s -> s module Parse (B : Builder.S) (L : sig val node : node_id -> attr list -> B.G.V.label (** how to build the node label out of the set of attributes *) val edge : attr list -> B.G.E.label (** how to build the edge label out of the set of attributes *) end) = struct module Attr = struct module M = Map.Make (struct type t = id let compare : t -> t -> int = Stdlib.compare end) let empty = M.empty let add = List.fold_left (fun a (x,v) -> M.add x v a) let addl = List.fold_left add let list a = M.fold (fun x v l -> (x,v) :: l) a [] end let create_graph_and_clusters dot = (* pass 1*) (* collect node attributes *) let def_node_attr = ref Attr.empty in let node_attr = Hashtbl.create 97 in (* collect cluster attributes *) let def_clust_attr = ref Attr.empty in let clust_attr = Hashtbl.create 97 in (* collect clusters nodes *) let clust_nodes = Hashtbl.create 97 in let add_node_attr id al = let l = try Hashtbl.find node_attr id with Not_found -> !def_node_attr in Hashtbl.replace node_attr id (Attr.addl l al) in let add_clust_attr id_opt al = match id_opt with | Some id -> let s = get_string id in let l = try Hashtbl.find clust_attr s with Not_found -> !def_clust_attr in Hashtbl.replace clust_attr s (Attr.addl l al) | _ -> () in let add_clust_node id_cluster id_node = let id_nodes = try Hashtbl.find clust_nodes id_cluster with Not_found -> [] in Hashtbl.add clust_nodes id_cluster (id_node :: id_nodes) in let rec collect_node_attr cluster_op stmts = List.iter ( function | Node_stmt (id, al) -> add_node_attr id al; begin match cluster_op with | Some id_cluster -> add_clust_node id_cluster id | _ -> () end | Attr_node al -> def_node_attr := Attr.addl !def_node_attr al | Edge_stmt (NodeId id, nl, _) -> add_node_attr id []; List.iter (function | NodeId id -> add_node_attr id [] | _ -> ()) nl | Subgraph (SubgraphDef (id, stmts)) -> collect_node_attr (Some id) stmts | Attr_graph al -> begin match cluster_op with | Some id -> add_clust_attr id al | None -> () end | _ -> () ) stmts in collect_node_attr None dot.stmts; (* pass 2: build the graph and the clusters *) let def_edge_attr = ref Attr.empty in let nodes = Hashtbl.create 97 in let node g id _ = try g, Hashtbl.find nodes id with Not_found -> let l = try Hashtbl.find node_attr id with Not_found -> Attr.empty in let n = B.G.V.create (L.node id [Attr.list l]) in Hashtbl.add nodes id n; B.add_vertex g n, n in let rec add_stmts g stmts = List.fold_left (fun g s -> match s with | Node_stmt (id, al) -> let g,_ = node g id al in g | Edge_stmt (NodeId id, nl, al) -> let al = Attr.addl !def_edge_attr al in let el = L.edge [Attr.list al] in let g,vn = node g id [] in fst (List.fold_left (fun (g,pvn) m -> match m with | NodeId idm -> let g,vm = node g idm [] in let e = B.G.E.create pvn el vm in ((B.add_edge_e g e),vm) | NodeSub _ -> (g,pvn)) (g,vn) nl) | Attr_edge al -> def_edge_attr := Attr.addl !def_edge_attr al; g | Subgraph (SubgraphDef (_, stmts)) -> add_stmts g stmts | _ -> g ) g stmts in let graph = add_stmts (B.empty ()) dot.stmts in let clusters_hash = let h = Hashtbl.create 30 in Hashtbl.iter (fun k a -> Hashtbl.add h k [Attr.list a]) clust_attr; h in graph, clusters_hash let get_graph_bb stmts = let graph_bb = ref None in let read_attr = function | (Ident "bb" , Some (String bb)) -> graph_bb := Some bb | _ -> () in let read_stmt = function | Attr_graph attrs -> List.iter (List.iter read_attr) attrs | _ -> () in List.iter read_stmt stmts; !graph_bb let parse_dot_from_chan c = let lb = Lexing.from_channel c in let dot = try Dot_parser.file Dot_lexer.token lb with Parsing.Parse_error -> let n = Lexing.lexeme_start lb in failwith (Printf.sprintf "Dot.parse: parse error character %d" n) in close_in c; dot let parse_dot f = let c = open_in f in parse_dot_from_chan c let parse f = fst (create_graph_and_clusters (parse_dot f)) let parse_bounding_box_and_clusters f = let dot = parse_dot f in let graph, clusters = create_graph_and_clusters dot in match get_graph_bb dot.stmts with | Some bounding_box -> graph, bounding_box, clusters | None -> failwith "Cannot read bounding box in xdot file" end
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>