(self, diagram, grid, masked=None, diagram_format="")
return XypicDiagramDrawer._build_xypic_string(
            diagram, grid, morphisms, morphisms_str_info, diagram_format)
r"""
        Returns the Xy-pic representation of ``diagram`` laid out in
        ``grid``.

        Consider the following simple triangle diagram.

        >>> from sympy.categories import Object, NamedMorphism, Diagram
        >>> from sympy.categories import DiagramGrid, XypicDiagramDrawer
        >>> A = Object("A")
        >>> B = Object("B")
        >>> C = Object("C")
        >>> f = NamedMorphism(A, B, "f")
        >>> g = NamedMorphism(B, C, "g")
        >>> diagram = Diagram([f, g], {g * f: "unique"})

        To draw this diagram, its objects need to be laid out with a
        :class:`DiagramGrid`::

        >>> grid = DiagramGrid(diagram)

        Finally, the drawing:

        >>> drawer = XypicDiagramDrawer()
        >>> print(drawer.draw(diagram, grid))
        \xymatrix{
        A \ar[d]_{g\circ f} \ar[r]^{f} & B \ar[ld]^{g} \\
        C &
        }

        The argument ``masked`` can be used to skip morphisms in the
        presentation of the diagram:

        >>> print(drawer.draw(diagram, grid, masked=[g * f]))
        \xymatrix{
        A \ar[r]^{f} & B \ar[ld]^{g} \\
        C &
        }

        Finally, the ``diagram_format`` argument can be used to
        specify the format string of the diagram.  For example, to
        increase the spacing by 1 cm, proceeding as follows:

        >>> print(drawer.draw(diagram, grid, diagram_format="@+1cm"))
        \xymatrix@+1cm{
        A \ar[d]_{g\circ f} \ar[r]^{f} & B \ar[ld]^{g} \\
        C &
        }
r"""
        Returns the Xy-pic representation of ``diagram`` laid out in
        ``grid``.
r Returns the Xy - pic representation of diagram laid out in grid .
def draw(self, diagram, grid, masked=None, diagram_format=""):
        r"""
        Returns the Xy-pic representation of ``diagram`` laid out in
        ``grid``.

        Consider the following simple triangle diagram.

        >>> from sympy.categories import Object, NamedMorphism, Diagram
        >>> from sympy.categories import DiagramGrid, XypicDiagramDrawer
        >>> A = Object("A")
        >>> B = Object("B")
        >>> C = Object("C")
        >>> f = NamedMorphism(A, B, "f")
        >>> g = NamedMorphism(B, C, "g")
        >>> diagram = Diagram([f, g], {g * f: "unique"})

        To draw this diagram, its objects need to be laid out with a
        :class:`DiagramGrid`::

        >>> grid = DiagramGrid(diagram)

        Finally, the drawing:

        >>> drawer = XypicDiagramDrawer()
        >>> print(drawer.draw(diagram, grid))
        \xymatrix{
        A \ar[d]_{g\circ f} \ar[r]^{f} & B \ar[ld]^{g} \\
        C &
        }

        The argument ``masked`` can be used to skip morphisms in the
        presentation of the diagram:

        >>> print(drawer.draw(diagram, grid, masked=[g * f]))
        \xymatrix{
        A \ar[r]^{f} & B \ar[ld]^{g} \\
        C &
        }

        Finally, the ``diagram_format`` argument can be used to
        specify the format string of the diagram.  For example, to
        increase the spacing by 1 cm, proceeding as follows:

        >>> print(drawer.draw(diagram, grid, diagram_format="@+1cm"))
        \xymatrix@+1cm{
        A \ar[d]_{g\circ f} \ar[r]^{f} & B \ar[ld]^{g} \\
        C &
        }

        """
        # This method works in several steps.  It starts by removing
        # the masked morphisms, if necessary, and then maps objects to
        # their positions in the grid (coordinate tuples).  Remember
        # that objects are unique in ``Diagram`` and in the layout
        # produced by ``DiagramGrid``, so every object is mapped to a
        # single coordinate pair.
        #
        # The next step is the central step and is concerned with
        # analysing the morphisms of the diagram and deciding how to
        # draw them.  For example, how to curve the arrows is decided
        # at this step.  The bulk of the analysis is implemented in
        # ``_process_morphism``, to the result of which the
        # appropriate formatters are applied.
        #
        # The result of the previous step is a list of
        # ``ArrowStringDescription``.  After the analysis and
        # application of formatters, some extra logic tries to assure
        # better positioning of morphism labels (for example, an
        # attempt is made to avoid the situations when arrows cross
        # labels).  This functionality constitutes the next step and
        # is implemented in ``_push_labels_out``.  Note that label
        # positions which have been set via a formatter are not
        # affected in this step.
        #
        # Finally, at the closing step, the array of
        # ``ArrowStringDescription`` and the layout information
        # incorporated in ``DiagramGrid`` are combined to produce the
        # resulting Xy-pic picture.  This part of code lies in
        # ``_build_xypic_string``.

        if not masked:
            morphisms_props = grid.morphisms
        else:
            morphisms_props = {}
            for m, props in grid.morphisms.items():
                if m in masked:
                    continue
                morphisms_props[m] = props

        # Build the mapping between objects and their position in the
        # grid.
        object_coords = {}
        for i in xrange(grid.height):
            for j in xrange(grid.width):
                if grid[i, j]:
                    object_coords[grid[i, j]] = (i, j)

        morphisms = sorted(morphisms_props,
                           key=lambda m: XypicDiagramDrawer._morphism_sort_key(
                               m, object_coords))

        # Build the tuples defining the string representations of
        # morphisms.
        morphisms_str_info = {}
        for morphism in morphisms:
            string_description = self._process_morphism(
                diagram, grid, morphism, object_coords, morphisms,
                morphisms_str_info)

            if self.default_arrow_formatter:
                self.default_arrow_formatter(string_description)

            for prop in morphisms_props[morphism]:
                # prop is a Symbol.  TODO: Find out why.
                if prop.name in self.arrow_formatters:
                    formatter = self.arrow_formatters[prop.name]
                    formatter(string_description)

            morphisms_str_info[morphism] = string_description

        # Reposition the labels a bit.
        self._push_labels_out(morphisms_str_info, grid, object_coords)

        return XypicDiagramDrawer._build_xypic_string(
            diagram, grid, morphisms, morphisms_str_info, diagram_format)
