U
    /e&                     @  s   d Z ddlmZ ddlZeeZddlmZm	Z	 ddl
mZ ddlmZ ddlmZmZm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mZ ddlmZmZmZm Z  ddl!m"Z" dZ)G dd dej*ej+Z,G dd deZ-dd Z.dS )a   Make javascript code blocks also include a live link to codepen.io for instant experiementation.

This directive takes a title to use for the codepen example:

.. code-block:: rest

    .. bokehjs-content::
        :title: Some Code

        alert('this is called in the codepen');

This directive is identical to the standard ``code-block`` directive
that Sphinx supplies, with the addition of one new option:

title : string
    A title for the codepen.
js_file : string
    location of javascript source file
include_html: string
    if present, this code block will be emitted as a complete HTML template with
    js inside a script block
disable_codepen: string
    if present, this code block will not have a 'try on codepen' button.  Currently
    necessary when 'include_html' is turned on.

Examples
--------

The inline example code above produces the following output:

.. bokehjs-content::
    :title: Some Code

    alert('this is called in the codepen');

    )annotationsN)basenamejoin)nodes)	unchanged)	CodeBlockcontainer_wrapperdedent_lines)SphinxError)__)loggingparselinenos)set_source_info   )PARALLEL_SAFE)BJS_CODEPEN_INITBJS_EPILOGUEBJS_HTMLBJS_PROLOGUE)get_sphinx_resources)bokehjs_contentBokehJSContentsetupc                   @  s0   e Zd Zedd Zedd ZejejfZdS )r   c                 C  sN   |d r,t dd}| jtj|j|jd | jtj|d |d d d S )Ninclude_bjs_headerTZinclude_bokehjs_api)	css_filesjs_files	target_idtitle)idr   )r   bodyappendr   renderr   r   r   )visitornode	resources r&   C/tmp/pip-unpacked-wheel-f5fndrjf/bokeh/sphinxext/bokehjs_content.py
visit_htmlq   s    
zbokehjs_content.visit_htmlc                 C  s*   | j tj|d |d  |d d d S )Nr   disable_codepen	js_source)r   Zenable_codepenr*   )r    r!   r   r"   )r#   r$   r&   r&   r'   depart_htmlz   s    zbokehjs_content.depart_htmlN)__name__
__module____qualname__staticmethodr(   r+   __func__htmlr&   r&   r&   r'   r   o   s
   

r   c                   @  sn   e Zd ZdZdZdZejZeje	d eje	d eje	d eje	d dd	 Z
d
d Zdd Zdd ZdS )r   Tr   r   )r   )js_file)include_html)r)   c              
     s  | j j}| j| j}| jd}|rzlt|d t	| }t
 fdd|D r~| jd }tjtd  d||d  fdd	|D }W q tk
r } z |jjt|| jd
g W Y S d}~X Y qX nd}d| jkr| j| j}|d}	t|	| jd |d}	d|	}t||}
||
d< d| jkpBd| jk|
d< |
d  | jdg 7  < i  }|
d< |dk	r||d< d| jkr| jd |d< t| |
 | jd}|rzt| |
|}
W n@ tk
r } z |jjt|| jd
g W Y S d}~X Y nX | |
 |
gS )zthis is copied from sphinx.directives.code.CodeBlock.run

        it has been changed to accept code and language as an arguments instead
        of reading from self

        zemphasize-lines
c                 3  s   | ]}| kV  qd S )Nr&   ).0inlinesr&   r'   	<genexpr>   s     z4BokehJSContent.get_codeblock_node.<locals>.<genexpr>z#line number spec is out of range(1-z): )locationc                   s   g | ]}| k r|d  qS )r   r&   )r5   xr7   r&   r'   
<listcomp>   s      z5BokehJSContent.get_codeblock_node.<locals>.<listcomp>)lineNdedentlanguageZlinenoszlineno-startclassesclassZhighlight_argshl_linesZlinenostartcaption)statedocumentstate_machineZget_source_and_linelinenooptionsgetlensplitr   anylogwarningr   
ValueErrorZreporterstrr	   r   r   Zliteral_blockr   r   Zadd_name)selfcoder?   rE   r:   ZlinespecrB   Z
emph_lineserrlinesliteral
extra_argsrC   excr&   r7   r'   get_codeblock_node   sJ    

0



.
z!BokehJSContent.get_codeblock_nodec                 C  s   | j dd}|r | jr td|rjtd| jjd|  |}|ds\t	| jj
j|}t| }n td| jj d	| j}|S )	Nr2   Fz?bokehjs-content:: directive can't have both js_file and contentz/[bokehjs-content] handling external example in z: /z-[bokehjs-content] handling inline example in r4   )rH   rI   contentr
   rM   debugenvZdocname
startswithr   appsrcdiropenread)rQ   r2   pathr*   r&   r&   r'   get_js_source   s    

zBokehJSContent.get_js_sourcec                 C  sL   |   }| jddr@tdd}tj|j|j|j|d}|dgS |dgS dS )	zL
        This is largely copied from bokeh.sphinxext.bokeh_plot.run
        r3   FTr   )r   r   hashesZ
bjs_scriptr1   Z
javascriptN)	rc   rH   rI   r   r   r"   r   r   rd   )rQ   r*   r%   Zhtml_sourcer&   r&   r'   get_code_language   s    
z BokehJSContent.get_code_languagec                 C  s   | j jjd }t|}| jd}| d| }|dd}tjdd|gd}t	 }||d< | j
d	d
|d	< d|d< | j
dd|d< |  |d< | j jj}t|dsd|_d|d< |  \}}	| ||	}
||
d  |j|
d  ||gS )NsourceZccbz.ccb-.- )idsr   r   zbokehjs exampleFr   r)   r*   bjs_seenTr   )rF   r$   rE   r   r\   Znew_serialnoreplacer   targetr   rH   rI   rc   hasattrrk   re   rX   Zsetup_childchildrenr!   )rQ   Z
rst_sourceZrst_filenameZ	serial_nor   Ztarget_noder$   Z
source_docZcode_contentr?   cbr&   r&   r'   run   s*    

zBokehJSContent.runN)r,   r-   r.   Zhas_contentZoptional_argumentsZrequired_argumentsr   Zoption_specupdater   rX   rc   re   rq   r&   r&   r&   r'   r      s   8r   c                 C  s    | j ttjd | dt tS )z+ Required Sphinx extension setup function. )r1   zbokehjs-content)add_noder   r1   Zadd_directiver   r   )r^   r&   r&   r'   r     s    r   )/__doc__
__future__r   r   	getLoggerr,   rM   os.pathr   r   Zdocutilsr   Zdocutils.parsers.rst.directivesr   Zsphinx.directives.coder   r   r	   Zsphinx.errorsr
   Zsphinx.localer   Zsphinx.utilr   Zsphinx.util.nodesr   ri   r   Z	templatesr   r   r   r   utilr   AnyDictListTupleZSphinxZConfig__all__ZGeneralElementr   r   r   r&   r&   r&   r'   <module>   s&   (
 