U
    ꥡcE+                     @   s   d Z ddlZddl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mZ ddlmZ ddlZddlmZ dejZd	ejZd
ejZedZG dd dejejZdd Z ddddZ!dd Z"dd Z#G dd de
Z$dd Z%dd Z&dd Z'dd Z(d d! Z)dS )"a  
Altair Plot Sphinx Extension
============================

This extension provides a means of inserting live-rendered Altair plots within
sphinx documentation. There are two directives defined: ``altair-setup`` and
``altair-plot``. ``altair-setup`` code is used to set-up various options
prior to running the plot code. For example::

    .. altair-plot::
        :output: none

        from altair import *
        import pandas as pd
        data = pd.DataFrame({'a': list('CCCDDDEEE'),
                             'b': [2, 7, 4, 1, 2, 6, 8, 4, 7]})

    .. altair-plot::

        Chart(data).mark_point().encode(
            x='a',
            y='b'
        )

In the case of the ``altair-plot`` code, the *last statement* of the code-block
should contain the chart object you wish to be rendered.

Options
-------
The directives have the following options::

    .. altair-plot::
        :namespace:  # specify a plotting namespace that is persistent within the doc
        :hide-code:  # if set, then hide the code and only show the plot
        :code-below:  # if set, then code is below rather than above the figure
        :output:  [plot|repr|stdout|none]
        :alt: text  # Alternate text when plot cannot be rendered
        :links: editor source export  # specify one or more of these options
        :chart-var-name: chart  # name of variable in namespace containing output


Additionally, this extension introduces a global configuration
``altairplot_links``, set in your ``conf.py`` which is a dictionary
of links that will appear below plots, unless the ``:links:`` option
again overrides it. It should look something like this::

    # conf.py
    # ...
    altairplot_links = {'editor': True, 'source': True, 'export': True}
    # ...

If this configuration is not specified, all are set to True.
    N)nodes)	Directive)flag	unchanged)_)
eval_blockz$https://cdn.jsdelivr.net/npm/vega@{}z)https://cdn.jsdelivr.net/npm/vega-lite@{}z*https://cdn.jsdelivr.net/npm/vega-embed@{}a  
<div id="{{ div_id }}">
<script>
  // embed when document is loaded, to ensure vega library is available
  // this works on all modern browsers, except IE8 and older
  document.addEventListener("DOMContentLoaded", function(event) {
      var spec = {{ spec }};
      var opt = {
        "mode": "{{ mode }}",
        "renderer": "{{ renderer }}",
        "actions": {{ actions}}
      };
      vegaEmbed('#{{ div_id }}', spec, opt).catch(console.err);
  });
</script>
</div>
c                   @   s   e Zd ZdS )altair_plotN)__name__
__module____qualname__ r   r   ?/tmp/pip-unpacked-wheel-y9_o96ar/altair/sphinxext/altairplot.pyr   g   s   r   c                 C   s    t |dsd S |j|i  d S )N_altair_namespaces)hasattrr   pop)appenvdocnamer   r   r   purge_altair_namespacesk   s    
r   T)Zeditorsourceexportc                    s\       dkrdS      t tt  }|rJtdt| fddtD S )NnoneFzFollowing links are invalid: {}c                    s   i | ]}|| kqS r   r   ).0linklinksr   r   
<dictcomp>|   s      z"validate_links.<locals>.<dictcomp>)	striplowersplitsetDEFAULT_ALTAIRPLOT_LINKSkeys
ValueErrorformatlist)r   Zdiffr   r   r   validate_linkst   s    r&   c                 C   s    |    } | dkrtd| S )N)plotreprstdoutr   z4:output: flag must be one of [plot|repr|stdout|none])r   r   r#   )outputr   r   r   validate_output   s    r+   c                   @   s,   e Zd ZdZeeeeeeedZdd Z	dS )AltairPlotDirectiveT)	hide-code
code-below	namespacer*   altr   chart-var-namec                 C   s  | j jjj}|j}d| jk}d| jk}t|ds6i |_| jdd}|j	|j
i 	|i }d| j}|rt||}d|d< | jjd	 }	tj|	}
tj|	}|d
}|dd}d||}d||}tjdd|gd}t }||d< ||d< ||d< ||d< tj|
|j|d< |	|d< | j|d< | jd|jjj|d< | jdd|d< | jdd |d< d| jkr| jd |d< |g}|r||g7 }|r||g7 }|s||g7 }|S )Nr-   r.   r   r/   default
pythonlanguager   altair-plot.-z{}-altair-plot-{}z{}-altair-source-{} )ids	target_iddiv_idcoderelpath
rst_source
rst_linenor   r*   r'   r1   r0   )statedocumentsettingsr   r   optionsr   r   get
setdefaultr   joincontentr   literal_blockZstate_machineospathdirnamebasenameZnew_serialnoreplacer$   targetr   r>   srcdirlinenoZbuilderconfigaltairplot_links)selfr   r   	show_codeZ
code_belowZnamespace_idr/   r=   Zsource_literalr?   Zrst_dirZrst_filenameZserialnoZrst_baser<   r;   Ztarget_nodeZ	plot_noderesultr   r   r   run   s^    


 

 


