Skip to content

Commit

Permalink
enhance documentation of colon-separated port/compass format
Browse files Browse the repository at this point in the history
- see #53
  • Loading branch information
xflr6 committed Jul 13, 2020
1 parent 9fb23ad commit c07b08b
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 31 deletions.
4 changes: 3 additions & 1 deletion CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ Changelog
Version 0.14.1 (in development)
-------------------------------


Document the colon-separated ``node[:port[:compass]]`` format used for ``tail``
and ``head`` points in the ``edge()``- and ``edges()``-methods' (PR Michał
Góral).


Version 0.14
Expand Down
2 changes: 2 additions & 0 deletions docs/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ structs_revisited.py
:align: center


.. _btree.py:

btree.py
--------

Expand Down
58 changes: 35 additions & 23 deletions docs/manual.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ Their constructors allow to set the graph's :attr:`~.Graph.name`, the
:attr:`~.Graph.comment` for the first source code line, etc.

Add nodes and edges to the graph object using its :meth:`~.Graph.node` and
:meth:`~.Graph.edge` or :meth:`~.Graph.edges` methods:
:meth:`~.Graph.edge`- or :meth:`~.Graph.edges`-methods:

.. code:: python
Expand Down Expand Up @@ -210,27 +210,6 @@ After creation, they can be edited on the graph object:

.. _attributes:

Port and Compass Points
-----------------------

:meth:`~.Graph.edge` accepts optional port and compass attributes which are
separated with colons in the following form: ``node:port:nw``. When present,
they are converted to native DOT equivalents and modify the edge placement
between two nodes.

.. code:: python
>>> dot.edge('node1:port1', 'node2:port5:nw')
>>> dot.edge('node3:port2:_', 'node4:port4:s')
If you need to use a colon in a node's label, you can declare a node with
:meth:`~.Graph.node` first:

.. code:: python
>>> dot.node('A', 'node:with:colon')
>>> dot.node('B', 'another:node:with:colon')
>>> dot.edge('A', 'B')
Attributes
----------

Expand Down Expand Up @@ -282,6 +261,39 @@ key-value pairs targeting the current (sub-)graph (e.g. for ``rankdir``,
:align: center


.. _ports:

Node ports & compass
--------------------

The :meth:`~.Graph.edge`- and :meth:`~.Graph.edges`-methods use the
colon-separated format ``node[:port[:compass]]`` for ``tail`` and ``head``
nodes. This allows to specify an optional node ``port`` plus an optional
``compass`` point the edge should aim at for the given tail or head node
(:ref:`example <btree.py>`).

As colons are used to indicate ``port`` and ``compass``, node names with
literal colon(s) (``:``) are not supported. Note that there is no such
restriction for the ``label`` argument, so you can work around by choosing a
colon-free ``name`` together with the wanted ``label``:

.. code:: python
>>> cpp = Digraph('C++')
>>> cpp.node('A', 'std::string')
>>> cpp.node('B', '"spam"')
>>> cpp.edge('A', 'B')
>>> print(cpp.source) # doctest: +NORMALIZE_WHITESPACE
digraph "C++" {
A [label="std::string"]
B [label="\"spam\""]
A -> B
}
Backslash escapes
-----------------

Expand Down Expand Up @@ -466,7 +478,7 @@ Custom DOT statements
To add arbitrary statements to the created DOT_ source, use the
:attr:`~.Graph.body` attribute of the :class:`.Graph` or :class:`.Digraph`
object. It holds the verbatim list of lines to be written to the source file.
Use its ``append()`` or ``extend()`` method:
Use its ``append()``- or ``extend()``-method:

.. code:: python
Expand Down
26 changes: 19 additions & 7 deletions graphviz/dot.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,14 +133,19 @@ def node(self, name, label=None, _attributes=None, **attrs):
self.body.append(line)

def edge(self, tail_name, head_name, label=None, _attributes=None, **attrs):
"""Create an edge between two nodes. Accepts colon-separated strings
which are splitted into node, port and compass.
"""Create an edge between two nodes.
Args:
tail_name: Start node identifier.
head_name: End node identifier.
tail_name: Start node identifier (format: ``node[:port[:compass]]``).
head_name: End node identifier (format: ``node[:port[:compass]]``).
label: Caption to be displayed near the edge.
attrs: Any additional edge attributes (must be strings).
Note:
The ``tail_name`` and ``head_name`` strings are separated by
(optional) colon(s) into ``node`` name, ``port`` name, and
``compass`` (e.g. ``sw``).
See :ref:`details in the User Guide <ports>`.
"""
tail_name = self._quote_edge(tail_name)
head_name = self._quote_edge(head_name)
Expand All @@ -152,7 +157,14 @@ def edges(self, tail_head_iter):
"""Create a bunch of edges.
Args:
tail_head_iter: Iterable of ``(tail_name, head_name)`` pairs.
tail_head_iter: Iterable of ``(tail_name, head_name)`` pairs (format:``node[:port[:compass]]``).
Note:
The ``tail_name`` and ``head_name`` strings are separated by
(optional) colon(s) into ``node`` name, ``port`` name, and
``compass`` (e.g. ``sw``).
See :ref:`details in the User Guide <ports>`.
"""
edge = self._edge_plain
quote = self._quote_edge
Expand Down Expand Up @@ -199,7 +211,7 @@ def subgraph(self, graph=None, name=None, comment=None,
See the :ref:`usage examples in the User Guide <subgraphs>`.
.. note::
Note:
If the ``name`` of the subgraph begins with ``'cluster'`` (all lowercase)
the layout engine will treat it as a special cluster subgraph.
"""
Expand Down Expand Up @@ -256,7 +268,7 @@ class Graph(Dot):
strict (bool): Rendering should merge multi-edges.
Note:
All parameters are optional and can be changed under their
All parameters are `optional` and can be changed under their
corresponding attribute name after instance creation.
"""

Expand Down

0 comments on commit c07b08b

Please sign in to comment.