U
    d/e4                     @   s  d Z ddlZddlZddlZddlZddlmZ ddlmZ ddlm	Z	 ddlm
Z
 dd	lmZ dd
lmZ dddgZejeje edddZeje dddZeje dddZejedddZdddejejef eeje eje ejdddZejejef ejdddZejd'ddddeeejejef eje eje ejeedf eejejedf eeedd dZejd(ddddeeje ejejedf eje eje ejeedf eejejedf eeedd"dZejd)ddddeeje ejejedf eje eje ejeedf eejejedf eeedd#dZejd$d%d*dd!d!deeje ejejedf eje eje ejeedf eejejedf eeedd&dZdS )+z.Render DOT source files with Graphviz ``dot``.    N   )DEFAULT_SOURCE_EXTENSION)_tools)
exceptions)
parameters   )dot_command)execute
get_formatget_filepathrender)outfileformatreturnc             
   C   s   zt | }W np tk
r|   |dkrPd| jdt| dt d}t|tj	d| jdd| dtj
d	 | Y S X |dk	st|dk	r| |krtj	d
|d|tjd	 |S |S dS )a
  Return format inferred from outfile suffix and/or given ``format``.

    Args:
        outfile: Path for the rendered output file.
        format: Output format for rendering (``'pdf'``, ``'png'``, ...).

    Returns:
        The given ``format`` falling back to the inferred format.

    Warns:
        graphviz.UnknownSuffixWarning: If the suffix of ``outfile``
            is empty/unknown.
        graphviz.FormatSuffixMismatchWarning: If the suffix of ``outfile``
            does not match the given ``format``.
    N*cannot infer rendering format from suffix  of outfile: z/ (provide format or outfile with a suffix from )zunknown outfile suffix z (expected: .)categoryzexpected format z) from outfile differs from given format: )infer_format
ValueErrorsuffixosfspathget_supported_suffixesr   RequiredArgumentErrorwarningswarnZUnknownSuffixWarningAssertionErrorlowerZFormatSuffixMismatchWarning)r   r   Zinferred_formatmsg r!   >/tmp/pip-unpacked-wheel-n8ok7rre/graphviz/backend/rendering.pyr
      s"    "

)r   c                   C   s   dd t  D S )zReturn a sorted list of supported outfile suffixes for exception/warning messages.

    >>> get_supported_suffixes()  # doctest: +ELLIPSIS
    ['.bmp', ...]
    c                 S   s   g | ]}d | qS )r   r!   ).0r   r!   r!   r"   
<listcomp>C   s     z*get_supported_suffixes.<locals>.<listcomp>)get_supported_formatsr!   r!   r!   r"   r   =   s    r   c                   C   s
   t tjS )zReturn a sorted list of supported formats for exception/warning messages.

    >>> get_supported_formats()  # doctest: +ELLIPSIS
    ['bmp', ...]
    )sortedr   ZFORMATSr!   r!   r!   r"   r%   F   s    r%   )r   r   c                 C   s   | j stdt| d| j d\}}}|r6|rFt| j d| }zt| W n@ tk
r   td| j dt| d|dt	 d		Y nX |S )
a  Return format inferred from outfile suffix.

    Args:
        outfile: Path for the rendered output file.

    Returns:
        The inferred format.

    Raises:
        ValueError: If the suffix of ``outfile`` is empty/unknown.

    >>> infer_format(pathlib.Path('spam.pdf'))  # doctest: +NO_EXE
    'pdf'

    >>> infer_format(pathlib.Path('spam.gv.svg'))
    'svg'

    >>> infer_format(pathlib.Path('spam.PNG'))
    'png'

    >>> infer_format(pathlib.Path('spam'))
    Traceback (most recent call last):
        ...
    ValueError: cannot infer rendering format from outfile: 'spam' (missing suffix)

    >>> infer_format(pathlib.Path('spam.wav'))  # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
    Traceback (most recent call last):
        ...
    ValueError: cannot infer rendering format from suffix '.wav' of outfile: 'spam.wav'
    (unknown format: 'wav', provide outfile with a suffix from ['.bmp', ...])
    z,cannot infer rendering format from outfile: z (missing suffix)r   z.startswith('.')r   r   z (unknown format: z%, provide outfile with a suffix from r   )
r   r   r   r   	partitionr   r   r   verify_formatr   )r   startsepZformat_r!   r!   r"   r   O   s     2r   )renderer	formatter)filepathr   r+   r,   r   c                C   sh   t | } tj|dd tj|dd tj|dd |||f}ddd |D }| | j d| S )zReturn ``filepath`` + ``[[.formatter].renderer].format``.

    See also:
        https://www.graphviz.org/doc/info/command.html#-O
    T)requiredFr   c                 s   s   | ]}|d k	r|V  qd S )Nr!   )r#   ar!   r!   r"   	<genexpr>   s      zget_outfile.<locals>.<genexpr>)	r   promote_pathliker   r(   Zverify_rendererZverify_formatterjoinwith_suffixr   )r-   r   r+   r,   Zsuffix_argsr   r!   r!   r"   get_outfile   s    	