zAltairPlotDirective.runN)
r	   r
   r   Zhas_contentr   r   r+   r&   Zoption_specrW   r   r   r   r   r,      s   
r,   c                 C   s  |d }z8t  }t| t|d |}W 5 Q R X | }W nN tk
r } z0td	|d |d |j
jt| tjW 5 d }~X Y nX |d }|d k	r||krtd	||| }|d }|d	krtjn:|d
kr|stjn t||}	d	|	d< ||	g n |dkrd|d kr.tjn4dt|dd }
t|
|
}d	|d< ||g n|dkrt|tjrz| }W n. tjjjk
r   td	|d Y nX |d }tj|d t|ddt|d}| j | ntd	|d |d  tjd S )Nr/   r=   z/altair-plot: {}:{} Code Execution failed:{}: {}r?   r@   r1   z,chart-var-name='{}' not present in namespacer*   r   r)   r5   r(   z    r3   z
    r'   zInvalid chart: {0}r   r<   z	vega-liteZcanvas)r<   specmodeZrendereractionszfaltair-plot: {}:{} Malformed block. Last line of code block should define a valid altair Chart object.)!ioStringIO
contextlibredirect_stdoutr   getvalue	Exceptionwarningswarnr$   	__class__r	   strr   SkipNoder#   rI   extendr(   rN   
isinstancer0   ZTopLevelMixinZto_dictutilsZschemapiZSchemaValidationErrorVGL_TEMPLATErenderjsondumpsbodyappend)rT   noder/   fZchartr)   eZ
chart_namer*   Zoutput_literalrepZrepr_literalrX   rZ   htmlr   r   r   html_visit_altair_plot   sz       




 rt   c                 C   s>   d|j kr$| jtd|d   n| jtd tjd S )Nr0   z[ graph: %s ]z	[ graph ])
attributesrm   rn   r   r   re   rT   ro   r   r   r   generic_visit_altair_plot%  s    
rw   c                 C   s   d S Nr   rv   r   r   r   depart_altair_plot.  s    ry   c                 C   s.   |  | jj |  | jj |  | jj d S rx   )Zadd_js_filerR   altairplot_vega_js_urlaltairplot_vegalite_js_urlaltairplot_vegaembed_js_urlr   r   r   r   builder_inited2  s    r~   c                 C   s   | t _| jt _| jt _| dtd | dtd | dtd | dtd | 	dt
 | d | jtttfttfttfttfttfd	 | d
t | dt ddiS )NrS   r   rz   rs   r{   r|   r6   zaltair-plot.css)rs   ZlatexZtexinfotextZmanzenv-purge-doczbuilder-initedversionz0.1)setupr   rR   ZconfdirZadd_config_valuer!   VEGA_JS_URL_DEFAULTVEGALITE_JS_URL_DEFAULTVEGAEMBED_JS_URL_DEFAULTZadd_directiver,   Zadd_css_fileadd_noder   rt   ry   rw   connectr   r~   r}   r   r   r   r   8  s0      
	r   )*__doc__r]   r[   rJ   rk   ra   Zjinja2Zdocutilsr   Zdocutils.parsers.rstr   Zdocutils.parsers.rst.directivesr   r   Zsphinx.localer   Zaltairr0   Zaltair.utils.execevalr   r$   ZVEGA_VERSIONr   ZVEGALITE_VERSIONr   ZVEGAEMBED_VERSIONr   Templateri   ZGeneralElementr   r   r!   r&   r+   r,   rt   rw   ry   r~   r   r   r   r   r   <module>   sB   6LS	