From b179a9118f5b3c3233f174f4b677d5e001b22815 Mon Sep 17 00:00:00 2001 From: mpan Date: Wed, 19 Jun 2024 15:22:59 +0100 Subject: [PATCH 1/9] initial updates to docs + updated the PackageInfo --- PackageInfo.g | 2 ++ gap/dot.gd | 79 ++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 62 insertions(+), 19 deletions(-) diff --git a/PackageInfo.g b/PackageInfo.g index cfb5046..ed94b02 100644 --- a/PackageInfo.g +++ b/PackageInfo.g @@ -31,6 +31,8 @@ Persons := [ rec( FirstNames := "Matthew", LastName := "Pancer", + WWWHome := "https://github.com/mpan322", + # TODO make personal website Email := "mp322@st-andrews.ac.uk", IsAuthor := true, IsMaintainer := true, diff --git a/gap/dot.gd b/gap/dot.gd index 0e6183a..c506c29 100644 --- a/gap/dot.gd +++ b/gap/dot.gd @@ -29,7 +29,8 @@ #! @Section Graphviz Categories -#! @BeginGroup Filters +#! @BeginGroup +#! @GroupTitle Filters #! @Description Every object in graphviz belongs to the IsGraphvizObject #! category. The categories following it are for further specificity on the #! type of objects. These are graphs, digraphs, nodes and edges respectively. @@ -73,6 +74,8 @@ DeclareOperation("GraphvizDigraph", []); #! objects. #! @Subsection For all graphviz objects. +#! This section covers the operations for getting information about any graphviz +#! object. #! @Arguments obj #! @Returns the name of the provided graphviz object @@ -85,18 +88,20 @@ DeclareOperation("GraphvizName", [IsGraphvizObject]); DeclareOperation("GraphvizAttrs", [IsGraphvizObject]); #! @Subsection For only graphs and digraphs. +#! This section covers the operations for getting information about graphviz +#! objects. #! @Arguments graph #! @Returns the nodes of the provided graphviz graph. #! @Description Gets the nodes of the provided graphviz graph. -# From https://graphviz.org/doc/info/lang.html -# An ID is one of the following: -# Any string of alphabetic ([a-zA-Z\200-\377]) characters, underscores ('_') or -# digits([0-9]), not beginning with a digit; -# a numeral [-]?(.[0-9]⁺ | [0-9]⁺(.[0-9]*)? ); -# any double-quoted string ("...") possibly containing escaped quotes (\")¹; -# an HTML string (<...>). -# TODO specify +#! From https://graphviz.org/doc/info/lang.html +#! An ID is one of the following: +#! Any string of alphabetic ([a-zA-Z\200-\377]) characters, underscores ('_') or +#! digits([0-9]), not beginning with a digit; +#! a numeral [-]?(.[0-9]⁺ | [0-9]⁺(.[0-9]*)? ); +#! any double-quoted string ("...") possibly containing escaped quotes (\")¹; +#! an HTML string (<...>). +#! TODO specify DeclareOperation("GraphvizNodes", [IsGraphvizGraphDigraphOrContext]); #! @Arguments graph @@ -116,18 +121,25 @@ DeclareOperation("GraphvizContexts", [IsGraphvizGraphDigraphOrContext]); #! Searches through the tree of subgraphs connected to this subgraph for a graph #! with the provided name. #! It returns the graph if it exists. -#! If no such graph exists then it will return fail. +#! If no such graph exists then it will return fail. DeclareOperation("GraphvizFindSubgraphRecursive", [IsGraphvizGraphDigraphOrContext, IsObject]); +#! @BeginGroup +#! @GroupTitle Getting Graphviz Edges #! @Arguments graph #! @Returns the edges of the provided graphviz graph. #! @Description Gets the edges of the provided graphviz graph. +#! If a head and tail are provided will only return edges +#! between those two nodes. DeclareOperation("GraphvizEdges", [IsGraphvizGraphDigraphOrContext]); +#! @Arguments graph, head, tail DeclareOperation("GraphvizEdges", [IsGraphvizGraphDigraphOrContext, IsObject, IsObject]); +#! @EndGroup #! @Subsection For only edges. +#! This section contains getters only applicable to graphviz edges. #! @Arguments edge #! @Returns the head of the provided graphviz edge. @@ -150,37 +162,66 @@ DeclareOperation("GraphvizTail", [IsGraphvizEdge]); DeclareOperation("GraphvizSetName", [IsGraphvizGraphDigraphOrContext, IsObject]); #! @Arguments graph, node -#! @Returns the modified graph. +#! @Returns the modified node. #! @Description Adds a node to the graph. #! If a node with the same name is already present the operation fails. DeclareOperation("GraphvizAddNode", [IsGraphvizGraphDigraphOrContext, IsObject]); -#! @Arguments graph, edge -#! @Returns the modified graph. -#! @Description Adds an edge to the graph. -#! If no nodes with the same name are in the graph then the edge's nodes will be -#! added to the graph. If different nodes with the same name are in the graph -#! then the operation fails. +#! @Arguments graph, head, tail +#! @Returns the new edge. +#! @Description adds an edge to the graph. +#! The head and tail can be objects, strings or graphviz nodes. +#! If the head and tail they will be converted to strings. +#! If strings are then interpreted as the names nodes. +#! If no nodes with the same name are in the graph, nodes automatically will be +#! added to the graph. +#! If there are nodes with the same name, they will be used. +#! However, if such nodes exist but are not the same objects as the provided +#! If different nodes with the same name are in the graph +#! head and tail, then the operation will fail. DeclareOperation("GraphvizAddEdge", [IsGraphvizGraphDigraphOrContext, IsObject, IsObject]); -#! @Arguments graph, filter, name +#! @BeginGroup +#! @GroupTitle Adding Subgraphs +#! @Arguments graph, name #! @Returns the new subgraph. #! @Description Adds a subgraph to a graph. +#! The type of graph (graph or digraph) will be the same as the parent graph. DeclareOperation("GraphvizAddSubgraph", [IsGraphvizGraphDigraphOrContext, IsObject]); +#! @Arguments graph DeclareOperation("GraphvizAddSubgraph", [IsGraphvizGraphDigraphOrContext]); +#! @EndGroup -#! @Arguments graph, filter, name +#! @BeginGroup +#! @GroupTitle Adding Contexts +#! @Arguments graph, name #! @Returns the new context. #! @Description Adds a context to a graph. +#! A context can be thought as being similar to a subgraph +#! when manipulating it in this package. +#! However, when rendered contexts do not +#! create a subgraph in outputted DOT code. +#! Instead their nodes are rendered inline within the parent graph. +#! This allows for scoping node and edge attributes +#! without modifying the rendering behaviour. +#! The type of graph edge (directed or undirected) +#! will be the same as the parent graph. DeclareOperation("GraphvizAddContext", [IsGraphvizGraphDigraphOrContext, IsObject]); +#! @Arguments graph DeclareOperation("GraphvizAddContext", [IsGraphvizGraphDigraphOrContext]); +#! @EndGroup #! @Arguments graph, node #! @Returns the modified graph. #! @Description Removes the node from the graph. +#! The node attribute may be an object, string or graphviz node. +#! Objects will be converted to strings. +#! Strings are then interpreted as the name of the node to remove. +#! All edges containing the node are also removed. +#! If no such node exists the operation fails. DeclareOperation("GraphvizRemoveNode", [IsGraphvizGraphDigraphOrContext, IsObject]); From bb1f2797a453dee12827594810269a52128a50a5 Mon Sep 17 00:00:00 2001 From: mpan Date: Fri, 21 Jun 2024 16:30:34 +0100 Subject: [PATCH 2/9] docs for functions pretty much done --- gap/dot.gd | 164 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 104 insertions(+), 60 deletions(-) diff --git a/gap/dot.gd b/gap/dot.gd index 075d6a8..804d250 100644 --- a/gap/dot.gd +++ b/gap/dot.gd @@ -28,22 +28,21 @@ #! @ChapterTitle The Graphviz Package #! @Section Graphviz Categories - -#! @BeginGroup -#! @GroupTitle Filters -#! @Description Every object in graphviz belongs to the IsGraphvizObject -#! category. The categories following it are for further specificity on the -#! type of objects. These are graphs, digraphs, nodes and edges respectively. -#! All are direct subcategories of IsGraphvizObject excluding IsGraphvizDigraph -#! which is a subcategory of is IsGraphvizGraph. - +#! @Description Every object in graphviz belongs to this category. DeclareCategory("IsGraphvizObject", IsObject); +#! @BeginGroup +#! @GroupTitle Graphs, digraphs and contexts +#! @Description These categories are for objects with graph like behaviour eg. +#! they can contain nodes, edges, subgraphs, etc. DeclareCategory("IsGraphvizGraphDigraphOrContext", IsGraphvizObject); DeclareCategory("IsGraphvizGraph", IsGraphvizGraphDigraphOrContext); DeclareCategory("IsGraphvizDigraph", IsGraphvizGraphDigraphOrContext); DeclareCategory("IsGraphvizContext", IsGraphvizGraphDigraphOrContext); +#! @EndGroup +#! @BeginGroup +#! @GroupTitle Nodes and edges DeclareCategory("IsGraphvizNodeOrEdge", IsGraphvizObject); DeclareCategory("IsGraphvizNode", IsGraphvizNodeOrEdge); DeclareCategory("IsGraphvizEdge", IsGraphvizNodeOrEdge); @@ -87,26 +86,22 @@ DeclareOperation("GraphvizName", [IsGraphvizObject]); #! @Description Gets the attributes of the provided graphviz object. DeclareOperation("GraphvizAttrs", [IsGraphvizObject]); -#! @Subsection For only graphs and digraphs. +#! @Subsection For only graphs, digraphs and contexts. #! This section covers the operations for getting information about graphviz -#! objects. +#! graphs, digraphs and contexts. #! @Arguments graph -#! @Returns the nodes of the provided graphviz graph. +#! @Returns the nodes of the provided graphviz graph +#! as a mapping from node ids to names. #! @Description Gets the nodes of the provided graphviz graph. -#! From https://graphviz.org/doc/info/lang.html -#! An ID is one of the following: -#! Any string of alphabetic ([a-zA-Z\200-\377]) characters, underscores ('_') or -#! digits([0-9]), not beginning with a digit; -#! a numeral [-]?(.[0-9]⁺ | [0-9]⁺(.[0-9]*)? ); -#! any double-quoted string ("...") possibly containing escaped quotes (\")¹; -#! an HTML string (<...>). -#! TODO specify +#! What constitutes a valid node ID +#! is defined here "https://graphviz.org/doc/info/lang.html". DeclareOperation("GraphvizNodes", [IsGraphvizGraphDigraphOrContext]); #! @Arguments graph #! @Returns the subgraphs of the provided graphviz graph. #! @Description gets the subgraphs of a provided graphviz graph. +#! Subgraphs are returned as a mapping from subgraph name to object. DeclareOperation("GraphvizSubgraphs", [IsGraphvizGraphDigraphOrContext]); #! @Arguments graph @@ -129,7 +124,9 @@ DeclareOperation("GraphvizFindSubgraphRecursive", #! @GroupTitle Getting Graphviz Edges #! @Arguments graph #! @Returns the edges of the provided graphviz graph. -#! @Description Gets the edges of the provided graphviz graph. +#! @Description +#! Gets the edges of the provided graphviz graph. +#! Returns a list of edge objects. #! If a head and tail are provided will only return edges #! between those two nodes. DeclareOperation("GraphvizEdges", [IsGraphvizGraphDigraphOrContext]); @@ -161,32 +158,30 @@ DeclareOperation("GraphvizTail", [IsGraphvizEdge]); #! @Description Sets the name of a graphviz graph or digraph. DeclareOperation("GraphvizSetName", [IsGraphvizGraphDigraphOrContext, IsObject]); -#! @Arguments graph, node -#! @Returns the modified node. -#! @Description Adds a node to the graph. -#! If a node with the same name is already present the operation fails. +#! @Arguments graph, id +#! @Returns the new node. +#! @Description Adds a node to the graph with ID id. +#! If the id parameter is not string it will be converted to one. +#! If a node with the same id is already present the operation fails. +#! What constitutes a valid node ID +#! is defined here "https://graphviz.org/doc/info/lang.html". +#! Currently nodes cannot be added directly to graphs, so +#! if id is of type GraphvizNode it will fail. DeclareOperation("GraphvizAddNode", [IsGraphvizGraphDigraphOrContext, IsObject]); #! @Arguments graph, head, tail #! @Returns the new edge. #! @Description adds an edge to the graph. -#! The head and tail can be objects, strings or graphviz nodes. -#! If the head and tail they will be converted to strings. -#! If strings are then interpreted as the names nodes. -#! If no nodes with the same name are in the graph, nodes automatically will be +#! The head and tail can be +#! general objects, strings or graphviz nodes. +#! If the head and tail are general objects, they will +#! be converted to strings. +#! Strings are then interpreted as node IDs. +#! If no nodes with the same id are in the (di)graph, nodes automatically will be #! added to the graph. -#! If there are nodes with the same name, they will be used. -#! However, if such nodes exist but are not the same objects as the provided -#! If different nodes with the same name are in the graph -#! head and tail, then the operation will fail. -#! @Arguments graph, edge -#! @Returns the modified graph. -#! @Description Adds an edge to the graph. -#! If no nodes with the same name are in the graph then the edge's nodes will be -#! added to the graph. If different nodes with the same name are in the graph -#! then the operation fails. -#! TODO I dont believe this is accurate - think it will connect existing ones -#! underlying private function would fail though - TODO double check. +#! If there are nodes with the same id, they will be used. +#! TODO: are we happy with this behaviour? +#! I think if fail if they have the same id but different objects. DeclareOperation("GraphvizAddEdge", [IsGraphvizGraphDigraphOrContext, IsObject, IsObject]); @@ -227,7 +222,7 @@ DeclareOperation("GraphvizAddContext", [IsGraphvizGraphDigraphOrContext]); #! @Description Removes the node from the graph. #! The node attribute may be an object, string or graphviz node. #! Objects will be converted to strings. -#! Strings are then interpreted as the name of the node to remove. +#! Strings are then interpreted as the id of the node to remove. #! All edges containing the node are also removed. #! If no such node exists the operation fails. DeclareOperation("GraphvizRemoveNode", @@ -239,29 +234,41 @@ DeclareOperation("GraphvizRemoveNode", DeclareOperation("GraphvizFilterEdges", [IsGraphvizGraphDigraphOrContext, IsFunction]); -#! @Arguments graph, head_name, tail_name +#! @Arguments graph, head_id, tail_id #! @Returns the modified graph. -#! @Description Filters the graph's edges, removing edges between nodes with -#! the specified names. +#! @Description +#! Filters the graph's edges, removing edges between nodes with +#! the specified ids. +#! If no edges exist between the two nodes, the operation fails. DeclareOperation("GraphvizRemoveEdges", [IsGraphvizGraphDigraphOrContext, IsObject, IsObject]); -#! @Subsection For modifying object attributes. +#! @Subsection Modifying object attributes +#! Operations for modifying attributes. +#! @BeginGroup +#! @GroupTitle Setting Attributes #! @Arguments obj, attrs #! @Returns the modified object. #! @Description -#! Updates the attributes of the object. -#! All current attributes remain. -#! If an attribute already exists and a new value is provided, the old value -#! will be overwritten. +#! Updates the attributes of the object. +#! All current attributes remain. +#! If an attribute already exists and a new value is provided, the old value +#! will be overwritten. DeclareOperation("GraphvizSetAttrs", [IsGraphvizObject, IsRecord]); +#! @Arguments obj, name, value DeclareOperation("GraphvizSetAttr", [IsGraphvizObject, IsObject, IsObject]); +#! @Arguments obj, name DeclareOperation("GraphvizSetAttr", [IsGraphvizObject, IsObject]); +#! @EndGroup #! @Arguments obj, attr #! @Returns the modified object. -#! @Description Removes an attribute from the object provided. +#! @Description +#! Removes an attribute from the object provided. +#! If no attributes are removed then the operation fails. +#! Attributes may be removed by key or by +#! key-value pair eg. "label" or "label=\"test\"". DeclareOperation("GraphvizRemoveAttr", [IsGraphvizObject, IsObject]); #! @Section Outputting @@ -272,26 +279,63 @@ DeclareOperation("AsString", [IsGraphvizGraphDigraphOrContext]); #! @Arguments obj #! @Returns the graphviz representation of the object. #! @Description -#! Unimplemented operation which depending packages can implement. -#! Should output the graphviz package representation of the object. +#! Unimplemented operation which depending packages can implement. +#! Should output the graphviz package representation of the object. DeclareOperation("Graphviz", [IsObject]); +#! @Arguments graph, colours +#! @Returns the modified object +#! @Description +#! Sets the colors of the nodes in the (di)graph. +#! If there are a different number of colours than nodes the operation fails. +#! Also sets the node style to filled. DeclareOperation("GraphvizSetNodeColors", [IsGraphvizGraphDigraphOrContext, IsList]); + +#! @Arguments graph, labels +#! @Returns the modified object +#! @Description +#! Sets the labels of the nodes in the (di)graph. +#! If there are fewer labels than nodes the operation fails. +#! If there is an invalid label the operation halts there and fails. +#! What constitutes a valid label can be found here, +#! "https://graphviz.org/doc/info/lang.html". DeclareOperation("GraphvizSetNodeLabels", [IsGraphvizGraphDigraphOrContext, IsList]); +#! @Arguments color +#! @Returns true or false +#! @Description +#! Determines if the color provided is a valid graphviz color. +#! Valid graphviz colors are described here, +#! "http://graphviz.org/doc/info/colors.html". DeclareGlobalFunction("ErrorIfNotValidColor"); -# TODO doc -DeclareOperation("\[\]", [IsGraphvizNode, IsObject]); -# TODO doc -DeclareOperation("\[\]\:\=", [IsGraphvizNode, IsObject, IsObject]); +#! @Section Shorthand +#! Shorthand for common operations. -# TODO doc +#! @BeginGroup +#! @GroupTitle Getting attributes +#! @Arguments edge, attr +#! @Returns the value associated with the provided attribute. +#! @Description +#! Gets the value associated with the attribute attr. DeclareOperation("\[\]", [IsGraphvizEdge, IsObject]); -# TODO doc +#! @Arguments node, attr +DeclareOperation("\[\]", [IsGraphvizNode, IsObject]); +#! @EndGroup + +#! @BeginGroup +#! @GroupTitle Setting attributes +#! @Arguments node, attr +#! @Description +#! Sets the value associated with the attribute attr. +DeclareOperation("\[\]\:\=", [IsGraphvizNode, IsObject, IsObject]); +#! @Arguments edge, attr DeclareOperation("\[\]\:\=", [IsGraphvizEdge, IsObject, IsObject]); -# TODO doc +#! @Arguments graph, node_name +#! @Returns The associated node or fail if no such node exists. +#! @Description +#! Gets a node from a (di)graph by id. DeclareOperation("\[\]", [IsGraphvizGraphDigraphOrContext, IsObject]); From 12978bb9427c330899d41fb87ef59dd1970986ac Mon Sep 17 00:00:00 2001 From: mpan Date: Wed, 26 Jun 2024 15:51:50 +0100 Subject: [PATCH 3/9] final edits to docs --- gap/dot.gd | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/gap/dot.gd b/gap/dot.gd index 804d250..74ed67b 100644 --- a/gap/dot.gd +++ b/gap/dot.gd @@ -73,8 +73,8 @@ DeclareOperation("GraphvizDigraph", []); #! objects. #! @Subsection For all graphviz objects. -#! This section covers the operations for getting information about any graphviz -#! object. +#! Operations below are applicable to all graphviz +#! objects. #! @Arguments obj #! @Returns the name of the provided graphviz object @@ -87,8 +87,8 @@ DeclareOperation("GraphvizName", [IsGraphvizObject]); DeclareOperation("GraphvizAttrs", [IsGraphvizObject]); #! @Subsection For only graphs, digraphs and contexts. -#! This section covers the operations for getting information about graphviz -#! graphs, digraphs and contexts. +#! This section covers the operations for getting information +#! specific to graphviz graphs, digraphs and contexts. #! @Arguments graph #! @Returns the nodes of the provided graphviz graph @@ -101,13 +101,16 @@ DeclareOperation("GraphvizNodes", [IsGraphvizGraphDigraphOrContext]); #! @Arguments graph #! @Returns the subgraphs of the provided graphviz graph. #! @Description gets the subgraphs of a provided graphviz graph. -#! Subgraphs are returned as a mapping from subgraph name to object. +#! Subgraphs are returned as a mapping from subgraph names to +#! corresponding objects. DeclareOperation("GraphvizSubgraphs", [IsGraphvizGraphDigraphOrContext]); #! @Arguments graph #! @Returns the contexts of the provided graphviz graph, digraph or context. #! @Description gets the contexts of a provided graphviz graph, digraph #! or context. +#! Subgraphs are returned as a mapping from context names to +#! corresponding objects. DeclareOperation("GraphvizContexts", [IsGraphvizGraphDigraphOrContext]); #! @Arguments graph, name @@ -152,6 +155,7 @@ DeclareOperation("GraphvizTail", [IsGraphvizEdge]); #! This section covers operations for modifying graphviz objects. #! @Subsection For modifying graphs. +#! Operations below only pertain to graphs, digraphs and contexts. #! @Arguments graph, name #! @Returns the modified graph. @@ -180,8 +184,6 @@ DeclareOperation("GraphvizAddNode", [IsGraphvizGraphDigraphOrContext, IsObject]) #! If no nodes with the same id are in the (di)graph, nodes automatically will be #! added to the graph. #! If there are nodes with the same id, they will be used. -#! TODO: are we happy with this behaviour? -#! I think if fail if they have the same id but different objects. DeclareOperation("GraphvizAddEdge", [IsGraphvizGraphDigraphOrContext, IsObject, IsObject]); @@ -190,7 +192,9 @@ DeclareOperation("GraphvizAddEdge", #! @Arguments graph, name #! @Returns the new subgraph. #! @Description Adds a subgraph to a graph. -#! The type of graph (graph or digraph) will be the same as the parent graph. +#! The type of structure (graph or digraph) will be the same as the parent graph. +#! At the moment it is not possible to add an existing graph as a +#! subgraph of another graph. DeclareOperation("GraphvizAddSubgraph", [IsGraphvizGraphDigraphOrContext, IsObject]); #! @Arguments graph @@ -211,6 +215,8 @@ DeclareOperation("GraphvizAddSubgraph", [IsGraphvizGraphDigraphOrContext]); #! without modifying the rendering behaviour. #! The type of graph edge (directed or undirected) #! will be the same as the parent graph. +#! At the moment it is not possible to add an existing context to +#! a new graph. DeclareOperation("GraphvizAddContext", [IsGraphvizGraphDigraphOrContext, IsObject]); #! @Arguments graph From f1fb123dc67e2f35d10e13e8133f2a230b6b80d5 Mon Sep 17 00:00:00 2001 From: "James D. Mitchell" Date: Fri, 21 Jun 2024 12:13:26 +0100 Subject: [PATCH 4/9] doc: add more preamble --- PackageInfo.g | 30 +++++++- gap/dot.gd | 203 ++++++++++++++++++++++++++++++++++++++++++++------ gap/splash.gd | 84 +++++++++++++++++++++ gap/splash.gi | 4 +- makedoc.g | 29 +++++++- 5 files changed, 322 insertions(+), 28 deletions(-) diff --git a/PackageInfo.g b/PackageInfo.g index ed94b02..1e9d83f 100644 --- a/PackageInfo.g +++ b/PackageInfo.g @@ -57,8 +57,6 @@ ArchiveURL := Concatenation(~.PackageWWWHome, ~.Version), ArchiveFormats := ".tar.gz", -AbstractHTML := "TODO", - PackageDoc := rec( BookName := "graphviz", ArchiveURLSubset := ["doc"], @@ -77,4 +75,30 @@ Dependencies := rec( AvailabilityTest := ReturnTrue, -TestFile := "tst/testall.g")); +TestFile := "tst/testall.g", + +AutoDoc := rec( + TitlePage := rec( + Copyright := """©right; by J. D. Mitchell and M. Pancer.

+ &GAPGraphviz; is free software; you can redistribute it and/or modify + it, under the terms of the GNU General Public License, version 3 of + the License, or (at your option) any later, version.""", + Abstract := """ + This package facilitates the creation and rendering of graph + descriptions in the &DOT; language of the &Graphviz; graph drawing + software from &GAP;. +

+ + Create a graphviz object, assemble the graph by adding nodes and edges, + and retrieve its &DOT; source code string. Save the source code to a file + and render it with the &Graphviz; installation of your system. +

+ + Use the function to directly inspect the resulting + graph. +

+ + This package was inspired by the python package of the same name + &PyGraphviz;.""")), + +AbstractHTML := ~.AutoDoc.TitlePage.Abstract)); diff --git a/gap/dot.gd b/gap/dot.gd index 74ed67b..5705079 100644 --- a/gap/dot.gd +++ b/gap/dot.gd @@ -9,43 +9,202 @@ ## #! @Chapter -#! @ChapterTitle An introduction to the DOT language and Graphviz. -#! This chapter explains what the DOT and graphviz are, -#! key basic concepts relating to them, and how this package interacts with them. - -#! @Section A Brief Introduction -#! DOT is a language for descrbing to a computer how to display a visualization -#! for a graph or digraph. Graphviz is a graph visualization software which can -#! consume DOT and produce visual outputs. This package is designed to allow -#! users to programmatically construct objects in GAP which can then be -#! converted into DOT. That DOT can then be inputted into the graphviz software -#! to produce a visual output. As DOT is central to the design of this package +#! @ChapterTitle Getting started +#! This chapter very briefly explains what &DOT; and &Graphviz; are, provides +#! some key basic concepts relating to them, and how this package interacts +#! with them. + +#! @Section A brief introduction +#! &DOT; is a language for descrbing to a computer how to display a visualization +#! of a graph or digraph. &Graphviz; is a graph visualization software which can +#! consume &DOT; and produce visual outputs. This package is designed to allow +#! users to programmatically construct objects in &GAP; which can then be +#! converted into &DOT;. That &DOT; can then be input to the &Graphviz; software +#! to produce a visual output. As &DOT; is central to the design of this package #! it will likely be helpful to have a basic understanding of the language. -#! For more information about DOT see +#! For more information about &DOT; see #! https://graphviz.org/doc/info/lang.html. - -#! @Chapter -#! @ChapterTitle The Graphviz Package +#!

+#! +#! The &GAPGraphviz; package for &GAP; is intended to facilitate the creation +#! and rendering of graph descriptions in the &DOT; language of the &Graphviz; +#! graph drawing software. +#!

+#! +#! You can create a &GAPGraphviz; object, assemble the graph by adding nodes +#! and edges, setting attributes, labels and so on, and retrieve its &DOT; +#! source code string. You can save the source code +#! to a file (using ) and render it +#! with the &Graphviz; installation of your system; or you can +#! use the function to directly inspect the resulting +#! graph (depending on your system and the software installed). + +#! @Section What this package is not +#! +#! This package does not implement a parser of the &DOT; language and does only +#! minimal checks when assembling a graph. In particular, if you set attributes +#! which don't exist in &DOT;, then the resulting string might not be valid, +#! and might not render correctly using &Graphviz;. + +#! @Section A first example +#! Here's an example of how to use the &GAPGraphviz; package, to construct a +#! &DOT; representation of a finite state automata. This example is taken from +#! https://graphviz.readthedocs.io/en/stable/examples.html or +#! https://graphviz.org/Gallery/directed/fsm.html. +#! +#! @BeginExampleSession +#! gap> LoadPackage("graphviz");; +#! gap> f := GraphvizDigraph("finite_state_machine"); +#! +#! gap> GraphvizSetAttr(f, "rankdir=LR"); +#! +#! gap> GraphvizSetAttr(f, "size=\"8,5\""); +#! +#! gap> terminals := GraphvizAddContext(f, "terminals"); +#! +#! gap> GraphvizSetAttr(terminals, "node [shape=doublecircle]"); +#! +#! gap> GraphvizAddNode(terminals, "LR_0"); +#! +#! gap> GraphvizAddNode(terminals, "LR_3"); +#! +#! gap> GraphvizAddNode(terminals, "LR_4"); +#! +#! gap> GraphvizAddNode(terminals, "LR_8"); +#! +#! gap> nodes := GraphvizAddContext(f, "nodes"); +#! +#! gap> GraphvizSetAttr(nodes, "node [shape=circle]"); +#! +#! gap> GraphvizSetAttr(GraphvizAddEdge(nodes, "LR_0", "LR_2"), +#! > "label", "\"SS(B)\""); +#! +#! gap> GraphvizSetAttr(GraphvizAddEdge(nodes, "LR_0", "LR_1"), +#! > "label", "\"SS(S)\""); +#! +#! gap> GraphvizSetAttr(GraphvizAddEdge(nodes, "LR_1", "LR_3"), +#! "label", "\"S($end)\""); +#! +#! gap> GraphvizSetAttr(GraphvizAddEdge(nodes, "LR_2", "LR_6"), +#! > "label", "\"SS(b)\""); +#! +#! gap> GraphvizSetAttr(GraphvizAddEdge(nodes, "LR_2", "LR_5"), +#! > "label", "\"SS(a)\""); +#! +#! gap> GraphvizSetAttr(GraphvizAddEdge(nodes, "LR_2", "LR_4"), +#! > "label", "\"S(A)\""); +#! +#! gap> GraphvizSetAttr(GraphvizAddEdge(nodes, "LR_5", "LR_7"), +#! > "label", "\"S(b)\""); +#! +#! gap> GraphvizSetAttr(GraphvizAddEdge(nodes, "LR_5", "LR_5"), +#! > "label", "\"S(a)\""); +#! +#! gap> GraphvizSetAttr(GraphvizAddEdge(nodes, "LR_6", "LR_6"), +#! > "label", "\"S(b)\""); +#! +#! gap> GraphvizSetAttr(GraphvizAddEdge(nodes, "LR_6", "LR_5"), +#! > "label", "\"S(a)\""); +#! +#! gap> GraphvizSetAttr(GraphvizAddEdge(nodes, "LR_7", "LR_8"), +#! > "label", "\"S(b)\""); +#! +#! gap> GraphvizSetAttr(GraphvizAddEdge(nodes, "LR_7", "LR_5"), +#! > "label", "\"S(a)\""); +#! +#! gap> GraphvizSetAttr(GraphvizAddEdge(nodes, "LR_8", "LR_6"), +#! > "label", "\"S(b)\""); +#! +#! gap> GraphvizSetAttr(GraphvizAddEdge(nodes, "LR_8", "LR_5"), +#! > "label", "\"S(a)\""); +#! +#! gap> Print(AsString(f), "\n"); +#! //dot +#! digraph finite_state_machine { +#! rankdir=LR size="8,5" +#! // terminals context +#! node [shape=doublecircle] +#! LR_0 +#! LR_3 +#! LR_4 +#! LR_8 +#! rankdir=LR size="8,5" +#! +#! // nodes context +#! 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)"] +#! rankdir=LR size="8,5" +#! +#! } +#! gap> Splash(f); +#! @EndExampleSession +#! +#! Provided that you have &Graphviz; installed on your computer, the last line +#! of the example Splash(f) will produce the following picture: +#! +#! +#! +#! +#! +#! ]]> +#! +#! +#! There are lots more examples in the examples directory within the +#! &Graphviz; package for &GAP; directory. + +#! @Chapter Full Reference +#! This chapter contains all of the gory details about the functionality of the +#! &GAPGraphviz; package for &GAP;. #! @Section Graphviz Categories -#! @Description Every object in graphviz belongs to this category. +#! Blurg + +#! @BeginGroup Filters +#! @Description Every object in graphviz belongs to the IsGraphvizObject +#! category. The categories following it are for further specificity on the +#! type of objects. These are graphs, digraphs, nodes and edges respectively. +#! All are direct subcategories of IsGraphvizObject excluding IsGraphvizDigraph +#! which is a subcategory of is IsGraphvizGraph. + +#! TODO DeclareCategory("IsGraphvizObject", IsObject); -#! @BeginGroup -#! @GroupTitle Graphs, digraphs and contexts -#! @Description These categories are for objects with graph like behaviour eg. -#! they can contain nodes, edges, subgraphs, etc. +#! TODO DeclareCategory("IsGraphvizGraphDigraphOrContext", IsGraphvizObject); +#! TODO DeclareCategory("IsGraphvizGraph", IsGraphvizGraphDigraphOrContext); +#! TODO DeclareCategory("IsGraphvizDigraph", IsGraphvizGraphDigraphOrContext); +#! TODO DeclareCategory("IsGraphvizContext", IsGraphvizGraphDigraphOrContext); #! @EndGroup -#! @BeginGroup -#! @GroupTitle Nodes and edges +#! TODO DeclareCategory("IsGraphvizNodeOrEdge", IsGraphvizObject); +#! TODO DeclareCategory("IsGraphvizNode", IsGraphvizNodeOrEdge); +#! TODO DeclareCategory("IsGraphvizEdge", IsGraphvizNodeOrEdge); + #! @EndGroup #! @Section Constructors diff --git a/gap/splash.gd b/gap/splash.gd index 919a68a..22e9857 100644 --- a/gap/splash.gd +++ b/gap/splash.gd @@ -12,4 +12,88 @@ # function was written by A. Egri-Nagy and Manuel Delgado, with some minor # modifications by J. Mitchell. +#! @ChapterInfo Full Reference, Outputting +#! @Arguments x[, opts] +#! @Returns Nothing. +#! @Description +#! This function attempts to convert the string str into a pdf +#! document and open this document, i.e. to splash it all over your monitor.

+#! +#! The argument x must be one of: TODO +#! +#! must correspond to a valid dot or +#! LaTeX text file and you must have have GraphViz and +#! pdflatex installed on your computer. For details about these file +#! formats, see https://www.latex-project.org and +#! https://www.graphviz.org.

+#! +#! The optional second argument opts should be a record with +#! components corresponding to various options, given below. +#! +#! +#! path +#! +#! this should be a string representing the path to the directory where +#! you want Splash to do its work. The default value of this +#! option is "~/". +#! +#! +#! directory +#! +#! this should be a string representing the name of the directory in +#! path where you want Splash to do its work. This function +#! will create this directory if does not already exist.

+#! +#! The default value of this option is "tmp.viz" if the option +#! path is present, and the result of +#! is used otherwise. +#! +#! +#! filename +#! +#! this should be a string representing the name of the file where +#! str will be written. The default value of this option is +#! "vizpicture". +#! +#! +#! viewer +#! +#! this should be a string representing the name of the program which +#! should open the files produced by GraphViz or pdflatex. +#! +#! +#! type +#! +#! this option can be used to specify that the string str contains +#! a &LaTeX; or dot document. You can specify this option in +#! str directly by making the first line "%latex" or +#! "//dot". There is no default value for this option, this +#! option must be specified in str or in opt.type. +#! +#! +#! engine +#! +#! this option can be used to specify the GraphViz engine to use +#! to render a dot document. The valid choices are "dot", +#! "neato", "circo", "twopi", "fdp", +#! "sfdp", and "patchwork". Please refer to the +#! GraphViz documentation for details on these engines. +#! The default value for this option is "dot", and it +#! must be specified in opt.engine. +#! +#! +#! filetype +#! +#! this should be a string representing the type of file which +#! Splash should produce. For &LaTeX; files, this option is +#! ignored and the default value "pdf" is used. +#! +#! +#! +#! This function was originally written by Attila Egri-Nagy and Manuel Delgado, +#! the present version incorporates some minor changes.

+#! @BeginLogSession +#! gap> TODO +#! gap> Splash(); +#! @EndLogSession DeclareGlobalFunction("Splash"); diff --git a/gap/splash.gi b/gap/splash.gi index 9d3c67e..41a3da2 100644 --- a/gap/splash.gi +++ b/gap/splash.gi @@ -32,7 +32,7 @@ function(arg...) file[i] := '_'; fi; od; - arg[1] := String(arg[1]); + arg[1] := AsString(arg[1]); else file := "vizpicture"; fi; @@ -42,7 +42,7 @@ function(arg...) if IsBound(arg[2]) and IsRecord(arg[2]) then opt := arg[2]; elif IsBound(arg[2]) then - ErrorNoReturn("the 2nd argument must be a record,"); + ErrorNoReturn("the 2nd argument must be a record"); fi; path := UserHomeExpand("~/"); diff --git a/makedoc.g b/makedoc.g index a04d383..5e2725f 100644 --- a/makedoc.g +++ b/makedoc.g @@ -10,9 +10,36 @@ ## This file is a script which compiles the package manual. +UrlEntity := function(name, url) + return StringFormatted("""{2} + {1}""", name, url); +end; + +PackageEntity := function(name) + if TestPackageAvailability(name) <> fail then + return UrlEntity(PackageInfo(name)[1].PackageName, + PackageInfo(name)[1].PackageWWWHome); + fi; + return StringFormatted("{1}", name); +end; + if fail = LoadPackage("AutoDoc", "2022.10.20") then Error("AutoDoc version 2022.10.20 or newer is required."); fi; -AutoDoc(rec(scaffold := true, autodoc := true)); +XMLEntities := rec(); + +XMLEntities.GAPGraphviz := PackageEntity("Graphviz"); +XMLEntities.PyGraphviz := UrlEntity("graphviz", + "https://pypi.org/project/graphviz/"); +XMLEntities.DOT := UrlEntity("DOT", + "https://www.graphviz.org/doc/info/lang.html"); +XMLEntities.Graphviz := UrlEntity("Graphviz", "https://www.graphviz.org"); + +AutoDoc("graphviz", +rec(scaffold := rec(entities := XMLEntities), autodoc := true)); + +Unbind(PackageEntity); +Unbind(UrlEntity); +Unbind(XMLEntities); QUIT; From 27584d1de6c694fc863fb15256a13af79482e6dc Mon Sep 17 00:00:00 2001 From: "James D. Mitchell" Date: Fri, 21 Jun 2024 12:58:21 +0100 Subject: [PATCH 5/9] README: incomplete 1st draft --- README.md | 195 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 185 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 7242a81..0ca4068 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,191 @@ -# The GAP package graphviz +## README -TODO: add a description of your package; perhaps also instructions how how to -install and use it, resp. where to find out more +### Graphviz package for GAP -## Contact +#### Copyright (C) 2024 by J. D. Mitchell and M. Pancer -TODO: add info on how to contact you and/or how to report issues with your -package +## Graphviz for GAP + +This package facilitates the creation and rendering of graph +descriptions in the [DOT][] language of the [Graphviz][] graph drawing +software from [GAP][]. + +You can create a graphviz object, assemble the graph by adding nodes and +edges, attributes, labels, colours, subgraphs, and clusters, and +retrieve its [DOT][] source code string. Save the source code to a file +and render it with the [Graphviz] installation on your system. + +You can use the [Splash] function to directly inspect the resulting +graph. + +This package was inspired by the python package of the same name +[Python Graphviz]. + +## Links + +- GitHub: https://github.com/xflr6/graphviz +- Documentation: https://graphviz.readthedocs.io +- Changelog: https://graphviz.readthedocs.io/en/latest/changelog.html +- Issue Tracker: https://github.com/xflr6/graphviz/issues +- Download: https://pypi.org/project/graphviz/#files + +## Installation + +This package requires [GAP][] version 4.11.0 or higher. The most +up-to-date version of GAP, and instructions on how to install it, can be +obtained from the [main GAP webpage](https://www.gap-system.org). This +package has no further dependencies! + +### From sources + +To get the latest version of the package, download the archive file +`graphviz-x.x.x.tar.gz` from the [Graphviz webpage][]. Then, inside the +`pkg` subdirectory of your GAP installation, unpack the archive +`graphviz-x.x.x.tar.gz` in your `gap/pkg` directory, using + + gunzip graphviz-x.x.x.tar.gz; tar xvf graphviz-x.x.x.tar + +for example. This will create a subdirectory `graphviz-x.x.x`. + +### Using the [PackageManager][] + +Start GAP in the usual way, then type: + + LoadPackage("PackageManager"); + InstallPackage("graphviz"); + +## Quickstart + +Create a graph object: + + gap> LoadPackage("graphviz"); + ─────────────────────────────────────────────────────────────────────────────────── + Loading graphviz 0.0.0 (TODO) + by James D. Mitchell (https://jdbm.me) and + Matthew Pancer (mp322@st-andrews.ac.uk). + Homepage: https://digraphs.github.io/graphviz + Report issues at https://github.com/digraphs/graphviz/issues + ─────────────────────────────────────────────────────────────────────────────────── + true + gap> dot := GraphvizDigraph("The Round Table"); + + +Add nodes and edges: + + gap> GraphvizSetAttr(GraphvizAddNode(dot, "A"), "label", "King Arthur"); + + gap> GraphvizSetAttr(GraphvizAddNode(dot, "B"), "label", "Sir Bedevere the Wise"); + + gap> GraphvizSetAttr(GraphvizAddNode(dot, "L"), "label", "Sir Lancelot the Brave"); + + gap> GraphvizAddEdge(dot, "A", "B"); + + gap> GraphvizAddEdge(dot, "A", "L"); + + gap> GraphvizSetAttr(GraphvizAddEdge(dot, "B", "L"), "constraint", false); + +Check the generated source code: + + gap> Print(AsString(dot)); + //dot + digraph { + A [label="King Arthur"] + B [label="Sir Bedevere the Wise"] + L [label="Sir Lancelot the Brave"] + A -> B + A -> L + B -> L [constraint=false] + } + +Save the source code: + + gap> FileString(TODO + +Save and render and view the result: + +.. code:: python + + >>> doctest_mark_exe() # skip this line + + >>> dot.render('doctest-output/round-table.gv', view=True) # doctest: +SKIP + 'doctest-output/round-table.gv.pdf' + +.. image:: https://raw.github.com/xflr6/graphviz/master/docs/_static/round-table.svg + :align: center + :alt: round-table.svg + +**Caveat:** +Backslash-escapes and strings of the form ``<...>`` +have a special meaning in the DOT language. +If you need to render arbitrary strings (e.g. from user input), +check the details in the `user guide`_. + +## Issues + +For questions, remarks, suggestions, and issues please use the +[issue tracker](https://github.com/digraphs/graphviz/issues). ## License -TODO: Provide information on the license of your package. A license is -important as it determines who has a right to distribute your package. The -"default" license to consider is GNU General Public License v2 or later, as -that is the license of GAP itself. +This package is distributed under the GNU General Public License v2 or later. +See the `LICENSE` file for more details. + +[PackageManager]: https://gap-packages.github.io/PackageManager +[Graphviz webpage]: https://digraphs.github.io/Digraphs +[GAP]: https://www.gap-system.org + + + +See also +-------- + +- pygraphviz_ |--| full-blown interface wrapping the Graphviz C library with SWIG +- graphviz-python_ |--| official Python bindings + (`documentation `_) +- pydot_ |--| stable pure-Python approach, requires pyparsing + + +License +------- + +This package is distributed under the `MIT license`_. + + +.. _Graphviz: https://www.graphviz.org +.. _DOT: https://www.graphviz.org/doc/info/lang.html +.. _upstream repo: https://gitlab.com/graphviz/graphviz/ +.. _upstream-download: https://www.graphviz.org/download/ +.. _upstream-archived: https://www2.graphviz.org/Archive/stable/ +.. _upstream-windows: https://forum.graphviz.org/t/new-simplified-installation-procedure-on-windows/224 + +.. _set-path-windows: https://www.computerhope.com/issues/ch000549.htm +.. _set-path-linux: https://stackoverflow.com/questions/14637979/how-to-permanently-set-path-on-linux-unix +.. _set-path-darwin: https://stackoverflow.com/questions/22465332/setting-path-environment-variable-in-osx-permanently + +.. _pip: https://pip.pypa.io + +.. _Jupyter notebooks: https://jupyter.org +.. _IPython notebooks: https://ipython.org/notebook.html +.. _Jupyter QtConsole: https://qtconsole.readthedocs.io + +.. _notebook: https://github.com/xflr6/graphviz/blob/master/examples/graphviz-notebook.ipynb +.. _notebook-nbviewer: https://nbviewer.org/github/xflr6/graphviz/blob/master/examples/graphviz-notebook.ipynb + +.. _Anaconda: https://docs.anaconda.com/anaconda/install/ +.. _conda-forge: https://conda-forge.org +.. _conda-forge-python-graphviz: https://anaconda.org/conda-forge/python-graphviz +.. _conda-forge-python-graphviz-feedstock: https://github.com/conda-forge/python-graphviz-feedstock +.. _conda-forge-graphviz: https://anaconda.org/conda-forge/graphviz +.. _conda-forge-graphviz-feedstock: https://github.com/conda-forge/graphviz-feedstock + +.. _user guide: https://graphviz.readthedocs.io/en/stable/manual.html + +.. _pygraphviz: https://pypi.org/project/pygraphviz/ +.. _graphviz-python: https://pypi.org/project/graphviz-python/ +.. _graphviz-python-docs: https://www.graphviz.org/pdf/gv.3python.pdf +.. _pydot: https://pypi.org/project/pydot/ + +.. _MIT license: https://opensource.org/licenses/MIT + + +.. |--| unicode:: U+2013 From 2628f83e740c78034da12b72497576656c2a6aed Mon Sep 17 00:00:00 2001 From: "James D. Mitchell" Date: Fri, 21 Jun 2024 15:26:06 +0100 Subject: [PATCH 6/9] README: more complete 2nd draft --- README.md | 117 ++++++++++++------------------------------------------ 1 file changed, 26 insertions(+), 91 deletions(-) diff --git a/README.md b/README.md index 0ca4068..8b0cb2c 100644 --- a/README.md +++ b/README.md @@ -19,15 +19,20 @@ You can use the [Splash] function to directly inspect the resulting graph. This package was inspired by the python package of the same name -[Python Graphviz]. +[Python Graphviz][]. + +## License + +This package is distributed under the GNU General Public License v2 or later. +See the `LICENSE` file for more details. ## Links -- GitHub: https://github.com/xflr6/graphviz -- Documentation: https://graphviz.readthedocs.io -- Changelog: https://graphviz.readthedocs.io/en/latest/changelog.html -- Issue Tracker: https://github.com/xflr6/graphviz/issues -- Download: https://pypi.org/project/graphviz/#files +- GitHub: [https://github.com/digraphs/graphviz](https://github.com/digraphs/graphviz) +- Documentation: TODO +- Changelog: TODO +- Issue Tracker: [https://github.com/digraphs/graphviz/issues](https://github.com/digraphs/graphviz/issues) +- Download: TODO ## Installation @@ -39,9 +44,9 @@ package has no further dependencies! ### From sources To get the latest version of the package, download the archive file -`graphviz-x.x.x.tar.gz` from the [Graphviz webpage][]. Then, inside the -`pkg` subdirectory of your GAP installation, unpack the archive -`graphviz-x.x.x.tar.gz` in your `gap/pkg` directory, using +`graphviz-x.x.x.tar.gz` from the [Graphviz package for GAP webpage][]. +Then, inside the `pkg` subdirectory of your GAP installation, unpack the +archive `graphviz-x.x.x.tar.gz` in your `gap/pkg` directory, using gunzip graphviz-x.x.x.tar.gz; tar xvf graphviz-x.x.x.tar @@ -51,8 +56,8 @@ for example. This will create a subdirectory `graphviz-x.x.x`. Start GAP in the usual way, then type: - LoadPackage("PackageManager"); - InstallPackage("graphviz"); + LoadPackage("PackageManager"); + InstallPackage("graphviz"); ## Quickstart @@ -99,93 +104,23 @@ Check the generated source code: Save the source code: - gap> FileString(TODO + gap> FileString("round-table.gv", AsString(dot)); + 134 -Save and render and view the result: +Render and view the result: -.. code:: python + gap> Splash(dot); - >>> doctest_mark_exe() # skip this line - - >>> dot.render('doctest-output/round-table.gv', view=True) # doctest: +SKIP - 'doctest-output/round-table.gv.pdf' - -.. image:: https://raw.github.com/xflr6/graphviz/master/docs/_static/round-table.svg - :align: center - :alt: round-table.svg - -**Caveat:** -Backslash-escapes and strings of the form ``<...>`` -have a special meaning in the DOT language. -If you need to render arbitrary strings (e.g. from user input), -check the details in the `user guide`_. +![The Round Table](https://raw.github.com/digraphs/graphviz/main/docs/png/The_Round_Table.png) ## Issues For questions, remarks, suggestions, and issues please use the [issue tracker](https://github.com/digraphs/graphviz/issues). -## License - -This package is distributed under the GNU General Public License v2 or later. -See the `LICENSE` file for more details. - -[PackageManager]: https://gap-packages.github.io/PackageManager -[Graphviz webpage]: https://digraphs.github.io/Digraphs +[DOT]: https://www.graphviz.org/doc/info/lang.html [GAP]: https://www.gap-system.org - - - -See also --------- - -- pygraphviz_ |--| full-blown interface wrapping the Graphviz C library with SWIG -- graphviz-python_ |--| official Python bindings - (`documentation `_) -- pydot_ |--| stable pure-Python approach, requires pyparsing - - -License -------- - -This package is distributed under the `MIT license`_. - - -.. _Graphviz: https://www.graphviz.org -.. _DOT: https://www.graphviz.org/doc/info/lang.html -.. _upstream repo: https://gitlab.com/graphviz/graphviz/ -.. _upstream-download: https://www.graphviz.org/download/ -.. _upstream-archived: https://www2.graphviz.org/Archive/stable/ -.. _upstream-windows: https://forum.graphviz.org/t/new-simplified-installation-procedure-on-windows/224 - -.. _set-path-windows: https://www.computerhope.com/issues/ch000549.htm -.. _set-path-linux: https://stackoverflow.com/questions/14637979/how-to-permanently-set-path-on-linux-unix -.. _set-path-darwin: https://stackoverflow.com/questions/22465332/setting-path-environment-variable-in-osx-permanently - -.. _pip: https://pip.pypa.io - -.. _Jupyter notebooks: https://jupyter.org -.. _IPython notebooks: https://ipython.org/notebook.html -.. _Jupyter QtConsole: https://qtconsole.readthedocs.io - -.. _notebook: https://github.com/xflr6/graphviz/blob/master/examples/graphviz-notebook.ipynb -.. _notebook-nbviewer: https://nbviewer.org/github/xflr6/graphviz/blob/master/examples/graphviz-notebook.ipynb - -.. _Anaconda: https://docs.anaconda.com/anaconda/install/ -.. _conda-forge: https://conda-forge.org -.. _conda-forge-python-graphviz: https://anaconda.org/conda-forge/python-graphviz -.. _conda-forge-python-graphviz-feedstock: https://github.com/conda-forge/python-graphviz-feedstock -.. _conda-forge-graphviz: https://anaconda.org/conda-forge/graphviz -.. _conda-forge-graphviz-feedstock: https://github.com/conda-forge/graphviz-feedstock - -.. _user guide: https://graphviz.readthedocs.io/en/stable/manual.html - -.. _pygraphviz: https://pypi.org/project/pygraphviz/ -.. _graphviz-python: https://pypi.org/project/graphviz-python/ -.. _graphviz-python-docs: https://www.graphviz.org/pdf/gv.3python.pdf -.. _pydot: https://pypi.org/project/pydot/ - -.. _MIT license: https://opensource.org/licenses/MIT - - -.. |--| unicode:: U+2013 +[Graphviz]: https://www.graphviz.org +[Graphviz webpage]: https://digraphs.github.io/Digraphs +[PackageManager]: https://gap-packages.github.io/PackageManager +[Python Graphviz]: https://pypi.org/project/graphviz/ From b68b4d7c2c257112a244973bed04341628f9622b Mon Sep 17 00:00:00 2001 From: "James D. Mitchell" Date: Fri, 21 Jun 2024 17:09:23 +0100 Subject: [PATCH 7/9] More doc --- gap/dot.gd | 353 +++++++++++++++++++++++++++++++------------------- gap/dot.gi | 16 +-- gap/gv.gi | 5 +- makedoc.g | 5 +- tst/testall.g | 2 +- 5 files changed, 239 insertions(+), 142 deletions(-) diff --git a/gap/dot.gd b/gap/dot.gd index 5705079..0680b99 100644 --- a/gap/dot.gd +++ b/gap/dot.gd @@ -34,7 +34,7 @@ #! You can create a &GAPGraphviz; object, assemble the graph by adding nodes #! and edges, setting attributes, labels and so on, and retrieve its &DOT; #! source code string. You can save the source code -#! to a file (using ) and render it +#! to a file (using ) and render it #! with the &Graphviz; installation of your system; or you can #! use the function to directly inspect the resulting #! graph (depending on your system and the software installed). @@ -52,7 +52,7 @@ #! https://graphviz.readthedocs.io/en/stable/examples.html or #! https://graphviz.org/Gallery/directed/fsm.html. #! -#! @BeginExampleSession +#! @BeginLogSession #! gap> LoadPackage("graphviz");; #! gap> f := GraphvizDigraph("finite_state_machine"); #! @@ -83,7 +83,7 @@ #! > "label", "\"SS(S)\""); #! #! gap> GraphvizSetAttr(GraphvizAddEdge(nodes, "LR_1", "LR_3"), -#! "label", "\"S($end)\""); +#! > "label", "\"S($end)\""); #! #! gap> GraphvizSetAttr(GraphvizAddEdge(nodes, "LR_2", "LR_6"), #! > "label", "\"SS(b)\""); @@ -155,10 +155,10 @@ #! #! } #! gap> Splash(f); -#! @EndExampleSession +#! @EndLogSession #! #! Provided that you have &Graphviz; installed on your computer, the last line -#! of the example Splash(f) will produce the following picture: +#! of the example Splash(f) would produce the following picture: #! #! #! IsGraphvizObject #! category. The categories following it are for further specificity on the -#! type of objects. These are graphs, digraphs, nodes and edges respectively. -#! All are direct subcategories of IsGraphvizObject excluding IsGraphvizDigraph -#! which is a subcategory of is IsGraphvizGraph. - -#! TODO +#! type of objects. These are graphs, digraphs, contexts, nodes, and +#! edges, and combinations of these that have some common features. DeclareCategory("IsGraphvizObject", IsObject); - -#! TODO DeclareCategory("IsGraphvizGraphDigraphOrContext", IsGraphvizObject); -#! TODO DeclareCategory("IsGraphvizGraph", IsGraphvizGraphDigraphOrContext); -#! TODO DeclareCategory("IsGraphvizDigraph", IsGraphvizGraphDigraphOrContext); -#! TODO DeclareCategory("IsGraphvizContext", IsGraphvizGraphDigraphOrContext); -#! @EndGroup - -#! TODO DeclareCategory("IsGraphvizNodeOrEdge", IsGraphvizObject); -#! TODO DeclareCategory("IsGraphvizNode", IsGraphvizNodeOrEdge); -#! TODO DeclareCategory("IsGraphvizEdge", IsGraphvizNodeOrEdge); - +#! The names of these categories are fairly descriptive, where a graph +#! has undirected edges, a digraph has directed edges, and a context is +#! a part of a &Graphviz; file/string consisting of objects (nodes, +#! edges, further contexts, subgraphs etc) that share some common +#! attributes. #! @EndGroup #! @Section Constructors #! @BeginGroup -#! @GroupTitle Constructors for Graphs +#! @GroupTitle Creating a new &GAPGraphviz; graphs #! @Arguments name -#! @Returns a new graphviz graph -#! @Description Creates a new graphviz graph optionally with the provided name. +#! @Returns A new &GAPGraphviz; graph. +#! @Description These operations create a new &GAPGraphviz; graph objects. +#! +#! In the first form, the created &GAPGraphviz; graph object has name +#! name. In the second form, the constructed &GAPGraphviz; graph +#! object has an empty string as a name. +#! +#! The argument name can be any &GAP; object for which there is a +#! method, and the name of the +#! created object will be equal to String(name). +#! +#! A "graph" in &Graphviz; has undirected edges that are represented +#! using the string "--" in the &DOT; language. +#! +#! See also: +#! * +#! * +#! * +#! +#! @BeginExampleSession +#! gap> gv := GraphvizGraph("GraphyMcGraphFace"); +#! +#! gap> GraphvizName(gv); +#! "GraphyMcGraphFace" +#! gap> GraphvizGraph(666); +#! +#! gap> gv := GraphvizGraph(); +#! +#! gap> GraphvizName(gv); +#! "" +#! @EndExampleSession DeclareOperation("GraphvizGraph", [IsObject]); DeclareOperation("GraphvizGraph", []); #! @EndGroup #! @BeginGroup -#! @GroupTitle Constructors for Digraphs +#! @GroupTitle Creating a new &GAPGraphviz; digraphs #! @Arguments name -#! @Returns a new graphviz digraph -#! @Description Creates a new graphviz digraph optionally with the provided name. +#! @Returns A new &GAPGraphviz; digraph. +#! @Description These operations create a new &GAPGraphviz; digraph objects. +#! +#! In the first form, the created &GAPGraphviz; digraph object has name +#! name. In the second form, the constructed &GAPGraphviz; digraph +#! object has an empty string as a name. +#! +#! The argument name can be any &GAP; object for which there is a +#! method, and the name of the +#! created object will be equal to String(name). +#! +#! A "digraph" in &Graphviz; has directed edges that are represented +#! using the string "->" in the &DOT; language. +#! +#! See also: +#! * +#! * +#! * +#! +#! @BeginExampleSession +#! gap> gv := GraphvizDigraph("GraphyMcGraphFace"); +#! +#! gap> GraphvizName(gv); +#! "GraphyMcGraphFace" +#! gap> GraphvizDigraph(666); +#! +#! gap> gv := GraphvizDigraph(); +#! +#! gap> GraphvizName(gv); +#! "" +#! @EndExampleSession DeclareOperation("GraphvizDigraph", [IsObject]); DeclareOperation("GraphvizDigraph", []); #! @EndGroup -#! @Section Get Operations -#! This section covers the operations for getting information about graphviz -#! objects. - -#! @Subsection For all graphviz objects. -#! Operations below are applicable to all graphviz -#! objects. +#! @Section Getters for any object +#! This section covers the operations for getting information about +#! &GAPGraphviz; any object. #! @Arguments obj -#! @Returns the name of the provided graphviz object -#! @Description Gets the name of the provided graphviz object. +#! @Returns A string. +#! @Description If the argument obj is a &GAPGraphviz; object +#! (), then this +#! function returns the name of the &Graphviz; object obj. +#! +#! @BeginExampleSession +#! gap> dot := GraphvizDigraph("The Round Table");; +#! gap> GraphvizName(dot); +#! "The Round Table" +#! gap> n := GraphvizSetAttr(GraphvizAddNode(dot, "A"), "label", "King Arthur"); +#! gap> GraphvizName(n); +#! "A" +#! gap> e := GraphvizAddEdge(dot, "A", "B");; +#! gap> GraphvizName(e); +#! "(A, B)" +#! @EndExampleSession DeclareOperation("GraphvizName", [IsGraphvizObject]); #! @Arguments obj #! @Returns the attributes of the provided graphviz object #! @Description Gets the attributes of the provided graphviz object. +#! @BeginExampleSession +#! gap> +#! @EndExampleSession +# HERE DeclareOperation("GraphvizAttrs", [IsGraphvizObject]); -#! @Subsection For only graphs, digraphs and contexts. -#! This section covers the operations for getting information -#! specific to graphviz graphs, digraphs and contexts. +#! @Section Getters for graphs and digraphs #! @Arguments graph #! @Returns the nodes of the provided graphviz graph #! as a mapping from node ids to names. #! @Description Gets the nodes of the provided graphviz graph. -#! What constitutes a valid node ID -#! is defined here "https://graphviz.org/doc/info/lang.html". +# From https://graphviz.org/doc/info/lang.html +# An ID is one of the following: +# Any string of alphabetic ([a-zA-Z\200-\377]) characters, underscores ('_') or +# digits([0-9]), not beginning with a digit; +# a numeral [-]?(.[0-9]⁺ | [0-9]⁺(.[0-9]*)? ); +# any double-quoted string ("...") possibly containing escaped quotes (\")¹; +# an HTML string (<...>). +# TODO specify +#! @BeginExampleSession +#! gap> +#! @EndExampleSession DeclareOperation("GraphvizNodes", [IsGraphvizGraphDigraphOrContext]); #! @Arguments graph #! @Returns the subgraphs of the provided graphviz graph. #! @Description gets the subgraphs of a provided graphviz graph. -#! Subgraphs are returned as a mapping from subgraph names to -#! corresponding objects. +#! @BeginExampleSession +#! gap> +#! @EndExampleSession DeclareOperation("GraphvizSubgraphs", [IsGraphvizGraphDigraphOrContext]); #! @Arguments graph #! @Returns the contexts of the provided graphviz graph, digraph or context. #! @Description gets the contexts of a provided graphviz graph, digraph #! or context. -#! Subgraphs are returned as a mapping from context names to -#! corresponding objects. +#! @BeginExampleSession +#! gap> +#! @EndExampleSession DeclareOperation("GraphvizContexts", [IsGraphvizGraphDigraphOrContext]); #! @Arguments graph, name @@ -279,6 +351,9 @@ DeclareOperation("GraphvizContexts", [IsGraphvizGraphDigraphOrContext]); #! with the provided name. #! It returns the graph if it exists. #! If no such graph exists then it will return fail. +#! @BeginExampleSession +#! gap> +#! @EndExampleSession DeclareOperation("GraphvizFindSubgraphRecursive", [IsGraphvizGraphDigraphOrContext, IsObject]); @@ -286,11 +361,12 @@ DeclareOperation("GraphvizFindSubgraphRecursive", #! @GroupTitle Getting Graphviz Edges #! @Arguments graph #! @Returns the edges of the provided graphviz graph. -#! @Description -#! Gets the edges of the provided graphviz graph. -#! Returns a list of edge objects. +#! @Description Gets the edges of the provided graphviz graph. #! If a head and tail are provided will only return edges #! between those two nodes. +#! @BeginExampleSession +#! gap> +#! @EndExampleSession DeclareOperation("GraphvizEdges", [IsGraphvizGraphDigraphOrContext]); #! @Arguments graph, head, tail DeclareOperation("GraphvizEdges", @@ -303,11 +379,17 @@ DeclareOperation("GraphvizEdges", #! @Arguments edge #! @Returns the head of the provided graphviz edge. #! @Description Gets the head of the provided graphviz graph. +#! @BeginExampleSession +#! gap> +#! @EndExampleSession DeclareOperation("GraphvizHead", [IsGraphvizEdge]); #! @Arguments edge #! @Returns the head of the provided graphviz tail. #! @Description Gets the tail of the provided graphviz graph. +#! @BeginExampleSession +#! gap> +#! @EndExampleSession DeclareOperation("GraphvizTail", [IsGraphvizEdge]); #! @Section Set Operations @@ -319,30 +401,31 @@ DeclareOperation("GraphvizTail", [IsGraphvizEdge]); #! @Arguments graph, name #! @Returns the modified graph. #! @Description Sets the name of a graphviz graph or digraph. +#! @BeginExampleSession +#! gap> +#! @EndExampleSession DeclareOperation("GraphvizSetName", [IsGraphvizGraphDigraphOrContext, IsObject]); -#! @Arguments graph, id -#! @Returns the new node. -#! @Description Adds a node to the graph with ID id. -#! If the id parameter is not string it will be converted to one. -#! If a node with the same id is already present the operation fails. -#! What constitutes a valid node ID -#! is defined here "https://graphviz.org/doc/info/lang.html". -#! Currently nodes cannot be added directly to graphs, so -#! if id is of type GraphvizNode it will fail. +#! @Arguments graph, node +#! @Returns the modified graph. +#! @Description Adds a node to the graph. +#! If a node with the same name is already present the operation fails. +#! @BeginExampleSession +#! gap> +#! @EndExampleSession DeclareOperation("GraphvizAddNode", [IsGraphvizGraphDigraphOrContext, IsObject]); -#! @Arguments graph, head, tail -#! @Returns the new edge. -#! @Description adds an edge to the graph. -#! The head and tail can be -#! general objects, strings or graphviz nodes. -#! If the head and tail are general objects, they will -#! be converted to strings. -#! Strings are then interpreted as node IDs. -#! If no nodes with the same id are in the (di)graph, nodes automatically will be -#! added to the graph. -#! If there are nodes with the same id, they will be used. +#! @Arguments graph, edge +#! @Returns the modified graph. +#! @Description Adds an edge to the graph. +#! If no nodes with the same name are in the graph then the edge's nodes will be +#! added to the graph. If different nodes with the same name are in the graph +#! then the operation fails. +#! TODO I dont believe this is accurate - think it will connect existing ones +#! underlying private function would fail though - TODO double check. +#! @BeginExampleSession +#! gap> +#! @EndExampleSession DeclareOperation("GraphvizAddEdge", [IsGraphvizGraphDigraphOrContext, IsObject, IsObject]); @@ -354,6 +437,9 @@ DeclareOperation("GraphvizAddEdge", #! The type of structure (graph or digraph) will be the same as the parent graph. #! At the moment it is not possible to add an existing graph as a #! subgraph of another graph. +#! @BeginExampleSession +#! gap> +#! @EndExampleSession DeclareOperation("GraphvizAddSubgraph", [IsGraphvizGraphDigraphOrContext, IsObject]); #! @Arguments graph @@ -376,6 +462,9 @@ DeclareOperation("GraphvizAddSubgraph", [IsGraphvizGraphDigraphOrContext]); #! will be the same as the parent graph. #! At the moment it is not possible to add an existing context to #! a new graph. +#! @BeginExampleSession +#! gap> +#! @EndExampleSession DeclareOperation("GraphvizAddContext", [IsGraphvizGraphDigraphOrContext, IsObject]); #! @Arguments graph @@ -390,21 +479,29 @@ DeclareOperation("GraphvizAddContext", [IsGraphvizGraphDigraphOrContext]); #! Strings are then interpreted as the id of the node to remove. #! All edges containing the node are also removed. #! If no such node exists the operation fails. +#! @BeginExampleSession +#! gap> +#! @EndExampleSession DeclareOperation("GraphvizRemoveNode", [IsGraphvizGraphDigraphOrContext, IsObject]); #! @Arguments graph, predicate #! @Returns the modified graph. #! @Description Filters the graph's edges using the provided predicate. +#! @BeginExampleSession +#! gap> +#! @EndExampleSession DeclareOperation("GraphvizFilterEdges", [IsGraphvizGraphDigraphOrContext, IsFunction]); #! @Arguments graph, head_id, tail_id #! @Returns the modified graph. -#! @Description -#! Filters the graph's edges, removing edges between nodes with -#! the specified ids. -#! If no edges exist between the two nodes, the operation fails. +#! @Description Filters the graph's edges, removing edges between nodes with +#! the specified names. +#! If no edges exist between the two nodes, the operation fails. +#! @BeginExampleSession +#! gap> +#! @EndExampleSession DeclareOperation("GraphvizRemoveEdges", [IsGraphvizGraphDigraphOrContext, IsObject, IsObject]); @@ -416,10 +513,13 @@ DeclareOperation("GraphvizRemoveEdges", #! @Arguments obj, attrs #! @Returns the modified object. #! @Description -#! Updates the attributes of the object. -#! All current attributes remain. -#! If an attribute already exists and a new value is provided, the old value -#! will be overwritten. +#! Updates the attributes of the object. +#! All current attributes remain. +#! If an attribute already exists and a new value is provided, the old value +#! will be overwritten. +#! @BeginExampleSession +#! gap> +#! @EndExampleSession DeclareOperation("GraphvizSetAttrs", [IsGraphvizObject, IsRecord]); #! @Arguments obj, name, value DeclareOperation("GraphvizSetAttr", [IsGraphvizObject, IsObject, IsObject]); @@ -429,78 +529,71 @@ DeclareOperation("GraphvizSetAttr", [IsGraphvizObject, IsObject]); #! @Arguments obj, attr #! @Returns the modified object. -#! @Description -#! Removes an attribute from the object provided. +#! @Description Removes an attribute from the object provided. #! If no attributes are removed then the operation fails. #! Attributes may be removed by key or by #! key-value pair eg. "label" or "label=\"test\"". +#! @BeginExampleSession +#! gap> +#! @EndExampleSession DeclareOperation("GraphvizRemoveAttr", [IsGraphvizObject, IsObject]); #! @Section Outputting #! @Arguments graph #! @Returns the dot representation of the graphviz object. +#! @Description TODO +#! @BeginExampleSession +#! gap> +#! @EndExampleSession DeclareOperation("AsString", [IsGraphvizGraphDigraphOrContext]); #! @Arguments obj #! @Returns the graphviz representation of the object. #! @Description -#! Unimplemented operation which depending packages can implement. -#! Should output the graphviz package representation of the object. +#! Unimplemented operation which depending packages can implement. +#! Should output the graphviz package representation of the object. +#! @BeginExampleSession +#! gap> +#! @EndExampleSession DeclareOperation("Graphviz", [IsObject]); -#! @Arguments graph, colours -#! @Returns the modified object -#! @Description -#! Sets the colors of the nodes in the (di)graph. -#! If there are a different number of colours than nodes the operation fails. -#! Also sets the node style to filled. +#! @BeginExampleSession +#! gap> +#! @EndExampleSession DeclareOperation("GraphvizSetNodeColors", [IsGraphvizGraphDigraphOrContext, IsList]); - -#! @Arguments graph, labels -#! @Returns the modified object -#! @Description -#! Sets the labels of the nodes in the (di)graph. -#! If there are fewer labels than nodes the operation fails. -#! If there is an invalid label the operation halts there and fails. -#! What constitutes a valid label can be found here, -#! "https://graphviz.org/doc/info/lang.html". +#! @BeginExampleSession +#! gap> +#! @EndExampleSession DeclareOperation("GraphvizSetNodeLabels", [IsGraphvizGraphDigraphOrContext, IsList]); -#! @Arguments color -#! @Returns true or false -#! @Description -#! Determines if the color provided is a valid graphviz color. -#! Valid graphviz colors are described here, -#! "http://graphviz.org/doc/info/colors.html". -DeclareGlobalFunction("ErrorIfNotValidColor"); - -#! @Section Shorthand -#! Shorthand for common operations. - -#! @BeginGroup -#! @GroupTitle Getting attributes -#! @Arguments edge, attr -#! @Returns the value associated with the provided attribute. -#! @Description -#! Gets the value associated with the attribute attr. -DeclareOperation("\[\]", [IsGraphvizEdge, IsObject]); -#! @Arguments node, attr +# TODO doc +#! @BeginExampleSession +#! gap> +#! @EndExampleSession DeclareOperation("\[\]", [IsGraphvizNode, IsObject]); -#! @EndGroup - -#! @BeginGroup -#! @GroupTitle Setting attributes -#! @Arguments node, attr -#! @Description -#! Sets the value associated with the attribute attr. +# TODO doc +#! @BeginExampleSession +#! gap> +#! @EndExampleSession DeclareOperation("\[\]\:\=", [IsGraphvizNode, IsObject, IsObject]); -#! @Arguments edge, attr + +# TODO doc +#! @BeginExampleSession +#! gap> +#! @EndExampleSession +DeclareOperation("\[\]", [IsGraphvizEdge, IsObject]); +# TODO doc +#! @BeginExampleSession +#! gap> +#! @EndExampleSession DeclareOperation("\[\]\:\=", [IsGraphvizEdge, IsObject, IsObject]); -#! @Arguments graph, node_name -#! @Returns The associated node or fail if no such node exists. -#! @Description -#! Gets a node from a (di)graph by id. +# TODO doc +#! @BeginExampleSession +#! gap> +#! @EndExampleSession DeclareOperation("\[\]", [IsGraphvizGraphDigraphOrContext, IsObject]); + +DeclareGlobalFunction("ErrorIfNotValidColor"); diff --git a/gap/dot.gi b/gap/dot.gi index f3be316..6766cae 100644 --- a/gap/dot.gi +++ b/gap/dot.gi @@ -27,6 +27,9 @@ function(name) Counter := 1)); end); +InstallMethod(GraphvizGraph, "for an object", [IsObject], +obj -> GraphvizGraph(String(obj))); + InstallMethod(GraphvizGraph, "for no args", [], {} -> GraphvizGraph("")); InstallMethod(GraphvizDigraph, "for a string", [IsString], @@ -46,6 +49,9 @@ end); InstallMethod(GraphvizDigraph, "for no args", [], {} -> GraphvizDigraph("")); +InstallMethod(GraphvizDigraph, "for an object", [IsObject], +obj -> GraphvizDigraph(String(obj))); + ############################################################################# # ViewString ############################################################################# @@ -54,15 +60,7 @@ InstallMethod(PrintString, "for a graphviz node", [IsGraphvizNode], n -> StringFormatted("", GraphvizName(n))); InstallMethod(PrintString, "for a graphviz edge", [IsGraphvizEdge], -function(e) - local head, tail; - head := GraphvizHead(e); - tail := GraphvizTail(e); - - return StringFormatted("", - GraphvizName(head), - GraphvizName(tail)); -end); +e -> StringFormatted("", GraphvizName(e))); InstallMethod(PrintString, "for a graphviz (di)graph or context", [IsGraphvizGraphDigraphOrContext], diff --git a/gap/gv.gi b/gap/gv.gi index 4d52941..7cba024 100644 --- a/gap/gv.gi +++ b/gap/gv.gi @@ -147,9 +147,12 @@ InstallMethod(GV_Edge, "for two graphviz nodes", [IsGraphvizGraphDigraphOrContext, IsGraphvizNode, IsGraphvizNode], function(graph, head, tail) local out; + out := Objectify(GV_EdgeType, rec( - Name := "", + Name := StringFormatted("({}, {})", + GraphvizName(head), + GraphvizName(tail)), Head := head, Tail := tail, Attrs := GV_Map(), diff --git a/makedoc.g b/makedoc.g index 5e2725f..b18c2fe 100644 --- a/makedoc.g +++ b/makedoc.g @@ -37,7 +37,10 @@ XMLEntities.DOT := UrlEntity("DOT", XMLEntities.Graphviz := UrlEntity("Graphviz", "https://www.graphviz.org"); AutoDoc("graphviz", -rec(scaffold := rec(entities := XMLEntities), autodoc := true)); +rec(scaffold := rec(entities := XMLEntities), + autodoc := true, + extract_examples := true, +)); Unbind(PackageEntity); Unbind(UrlEntity); diff --git a/tst/testall.g b/tst/testall.g index a5ad9d1..e737bce 100644 --- a/tst/testall.g +++ b/tst/testall.g @@ -4,6 +4,6 @@ LoadPackage("graphviz"); TestDirectory(DirectoriesPackageLibrary("graphviz", "tst"), - rec(exitGAP := true)); + rec(exitGAP := true, compareFunction := "uptowhitespace")); FORCE_QUIT_GAP(1); # if we ever get here, there was an error From c0ca59e17c36622016b31ec537fe86819803e9a9 Mon Sep 17 00:00:00 2001 From: mpan Date: Wed, 26 Jun 2024 17:50:45 +0100 Subject: [PATCH 8/9] Added back docs for the shortcut functions at the bottom from my doc branch. - TOOD: fix links in docs to the graphviz docs about valid IDs. - Fix mutability issues - Add proper errors for adding subgraphs directly to a graph --- gap/dot.gd | 57 ++++++++++++++++----- tst/graphviz01.tst | 124 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 169 insertions(+), 12 deletions(-) create mode 100644 tst/graphviz01.tst diff --git a/gap/dot.gd b/gap/dot.gd index 0680b99..1320241 100644 --- a/gap/dot.gd +++ b/gap/dot.gd @@ -557,43 +557,76 @@ DeclareOperation("AsString", [IsGraphvizGraphDigraphOrContext]); #! @EndExampleSession DeclareOperation("Graphviz", [IsObject]); +#! @Section Shortcuts +#! @Arguments graph, colours +#! @Returns the modified object +#! @Description +#! Sets the colors of the nodes in the (di)graph. +#! If there are a different number of colours than nodes the operation fails. +#! Also sets the node style to filled. #! @BeginExampleSession #! gap> #! @EndExampleSession DeclareOperation("GraphvizSetNodeColors", [IsGraphvizGraphDigraphOrContext, IsList]); + +#! @Arguments graph, labels +#! @Returns the modified object +#! @Description +#! Sets the labels of the nodes in the (di)graph. +#! If there are fewer labels than nodes the operation fails. +#! If there is an invalid label the operation halts there and fails. +#! What constitutes a valid label can be found here, +#! "https://graphviz.org/doc/info/lang.html". #! @BeginExampleSession #! gap> #! @EndExampleSession DeclareOperation("GraphvizSetNodeLabels", [IsGraphvizGraphDigraphOrContext, IsList]); -# TODO doc -#! @BeginExampleSession -#! gap> -#! @EndExampleSession -DeclareOperation("\[\]", [IsGraphvizNode, IsObject]); -# TODO doc +#! @Arguments color +#! @Returns true or false +#! @Description +#! Determines if the color provided is a valid graphviz color. +#! Valid graphviz colors are described here, +#! "http://graphviz.org/doc/info/colors.html". #! @BeginExampleSession #! gap> #! @EndExampleSession -DeclareOperation("\[\]\:\=", [IsGraphvizNode, IsObject, IsObject]); +DeclareGlobalFunction("ErrorIfNotValidColor"); -# TODO doc +#! @BeginGroup +#! @GroupTitle Getting attributes +#! @Arguments edge, attr +#! @Returns the value associated with the provided attribute. +#! @Description +#! Gets the value associated with the attribute attr. #! @BeginExampleSession #! gap> #! @EndExampleSession DeclareOperation("\[\]", [IsGraphvizEdge, IsObject]); -# TODO doc +#! @Arguments node, attr +DeclareOperation("\[\]", [IsGraphvizNode, IsObject]); +#! @EndGroup + +#! @BeginGroup +#! @GroupTitle Setting attributes +#! @Arguments node, attr +#! @Description +#! Sets the value associated with the attribute attr. #! @BeginExampleSession #! gap> #! @EndExampleSession +DeclareOperation("\[\]\:\=", [IsGraphvizNode, IsObject, IsObject]); +#! @Arguments edge, attr DeclareOperation("\[\]\:\=", [IsGraphvizEdge, IsObject, IsObject]); +#! @EndGroup -# TODO doc +#! @Arguments graph, node_name +#! @Returns The associated node or fail if no such node exists. +#! @Description +#! Gets a node from a (di)graph by id. #! @BeginExampleSession #! gap> #! @EndExampleSession DeclareOperation("\[\]", [IsGraphvizGraphDigraphOrContext, IsObject]); - -DeclareGlobalFunction("ErrorIfNotValidColor"); diff --git a/tst/graphviz01.tst b/tst/graphviz01.tst new file mode 100644 index 0000000..25b2630 --- /dev/null +++ b/tst/graphviz01.tst @@ -0,0 +1,124 @@ +# graphviz, chapter 2 +# +# DO NOT EDIT THIS FILE - EDIT EXAMPLES IN THE SOURCE INSTEAD! +# +# This file has been generated by AutoDoc. It contains examples extracted from +# the package documentation. Each example is preceded by a comment which gives +# the name of a GAPDoc XML file and a line range from which the example were +# taken. Note that the XML file in turn may have been generated by AutoDoc +# from some other input. +# +gap> START_TEST("graphviz01.tst"); + +# doc/_Chapter_Full_Reference.xml:78-89 +gap> gv := GraphvizGraph("GraphyMcGraphFace"); + +gap> GraphvizName(gv); +"GraphyMcGraphFace" +gap> GraphvizGraph(666); + +gap> gv := GraphvizGraph(); + +gap> GraphvizName(gv); +"" + +# doc/_Chapter_Full_Reference.xml:131-142 +gap> gv := GraphvizDigraph("GraphyMcGraphFace"); + +gap> GraphvizName(gv); +"GraphyMcGraphFace" +gap> GraphvizDigraph(666); + +gap> gv := GraphvizDigraph(); + +gap> GraphvizName(gv); +"" + +# doc/_Chapter_Full_Reference.xml:167-177 +gap> dot := GraphvizDigraph("The Round Table");; +gap> GraphvizName(dot); +"The Round Table" +gap> n := GraphvizSetAttr(GraphvizAddNode(dot, "A"), "label", "King Arthur"); +gap> GraphvizName(n); +"A" +gap> e := GraphvizAddEdge(dot, "A", "B");; +gap> GraphvizName(e); +"(A, B)" + +# doc/_Chapter_Full_Reference.xml:196-198 +gap> + +# doc/_Chapter_Full_Reference.xml:211-213 +gap> + +# doc/_Chapter_Full_Reference.xml:227-229 +gap> + +# doc/_Chapter_Full_Reference.xml:245-247 +gap> + +# doc/_Chapter_Full_Reference.xml:264-266 +gap> + +# doc/_Chapter_Full_Reference.xml:287-289 +gap> + +# doc/_Chapter_Full_Reference.xml:302-304 +gap> + +# doc/_Chapter_Full_Reference.xml:331-333 +gap> + +# doc/_Chapter_Full_Reference.xml:347-349 +gap> + +# doc/_Chapter_Full_Reference.xml:367-369 +gap> + +# doc/_Chapter_Full_Reference.xml:387-389 +gap> + +# doc/_Chapter_Full_Reference.xml:416-418 +gap> + +# doc/_Chapter_Full_Reference.xml:437-439 +gap> + +# doc/_Chapter_Full_Reference.xml:452-454 +gap> + +# doc/_Chapter_Full_Reference.xml:469-471 +gap> + +# doc/_Chapter_Full_Reference.xml:497-499 +gap> + +# doc/_Chapter_Full_Reference.xml:516-518 +gap> + +# doc/_Chapter_Full_Reference.xml:537-539 +gap> + +# doc/_Chapter_Full_Reference.xml:553-555 +gap> + +# doc/_Chapter_Full_Reference.xml:661-663 +gap> + +# doc/_Chapter_Full_Reference.xml:680-682 +gap> + +# doc/_Chapter_Full_Reference.xml:697-699 +gap> + +# doc/_Chapter_Full_Reference.xml:714-716 +gap> + +# doc/_Chapter_Full_Reference.xml:730-732 +gap> + +# doc/_Chapter_Full_Reference.xml:746-748 +gap> + +# +gap> STOP_TEST("graphviz01.tst", 1); From 89a719a3bf08ad9d68563444a4157b244b8d0ea9 Mon Sep 17 00:00:00 2001 From: mpan Date: Wed, 26 Jun 2024 17:54:05 +0100 Subject: [PATCH 9/9] fixed odd issue in test file - graphviz01.tst --- tst/graphviz01.tst | 77 +--------------------------------------------- 1 file changed, 1 insertion(+), 76 deletions(-) diff --git a/tst/graphviz01.tst b/tst/graphviz01.tst index 25b2630..8fa4ba4 100644 --- a/tst/graphviz01.tst +++ b/tst/graphviz01.tst @@ -38,87 +38,12 @@ gap> GraphvizName(gv); gap> dot := GraphvizDigraph("The Round Table");; gap> GraphvizName(dot); "The Round Table" -gap> n := GraphvizSetAttr(GraphvizAddNode(dot, "A"), "label", "King Arthur"); +gap> n := GraphvizSetAttr(GraphvizAddNode(dot, "A"), "label", "King Arthur");; gap> GraphvizName(n); "A" gap> e := GraphvizAddEdge(dot, "A", "B");; gap> GraphvizName(e); "(A, B)" -# doc/_Chapter_Full_Reference.xml:196-198 -gap> - -# doc/_Chapter_Full_Reference.xml:211-213 -gap> - -# doc/_Chapter_Full_Reference.xml:227-229 -gap> - -# doc/_Chapter_Full_Reference.xml:245-247 -gap> - -# doc/_Chapter_Full_Reference.xml:264-266 -gap> - -# doc/_Chapter_Full_Reference.xml:287-289 -gap> - -# doc/_Chapter_Full_Reference.xml:302-304 -gap> - -# doc/_Chapter_Full_Reference.xml:331-333 -gap> - -# doc/_Chapter_Full_Reference.xml:347-349 -gap> - -# doc/_Chapter_Full_Reference.xml:367-369 -gap> - -# doc/_Chapter_Full_Reference.xml:387-389 -gap> - -# doc/_Chapter_Full_Reference.xml:416-418 -gap> - -# doc/_Chapter_Full_Reference.xml:437-439 -gap> - -# doc/_Chapter_Full_Reference.xml:452-454 -gap> - -# doc/_Chapter_Full_Reference.xml:469-471 -gap> - -# doc/_Chapter_Full_Reference.xml:497-499 -gap> - -# doc/_Chapter_Full_Reference.xml:516-518 -gap> - -# doc/_Chapter_Full_Reference.xml:537-539 -gap> - -# doc/_Chapter_Full_Reference.xml:553-555 -gap> - -# doc/_Chapter_Full_Reference.xml:661-663 -gap> - -# doc/_Chapter_Full_Reference.xml:680-682 -gap> - -# doc/_Chapter_Full_Reference.xml:697-699 -gap> - -# doc/_Chapter_Full_Reference.xml:714-716 -gap> - -# doc/_Chapter_Full_Reference.xml:730-732 -gap> - -# doc/_Chapter_Full_Reference.xml:746-748 -gap> - # gap> STOP_TEST("graphviz01.tst", 1);