text: """Save DOT code objects, render with Graphviz ``dot``, and open in viewer."""
  
  import logging
  import os
  import pathlib
  import typing
  
  from . import _tools
  from . import backend
  from . import saving
  
  __all__ = ['Render']
  
  
  log = logging.getLogger(__name__)
  
  
  class Render(saving.Save, backend.Render, backend.View):
      """Write source lines to file and render with Graphviz."""
  
      @_tools.deprecate_positional_args(supported_number=2)
      def render(self,
                 filename: typing.Union[os.PathLike, str, None] = None,
                 directory: typing.Union[os.PathLike, str, None] = None,
                 view: bool = False,
                 cleanup: bool = False,
                 format: typing.Optional[str] = None,
                 renderer: typing.Optional[str] = None,
                 formatter: typing.Optional[str] = None,
                 quiet: bool = False,
                 quiet_view: bool = False, *,
                 outfile: typing.Union[os.PathLike, str, None] = None,
                 engine: typing.Optional[str] = None,
                 raise_if_result_exists: bool = False,
                 overwrite_source: bool = False) -> str:
          r"""Save the source to file and render with the Graphviz engine.
  
          Args:
              filename: Filename for saving the source
                  (defaults to ``name`` + ``'.gv'``).s
              directory: (Sub)directory for source saving and rendering.
              view (bool): Open the rendered result
                  with the default application.
              cleanup (bool): Delete the source file
                  after successful rendering.
              format: The output format used for rendering
                  (``'pdf'``, ``'png'``, etc.).
              renderer: The output renderer used for rendering
                  (``'cairo'``, ``'gd'``, ...).
              formatter: The output formatter used for rendering
                  (``'cairo'``, ``'gd'``, ...).
              quiet (bool): Suppress ``stderr`` output
                  from the layout subprocess.
              quiet_view (bool): Suppress ``stderr`` output
                  from the viewer process
                  (implies ``view=True``, ineffective on Windows platform).
              outfile: Path for the rendered output file.
              engine: Layout engine for rendering
                  (``'dot'``, ``'neato'``, ...).
              raise_if_result_exits: Raise :exc:`graphviz.FileExistsError`
                  if the result file exists.
              overwrite_source: Allow ``dot`` to write to the file it reads from.
                  Incompatible with ``raise_if_result_exists``.
  
          Returns:
              The (possibly relative) path of the rendered file.
  
          Raises:
              ValueError: If ``engine``, ``format``, ``renderer``, or ``formatter``
                  are unknown.
              graphviz.RequiredArgumentError: If ``formatter`` is given
                  but ``renderer`` is None.
              ValueError: If ``outfile`` is the same file as the source file
                  unless ``overwite_source=True``.
              graphviz.ExecutableNotFound: If the Graphviz ``dot`` executable
                  is not found.
              graphviz.CalledProcessError: If the returncode (exit status)
                  of the rendering ``dot`` subprocess is non-zero.
              RuntimeError: If viewer opening is requested but not supported.
  
          Example:
              >>> doctest_mark_exe()
              >>> import graphviz
              >>> dot = graphviz.Graph(name='spam', directory='doctest-output')
              >>> dot.render(format='png').replace('\\', '/')
              'doctest-output/spam.gv.png'
              >>> dot.render(outfile='spam.svg').replace('\\', '/')
              'doctest-output/spam.svg'
  
          Note:
              The layout command is started from the directory of ``filepath``,
              so that references to external files
              (e.g. ``[image=images/camelot.png]``)
              can be given as paths relative to the DOT source file.
          """
          outfile = _tools.promote_pathlike(outfile)
          if outfile is not None:
              format = self._get_format(outfile, format=format)
              if directory is None:
                  outfile = pathlib.Path(self.directory, outfile)
  
          args, kwargs = self._get_render_parameters(engine=engine,
                                                     format=format,
                                                     renderer=renderer,
                                                     formatter=formatter,
                                                     quiet=quiet,
                                                     outfile=outfile,
                                                     raise_if_result_exists=raise_if_result_exists,
                                                     overwrite_source=overwrite_source,
                                                     verify=True)
  
          if outfile is not None and filename is None:
              filename = self._get_filepath(outfile)
  
          filepath = self.save(filename, directory=directory, skip_existing=None)
  
          args.append(filepath)
  
          rendered = self._render(*args, **kwargs)
  
          if cleanup:
              log.debug('delete %r', filepath)
              os.remove(filepath)
  
          if quiet_view or view:
              self._view(rendered, format=self._format, quiet=quiet_view)
  
          return rendered
  
      def _view(self, filepath: typing.Union[os.PathLike, str], *,
                format: str, quiet: bool) -> None:
          """Start the right viewer based on file format and platform."""
          methodnames = [
              f'_view_{format}_{backend.viewing.PLATFORM}',
              f'_view_{backend.viewing.PLATFORM}',
          ]
          for name in methodnames:
              view_method = getattr(self, name, None)
              if view_method is not None:
                  break
          else:
              raise RuntimeError(f'{self.__class__!r} has no built-in viewer'
                                 f' support for {format!r}'
                                 f' on {backend.viewing.PLATFORM!r} platform')
          view_method(filepath, quiet=quiet)
  
      @_tools.deprecate_positional_args(supported_number=2)
      def view(self,
               filename: typing.Union[os.PathLike, str, None] = None,
               directory: typing.Union[os.PathLike, str, None] = None,
               cleanup: bool = False,
               quiet: bool = False,
               quiet_view: bool = False) -> str:
          """Save the source to file, open the rendered result in a viewer.
  
          Convenience short-cut for running ``.render(view=True)``.
  
          Args:
              filename: Filename for saving the source
                  (defaults to ``name`` + ``'.gv'``).
              directory: (Sub)directory for source saving and rendering.
              cleanup (bool): Delete the source file after successful rendering.
              quiet (bool): Suppress ``stderr`` output from the layout subprocess.
              quiet_view (bool): Suppress ``stderr`` output
                  from the viewer process (ineffective on Windows).
  
          Returns:
              The (possibly relative) path of the rendered file.
  
          Raises:
              graphviz.ExecutableNotFound: If the Graphviz executable
                  is not found.
              graphviz.CalledProcessError: If the exit status is non-zero.
              RuntimeError: If opening the viewer is not supported.
  
          Short-cut method for calling :meth:`.render` with ``view=True``.
  
          Note:
              There is no option to wait for the application to close,
              and no way to retrieve the application's exit status.
          """
          return self.render(filename=filename, directory=directory, view=True,
                             cleanup=cleanup, quiet=quiet, quiet_view=quiet_view)
  