B
    .Kc!                 @   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mZm	Z	m
Z
 ddlmZ yddlmZ W n  ek
r   ddlmZ Y nX 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 erddlmZ eeZe  Z!dZ"e#e#ddddZ$G dd dZ%e#e&dddZ'G dd dZ(dS )z"Theming support for HTML builders.    N)path)TYPE_CHECKINGAnyDictList)ZipFile)entry_points)package_dir)
ThemeError)__)logging)	ensuredir)Sphinxz
theme.conf)filename	targetdirreturnc             C   s   t | t| j}xb| D ]V}|dr,qt||}t t| tt|d}||	| W dQ R X qW W dQ R X dS )z%Extract zip file to target directory./wbN)
r   r   namelistendswithr   joindirnameopenwriteread)r   r   archivenameentryfp r   -lib/python3.7/site-packages/sphinx/theming.pyextract_zip    s    

r!   c               @   s   e Zd ZdZeedddddZee ddd	Zefeee	e	d
ddZ
i feee	f eee	f dddZddddZdS )ThemezA Theme is a set of HTML templates and configurations.

    This class supports both theme directory and theme archive (zipped theme).HTMLThemeFactoryN)r   
theme_pathfactoryr   c          
   C   sN  || _ d | _d | _t|r*d | _|| _n(td| _t| j|| _t	|| j t
 | _| jjt| jtdd y| jdd}W nj t
jk
r } zttd| |W d d }~X Y n6 t
jk
r } zttd| |W d d }~X Y nX |dkrJy||| _W n: tk
rH } zttd	||f |W d d }~X Y nX d S )
NZsxtzutf-8)encodingthemeinheritz%theme %r doesn't have "theme" settingz'theme %r doesn't have "inherit" settingZnonez(no theme named %r found, inherited by %r)r   baserootdirr   isdirthemedirtempfileZmkdtempr   r!   configparserZRawConfigParserconfigr   	THEMECONFgetNoSectionErrorr
   r   NoOptionErrorcreate)selfr   r$   r%   r(   excr   r   r    __init__3   s.    

"$
zTheme.__init__)r   c             C   s(   | j dkr| jgS | jg| j   S dS )zReturn a list of theme directories, beginning with this theme's,
        then the base theme's, then that one's base theme's, etc.
        N)r)   r,   get_theme_dirs)r5   r   r   r    r8   S   s    
zTheme.get_theme_dirs)sectionr   defaultr   c          
   C   sx   y| j ||S  tjtjfk
rr } z>| jr>| j|||S |tkr^tt	d||f |n|S W dd}~X Y nX dS )zdReturn the value for a theme configuration setting, searching the
        base theme chain.
        z:setting %s.%s occurs in none of the searched theme configsN)
r/   r1   r.   r3   r2   r)   
get_config	NODEFAULTr
   r   )r5   r9   r   r:   r6   r   r   r    r;   \   s    zTheme.get_config)	overridesr   c             C   s   | j r| j  }ni }y|| jd W n tjk
rB   Y nX x8| D ],\}}||krrtt	d|  qN|||< qNW |S )z6Return a dictionary of theme options and their values.optionsz!unsupported theme option %r given)
r)   get_optionsupdater/   itemsr.   r2   loggerwarningr   )r5   r=   r>   optionvaluer   r   r    r?   l   s    zTheme.get_optionsc             C   s@   | j r,yt| j  W n tk
r*   Y nX | jr<| j  dS )zRemove temporary directories.N)r*   shutilZrmtree	Exceptionr)   cleanup)r5   r   r   r    rH      s    zTheme.cleanup)__name__
__module____qualname____doc__strr7   r   r8   r<   r   r;   r   r?   rH   r   r   r   r    r"   .   s    	$r"   )r   r   c          	   C   s:   y t | }t| kS Q R X W n tk
r4   dS X dS )zBCheck whether the specified file is an archived theme file or not.NF)r   r0   r   rG   )r   fr   r   r    is_archived_theme   s
    
