123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951(**************************************************************************)(* *)(* 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. *)(* *)(**************************************************************************)(** Interface with {i GraphViz}
This module provides a basic interface with dot and neato,
two programs of the GraphViz toolbox.
These tools are available at the following URLs:
http://www.graphviz.org/
http://www.research.att.com/sw/tools/graphviz/ *)openFormat(***************************************************************************)(** {2 Common stuff} *)(** Because the neato and dot engines present a lot of common points -
in particular in the graph description language, large parts of
the code is shared. First, the [!CommonAttributes] module defines
attributes of graphs, nodes and edges that are understood by the
two engines. Second, given a module (of type [!ENGINE])
describing an engine the [!MakeEngine] functor provides suitable
interface function for it. *)(*-------------------------------------------------------------------------*)(** {3 Common attributes} *)typecolor=inttypecolor_with_transparency=int32letcolor_to_color_with_transparencycolor=Int32.add(Int32.shift_left(Int32.of_intcolor)8)0xFFlletfprint_colorppfcolor=fprintfppf"\"#%06X\""colorletfprint_color_with_transparencyppfcolor=fprintfppf"\"#%08lX\""colorletfprint_stringppfs=fprintfppf"\"%s\""s(* let s' = String.escaped s in
if s' = s && s <> ""
then fprintf ppf "%s" s
else fprintf ppf "\"%s\"" s'*)letfprint_string_userppfs=(* let s = String.escaped s in*)fprintfppf"\"%s\""sletfprint_htmlstring_userppfs=fprintfppf"<%s>"sletfprint_square_not_emptyprinterppf=function|[]->()|l->fprintfppf" [%a]"printerltypearrow_style=[`None|`Normal|`Onormal|`Inv|`Dot|`Odot|`Invdot|`Invodot]letfprint_arrow_styleppf=function`None->fprintfppf"none"|`Normal->fprintfppf"normal"|`Onormal->fprintfppf"onormal"|`Inv->fprintfppf"inv"|`Dot->fprintfppf"dot"|`Odot->fprintfppf"odot"|`Invdot->fprintfppf"invdot"|`Invodot->fprintfppf"invodot"letfprint_dirppf=function`TopToBottom->fprintfppf"TB"|`BottomToTop->fprintfppf"BT"|`LeftToRight->fprintfppf"LR"|`RightToLeft->fprintfppf"RL"typesymbseq=|COMMA|SEMIletfprint_symbseqppf=function|COMMA->pp_print_stringppf","|SEMI->pp_print_stringppf";"(** The [ATTRIBUTES] module type defines the interface for the engines. *)moduletypeATTRIBUTES=sigtypegraph(** Attributes of graphs. *)typevertex(** Attributes of vertices. *)typeedge(** Attributes of edges. *)(** Attributes of (optional) boxes around vertices. *)typesubgraph={sg_name:string;(** Box name. *)sg_attributes:vertexlist;(** Box attributes. *)sg_parent:stringoption;(** Nested subgraphs. *)}end(** The [CommonAttributes] module defines attributes for graphs, nodes and
edges that are available in the two engines, dot and neato. *)moduleCommonAttributes=struct(** Attributes of graphs. *)typegraph=[`Centerofbool(** Centers the drawing on the page. Default value is [false]. *)|`Fontcolorofcolor(** Sets the font color. Default value is [black]. *)|`Fontnameofstring(** Sets the font family name. Default value is ["Times-Roman"]. *)|`Fontsizeofint(** Sets the type size (in points). Default value is [14]. *)|`Labelofstring(** Caption for graph drawing. *)|`HtmlLabelofstring|`Orientationof[`Portrait|`Landscape](** Sets the page orientation. Default value is [`Portrait]. *)|`Pageoffloat*float(** Sets the PostScript pagination unit, e.g [8.5, 11.0]. *)|`Pagedirof[`TopToBottom|`LeftToRight](** Traversal order of pages. Default value is [`TopToBottom]. *)|`Sizeoffloat*float(** Sets the bounding box of drawing (in inches). *)|`OrderingOut(** Constrains order of out-edges in a subgraph according to
their file sequence *)](** Attributes of nodes. *)typevertex=[`Colorofcolor(** Sets the color of the border of the node. Default value is [black]
*)|`ColorWithTransparencyofcolor_with_transparency(** Sets the color of the border of the vertex with a transparency
component. Default value is fully opaque [black] *)|`Fontcolorofcolor(** Sets the label font color. Default value is [black]. *)|`Fontnameofstring(** Sets the label font family name. Default value is
["Times-Roman"]. *)|`Fontsizeofint(** Sets the label type size (in points). Default value is [14]. *)|`Heightoffloat(** Sets the minimum height. Default value is [0.5]. *)|`Labelofstring(** Sets the label printed in the node. The string may include escaped
newlines [\n], [\l], or [\r] for center, left, and right justified
lines.
Record labels may contain recursive box lists delimited by { | }.
*)|`HtmlLabelofstring|`Orientationoffloat(** Node rotation angle, in degrees. Default value is [0.0]. *)|`Penwidthoffloat(** Width of the pen (in points) used to draw the border of the node.
Default value is [1.0]. *)|`Peripheriesofint(** Sets the number of periphery lines drawn around the polygon. *)|`Regularofbool(** If [true], then the polygon is made regular, i.e. symmetric about
the x and y axis, otherwise the polygon takes on the aspect
ratio of the label. Default value is [false]. *)|`Shapeof[`Ellipse|`Box|`Circle|`Doublecircle|`Diamond|`Oval|`Egg|`Triangle|`Invtriangle|`Trapezium|`Invtrapezium|`House|`Invhouse|`Parallelogram|`Doubleoctagon|`Tripleoctagon|`Mdiamond|`Mcircle|`Msquare|`Star|`Underline|`Note|`Tab|`Folder|`Box3d|`Component|`Promoter|`Cds|`Terminator|`Utr|`Primersite|`Restrictionsite|`Fivepoverhang|`Threepoverhang|`Noverhang|`Assembly|`Signature|`Insulator|`Ribosite|`Rnastab|`Proteasesite|`Proteinstab|`Rpromoter|`Rarrow|`Larrow|`Lpromoter|`Plaintext|`Record|`Polygonofint*float](** Sets the shape of the node. Default value is [`Ellipse].
[`Polygon (i, f)] draws a polygon with [n] sides and a skewing
of [f]. *)|`Styleof[`Rounded|`Filled|`Solid|`Dashed|`Dotted|`Bold|`Invis](** Sets the layout style of the node. Several styles may be combined
simultaneously. *)|`Widthoffloat(** Sets the minimum width. Default value is [0.75]. *)](** Attributes of edges. *)typeedge=[`Colorofcolor(** Sets the edge stroke color. Default value is [black]. *)|`ColorWithTransparencyofcolor_with_transparency(** Sets the color of the border of the vertex with a transparency
component. Default value is fully opaque [black] *)|`Decorateofbool(** If [true], draws a line connecting labels with their edges. *)|`Dirof[`Forward|`Back|`Both|`None](** Sets arrow direction. Default value is [`Forward]. *)|`Fontcolorofcolor(** Sets the label font color. Default value is [black]. *)|`Fontnameofstring(** Sets the label font family name. Default value is
["Times-Roman"]. *)|`Fontsizeofint(** Sets the label type size (in points). Default value is [14]. *)|`Labelofstring(** Sets the label to be attached to the edge. The string may include
escaped newlines [\n], [\l], or [\r] for centered, left, or right
justified lines. *)|`HtmlLabelofstring|`Labelfontcolorofcolor(** Sets the font color for head and tail labels. Default value is
[black]. *)|`Labelfontnameofstring(** Sets the font family name for head and tail labels. Default
value is ["Times-Roman"]. *)|`Labelfontsizeofint(** Sets the font size for head and tail labels (in points).
Default value is [14]. *)|`Penwidthoffloat(** Width of the pen (in points) used to draw the edge. Default value
is [1.0]. *)|`Styleof[`Solid|`Dashed|`Dotted|`Bold|`Invis](** Sets the layout style of the edge. Several styles may be combined
simultaneously. *)](** Pretty-print. *)letfprint_orientationppf=function`Portrait->fprintfppf"portrait"|`Landscape->fprintfppf"landscape"letfprint_graphppf=function`Centerb->fprintfppf"center=%i"(ifbthen1else0)|`Fontcolora->fprintfppf"fontcolor=%a"fprint_colora|`Fontnames->fprintfppf"fontname=%a"fprint_strings|`Fontsizei->fprintfppf"fontsize=%i"i|`Labels->fprintfppf"label=%a"fprint_string_users|`HtmlLabels->fprintfppf"label=%a"fprint_htmlstring_users|`Orientationa->fprintfppf"orientation=%a"fprint_orientationa|`Page(x,y)->fprintfppf"page=\"%f,%f\""xy|`Pagedira->fprintfppf"pagedir=%a"fprint_dira|`Size(x,y)->fprintfppf"size=\"%f,%f\""xy|`OrderingOut->fprintfppf"ordering=out"letfprint_shapeppf=function|`Ellipse->fprintfppf"ellipse"|`Box->fprintfppf"box"|`Circle->fprintfppf"circle"|`Doublecircle->fprintfppf"doublecircle"|`Diamond->fprintfppf"diamond"|`Plaintext->fprintfppf"plaintext"|`Record->fprintfppf"record"|`Egg->fprintfppf"egg"|`House->fprintfppf"house"|`Invhouse->fprintfppf"invhouse"|`Trapezium->fprintfppf"trapezium"|`Invtrapezium->fprintfppf"invtrapezium"|`Triangle->fprintfppf"triangle"|`Invtriangle->fprintfppf"invtriangle"|`Oval->fprintfppf"oval"|`Assembly->fprintfppf"assembly"|`Box3d->fprintfppf"box3d"|`Cds->fprintfppf"cds"|`Component->fprintfppf"component"|`Doubleoctagon->fprintfppf"doubleoctagon"|`Fivepoverhang->fprintfppf"fivepoverhang"|`Folder->fprintfppf"folder"|`Insulator->fprintfppf"insulator"|`Larrow->fprintfppf"larrow"|`Lpromoter->fprintfppf"lpromoter"|`Mcircle->fprintfppf"mcircle"|`Mdiamond->fprintfppf"mdiamond"|`Msquare->fprintfppf" msquare"|`Note->fprintfppf"note"|`Noverhang->fprintfppf"noverhang"|`Parallelogram->fprintfppf"parallelogram"|`Primersite->fprintfppf"primersite"|`Promoter->fprintfppf"promoter"|`Proteasesite->fprintfppf"proteasesite"|`Proteinstab->fprintfppf"proteinstab"|`Rarrow->fprintfppf"rarrow"|`Restrictionsite->fprintfppf"restrictionsite"|`Ribosite->fprintfppf"ribosite"|`Rnastab->fprintfppf"rnastab"|`Rpromoter->fprintfppf"rpromoter"|`Signature->fprintfppf"signature"|`Star->fprintfppf"star"|`Tab->fprintfppf"tab"|`Terminator->fprintfppf"terminator"|`Threepoverhang->fprintfppf"threepoverhang"|`Tripleoctagon->fprintfppf"tripleoctagon"|`Underline->fprintfppf"underline"|`Utr->fprintfppf"utr"|`Polygon(i,f)->fprintfppf"polygon, sides=%i, skew=%f"ifletrecfprint_string_listppf=function|[]->()|[hd]->fprintfppf"%s"hd|hd::tl->fprintfppf"%s,%a"hdfprint_string_listtlletnode_style_str=function|`Rounded->"rounded"|`Filled->"filled"|`Solid->"solid"|`Dashed->"dashed"|`Dotted->"dotted"|`Bold->"bold"|`Invis->"invis"letfprint_style_listsepppfa=fprintfppf"style=\"%a\"%a@ "fprint_string_list(List.mapnode_style_stra)fprint_symbseqsepletfprint_vertexppf=function|`Colora->fprintfppf"color=%a"fprint_colora|`ColorWithTransparencya->fprintfppf"color=%a"fprint_color_with_transparencya|`Fontcolora->fprintfppf"fontcolor=%a"fprint_colora|`Fontnames->fprintfppf"fontname=%a"fprint_strings|`Fontsizei->fprintfppf"fontsize=%i"i|`Heightf->fprintfppf"height=%f"f|`Labels->fprintfppf"label=%a"fprint_string_users|`HtmlLabels->fprintfppf"label=%a"fprint_htmlstring_users|`Orientationf->fprintfppf"orientation=%f"f|`Penwidthf->fprintfppf"penwidth=%f"f|`Peripheriesi->fprintfppf"peripheries=%i"i|`Regularb->fprintfppf"regular=%b"b|`Shapea->fprintfppf"shape=%a"fprint_shapea|`Style_->assertfalse|`Widthf->fprintfppf"width=%f"fletfprint_arrow_directionppf=function`Forward->fprintfppf"forward"|`Back->fprintfppf"back"|`Both->fprintfppf"both"|`None->fprintfppf"none"letfprint_edgeppf=function|`Colora->fprintfppf"color=%a"fprint_colora|`ColorWithTransparencya->fprintfppf"color=%a"fprint_color_with_transparencya|`Decorateb->fprintfppf"decorate=%b"b|`Dira->fprintfppf"dir=%a"fprint_arrow_directiona|`Fontcolora->fprintfppf"fontcolor=%a"fprint_colora|`Fontnames->fprintfppf"fontname=%a"fprint_strings|`Fontsizei->fprintfppf"fontsize=%i"i|`Labels->fprintfppf"label=%a"fprint_string_users|`HtmlLabels->fprintfppf"label=%a"fprint_htmlstring_users|`Labelfontcolora->fprintfppf"labelfontcolor=%a"fprint_colora|`Labelfontnames->fprintfppf"labelfontname=\"%s\""s(* (String.escaped s) *)|`Labelfontsizei->fprintfppf"labelfontsize=%i"i|`Penwidthf->fprintfppf"penwidth=%f"f|`Style_->assertfalseletrecfilter_stylealsll=matchlwith|[]->al,sl|`Styles::l->filter_styleal(s::sl)l|a::l->filter_style(a::al)sll(** [fprint_graph_attribute printer ppf list] pretty prints a list of
attributes on the formatter [ppf], using the printer [printer] for
each attribute. The list appears between brackets and attributes
are speparated by ",". If the list is empty, nothing is printed. *)letfprint_attributesfprint_style_listfprint_attributesepppflist=iflist<>[]thenbeginletlist,styles=filter_style[][]listinletrecfprint_attributes_recppf=function|[]->()|hd::tl->fprintfppf"%a%a@ "fprint_attributehdfprint_symbseqsep;fprint_attributes_recppftlinfprintfppf"@[<hov>%a"fprint_attributes_reclist;ifstyles<>[]thenbeginfprint_style_listsepppfstylesend;fprintfppf"@]"endend(*-------------------------------------------------------------------------*)(** {3 The [MakeEngine] functor} *)(** An engine is described by a module of the following signature. *)moduletypeENGINE=sigmoduleAttributes:sigincludeATTRIBUTESvalfprint_graph:formatter->graph->unitvalfprint_vertex_list:symbseq->formatter->vertexlist->unitvalfprint_edge_list:symbseq->formatter->edgelist->unitend(** The litteral name of the engine. *)valname:string(** The keyword for graphs ("digraph" for dot, "graph" for neato) *)valopening:string(** The litteral for edge arrows ("->" for dot, "--" for neato) *)valedge_arrow:stringendmoduletypeGRAPH=sigendmoduleMakeEngine(EN:ENGINE)(X:sigtypetmoduleV:sigtypetendmoduleE:sigtypetvalsrc:t->V.tvaldst:t->V.tendvaliter_vertex:(V.t->unit)->t->unitvaliter_edges_e:(E.t->unit)->t->unitvalgraph_attributes:t->EN.Attributes.graphlistvaldefault_vertex_attributes:t->EN.Attributes.vertexlistvalvertex_name:V.t->stringvalvertex_attributes:V.t->EN.Attributes.vertexlistvaldefault_edge_attributes:t->EN.Attributes.edgelistvaledge_attributes:E.t->EN.Attributes.edgelistvalget_subgraph:V.t->EN.Attributes.subgraphoptionend)=structletcommand=refEN.nameletset_commandcmd=command:=cmdexceptionErrorofstringlethandle_errorfarg=tryfargwithErrormsg->Printf.eprintf"%s: %s failure\n %s\n"Sys.argv.(0)EN.namemsg;flushstderr;exit2(** [fprint_graph_attributes ppf list] pretty prints a list of
graph attributes on the formatter [ppf]. Attributes are separated
by a ";". *)letfprint_graph_attributesppflist=List.iter(functionatt->fprintfppf"%a;@ "EN.Attributes.fprint_graphatt)list(** [fprint_graph ppf graph] pretty prints the graph [graph] in
the CGL language on the formatter [ppf]. *)letfprint_graphppfgraph=letmoduleSG=Map.Make(String)inletsubgraphs=refSG.emptyin(* Printing nodes. *)letprint_nodesppf=letdefault_node_attributes=X.default_vertex_attributesgraphinifdefault_node_attributes<>[]thenfprintfppf"node%a;@ "(fprint_square_not_empty(EN.Attributes.fprint_vertex_listCOMMA))default_node_attributes;X.iter_vertex(functionnode->beginmatchX.get_subgraphnodewith|None->()|Somesg->let(sg,nodes)=ifSG.memsg.EN.Attributes.sg_name!subgraphsthenSG.findsg.EN.Attributes.sg_name!subgraphselse(sg,[])insubgraphs:=SG.addsg.EN.Attributes.sg_name(sg,node::nodes)!subgraphsend;fprintfppf"%s%a;@ "(X.vertex_namenode)(fprint_square_not_empty(EN.Attributes.fprint_vertex_listCOMMA))(X.vertex_attributesnode))graphin(* Printing subgraphs *)letrecprint_nested_subgraphsppf=function|[]->()(* no more work to do, so terminate *)|name::worklist->letsg,nodes=SG.findname!subgraphsinletchildren=SG.filter(fun_(sg,_)->sg.EN.Attributes.sg_parent=Somename)!subgraphsinfprintfppf"@[<v 2>subgraph cluster_%s { %a%t@ %t };@]@\n"name(EN.Attributes.fprint_vertex_listSEMI)sg.EN.Attributes.sg_attributes(funppf->(List.iter(funn->fprintfppf"%s;"(X.vertex_namen))nodes))(funppf->print_nested_subgraphsppf(List.mapfst(SG.bindingschildren)));print_nested_subgraphsppfworklistinletprint_subgraphsppf=letroot_worklist=SG.filter(fun_(sg,_)->sg.EN.Attributes.sg_parent=None)!subgraphsinprint_nested_subgraphsppf(List.mapfst(SG.bindingsroot_worklist))in(* Printing edges *)letprint_edgesppf=letdefault_edge_attributes=X.default_edge_attributesgraphinifdefault_edge_attributes<>[]thenfprintfppf"edge%a;@ "(fprint_square_not_empty(EN.Attributes.fprint_edge_listCOMMA))default_edge_attributes;X.iter_edges_e(functionedge->fprintfppf"%s %s %s%a;@ "(X.vertex_name(X.E.srcedge))EN.edge_arrow(X.vertex_name(X.E.dstedge))(fprint_square_not_empty(EN.Attributes.fprint_edge_listCOMMA))(X.edge_attributesedge))graphinfprintfppf"@[<v>%s G {@ @[<v 2> %a"EN.openingfprint_graph_attributes(X.graph_attributesgraph);fprintfppf"%t@ "print_nodes;fprintfppf"%t@ "print_subgraphs;fprintfppf"%t@ "print_edges;fprintfppf"@]}@;@]"(** [output_graph oc graph] pretty prints the graph [graph] in the dot
language on the channel [oc]. *)letoutput_graphocgraph=letppf=formatter_of_out_channelocinfprint_graphppfgraph;pp_print_flushppf()end(***************************************************************************)(** {2 Interface with the dot engine} *)(** The [DotAttributes] module defines attributes for graphs, nodes and edges
that are available in the dot engine. *)moduleDotAttributes=struct(** Attributes of graphs. They include all common graph attributes and
several specific ones. All attributes described in the "dot User's
Manual, February 4, 2002" are handled, excepted: clusterank, color,
compound, labeljust, labelloc, ordering, rank, remincross, rotate,
searchsize and style.
*)typegraph=[CommonAttributes.graph|`Bgcolorofcolor(** Sets the background color and the inital fill color. *)|`BgcolorWithTransparencyofcolor_with_transparency(** Sets the background color and the inital fill color with
a transparency component. *)|`Commentofstring(** Comment string. *)|`Concentrateofbool(** If [true], enables edge concentrators. Default value is [false]. *)|`Fontpathofstring(** List of directories for fonts. *)|`Layersofstringlist(** List of layers. *)|`Marginoffloat(** Sets the page margin (included in the page size). Default value is
[0.5]. *)|`Mclimitoffloat(** Scale factor for mincross iterations. Default value is [1.0]. *)|`Nodesepoffloat(** Sets the minimum separation between nodes, in inches. Default
value is [0.25]. *)|`Nslimitofint(** If set of [f], bounds network simplex iterations by [f *
<number of nodes>] when ranking nodes. *)|`Nslimit1ofint(** If set of [f], bounds network simplex iterations by [f *
<number of nodes>] when setting x-coordinates. *)|`Ranksepoffloat(** Sets the minimum separation between ranks. *)|`Quantumoffloat(** If not [0.0], node label dimensions will be rounded to integral
multiples of it. Default value is [0.0]. *)|`Rankdirof[`TopToBottom|`BottomToTop|`LeftToRight|`RightToLeft](** Direction of rank ordering. Default value is [`TopToBottom]. *)|`Ratioof[`Floatoffloat|`Fill|`Compress|`Auto](** Sets the aspect ratio. *)|`Samplepointsofint(** Number of points used to represent ellipses and circles on output.
Default value is [8]. *)|`Urlofstring(** URL associated with graph (format-dependent). *)](** Attributes of nodes. They include all common node attributes and
several specific ones. All attributes described in the "dot User's
Manual, February 4, 2002" are handled, excepted: bottomlabel, group,
shapefile and toplabel.
*)typevertex=[CommonAttributes.vertex|`Commentofstring(** Comment string. *)|`Distortionoffloat(* TEMPORARY *)|`Fillcolorofcolor(** Sets the fill color (used when `Style filled). Default value
is [lightgrey]. *)|`FillcolorWithTransparencyofcolor_with_transparency(** Sets the fill color (used when `Style filled) with a transparency
component. Default value is fully opaque [lightgrey]. *)|`Fixedsizeofbool(** If [true], forces the given dimensions to be the actual ones.
Default value is [false]. *)|`Layerofstring(** Overlay. *)|`Urlofstring(** The default url for image map files; in PostScript files,
the base URL for all relative URLs, as recognized by Acrobat
Distiller 3.0 and up. *)|`Zoffloat(** z coordinate for VRML output. *)](** Attributes of edges. They include all common edge attributes and
several specific ones. All attributes described in the "dot User's
Manual, February 4, 2002" are handled, excepted: lhead and ltail.
*)typeedge=[CommonAttributes.edge|`Arrowheadofarrow_style(** Sets the style of the head arrow. Default value is [`Normal]. *)|`Arrowsizeoffloat(** Sets the scaling factor of arrowheads. Default value is [1.0]. *)|`Arrowtailofarrow_style(** Sets the style of the tail arrow. Default value is [`Normal]. *)|`Commentofstring(** Comment string. *)|`Constraintofbool(** If [false], causes an edge to be ignored for rank assignment.
Default value is [true]. *)|`Headlabelofstring(** Sets the label attached to the head arrow. *)|`Headportof[`N|`NE|`E|`SE|`S|`SW|`W|`NW](* TEMPORARY *)|`Headurlofstring(** Url attached to head label if output format is ismap. *)|`Labelangleoffloat(** Angle in degrees which head or tail label is rotated off edge.
Default value is [-25.0]. *)|`Labeldistanceoffloat(** Scaling factor for distance of head or tail label from node.
Default value is [1.0]. *)|`Labelfloatofbool(** If [true], lessen constraints on edge label placement.
Default value is [false]. *)|`Layerofstring(** Overlay. *)|`Minlenofint(** Minimum rank distance between head an tail. Default value is [1]. *)|`Sameheadofstring(** Tag for head node; edge heads with the same tag are merged onto the
same port. *)|`Sametailofstring(** Tag for tail node; edge tails with the same tag are merged onto the
same port. *)|`Taillabelofstring(** Sets the label attached to the tail arrow. *)|`Tailportof[`N|`NE|`E|`SE|`S|`SW|`W|`NW](* TEMPORARY *)|`Tailurlofstring(** Url attached to tail label if output format is ismap. *)|`Weightofint(** Sets the integer cost of stretching the edge. Default value is
[1]. *)]typesubgraph={sg_name:string;sg_attributes:vertexlist;sg_parent:stringoption;}(** {4 Pretty-print of attributes} *)letrecfprint_string_listppf=function[]->()|[hd]->fprintfppf"%s"hd|hd::tl->fprintfppf"%s,%a"hdfprint_string_listtlletfprint_ratioppf=function`Floatf->fprintfppf"%f"f|`Fill->fprintfppf"fill"|`Compress->fprintfppf"compress"|`Auto->fprintfppf"auto"letfprint_graphppf=function#CommonAttributes.graphasatt->CommonAttributes.fprint_graphppfatt|`Bgcolora->fprintfppf"bgcolor=%a"fprint_colora|`BgcolorWithTransparencya->fprintfppf"bgcolor=%a"fprint_color_with_transparencya|`Comments->fprintfppf"comment=%a"fprint_strings|`Concentrateb->fprintfppf"concentrate=%b"b|`Fontpaths->fprintfppf"fontpath=%a"fprint_strings|`Layerss->fprintfppf"layers=%a"fprint_string_lists|`Marginf->fprintfppf"margin=%f"f|`Mclimitf->fprintfppf"mclimit=%f"f|`Nodesepf->fprintfppf"nodesep=%f"f|`Nslimiti->fprintfppf"nslimit=%i"i|`Nslimit1i->fprintfppf"nslimit1=%i"i|`Ranksepf->fprintfppf"ranksep=%f"f|`Quantumf->fprintfppf"quantum=%f"f|`Rankdira->fprintfppf"rankdir=%a"fprint_dira|`Ratioa->fprintfppf"ratio=%a"fprint_ratioa|`Samplepointsi->fprintfppf"samplepoints=%i"i|`Urls->fprintfppf"URL=\"%s\""s(*(String.escaped s)*)letfprint_vertexppf=function#CommonAttributes.vertexasatt->CommonAttributes.fprint_vertexppfatt|`Comments->fprintfppf"comment=%a"fprint_strings|`Distortionf->fprintfppf"distortion=%f"f|`Fillcolora->fprintfppf"fillcolor=%a"fprint_colora|`FillcolorWithTransparencya->fprintfppf"fillcolor=%a"fprint_color_with_transparencya|`Fixedsizeb->fprintfppf"fixedsize=%b"b|`Layers->fprintfppf"layer=%a"fprint_strings|`Urls->fprintfppf"URL=\"%s\""s(*(String.escaped s)*)|`Zf->fprintfppf"z=%f"fletfprint_portppf=function`N->fprintfppf"n"|`NE->fprintfppf"ne"|`E->fprintfppf"e"|`SE->fprintfppf"se"|`S->fprintfppf"s"|`SW->fprintfppf"sw"|`W->fprintfppf"w"|`NW->fprintfppf"nw"letfprint_edgeppf=function#CommonAttributes.edgeasatt->CommonAttributes.fprint_edgeppfatt|`Arrowheada->fprintfppf"arrowhead=%a"fprint_arrow_stylea|`Arrowsizef->fprintfppf"arrowsize=%f"f|`Arrowtaila->fprintfppf"arrowtail=%a"fprint_arrow_stylea|`Comments->fprintfppf"comment=%a"fprint_strings|`Constraintb->fprintfppf"constraint=%b"b|`Headlabels->fprintfppf"headlabel=%a"fprint_strings|`Headporta->fprintfppf"headport=%a"fprint_porta|`Headurls->fprintfppf"headURL=%a"fprint_strings|`Labelanglef->fprintfppf"labelangle=%f"f|`Labeldistancef->fprintfppf"labeldistance=%f"f|`Labelfloatb->fprintfppf"labelfloat=%b"b|`Layers->fprintfppf"layer=%a"fprint_strings|`Minleni->fprintfppf"minlen=%i"i|`Sameheads->fprintfppf"samehead=%a"fprint_strings|`Sametails->fprintfppf"sametail=%a"fprint_strings|`Taillabels->fprintfppf"taillabel=%a"fprint_strings|`Tailporta->fprintfppf"tailport=%a"fprint_porta|`Tailurls->fprintfppf"tailURL=%a"fprint_strings|`Weighti->fprintfppf"weight=%i"iletfprint_vertex_list=CommonAttributes.fprint_attributesCommonAttributes.fprint_style_listfprint_vertexletfprint_edge_list=CommonAttributes.fprint_attributesCommonAttributes.fprint_style_listfprint_edgeend(** Graph modules with dot attributes *)moduletypeGraphWithDotAttrs=sigincludeSig.G(** Graph, vertex and edge attributes. *)valgraph_attributes:t->DotAttributes.graphlist(** Vertex attributes *)valdefault_vertex_attributes:t->DotAttributes.vertexlistvalvertex_name:V.t->stringvalvertex_attributes:V.t->DotAttributes.vertexlist(** Edge attributes *)valdefault_edge_attributes:t->DotAttributes.edgelistvaledge_attributes:E.t->DotAttributes.edgelistvalget_subgraph:V.t->DotAttributes.subgraphoption(** The box (if exists) which the vertex belongs to. Boxes with same
names are not distinguished and so they should have the same
attributes. *)endmoduleDot=MakeEngine(structmoduleAttributes=DotAttributesletname="dot"letopening="digraph"letedge_arrow="->"end)(***************************************************************************)(** {2 Interface with the neato engine} *)(** The [NeatoAttributes] module defines attributes for graphs, nodes and edges
that are available in the neato engine. *)moduleNeatoAttributes=struct(** Attributes of graphs. They include all common graph attributes and
several specific ones. All attributes described in the "Neato User's
manual, April 10, 2002" are handled. *)typegraph=[CommonAttributes.graph|`Marginoffloat*float(** Sets the page margin (included in the page size). Default value is
[0.5, 0.5]. *)|`Startofint(** Seed for random number generator. *)|`Overlapofbool(** Default value is [true]. *)|`Splineofbool(** [true] makes edge splines if nodes don't overlap.
Default value is [false]. *)|`Sepoffloat(** Edge spline separation factor from nodes. Default value
is [0.0]. *)](** Attributes of nodes. They include all common node attributes and
several specific ones. All attributes described in the "Neato User's
manual, April 10, 2002" are handled. *)typevertex=[CommonAttributes.vertex|`Posoffloat*float(** Initial coordinates of the node. *)|`PosPinnedoffloat*float(** Initial coordinates of the vertex, pinned. *)](** Attributes of edges. They include all common edge attributes and
several specific ones. All attributes described in the "Neato User's
manual, April 10, 2002" are handled. *)typeedge=[CommonAttributes.edge|`Idofstring(** Optional value to distinguish multiple edges. *)|`Lenoffloat(** Preferred length of edge. Default value is [1.0]. *)|`Weightoffloat(** Strength of edge spring. Default value is [1.0]. *)]typesubgraph={sg_name:string;sg_attributes:vertexlist;sg_parent:stringoption;}(** {4 Pretty-print of attributes} *)letfprint_graphppf=function#CommonAttributes.graphasatt->CommonAttributes.fprint_graphppfatt|`Margin(f1,f2)->fprintfppf"margin=\"%f,%f\""f1f2|`Starti->fprintfppf"start=%i"i|`Overlapb->fprintfppf"overlap=%b"b|`Splineb->fprintfppf"spline=%b"b|`Sepf->fprintfppf"sep=%f"fletfprint_vertexppf=function#CommonAttributes.vertexasatt->CommonAttributes.fprint_vertexppfatt|`Pos(f1,f2)->fprintfppf"pos=\"%f,%f\""f1f2|`PosPinned(f1,f2)->fprintfppf"pos=\"%f,%f!\""f1f2letfprint_edgeppf=function#CommonAttributes.edgeasatt->CommonAttributes.fprint_edgeppfatt|`Ids->fprintfppf"id=%a"fprint_strings|`Lenf->fprintfppf"len=%f"f|`Weightf->fprintfppf"weight=%f"fletfprint_vertex_list=CommonAttributes.fprint_attributesCommonAttributes.fprint_style_listfprint_vertexletfprint_edge_list=CommonAttributes.fprint_attributesCommonAttributes.fprint_style_listfprint_edgeendmoduleNeato=MakeEngine(structmoduleAttributes=NeatoAttributesletname="neato"letopening="graph"letedge_arrow="--"end)