diff --git a/gap/gv.gi b/gap/gv.gi index 8ec4c77..bf123de 100644 --- a/gap/gv.gi +++ b/gap/gv.gi @@ -239,6 +239,18 @@ function(graph) return graph; end); +BindGlobal("GV_Indent", lvl -> ListWithIdenticalEntries(2 * lvl, ' ')); + +BindGlobal("GV_Depth", function(gv) + local depth; + depth := 0; + while GV_GetParent(gv) <> fail do + gv := GV_GetParent(gv); + depth := depth + 1; + od; + return depth; +end); + InstallMethod(GV_AddNode, "for a graphviz graph and node", [IsGraphvizGraphDigraphOrContext, IsGraphvizNode], @@ -272,11 +284,17 @@ graph -> StringFormatted("digraph {} {{\n", GraphvizName(graph))); # @ Return DOT subgraph head line. BindGlobal("GV_StringifySubgraphHead", -graph -> StringFormatted("subgraph {} {{\n", GraphvizName(graph))); +gv -> StringFormatted("{}subgraph {} {{\n", GV_Indent(GV_Depth(gv)), GraphvizName(gv))); # @ Return DOT subgraph head line. BindGlobal("GV_StringifyContextHead", -graph -> StringFormatted("// {} context \n{{\n", GraphvizName(graph))); +function(gv) + local indent; + indent := GV_Indent(GV_Depth(gv)); + return StringFormatted("{1}{{\n{1} // context \"{2}\" \n", + indent, + GraphvizName(gv)); +end); BindGlobal("GV_StringifyNodeName", function(node) @@ -289,13 +307,7 @@ function(node) and not StartsWith(name, "\"") then old := name; name := StringFormatted("\"{}\"", name); - Info(InfoWarning, - 1, - "invalid node name ", - old, - " using ", - name, - " instead"); + Info(InfoWarning, 1, "invalid node name ", old, " using ", name, " instead"); fi; return name; end); @@ -339,7 +351,10 @@ function(node) local name, attrs; name := GV_StringifyNodeName(node); attrs := GraphvizAttrs(node); - return StringFormatted("\t{}{}\n", name, GV_StringifyAttrList(attrs)); + return StringFormatted("{}{}{}\n", + GV_Indent(GV_Depth(node)), + name, + GV_StringifyAttrList(attrs)); end); # @ Return DOT graph edge statement line. @@ -353,7 +368,8 @@ function(edge, edge_str) attrs := GraphvizAttrs(edge); # handle : syntax - return StringFormatted("\t{} {} {}{}\n", + return StringFormatted("{}{} {} {}{}\n", + GV_Indent(GV_Depth(edge)), head, edge_str, tail, @@ -413,7 +429,11 @@ function(graph, is_subgraph) for type in ["graph", "node", "edge"] do record := GraphvizAttrs(graph).(type); if Length(RecNames(record)) > 0 then - Append(result, StringFormatted("{} {}\n", type, GV_StringifyAttrList(record))); + Append(result, + StringFormatted("{}{}{}\n", + GV_Indent(GV_Depth(graph) + 1), + type, + GV_StringifyAttrList(record))); fi; od; @@ -432,7 +452,10 @@ function(graph, is_subgraph) fi; od; - Append(result, "}\n"); + Append(result, StringFormatted("{}}}", GV_Indent(GV_Depth(graph)))); + if GV_Depth(graph) > 0 then + Append(result, "\n"); + fi; return result; end); diff --git a/tst/dot.tst b/tst/dot.tst index b2e32a8..619f223 100644 --- a/tst/dot.tst +++ b/tst/dot.tst @@ -38,8 +38,11 @@ rec( edge := rec( ), gap> g := GraphvizGraph();; gap> n := GraphvizAddNode(g, "test");; gap> GraphvizSetAttrs(n, rec(color := "red", label := "lab"));; -gap> AsString(g); -"//dot\ngraph {\n\ttest [color=\"red\", label=\"lab\"]\n}\n" +gap> Print(AsString(g), "\n"); +//dot +graph { + test [color="red", label="lab"] +} gap> GraphvizRemoveNode(g, "banana"); Error, the 2nd argument (node name string) "banana" is not a node of the 1st a\ rgument (a graphviz (di)graph/context) @@ -52,9 +55,13 @@ gap> GraphvizSetAttrs(a, rec(color := "blue"));; gap> GraphvizSetAttrs(b, rec(color := "red"));; gap> e := GraphvizAddEdge(g, a, b);; gap> GraphvizSetAttrs(e, rec(color := "green"));; -gap> AsString(g); -"//dot\ndigraph {\n\ta [color=\"blue\"]\n\tb [color=\"red\"]\n\ta -> b [color\ -=\"green\"]\n}\n" +gap> Print(AsString(g), "\n"); +//dot +digraph { + a [color="blue"] + b [color="red"] + a -> b [color="green"] +} # Test stringify with edge (graph) gap> g := GraphvizGraph();; @@ -64,14 +71,20 @@ gap> GraphvizSetAttrs(a, rec(color := "blue"));; gap> GraphvizSetAttrs(b, rec(color := "red"));; gap> e := GraphvizAddEdge(g, a, b);; gap> GraphvizSetAttrs(e, rec(color := "green"));; -gap> AsString(g); -"//dot\ngraph {\n\ta [color=\"blue\"]\n\tb [color=\"red\"]\n\ta -- b [color=\ -\"green\"]\n}\n" +gap> Print(AsString(g), "\n"); +//dot +graph { + a [color="blue"] + b [color="red"] + a -- b [color="green"] +} # Test stringify empty gap> g := GraphvizGraph();; -gap> AsString(g); -"//dot\ngraph {\n}\n" +gap> Print(AsString(g), "\n"); +//dot +graph { +} # Test unknown attributes (node) gap> g := GraphvizGraph();; @@ -88,25 +101,41 @@ gap> GraphvizSetAttr(g, "test", "false"); gap> g := GraphvizGraph();; gap> n := GraphvizAddNode(g, "node");; gap> GraphvizSetAttr(n, "label", ">>hello");; -gap> AsString(g); -"//dot\ngraph {\n\tnode [label=\">>hello\"]\n}\n" +gap> Print(AsString(g), "\n"); +//dot +graph { + node [label=">>hello"] +} gap> g := GraphvizGraph();; gap> n := GraphvizAddNode(g, "node");; gap> GraphvizSetAttr(n, "label", "before>>hello");; -gap> AsString(g); -"//dot\ngraph {\n\tnode [label=\"before>>hello\"]\n}\n" +gap> Print(AsString(g), "\n"); +//dot +graph { + node [label="before>>hello"] +} # Test strngifying labels with ">>" inside (edge attrs) gap> g := GraphvizGraph();; gap> e := GraphvizAddEdge(g, "a", "b");; gap> GraphvizSetAttr(e, "label", ">>hello");; -gap> AsString(g); -"//dot\ngraph {\n\ta\n\tb\n\ta -- b [label=\">>hello\"]\n}\n" +gap> Print(AsString(g), "\n"); +//dot +graph { + a + b + a -- b [label=">>hello"] +} gap> g := GraphvizGraph();; gap> e := GraphvizAddEdge(g, "a", "b");; gap> GraphvizSetAttr(e, "label", "before>>hello");; -gap> AsString(g); -"//dot\ngraph {\n\ta\n\tb\n\ta -- b [label=\"before>>hello\"]\n}\n" +gap> Print(AsString(g), "\n"); +//dot +graph { + a + b + a -- b [label="before>>hello"] +} # Test GraphvizSetNodeLabels gap> gv := GraphvizGraph("xxx"); @@ -119,21 +148,21 @@ gap> GraphvizAddNode(gv, 3); gap> GraphvizSetNodeLabels(gv, ["i", "ii", "iii"]); -gap> Print(AsString(gv)); +gap> Print(AsString(gv), "\n"); //dot graph xxx { - 1 [label="i"] - 2 [label="ii"] - 3 [label="iii"] + 1 [label="i"] + 2 [label="ii"] + 3 [label="iii"] } gap> GraphvizSetNodeLabels(gv, ["a", "b", "c"]); -gap> Print(AsString(gv)); +gap> Print(AsString(gv), "\n"); //dot graph xxx { - 1 [label="a"] - 2 [label="b"] - 3 [label="c"] + 1 [label="a"] + 2 [label="b"] + 3 [label="c"] } gap> GraphvizSetNodeLabels(gv, ["i", "ii"]); Error, the 2nd argument (list of node labels) has incorrect length, expected 3\ @@ -157,30 +186,30 @@ Error, invalid color "i" (list (string)), valid colors are RGB values or names\ .html gap> GraphvizSetNodeColors(gv, ["red", "green", "blue"]); -gap> Print(AsString(gv)); +gap> Print(AsString(gv), "\n"); //dot graph xxx { - 1 [color="red", style="filled"] - 2 [color="green", style="filled"] - 3 [color="blue", style="filled"] + 1 [color="red", style="filled"] + 2 [color="green", style="filled"] + 3 [color="blue", style="filled"] } gap> GraphvizSetNodeColors(gv, ["red", "#00FF00", "blue"]); -gap> Print(AsString(gv)); +gap> Print(AsString(gv), "\n"); //dot graph xxx { - 1 [color="red", style="filled"] - 2 [color="#00FF00", style="filled"] - 3 [color="blue", style="filled"] + 1 [color="red", style="filled"] + 2 [color="#00FF00", style="filled"] + 3 [color="blue", style="filled"] } gap> GraphvizSetNodeColors(gv, ["#FF0000", "#00FF00", "#0000FF"]); -gap> Print(AsString(gv)); +gap> Print(AsString(gv), "\n"); //dot graph xxx { - 1 [color="#FF0000", style="filled"] - 2 [color="#00FF00", style="filled"] - 3 [color="#0000FF", style="filled"] + 1 [color="#FF0000", style="filled"] + 2 [color="#00FF00", style="filled"] + 3 [color="#0000FF", style="filled"] } gap> GraphvizSetNodeColors(gv, ["#FF0000", "#00FF00", "#0000FG"]); Error, invalid color "#0000FG" (list (string)), valid colors are RGB values or\ @@ -206,14 +235,14 @@ gap> n := GraphvizSetAttr(n, "probably not ok", 1); gap> Print(AsString(gv : invalidDOT := "unquoted attribute name with spaces"), "\n"); //dot graph xxx { - 1 [probably not ok="1"] + 1 [probably not ok="1"] } gap> GraphvizSetAttr(n, "label", "<<>>"); gap> Print(AsString(gv : invalidDOT := "unquoted attribute name with spaces"), "\n"); //dot graph xxx { - 1 [label="<<>>", probably not ok="1"] + 1 [label="<<>>", probably not ok="1"] } # Issue 68 @@ -223,14 +252,25 @@ gap> a := GraphvizAddNode(g, "a"); gap> e := GraphvizAddEdge(g, a, "b"); -gap> GraphvizNodes(g); AsString(g); +gap> GraphvizNodes(g); Print(AsString(g), "\n"); rec( a := , b := ) -"//dot\ndigraph unexpected {\n\ta\n\tb\n\ta -> b\n}\n" +//dot +digraph unexpected { + a + b + a -> b +} gap> e := GraphvizAddEdge(g, "b", a); -gap> GraphvizNodes(g); AsString(g); +gap> GraphvizNodes(g); Print(AsString(g), "\n"); rec( a := , b := ) -"//dot\ndigraph unexpected {\n\ta\n\tb\n\ta -> b\n\tb -> a\n}\n" +//dot +digraph unexpected { + a + b + a -> b + b -> a +} # gap> STOP_TEST("graphviz package: dot.tst", 0); diff --git a/tst/examples/angles.tst b/tst/examples/angles.tst index 43417c0..b49a1a1 100644 --- a/tst/examples/angles.tst +++ b/tst/examples/angles.tst @@ -67,41 +67,41 @@ gap> GraphvizSetAttr(cluster2, "label", gap> GraphvizAddEdge(g, "n5", "n14"); -gap> Print(AsString(g)); +gap> Print(AsString(g), "\n"); //dot digraph G { -graph [bgcolor="blue"] -subgraph cluster_1 { -graph [fontcolor="white", label="Linear Angle Variations (white to black grad\ -ient)"] -node [fillcolor="white:black", fontcolor="black", gradientangle="360", label=\ -"n9:n360", shape="circle", style="filled"] - n9 - n8 [gradientangle="315", label="n8:315"] - n7 [gradientangle="270", label="n7:270"] - n6 [gradientangle="225", label="n6:225"] - n5 [gradientangle="180", label="n5:180"] - n4 [gradientangle="135", label="n4:135"] - n3 [gradientangle="90", label="n3:90"] - n2 [gradientangle="45", label="n2:45"] - n1 [gradientangle="0", label="n1:0"] -} -subgraph cluster_2 { -graph [fontcolor="white", label="Radial Angle Variations (white to black grad\ -ient)"] -node [fillcolor="white:black", fontcolor="black", gradientangle="360", label=\ -"n9:n360", shape="circle", style="radial"] - n18 - n17 [gradientangle="315", label="n17:315"] - n16 [gradientangle="270", label="n16:270"] - n15 [gradientangle="225", label="n15:225"] - n14 [gradientangle="180", label="n14:180"] - n13 [gradientangle="135", label="n13:135"] - n12 [gradientangle="90", label="n12:90"] - n11 [gradientangle="45", label="n11:45"] - n10 [gradientangle="0", label="n10:0"] -} - n5 -> n14 + graph [bgcolor="blue"] + subgraph cluster_1 { + graph [fontcolor="white", label="Linear Angle Variations (white to black g\ +radient)"] + node [fillcolor="white:black", fontcolor="black", gradientangle="360", lab\ +el="n9:n360", shape="circle", style="filled"] + n9 + n8 [gradientangle="315", label="n8:315"] + n7 [gradientangle="270", label="n7:270"] + n6 [gradientangle="225", label="n6:225"] + n5 [gradientangle="180", label="n5:180"] + n4 [gradientangle="135", label="n4:135"] + n3 [gradientangle="90", label="n3:90"] + n2 [gradientangle="45", label="n2:45"] + n1 [gradientangle="0", label="n1:0"] + } + subgraph cluster_2 { + graph [fontcolor="white", label="Radial Angle Variations (white to black g\ +radient)"] + node [fillcolor="white:black", fontcolor="black", gradientangle="360", lab\ +el="n9:n360", shape="circle", style="radial"] + n18 + n17 [gradientangle="315", label="n17:315"] + n16 [gradientangle="270", label="n16:270"] + n15 [gradientangle="225", label="n15:225"] + n14 [gradientangle="180", label="n14:180"] + n13 [gradientangle="135", label="n13:135"] + n12 [gradientangle="90", label="n12:90"] + n11 [gradientangle="45", label="n11:45"] + n10 [gradientangle="0", label="n10:0"] + } + n5 -> n14 } # diff --git a/tst/examples/btree.tst b/tst/examples/btree.tst index ecc45f0..a975a66 100644 --- a/tst/examples/btree.tst +++ b/tst/examples/btree.tst @@ -55,19 +55,44 @@ gap> GraphvizAddEdge(s, "node4:f2", "node6:f1"); gap> GraphvizAddEdge(s, "node4:f0", "node5:f1"); -gap> AsString(s) = -> "//dot\ndigraph g {\nnode [height=\".1\", shape=\"record\"]\n\tnode0 [label=\ -> \" | G|\"]\n\tnode1 [label=\" | E|\"]\n\tnode2 [label=\ -> \" | B|\"]\n\tnode3 [label=\" | F|\"]\n\tnode4 [label=\ -> \" | R|\"]\n\tnode5 [label=\" | H|\"]\n\tnode6 [label=\ -> \" | Y|\"]\n\tnode7 [label=\" | A|\"]\n\tnode8 [label=\ -> \" | C|\"]\n\tnode0:f2\n\tnode4:f1\n\tnode0:f2 -> node4:f1\n\tnode\ -> 0:f0\n\tnode1:f1\n\tnode0:f0 -> node1:f1\n\tnode1:f0\n\tnode2:f1\n\tnode1:f0 -\ -> > node2:f1\n\tnode1:f2\n\tnode3:f1\n\tnode1:f2 -> node3:f1\n\tnode2:f2\n\tnode\ -> 8:f1\n\tnode2:f2 -> node8:f1\n\tnode2:f0\n\tnode7:f1\n\tnode2:f0 -> node7:f1\n\ -> \tnode4:f2\n\tnode6:f1\n\tnode4:f2 -> node6:f1\n\tnode4:f0\n\tnode5:f1\n\tnode\ -> 4:f0 -> node5:f1\n}\n"; -true +gap> Print(AsString(s), "\n"); +//dot +digraph g { + node [height=".1", shape="record"] + node0 [label=" | G|"] + node1 [label=" | E|"] + node2 [label=" | B|"] + node3 [label=" | F|"] + node4 [label=" | R|"] + node5 [label=" | H|"] + node6 [label=" | Y|"] + node7 [label=" | A|"] + node8 [label=" | C|"] + node0:f2 + node4:f1 + node0:f2 -> node4:f1 + node0:f0 + node1:f1 + node0:f0 -> node1:f1 + node1:f0 + node2:f1 + node1:f0 -> node2:f1 + node1:f2 + node3:f1 + node1:f2 -> node3:f1 + node2:f2 + node8:f1 + node2:f2 -> node8:f1 + node2:f0 + node7:f1 + node2:f0 -> node7:f1 + node4:f2 + node6:f1 + node4:f2 -> node6:f1 + node4:f0 + node5:f1 + node4:f0 -> node5:f1 +} # gap> STOP_TEST("graphviz package: btree.tst"); diff --git a/tst/examples/cluster.tst b/tst/examples/cluster.tst index b1c97a5..3f7d99d 100644 --- a/tst/examples/cluster.tst +++ b/tst/examples/cluster.tst @@ -74,14 +74,41 @@ gap> GraphvizSetAttr(GraphvizNode(graph, "end"), "shape", "Msquare"); # -gap> AsString(graph); -"//dot\ndigraph G {\nsubgraph cluster_0 {\ngraph [color=\"lightgrey\", label=\ -\"process #1\", style=\"filled\"]\nnode [color=\"white\", style=\"filled\"]\n\ -\ta0\n\ta1\n\ta0 -> a1\n\ta2\n\ta1 -> a2\n\ta3\n\ta2 -> a3\n}\nsubgraph cluste\ -r_1 {\ngraph [color=\"blue\", label=\"process #2\"]\nnode [style=\"filled\"]\ -\n\tb0\n\tb1\n\tb0 -> b1\n\tb2\n\tb1 -> b2\n\tb3\n\tb2 -> b3\n}\n\tstart [shap\ -e=\"Mdiamond\"]\n\tstart -> a0\n\tstart -> b0\n\ta1 -> b3\n\tb2 -> a3\n\ta3 ->\ - a0\n\tend [shape=\"Msquare\"]\n\ta3 -> end\n\tb3 -> end\n}\n" +gap> Print(AsString(graph), "\n"); +//dot +digraph G { + subgraph cluster_0 { + graph [color="lightgrey", label="process #1", style="filled"] + node [color="white", style="filled"] + a0 + a1 + a0 -> a1 + a2 + a1 -> a2 + a3 + a2 -> a3 + } + subgraph cluster_1 { + graph [color="blue", label="process #2"] + node [style="filled"] + b0 + b1 + b0 -> b1 + b2 + b1 -> b2 + b3 + b2 -> b3 + } + start [shape="Mdiamond"] + start -> a0 + start -> b0 + a1 -> b3 + b2 -> a3 + a3 -> a0 + end [shape="Msquare"] + a3 -> end + b3 -> end +} # gap> STOP_TEST("graphviz package: examples/cluster.tst"); diff --git a/tst/examples/cluster_edge.tst b/tst/examples/cluster_edge.tst index 0a931e5..b8c567b 100644 --- a/tst/examples/cluster_edge.tst +++ b/tst/examples/cluster_edge.tst @@ -53,12 +53,34 @@ gap> GraphvizSetAttr(e, "ltail", "cluster0"); gap> GraphvizAddEdge(g, "d", "h"); -gap> AsString(g); -"//dot\ndigraph G {\ngraph [compound=\"true\"]\nsubgraph cluster0 {\n\ta\n\tb\ -\n\ta -> b\n\tc\n\ta -> c\n\td\n\tb -> d\n\tc -> d\n}\nsubgraph cluster1 {\n\t\ -e\n\tg\n\te -> g\n\tf\n\te -> f\n}\n\tb -> f [lhead=\"cluster1\"]\n\td -> e\n\ -\tc -> g [lhead=\"cluster1\", ltail=\"cluster0\"]\n\tc -> e [ltail=\"cluster0\ -\"]\n\th\n\td -> h\n}\n" +gap> Print(AsString(g), "\n"); +//dot +digraph G { + graph [compound="true"] + subgraph cluster0 { + a + b + a -> b + c + a -> c + d + b -> d + c -> d + } + subgraph cluster1 { + e + g + e -> g + f + e -> f + } + b -> f [lhead="cluster1"] + d -> e + c -> g [lhead="cluster1", ltail="cluster0"] + c -> e [ltail="cluster0"] + h + d -> h +} # gap> STOP_TEST("graphviz package: examples/cluster_edge.tst"); diff --git a/tst/examples/colors.tst b/tst/examples/colors.tst index a7bf9d4..157d294 100644 --- a/tst/examples/colors.tst +++ b/tst/examples/colors.tst @@ -54,15 +54,18 @@ gap> GraphvizSetAttr(node, "fillcolor", "deeppink"); # -gap> AsString(g); +gap> Print(AsString(g), "\n"); #I invalid node name RGB: #40e0d0 using "RGB: #40e0d0" instead #I invalid node name RGBA: #ff000042 using "RGBA: #ff000042" instead #I invalid node name HSV: 0.051 0.718 0.627 using "HSV: 0.051 0.718 0.627" instead #I invalid node name name: deeppink using "name: deeppink" instead -"//dot\ngraph {\n\t\"RGB: #40e0d0\" [fillcolor=\"#40e0d0\", style=\"filled\"]\ -\n\t\"RGBA: #ff000042\" [fillcolor=\"#ff000042\", style=\"filled\"]\n\t\"HSV: \ -0.051 0.718 0.627\" [fillcolor=\"0.051 0.718 0.627\", style=\"filled\"]\n\t\"n\ -ame: deeppink\" [fillcolor=\"deeppink\", style=\"filled\"]\n}\n" +//dot +graph { + "RGB: #40e0d0" [fillcolor="#40e0d0", style="filled"] + "RGBA: #ff000042" [fillcolor="#ff000042", style="filled"] + "HSV: 0.051 0.718 0.627" [fillcolor="0.051 0.718 0.627", style="filled"] + "name: deeppink" [fillcolor="deeppink", style="filled"] +} # gap> STOP_TEST("graphviz package: examples/colors.tst"); diff --git a/tst/examples/er.tst b/tst/examples/er.tst index c4fb0ef..508e8e2 100644 --- a/tst/examples/er.tst +++ b/tst/examples/er.tst @@ -10,8 +10,6 @@ # https://graphviz.readthedocs.io/en/stable/examples.html # https://graphviz.org/Gallery/undirected/ER.html - -#@local context1, context2, e, label, len, start gap> START_TEST("graphviz package: examples/er.tst"); gap> LoadPackage("GraphvizForGAP"); true @@ -104,7 +102,7 @@ gap> GraphvizSetAttrs(e, rec(fontsize := "20")); # -gap> AsString(e); +gap> Print(AsString(e), "\n"); #I invalid node name C-I using "C-I" instead #I invalid node name S-C using "S-C" instead #I invalid node name S-I using "S-I" instead @@ -114,18 +112,47 @@ gap> AsString(e); #I invalid node name S-I using "S-I" instead #I invalid node name S-C using "S-C" instead #I invalid node name S-C using "S-C" instead -"//dot\ngraph ER {\ngraph [engine=\"neato\", fontsize=\"20\", label=\"Entity \ -Relation Diagram\ndrawn by NEATO\"]\n// context_start context \n{\nnode [shap\ -e=\"box\"]\n\tcourse\n\tinstitute\n\tstudent\n}\n// context1 context \n{\nnode\ - [shape=\"ellipse\"]\n\tname0 [label=\"name\"]\n\tname1 [label=\"name\"]\n\tn\ -ame2 [label=\"name\"]\n\tcode\n\tgrade\n\tnumber\n}\n// context2 context \n{\n\ -node [color=\"lightgrey\", shape=\"diamond\", style=\"filled\"]\n\t\"C-I\"\n\ -\t\"S-C\"\n\t\"S-I\"\n}\n\tname0 -- course\n\tcode -- course\n\t\"C-I\" -- cou\ -rse [label=\"n\", len=\"1.00\"]\n\tinstitute -- \"C-I\" [label=\"1\", len=\"1.\ -00\"]\n\tname1 -- institute\n\t\"S-I\" -- institute [label=\"1\", len=\"1.00\"\ -]\n\tstudent -- \"S-I\" [label=\"n\", len=\"1.00\"]\n\tgrade -- student\n\tnam\ -e2 -- student\n\tnumber -- student\n\t\"S-C\" -- student [label=\"m\", len=\"1\ -.00\"]\n\tcourse -- \"S-C\" [label=\"n\", len=\"1.00\"]\n}\n" +//dot +graph ER { + graph [engine="neato", fontsize="20", label="Entity Relation Diagram +drawn by NEATO"] + { + // context "context_start" + node [shape="box"] + course + institute + student + } + { + // context "context1" + node [shape="ellipse"] + name0 [label="name"] + name1 [label="name"] + name2 [label="name"] + code + grade + number + } + { + // context "context2" + node [color="lightgrey", shape="diamond", style="filled"] + "C-I" + "S-C" + "S-I" + } + name0 -- course + code -- course + "C-I" -- course [label="n", len="1.00"] + institute -- "C-I" [label="1", len="1.00"] + name1 -- institute + "S-I" -- institute [label="1", len="1.00"] + student -- "S-I" [label="n", len="1.00"] + grade -- student + name2 -- student + number -- student + "S-C" -- student [label="m", len="1.00"] + course -- "S-C" [label="n", len="1.00"] +} # gap> STOP_TEST("graphviz package: examples/er.tst"); diff --git a/tst/examples/fsm.tst b/tst/examples/fsm.tst index ec10d81..c135252 100644 --- a/tst/examples/fsm.tst +++ b/tst/examples/fsm.tst @@ -73,17 +73,42 @@ gap> GraphvizSetAttr(GraphvizAddEdge(nodes, "LR_8", "LR_5"), "label", "\"S(a)\"" # -gap> AsString(f); -"//dot\ndigraph finite_state_machine {\ngraph [rankdir=\"LR\", size=\"8,5\"]\ -\n// terminals context \n{\nnode [shape=\"doublecircle\"]\n\tLR_0\n\tLR_3\n\t\ -LR_4\n\tLR_8\n}\n// nodes context \n{\nnode [shape=\"circle\"]\n\tLR_2\n\tLR_\ -0 -> LR_2 [label=\"SS(B)\"]\n\tLR_1\n\tLR_0 -> LR_1 [label=\"SS(S)\"]\n\tLR_1 \ --> LR_3 [label=\"S($end)\"]\n\tLR_6\n\tLR_2 -> LR_6 [label=\"SS(b)\"]\n\tLR_5\ -\n\tLR_2 -> LR_5 [label=\"SS(a)\"]\n\tLR_2 -> LR_4 [label=\"S(A)\"]\n\tLR_7\n\ -\tLR_5 -> LR_7 [label=\"S(b)\"]\n\tLR_5 -> LR_5 [label=\"S(a)\"]\n\tLR_6 -> LR\ -_6 [label=\"S(b)\"]\n\tLR_6 -> LR_5 [label=\"S(a)\"]\n\tLR_7 -> LR_8 [label=\"\ -S(b)\"]\n\tLR_7 -> LR_5 [label=\"S(a)\"]\n\tLR_8 -> LR_6 [label=\"S(b)\"]\n\tL\ -R_8 -> LR_5 [label=\"S(a)\"]\n}\n}\n" +gap> Print(AsString(f), "\n"); +//dot +digraph finite_state_machine { + graph [rankdir="LR", size="8,5"] + { + // context "terminals" + node [shape="doublecircle"] + LR_0 + LR_3 + LR_4 + LR_8 + } + { + // context "nodes" + node [shape="circle"] + LR_2 + LR_0 -> LR_2 [label="SS(B)"] + LR_1 + LR_0 -> LR_1 [label="SS(S)"] + LR_1 -> LR_3 [label="S($end)"] + LR_6 + LR_2 -> LR_6 [label="SS(b)"] + LR_5 + LR_2 -> LR_5 [label="SS(a)"] + LR_2 -> LR_4 [label="S(A)"] + LR_7 + LR_5 -> LR_7 [label="S(b)"] + LR_5 -> LR_5 [label="S(a)"] + LR_6 -> LR_6 [label="S(b)"] + LR_6 -> LR_5 [label="S(a)"] + LR_7 -> LR_8 [label="S(b)"] + LR_7 -> LR_5 [label="S(a)"] + LR_8 -> LR_6 [label="S(b)"] + LR_8 -> LR_5 [label="S(a)"] + } +} # gap> STOP_TEST("graphviz package: examples/fsm.tst"); diff --git a/tst/examples/g_c_n.tst b/tst/examples/g_c_n.tst index b555a79..cc60611 100644 --- a/tst/examples/g_c_n.tst +++ b/tst/examples/g_c_n.tst @@ -33,17 +33,17 @@ gap> GraphvizSetAttrs(cluster1, gap> GraphvizAddNode(cluster1, "anode"); -gap> Print(AsString(g)); +gap> Print(AsString(g), "\n"); //dot graph G { -graph [bgcolor="purple:pink", fontcolor="white", label="agraph"] -subgraph cluster1 { -graph [fillcolor="blue:cyan", fontcolor="white", gradientangle="270", label="\ -acluster", style="filled"] -node [fillcolor="red:yellow", gradientangle="90", shape="box", style="filled"\ -] - anode -} + graph [bgcolor="purple:pink", fontcolor="white", label="agraph"] + subgraph cluster1 { + graph [fillcolor="blue:cyan", fontcolor="white", gradientangle="270", labe\ +l="acluster", style="filled"] + node [fillcolor="red:yellow", gradientangle="90", shape="box", style="fill\ +ed"] + anode + } } # diff --git a/tst/examples/hello.tst b/tst/examples/hello.tst index daee715..b30cc9d 100644 --- a/tst/examples/hello.tst +++ b/tst/examples/hello.tst @@ -20,8 +20,13 @@ gap> graph := GraphvizDigraph("G"); gap> GraphvizAddEdge(graph, "hello", "world"); -gap> AsString(graph); -"//dot\ndigraph G {\n\thello\n\tworld\n\thello -> world\n}\n" +gap> Print(AsString(graph), "\n"); +//dot +digraph G { + hello + world + hello -> world +} # gap> STOP_TEST("graphviz package: examples/hello.tst"); diff --git a/tst/examples/process.tst b/tst/examples/process.tst index 0cfbd9c..e4f4b70 100644 --- a/tst/examples/process.tst +++ b/tst/examples/process.tst @@ -47,12 +47,33 @@ gap> GraphvizAddEdge(graph, "runswap", "runmem"); gap> GraphvizAddEdge(graph, "new", "runmem"); -gap> AsString(graph); -"//dot\ngraph G {\ngraph [engine=\"sfdp\"]\n\trun\n\tintr\n\trun -- intr\n\tr\ -unbl\n\tintr -- runbl\n\trunbl -- run\n\tkernel\n\trun -- kernel\n\tzombie\n\t\ -kernel -- zombie\n\tsleep\n\tkernel -- sleep\n\trunmem\n\tkernel -- runmem\n\t\ -swap\n\tsleep -- swap\n\trunswap\n\tswap -- runswap\n\tnew\n\trunswap -- new\n\ -\trunswap -- runmem\n\tnew -- runmem\n}\n" +gap> Print(AsString(graph), "\n"); +//dot +graph G { + graph [engine="sfdp"] + run + intr + run -- intr + runbl + intr -- runbl + runbl -- run + kernel + run -- kernel + zombie + kernel -- zombie + sleep + kernel -- sleep + runmem + kernel -- runmem + swap + sleep -- swap + runswap + swap -- runswap + new + runswap -- new + runswap -- runmem + new -- runmem +} # gap> STOP_TEST("graphviz package: examples/process.tst"); diff --git a/tst/examples/rank_same.tst b/tst/examples/rank_same.tst index 32f7f6d..64ca18b 100644 --- a/tst/examples/rank_same.tst +++ b/tst/examples/rank_same.tst @@ -58,10 +58,26 @@ gap> GraphvizAddEdge(g, "X", "Y"); # -gap> AsString(g); -"//dot\ndigraph {\nsubgraph no_name_1 {\ngraph [rank=\"same\"]\n\tA\n\tX\n}\ -\n\tC\nsubgraph no_name_3 {\ngraph [rank=\"same\"]\n\tB\n\tD\n\tY\n}\n\tA -> \ -B\n\tA -> C\n\tC -> D\n\tX -> Y\n}\n" +gap> Print(AsString(g), "\n"); +//dot +digraph { + subgraph no_name_1 { + graph [rank="same"] + A + X + } + C + subgraph no_name_3 { + graph [rank="same"] + B + D + Y + } + A -> B + A -> C + C -> D + X -> Y +} # gap> STOP_TEST("graphviz package: examples/rank_same.tst"); diff --git a/tst/examples/structs.tst b/tst/examples/structs.tst index 94eb987..5252598 100644 --- a/tst/examples/structs.tst +++ b/tst/examples/structs.tst @@ -63,18 +63,46 @@ gap> GraphvizAddEdge(s, "struct1:f2", "struct3:here"); # -gap> AsString(s : invalidDOT := "inappropriate addition of quotes to HTML labels FIXME"); -"//dot\ndigraph structs {\nnode [shape=\"plaintext\"]\n\tstruct1 [label=\"<\n\nleft\nmiddleright\n\n>\"]\n\tst\ -ruct2 [label=\"<\n\ -\n\n\n\n
onetwo
>\"]\n\tstruct3 [labe\ -l=\"<\ -\n\n\n\n\n\n\n\n\n\n\n\n\n\n\ -\n
hello
world
bgh
cde
f
>\"]\n\tstruct1:f1\n\tstruct2:f0\n\tstruct1:f1 -> struct2:f0\n\tstru\ -ct1:f2\n\tstruct3:here\n\tstruct1:f2 -> struct3:here\n}\n" +gap> Print(AsString(s : invalidDOT := "inappropriate addition of quotes to HTML labels FIXME"), "\n"); +//dot +digraph structs { + node [shape="plaintext"] + struct1 [label="< + + + + +
leftmiddleright
>"] + struct2 [label="< + + + + +
onetwo
>"] + struct3 [label="< + + + + + + + + + + + + + + +
hello
world
bgh
cde
f
>"] + struct1:f1 + struct2:f0 + struct1:f1 -> struct2:f0 + struct1:f2 + struct3:here + struct1:f2 -> struct3:here +} # gap> STOP_TEST("graphviz package: examples/structs.tst"); diff --git a/tst/examples/traffic_lights.tst b/tst/examples/traffic_lights.tst index 5ad450a..31f3ba7 100644 --- a/tst/examples/traffic_lights.tst +++ b/tst/examples/traffic_lights.tst @@ -78,16 +78,48 @@ gap> GraphvizSetAttrs(t, rec(fontsize := "12")); # -gap> AsString(t); -"//dot\ndigraph TrafficLights {\ngraph [engine=\"neato\", fontsize=\"12\", la\ -bel=\"PetriNet Model TrafficLights\nExtracted from ConceptBase and laid out by\ - Graphviz\", overlap=\"false\"]\nsubgraph ctx1 {\nnode [shape=\"box\"]\n\tgy2\ -\n\tyr2\n\trg2\n\tgy1\n\tyr1\n\trg1\n}\nsubgraph ctx2 {\nnode [fixedsize=\"tr\ -ue\", shape=\"circle\", width=\"0.9\"]\n\tgreen2\n\tyellow2\n\tred2\n\tsafe2\n\ -\tgreen1\n\tyellow1\n\tred1\n\tsafe1\n}\n\tgy2 -> yellow2\n\trg2 -> green2\n\t\ -yr2 -> safe1\n\tyr2 -> red2\n\tsafe2 -> rg2\n\tgreen2 -> gy2\n\tyellow2 -> yr2\ -\n\tred2 -> rg2\n\tgy1 -> yellow1\n\trg1 -> green1\n\tyr1 -> safe2\n\tyr1 -> r\ -ed1\n\tsafe1 -> rg1\n\tgreen1 -> gy1\n\tyellow1 -> yr1\n\tred1 -> rg1\n}\n" +gap> Print(AsString(t), "\n"); +//dot +digraph TrafficLights { + graph [engine="neato", fontsize="12", label="PetriNet Model TrafficLights +Extracted from ConceptBase and laid out by Graphviz", overlap="false"] + subgraph ctx1 { + node [shape="box"] + gy2 + yr2 + rg2 + gy1 + yr1 + rg1 + } + subgraph ctx2 { + node [fixedsize="true", shape="circle", width="0.9"] + green2 + yellow2 + red2 + safe2 + green1 + yellow1 + red1 + safe1 + } + gy2 -> yellow2 + rg2 -> green2 + yr2 -> safe1 + yr2 -> red2 + safe2 -> rg2 + green2 -> gy2 + yellow2 -> yr2 + red2 -> rg2 + gy1 -> yellow1 + rg1 -> green1 + yr1 -> safe2 + yr1 -> red1 + safe1 -> rg1 + green1 -> gy1 + yellow1 -> yr1 + red1 -> rg1 +} # gap> STOP_TEST("graphviz package: examples/traffic_lights.tst"); diff --git a/tst/examples/unix.tst b/tst/examples/unix.tst index 63ea0e7..9e62998 100644 --- a/tst/examples/unix.tst +++ b/tst/examples/unix.tst @@ -124,37 +124,7 @@ gap> GraphvizAddEdge(u, "System V.2", "System V.3"); # -gap> AsString(u) = -> "//dot\ndigraph unix {\nnode [color=\"lightblue2\", size=\"6,6\", style=\"fil\ -> led\"]\n\t\"5th Edition\"\n\t\"6th Edition\"\n\t\"5th Edition\" -> \"6th Editi\ -> on\"\n\t\"PWB 1.0\"\n\t\"5th Edition\" -> \"PWB 1.0\"\n\tLSX\n\t\"6th Edition\ -> \" -> LSX\n\t\"1 BSD\"\n\t\"6th Edition\" -> \"1 BSD\"\n\t\"Mini Unix\"\n\t\"6\ -> th Edition\" -> \"Mini Unix\"\n\tWollongong\n\t\"6th Edition\" -> Wollongong\n\ -> \tInterdata\n\t\"6th Edition\" -> Interdata\n\t\"Unix/TS 3.0\"\n\t\"Unix/TS 3.\ -> 0\" -> Interdata\n\t\"PWB 2.0\"\n\tInterdata -> \"PWB 2.0\"\n\t\"7th Edition\"\ -> \n\tInterdata -> \"7th Edition\"\n\t\"8th Edition\"\n\t\"7th Edition\" -> \"8t\ -> h Edition\"\n\t\"32V\"\n\t\"7th Edition\" -> \"32V\"\n\tV7M\n\t\"7th Edition\"\ -> -> V7M\n\t\"Ultrix-11\"\n\t\"7th Edition\" -> \"Ultrix-11\"\n\tXenix\n\t\"7th\ -> Edition\" -> Xenix\n\t\"UniPlus+\"\n\t\"7th Edition\" -> \"UniPlus+\"\n\tV7M \ -> -> \"Ultrix-11\"\n\t\"9th Edition\"\n\t\"8th Edition\" -> \"9th Edition\"\n\t\ -> \"2 BSD\"\n\t\"1 BSD\" -> \"2 BSD\"\n\t\"2.8 BSD\"\n\t\"2 BSD\" -> \"2.8 BSD\"\ -> \n\t\"2.8 BSD\" -> \"Ultrix-11\"\n\t\"2.9 BSD\"\n\t\"2.8 BSD\" -> \"2.9 BSD\"\ -> \n\t\"3 BSD\"\n\t\"32V\" -> \"3 BSD\"\n\t\"4 BSD\"\n\t\"3 BSD\" -> \"4 BSD\"\n\ -> \t\"4.1 BSD\"\n\t\"4 BSD\" -> \"4.1 BSD\"\n\t\"4.2 BSD\"\n\t\"4.1 BSD\" -> \"4\ -> .2 BSD\"\n\t\"4.1 BSD\" -> \"2.8 BSD\"\n\t\"4.1 BSD\" -> \"8th Edition\"\n\t\"\ -> 4.3 BSD\"\n\t\"4.2 BSD\" -> \"4.3 BSD\"\n\t\"Ultrix-32\"\n\t\"4.2 BSD\" -> \"U\ -> ltrix-32\"\n\t\"PWB 1.2\"\n\t\"PWB 1.0\" -> \"PWB 1.2\"\n\t\"USG 1.0\"\n\t\"PW\ -> B 1.0\" -> \"USG 1.0\"\n\t\"PWB 1.2\" -> \"PWB 2.0\"\n\t\"CB Unix 1\"\n\t\"USG\ -> 1.0\" -> \"CB Unix 1\"\n\t\"USG 2.0\"\n\t\"USG 1.0\" -> \"USG 2.0\"\n\t\"CB U\ -> nix 2\"\n\t\"CB Unix 1\" -> \"CB Unix 2\"\n\t\"CB Unix 3\"\n\t\"CB Unix 2\" ->\ -> \"CB Unix 3\"\n\t\"Unix/TS++\"\n\t\"CB Unix 3\" -> \"Unix/TS++\"\n\t\"PDP-11 \ -> Sys V\"\n\t\"CB Unix 3\" -> \"PDP-11 Sys V\"\n\t\"USG 3.0\"\n\t\"USG 2.0\" -> \ -> \"USG 3.0\"\n\t\"USG 3.0\" -> \"Unix/TS 3.0\"\n\t\"PWB 2.0\" -> \"Unix/TS 3.0\ -> \"\n\t\"Unix/TS 1.0\"\n\t\"Unix/TS 1.0\" -> \"Unix/TS 3.0\"\n\t\"TS 4.0\"\n\t\ -> \"Unix/TS 3.0\" -> \"TS 4.0\"\n\t\"Unix/TS++\" -> \"TS 4.0\"\n\t\"CB Unix 3\" \ -> -> \"TS 4.0\"\n\t\"System V.0\"\n\t\"TS 4.0\" -> \"System V.0\"\n\t\"System V.\ -> 2\"\n\t\"System V.0\" -> \"System V.2\"\n\t\"System V.3\"\n\t\"System V.2\" ->\ -> \"System V.3\"\n}\n"; +gap> Print(AsString(u), "\n"); #I invalid node name 5th Edition using "5th Edition" instead #I invalid node name 6th Edition using "6th Edition" instead #I invalid node name 5th Edition using "5th Edition" instead @@ -280,7 +250,100 @@ gap> AsString(u) = #I invalid node name System V.3 using "System V.3" instead #I invalid node name System V.2 using "System V.2" instead #I invalid node name System V.3 using "System V.3" instead -true +//dot +digraph unix { + node [color="lightblue2", size="6,6", style="filled"] + "5th Edition" + "6th Edition" + "5th Edition" -> "6th Edition" + "PWB 1.0" + "5th Edition" -> "PWB 1.0" + LSX + "6th Edition" -> LSX + "1 BSD" + "6th Edition" -> "1 BSD" + "Mini Unix" + "6th Edition" -> "Mini Unix" + Wollongong + "6th Edition" -> Wollongong + Interdata + "6th Edition" -> Interdata + "Unix/TS 3.0" + "Unix/TS 3.0" -> Interdata + "PWB 2.0" + Interdata -> "PWB 2.0" + "7th Edition" + Interdata -> "7th Edition" + "8th Edition" + "7th Edition" -> "8th Edition" + "32V" + "7th Edition" -> "32V" + V7M + "7th Edition" -> V7M + "Ultrix-11" + "7th Edition" -> "Ultrix-11" + Xenix + "7th Edition" -> Xenix + "UniPlus+" + "7th Edition" -> "UniPlus+" + V7M -> "Ultrix-11" + "9th Edition" + "8th Edition" -> "9th Edition" + "2 BSD" + "1 BSD" -> "2 BSD" + "2.8 BSD" + "2 BSD" -> "2.8 BSD" + "2.8 BSD" -> "Ultrix-11" + "2.9 BSD" + "2.8 BSD" -> "2.9 BSD" + "3 BSD" + "32V" -> "3 BSD" + "4 BSD" + "3 BSD" -> "4 BSD" + "4.1 BSD" + "4 BSD" -> "4.1 BSD" + "4.2 BSD" + "4.1 BSD" -> "4.2 BSD" + "4.1 BSD" -> "2.8 BSD" + "4.1 BSD" -> "8th Edition" + "4.3 BSD" + "4.2 BSD" -> "4.3 BSD" + "Ultrix-32" + "4.2 BSD" -> "Ultrix-32" + "PWB 1.2" + "PWB 1.0" -> "PWB 1.2" + "USG 1.0" + "PWB 1.0" -> "USG 1.0" + "PWB 1.2" -> "PWB 2.0" + "CB Unix 1" + "USG 1.0" -> "CB Unix 1" + "USG 2.0" + "USG 1.0" -> "USG 2.0" + "CB Unix 2" + "CB Unix 1" -> "CB Unix 2" + "CB Unix 3" + "CB Unix 2" -> "CB Unix 3" + "Unix/TS++" + "CB Unix 3" -> "Unix/TS++" + "PDP-11 Sys V" + "CB Unix 3" -> "PDP-11 Sys V" + "USG 3.0" + "USG 2.0" -> "USG 3.0" + "USG 3.0" -> "Unix/TS 3.0" + "PWB 2.0" -> "Unix/TS 3.0" + "Unix/TS 1.0" + "Unix/TS 1.0" -> "Unix/TS 3.0" + "TS 4.0" + "Unix/TS 3.0" -> "TS 4.0" + "Unix/TS++" -> "TS 4.0" + "CB Unix 3" -> "TS 4.0" + "System V.0" + "TS 4.0" -> "System V.0" + "System V.2" + "System V.0" -> "System V.2" + "System V.3" + "System V.2" -> "System V.3" +} # gap> STOP_TEST("graphviz package: examples/unix.tst"); diff --git a/tst/graph.tst b/tst/graph.tst index 6eba0ac..c5b70de 100644 --- a/tst/graph.tst +++ b/tst/graph.tst @@ -179,8 +179,11 @@ rec( edge := rec( ), graph := rec( color := "red" ), node := rec( ) ) gap> g := GraphvizGraph();; gap> GraphvizSetAttr(g, "color", "red");; gap> GraphvizSetAttr(g, "color", "blue");; -gap> AsString(g); -"//dot\ngraph {\ngraph [color=\"blue\"]\n}\n" +gap> Print(AsString(g), "\n"); +//dot +graph { + graph [color="blue"] +} # # Test removing attributes from a graph TODO uncomment or delete # gap> g := GraphvizGraph();; diff --git a/tst/node.tst b/tst/node.tst index 3d9b9d3..89e6235 100644 --- a/tst/node.tst +++ b/tst/node.tst @@ -54,15 +54,21 @@ rec( shape := "circle" ) # Test name containing ':' gap> g := GraphvizGraph();; gap> GraphvizAddNode(g, "test:colon");; -gap> AsString(g); -"//dot\ngraph {\n\ttest:colon\n}\n" +gap> Print(AsString(g), "\n"); +//dot +graph { + test:colon +} # Test non-string name containing ':' gap> g := GraphvizGraph();; gap> n := GraphvizAddNode(g, 111); -gap> AsString(g); -"//dot\ngraph {\n\t111\n}\n" +gap> Print(AsString(g), "\n"); +//dot +graph { + 111 +} gap> GraphvizGetAttr(n, 1); fail gap> GraphvizSetAttr(n, 1, 2); diff --git a/tst/subgraph.tst b/tst/subgraph.tst index ba19045..8182137 100644 --- a/tst/subgraph.tst +++ b/tst/subgraph.tst @@ -149,9 +149,18 @@ gap> GraphvizAddEdge(g, "x", "y");; gap> GraphvizSetAttr(s, "color", "red");; gap> GraphvizSetAttrs(s, rec(node := rec(color := "red")));; gap> GraphvizSetAttrs(s, rec(edge := rec(color := "red")));; -gap> AsString(g); -"//dot\ndigraph {\nsubgraph a {\ngraph [color=\"red\"]\nnode [color=\"red\"\ -]\nedge [color=\"red\"]\n}\n\tx\n\ty\n\tx -> y\n}\n" +gap> Print(AsString(g), "\n"); +//dot +digraph { + subgraph a { + graph [color="red"] + node [color="red"] + edge [color="red"] + } + x + y + x -> y +} # Test stringifying subgraph graph gap> g := GraphvizGraph();; @@ -160,9 +169,18 @@ gap> GraphvizAddEdge(g, "x", "y");; gap> GraphvizSetAttr(s, "color", "red");; gap> GraphvizSetAttrs(s, rec(node := rec(color := "red")));; gap> GraphvizSetAttrs(s, rec(edge := rec(color := "red")));; -gap> AsString(g); -"//dot\ngraph {\nsubgraph a {\ngraph [color=\"red\"]\nnode [color=\"red\"]\ -\nedge [color=\"red\"]\n}\n\tx\n\ty\n\tx -- y\n}\n" +gap> Print(AsString(g), "\n"); +//dot +graph { + subgraph a { + graph [color="red"] + node [color="red"] + edge [color="red"] + } + x + y + x -- y +} # Test stringifying subgraph context (graph) gap> g := GraphvizGraph();; @@ -171,9 +189,19 @@ gap> GraphvizAddEdge(g, "x", "y");; gap> GraphvizSetAttr(s, "color", "red");; gap> GraphvizSetAttrs(s, rec(node := rec(color := "red")));; gap> GraphvizSetAttrs(s, rec(edge := rec(color := "red")));; -gap> AsString(g); -"//dot\ngraph {\n// a context \n{\ngraph [color=\"red\"]\nnode [color=\"red\ -\"]\nedge [color=\"red\"]\n}\n\tx\n\ty\n\tx -- y\n}\n" +gap> Print(AsString(g), "\n"); +//dot +graph { + { + // context "a" + graph [color="red"] + node [color="red"] + edge [color="red"] + } + x + y + x -- y +} # Test stringifying subgraph context (digraph) gap> g := GraphvizDigraph();; @@ -182,15 +210,29 @@ gap> GraphvizAddEdge(g, "x", "y");; gap> GraphvizSetAttr(s, "color", "red");; gap> GraphvizSetAttrs(s, rec(node := rec(color := "red")));; gap> GraphvizSetAttrs(s, rec(edge := rec(color := "red")));; -gap> AsString(g); -"//dot\ndigraph {\n// a context \n{\ngraph [color=\"red\"]\nnode [color=\"r\ -ed\"]\nedge [color=\"red\"]\n}\n\tx\n\ty\n\tx -> y\n}\n" +gap> Print(AsString(g), "\n"); +//dot +digraph { + { + // context "a" + graph [color="red"] + node [color="red"] + edge [color="red"] + } + x + y + x -> y +} # Test stringifying subgraph w/o name gap> g := GraphvizDigraph();; gap> s := GraphvizAddSubgraph(g);; -gap> AsString(g); -"//dot\ndigraph {\nsubgraph no_name_1 {\n}\n}\n" +gap> Print(AsString(g), "\n"); +//dot +digraph { + subgraph no_name_1 { + } +} # finding a node in a sibling graph gap> g := GraphvizDigraph();; @@ -258,10 +300,18 @@ gap> GraphvizSetAttrs(g, rec(node := rec(color := "blue"), > edge := rec(label := "testing123", color := "blue")));; gap> GraphvizSetAttrs(ctx, rec(node := rec(color := "red")));; gap> GraphvizAddNode(ctx, "a");; -gap> AsString(g); -"//dot\ndigraph {\ngraph [color=\"green\"]\nnode [color=\"blue\"]\nedge [c\ -olor=\"blue\", label=\"testing123\"]\n// no_name_1 context \n{\nnode [color=\ -\"red\"]\n\ta\n}\n}\n" +gap> Print(AsString(g), "\n"); +//dot +digraph { + graph [color="green"] + node [color="blue"] + edge [color="blue", label="testing123"] + { + // context "no_name_1" + node [color="red"] + a + } +} # Test adding subgraphs with the same name gap> g := GraphvizDigraph();; @@ -307,8 +357,14 @@ gap> GraphvizSubgraphs(s1).c; gap> g := GraphvizGraph();; gap> s1 := GraphvizAddSubgraph(g, "a");; gap> s2 := GraphvizAddSubgraph(s1, "c");; -gap> AsString(g); -"//dot\ngraph {\nsubgraph a {\nsubgraph c {\n}\n}\n}\n" +gap> Print(AsString(g), "\n"); +//dot +graph { + subgraph a { + subgraph c { + } + } +} # Test subgraphs with non-string names gap> g := GraphvizGraph();; @@ -379,18 +435,38 @@ gap> g := GraphvizGraph("g");; gap> parent := GraphvizAddContext(g, "parent");; gap> ctx := GraphvizAddContext(parent, "ctx");; gap> GraphvizAddEdge(ctx, "a", "b");; -gap> AsString(g); -"//dot\ngraph g {\n// parent context \n{\n// ctx context \n{\n\ta\n\tb\n\ta --\ - b\n}\n}\n}\n" +gap> Print(AsString(g), "\n"); +//dot +graph g { + { + // context "parent" + { + // context "ctx" + a + b + a -- b + } + } +} # Test nested contexts have correct edge types (digraph) gap> g := GraphvizDigraph("g");; gap> parent := GraphvizAddContext(g, "parent");; gap> ctx := GraphvizAddContext(parent, "ctx");; gap> GraphvizAddEdge(ctx, "a", "b");; -gap> AsString(g); -"//dot\ndigraph g {\n// parent context \n{\n// ctx context \n{\n\ta\n\tb\n\ta \ --> b\n}\n}\n}\n" +gap> Print(AsString(g), "\n"); +//dot +digraph g { + { + // context "parent" + { + // context "ctx" + a + b + a -> b + } + } +} # Test finding subgraph (non-string name) gap> g := GraphvizGraph("r");; @@ -410,9 +486,17 @@ gap> GraphvizSetAttrs(legend, rec(node := rec(shape := "plaintext"))); gap> GraphvizAddSubgraph(legend, "legend"); -gap> AsString(gv); -"//dot\ngraph context_and_subgraph {\nnode [shape=\"box\"]\n// legend context\ - \n{\nnode [shape=\"plaintext\"]\nsubgraph legend {\n}\n}\n}\n" +gap> Print(AsString(gv), "\n"); +//dot +graph context_and_subgraph { + node [shape="box"] + { + // context "legend" + node [shape="plaintext"] + subgraph legend { + } + } +} # Test a context containing a subdigraph gap> gv := GraphvizDigraph("context+subgraph");;