rO   c               @   s   e Zd ZdZdddddZdddd	Zedd
ddZeddddZddddZ	ddddZ
eddddZeeeef dddZeedddZdS )r#   z A factory class for HTML Themes.r   N)appr   c             C   s8   || _ |jj| _|   t|jdd r4| |jj d S )Nhtml_theme_path)	rP   registryZhtml_themesthemesload_builtin_themesgetattrr/   load_additional_themesrQ   )r5   rP   r   r   r    r7      s
    
zHTMLThemeFactory.__init__)r   c             C   s6   |  ttd}x| D ]\}}|| j|< qW dS )zLoad built-in themes.rS   N)find_themesr   r   r	   rA   rS   )r5   rS   r   r'   r   r   r    rT      s    z$HTMLThemeFactory.load_builtin_themes)theme_pathsr   c             C   sR   xL|D ]D}t t | jj|}| |}x| D ]\}}|| j|< q4W qW dS )z7Load additional themes placed at specified directories.N)r   abspathr   rP   ZconfdirrW   rA   rS   )r5   rX   r$   Zabs_theme_pathrS   r   r'   r   r   r    rV      s
    

z'HTMLThemeFactory.load_additional_themes)r   r   c             C   s    |dkr|    n
| | dS )z,Try to load a theme with the specified name.	alabasterN)load_alabaster_themeload_external_theme)r5   r   r   r   r    load_extra_theme   s    
z!HTMLThemeFactory.load_extra_themec             C   s"   ddl }t| d| jd< dS )zLoad alabaster theme.r   NrZ   )rZ   r   r   Zget_pathrS   )r5   rZ   r   r   r    r[      s    z%HTMLThemeFactory.load_alabaster_themec             C   s@   y&ddl }| }t|d| jd< W n tk
r:   Y nX dS )z+Load sphinx_rtd_theme theme (if installed).r   Nsphinx_rtd_theme)r^   Zget_html_theme_pathr   r   rS   ImportError)r5   r^   r$   r   r   r    load_sphinx_rtd_theme   s    z&HTMLThemeFactory.load_sphinx_rtd_themec             C   sP   t dd}y,|| }| jj| j|j | jj  dS  tk
rJ   Y nX dS )zjTry to load a theme using entry_points.

        Sphinx refers to ``sphinx_themes`` entry_points.
        zsphinx.html_themes)groupN)r   rP   rR   Zload_extensionmoduler/   Zpost_init_valuesKeyError)r5   r   Ztheme_entry_pointsZentry_pointr   r   r    r\      s    
z$HTMLThemeFactory.load_external_theme)r$   r   c             C   s   i }t |s|S xt|D ]r}t ||}t |rv| drvt|rd|dd }|||< qt	
td| qt t |tr|||< qW |S )z'Search themes from specified directory.z.zipNzAfile %r on theme path is not a valid zipfile or contains no theme)r   r+   oslistdirr   isfilelowerr   rO   rB   rC   r   r0   )r5   r$   rS   r   pathnamer   r   r   r    rW      s    


zHTMLThemeFactory.find_themesc             C   sj   || j kr| | || j kr<|dkr<ttd |   || j krVttd| t|| j | | dS )zCreate an instance of theme.r^   zKsphinx_rtd_theme (< 0.3.0) found. It will not be available since Sphinx-6.0z-no theme named %r found (missing theme.conf?))r%   )rS   r]   rB   rC   r   r`   r
   r"   )r5   r   r   r   r    r4      s    


zHTMLThemeFactory.create)rI   rJ   rK   rL   r7   rT   rM   rV   r]   r[   r`   r\   r   rW   r"   r4   r   r   r   r    r#      s   	r#   ))rL   r.   re   rF   r-   r   typingr   r   r   r   Zzipfiler   Zimportlib_metadatar   r_   Zimportlib.metadataZsphinxr	   Zsphinx.errorsr
   Zsphinx.localer   Zsphinx.utilr   Zsphinx.util.osutilr   Zsphinx.applicationr   Z	getLoggerrI   rB   objectr<   r0   rM   r!   r"   boolrO   r#   r   r   r   r    <module>   s2   
]	