r4   c                 C   s   t | } | dt S )z&Return ``outfile.with_suffix('.gv')``.r   )r   r1   r3   r   )r   r!   r!   r"   r      s    
.)r   raise_if_result_existsoverwrite_filepath)enginer   r-   r+   r,   neato_no_opquietr   r5   r6   r   c          
      C   s   dS )zBRequire ``format`` and ``filepath`` with default ``outfile=None``.Nr!   
r7   r   r-   r+   r,   r8   r9   r   r5   r6   r!   r!   r"   r      s    Fc          
      C   s   dS )z<Optional ``format`` and ``filepath`` with given ``outfile``.Nr!   r:   r!   r!   r"   r      s    c          
      C   s   dS )zGRequired/optional ``format`` and ``filepath`` depending on ``outfile``.Nr!   r:   r!   r!   r"   r      s       )Zsupported_numberc                C   sn  |r|	rt dttj||f\}}|dk	rt||d}|dkrHt|}|	s|j|jkr| | krt d|jd|jd|j|jkr| n|j}
d|
|jg}nR|dkrt	
d|d	n6|dkrt	
d
|d	nt||||d}d|jg}tj| ||||d}|r:tj|r:t	dt|||7 }tj||jjrX|jnd|dd t|S )aX  Render file with ``engine`` into ``format`` and return result filename.

    Args:
        engine: Layout engine for rendering (``'dot'``, ``'neato'``, ...).
        format: Output format for rendering (``'pdf'``, ``'png'``, ...).
            Can be omitted if an ``outfile`` with a known ``format`` is given,
            i.e. if ``outfile`` ends  with a known ``.{format}`` suffix.
        filepath: Path to the DOT source file to render.
            Can be omitted if ``outfile`` is given,
            in which case it defaults to ``outfile.with_suffix('.gv')``.
        renderer: Output renderer (``'cairo'``, ``'gd'``, ...).
        formatter: Output formatter (``'cairo'``, ``'gd'``, ...).
        neato_no_op: Neato layout engine no-op flag.
        quiet: Suppress ``stderr`` output from the layout subprocess.
        outfile: Path for the rendered output file.
        raise_if_result_exits: Raise :exc:`graphviz.FileExistsError`
            if the result file exists.
        overwrite_filepath: 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 ``format`` or ``filepath`` are None
            unless ``outfile`` is given.
        graphviz.RequiredArgumentError: If ``formatter`` is given
            but ``renderer`` is None.
        ValueError: If ``outfile`` and ``filename`` are the same file
            unless ``overwite_filepath=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.
        graphviz.FileExistsError: If ``raise_if_exists``
            and the result file exists.

    Warns:
        graphviz.UnknownSuffixWarning: If the suffix of ``outfile``
            is empty or unknown.
        graphviz.FormatSuffixMismatchWarning: If the suffix of ``outfile``
            does not match the given ``format``.

    Example:
        >>> doctest_mark_exe()
        >>> import pathlib
        >>> import graphviz
        >>> assert pathlib.Path('doctest-output/spam.gv').write_text('graph { spam }') == 14
        >>> graphviz.render('dot', 'png', 'doctest-output/spam.gv').replace('\\', '/')
        'doctest-output/spam.gv.png'
        >>> graphviz.render('dot', filepath='doctest-output/spam.gv',
        ...                 outfile='doctest-output/spam.png').replace('\\', '/')
        'doctest-output/spam.png'
        >>> graphviz.render('dot', outfile='doctest-output/spam.pdf').replace('\\', '/')
        'doctest-output/spam.pdf'

    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.

    See also:
        Upstream docs: https://www.graphviz.org/doc/info/command.html
    zAoverwrite_filepath cannot be combined with raise_if_result_existsN)r   zoutfile z# must be different from input file z+ (pass overwrite_filepath=True to override)z-oz1filepath: (required if outfile is not given, got r   z/format: (required if outfile is not given, got )r   r+   r,   z-O)r+   r,   r8   zoutput file exists: T)cwdr9   capture_output)r   mapr   r1   r
   r   nameresolveparentr   r   r4   r   commandr   pathexistsFileExistsErrorr   r	   Z	run_checkparts)r7   r   r-   r+   r,   r8   r9   r   r5   r6   Zoutfile_argargscmdr!   r!   r"   r      sN    N
)....).....F).....F)NNNNNF)__doc__r   pathlibtypingr   	_defaultsr    r   r   r   r   r	   __all__PathOptionalstrr
   Listr   r%   r   UnionPathLiker4   r   overloadboolintr   Zdeprecate_positional_argsr!   r!   r!   r"   <module>   s   
*		6                    
       