def draw ( self , diagram , grid , masked = None , diagram_format = "" ) : # This method works in several steps.  It starts by removing # the masked morphisms, if necessary, and then maps objects to # their positions in the grid (coordinate tuples).  Remember # that objects are unique in ``Diagram`` and in the layout # produced by ``DiagramGrid``, so every object is mapped to a # single coordinate pair. # # The next step is the central step and is concerned with # analysing the morphisms of the diagram and deciding how to # draw them.  For example, how to curve the arrows is decided # at this step.  The bulk of the analysis is implemented in # ``_process_morphism``, to the result of which the # appropriate formatters are applied. # # The result of the previous step is a list of # ``ArrowStringDescription``.  After the analysis and # application of formatters, some extra logic tries to assure # better positioning of morphism labels (for example, an # attempt is made to avoid the situations when arrows cross # labels).  This functionality constitutes the next step and # is implemented in ``_push_labels_out``.  Note that label # positions which have been set via a formatter are not # affected in this step. # # Finally, at the closing step, the array of # ``ArrowStringDescription`` and the layout information # incorporated in ``DiagramGrid`` are combined to produce the # resulting Xy-pic picture.  This part of code lies in # ``_build_xypic_string``. if not masked : morphisms_props = grid . morphisms else : morphisms_props = { } for m , props in grid . morphisms . items ( ) : if m in masked : continue morphisms_props [ m ] = props # Build the mapping between objects and their position in the # grid. object_coords = { } for i in xrange ( grid . height ) : for j in xrange ( grid . width ) : if grid [ i , j ] : object_coords [ grid [ i , j ] ] = ( i , j ) morphisms = sorted ( morphisms_props , key = lambda m : XypicDiagramDrawer . _morphism_sort_key ( m , object_coords ) ) # Build the tuples defining the string representations of # morphisms. morphisms_str_info = { } for morphism in morphisms : string_description = self . _process_morphism ( diagram , grid , morphism , object_coords , morphisms , morphisms_str_info ) if self . default_arrow_formatter : self . default_arrow_formatter ( string_description ) for prop in morphisms_props [ morphism ] : # prop is a Symbol.  TODO: Find out why. if prop . name in self . arrow_formatters : formatter = self . arrow_formatters [ prop . name ] formatter ( string_description ) morphisms_str_info [ morphism ] = string_description # Reposition the labels a bit. self . _push_labels_out ( morphisms_str_info , grid , object_coords ) return XypicDiagramDrawer . _build_xypic_string ( diagram , grid , morphisms , morphisms_str_info , diagram_format )