o
    Æiéa‚R  ã                   @   s”  d dl Z d dlmZ d dlmZ d dlmZ d dlZd dlZd dl	m
Z
mZmZ d dlmZmZ G dd„ dƒZG d	d
„ d
eeƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd „ d eƒZG d!d"„ d"eƒZG d#d$„ d$eƒZG d%d&„ d&eƒZG d'd(„ d(eƒZ G d)d*„ d*eƒZ!G d+d,„ d,eƒZ"dS )-é    N)Ú
namedtuple)ÚSequence)Úurlparse)ÚutilsÚthemeÚplugins)ÚConfigÚValidationErrorc                   @   sD   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dS )ÚBaseConfigOptionc                 C   s   g | _ d | _d S ©N)ÚwarningsÚdefault©Úself© r   ú>/usr/lib/python3/dist-packages/mkdocs/config/config_options.pyÚ__init__   s   
zBaseConfigOption.__init__c                 C   ó   dS ©NFr   r   r   r   r   Úis_required   s   zBaseConfigOption.is_requiredc                 C   s
   |   |¡S r   )Úrun_validation©r   Úvaluer   r   r   Úvalidate   ó   
zBaseConfigOption.validatec                 C   s
   g | _ d S r   )r   r   r   r   r   Úreset_warnings   r   zBaseConfigOption.reset_warningsc                 C   r   )z¥
        Before all options are validated, perform a pre-validation process.

        The pre-validation process method should be implemented by subclasses.
        Nr   ©r   ÚconfigÚkey_namer   r   r   Úpre_validation   ó    zBaseConfigOption.pre_validationc                 C   s   |S )zy
        Perform validation for a value.

        The run_validation method should be implemented by subclasses.
        r   r   r   r   r   r   "   s   zBaseConfigOption.run_validationc                 C   r   )zõ
        After all options have passed validation, perform a post-validation
        process to do any additional changes dependant on other config values.

        The post-validation process method should be implemented by subclasses.
        Nr   r   r   r   r   Úpost_validation*   r    z BaseConfigOption.post_validationN)
Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r   r!   r   r   r   r   r
      s    r
   c                   @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )Ú	SubConfigc                 G   s    t  | ¡ t | |¡ i | _d S r   )r
   r   r   r   )r   Úconfig_optionsr   r   r   r   4   s   

zSubConfig.__init__c                 C   s   |   |¡ |  |¡S r   )Ú	load_dictr   r   r   r   r   r   9   ó   

zSubConfig.validatec                 C   s   t  | ¡ | S r   )r   r   r   r   r   r   r   =   s   
zSubConfig.run_validationN)r"   r#   r$   r   r   r   r   r   r   r   r%   3   s    r%   c                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	ÚConfigItemszp
    Config Items Option

    Validates a list of mappings that all must match the same set of
    options.
    c                 O   s&   t  | ¡ t|Ž | _| dd¡| _d S )NÚrequiredF)r
   r   r%   Úitem_configÚgetr*   )r   r&   Úkwargsr   r   r   r   I   s   

zConfigItems.__init__c                 C   s   d  | jj| j¡S )Nz{}: {})ÚformatÚ	__class__r"   r+   r   r   r   r   Ú__repr__N   ó   zConfigItems.__repr__c                 C   sX   |d u r| j rtdƒ‚dS t|tƒstdt|ƒ ƒ‚g }|D ]}| | j |¡¡ q|S )Nú$Required configuration not provided.r   z4Expected a sequence of mappings, but a %s was given.)r*   r	   Ú
isinstancer   ÚtypeÚappendr+   r   )r   r   ÚresultÚitemr   r   r   r   Q   s   
ÿzConfigItems.run_validationN)r"   r#   r$   Ú__doc__r   r0   r   r   r   r   r   r)   B   s
    r)   c                       ó2   e Zd ZdZd
‡ fdd„	Zdd„ Zdd	„ Z‡  ZS )ÚOptionallyRequiredz�
    A subclass of BaseConfigOption that adds support for default values and
    required values. It is a base class for config options.
    NFc                    s   t ƒ  ¡  || _|| _d S r   )Úsuperr   r   r*   ©r   r   r*   ©r/   r   r   r   g   ó   

zOptionallyRequired.__init__c                 C   s   | j S r   )r*   r   r   r   r   r   l   s   zOptionallyRequired.is_requiredc                 C   sT   |du r%| j durt| j dƒr| j  ¡ }n| j }n| jsdS | jr%tdƒ‚|  |¡S )zû
        Perform some initial validation.

        If the option is empty (None) and isn't required, leave it as such. If
        it is empty but has a default, use that. Finally, call the
        run_validation method on the subclass unless.
        NÚcopyr2   )r   Úhasattrr?   r*   r	   r   r   r   r   r   r   o   s   	

zOptionallyRequired.validater   )r"   r#   r$   r8   r   r   r   Ú__classcell__r   r   r=   r   r:   a   s
    r:   c                       s*   e Zd ZdZd‡ fdd„	Zdd„ Z‡  ZS )ÚTypezc
    Type Config Option

    Validate the type of a config option against a given Python type.
    Nc                    s"   t ƒ jdi |¤Ž || _|| _d S ©Nr   )r;   r   Ú_typeÚlength)r   Útype_rE   r-   r=   r   r   r   Ž   s   
zType.__init__c                 C   sb   t || jƒsd | jt|ƒ¡}t|ƒ‚| jd ur/t|ƒ| jkr/d | j|| jt|ƒ¡}t|ƒ‚|S )Nz"Expected type: {} but received: {}zDExpected type: {0} with length {2} but received: {1} with length {3})r3   rD   r.   r4   rE   Úlenr	   ©r   r   Úmsgr   r   r   r   “   s   ÿ	ùÿÿþzType.run_validationr   ©r"   r#   r$   r8   r   r   rA   r   r   r=   r   rB   ‡   s    rB   c                       s(   e Zd ZdZ‡ fdd„Zdd„ Z‡  ZS )ÚChoicez^
    Choice Config Option

    Validate the config option against a strict set of values.
    c                    sX   t ƒ jdi |¤Ž zt|ƒ}W n ty   d}Y nw |r"t|tƒr'td|ƒ‚|| _d S )Nr   z$Expected iterable of choices, got {}r   )r;   r   rG   Ú	TypeErrorr3   ÚstrÚ
ValueErrorÚchoices)r   rO   r-   rE   r=   r   r   r   ©   s   ÿ

zChoice.__init__c                 C   s$   || j vrd | j |¡}t|ƒ‚|S )Nz$Expected one of: {} but received: {})rO   r.   r	   rH   r   r   r   r   µ   s   

ÿþzChoice.run_validationrJ   r   r   r=   r   rK   ¢   s    rK   c                       s&   e Zd Zd‡ fdd„	Zdd„ Z‡  ZS )Ú
DeprecatedNc                    s   t ƒ  ¡  d | _|| _d S r   )r;   r   r   Úmoved_to)r   rQ   r=   r   r   r   Á   r>   zDeprecated.__init__c                 C   sœ   |  |¡d u s| jd u rd S d |¡}| j |¡ d| jvr$|}| j}n!| j dd¡\}}|}| d¡D ]}| |i ¡}t|t	ƒsD d S q4| 
|¡||< d S )NzbThe configuration option {} has been deprecated and will be removed in a future release of MkDocs.Ú.é   )r,   rQ   r.   r   r5   ÚrsplitÚsplitÚ
setdefaultr3   ÚdictÚpop)r   r   r   ÚwarningÚtargetÚ
target_keyÚmove_toÚkeyr   r   r   r   Æ   s"   þ

þzDeprecated.pre_validationr   )r"   r#   r$   r   r   rA   r   r   r=   r   rP   ¿   s    rP   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )Ú	IpAddressz^
    IpAddress Config Option

    Validate that an IP address is in an apprioriate format
    c              
   C   s²   z
|  dd¡\}}W n ty   tdƒ‚w |dkr4z	tt |¡ƒ}W n ty3 } zt|ƒ‚d }~ww zt|ƒ}W n tyH   td |¡ƒ‚w G dd„ dt	ddƒƒ}|||ƒS )	Nú:rS   z$Must be a string of format 'IP:PORT'Ú	localhostz'{}' is not a valid portc                   @   s   e Zd Zdd„ ZdS )z)IpAddress.run_validation.<locals>.Addressc                 S   s   d  | j| j¡S )Nz{}:{})r.   ÚhostÚportr   r   r   r   Ú__str__û   ó   z1IpAddress.run_validation.<locals>.Address.__str__N)r"   r#   r$   rc   r   r   r   r   ÚAddressú   s    re   z	host port)
rT   Ú	Exceptionr	   rM   Ú	ipaddressÚ
ip_addressrN   Úintr.   r   )r   r   ra   rb   Úere   r   r   r   r   è   s&   ÿ€ÿÿ
zIpAddress.run_validationc                 C   s8   || j }|dkr|dv r| j d |¡¡ d S d S d S )NÚdev_addr)z0.0.0.0z::zþThe use of the IP address '{}' suggests a production environment or the use of a proxy to connect to the MkDocs server. However, the MkDocs' server is intended for local development purposes only. Please use a third party production-ready server instead.)ra   r   r5   r.   )r   r   r   ra   r   r   r   r!      s   
üÿzIpAddress.post_validationN)r"   r#   r$   r8   r   r!   r   r   r   r   r^   á   s    r^   c                       s*   e Zd ZdZd‡ fdd„	Zdd„ Z‡  ZS )	ÚURLzQ
    URL Config Option

    Validate a URL by requiring a scheme is present.
    Ú Fc                    s   t ƒ  ||¡ d S r   )r;   r   r<   r=   r   r   r     r1   zURL.__init__c              	   C   sF   |dkr|S zt |ƒ}W n ttfy   tdƒ‚w |jr|S tdƒ‚)Nrm   zUnable to parse the URL.z;The URL isn't valid, it should include the http:// (scheme))r   ÚAttributeErrorrL   r	   Úscheme)r   r   Ú
parsed_urlr   r   r   r     s   ÿÿzURL.run_validation)rm   FrJ   r   r   r=   r   rl     s    rl   c                   @   ó   e Zd ZdZdd„ ZdS )ÚRepoURLz«
    Repo URL Config Option

    A small extension to the URL config that sets the repo_name and edit_uri,
    based on the url if they haven't already been provided.
    c                 C   s  t |d ƒj ¡ }| d¡}|d d urA| d¡d u rA|dkr$d|d< n|dkr-d|d< n|dkr6d	|d< n| d
¡d  ¡ |d< |d d ur_|d u r_|dksS|dkrVd}n	|dkr]d}nd}|r~| d¡su|d  d¡su|d  d7  < | d¡s~|d7 }||d< d S )NÚrepo_urlÚedit_uriÚ	repo_namez
github.comÚGitHubzbitbucket.orgÚ	Bitbucketz
gitlab.comÚGitLabrR   r   zedit/master/docs/zsrc/default/docs/rm   )ú?ú#ú/)r   ÚnetlocÚlowerr,   rU   ÚtitleÚ
startswithÚendswith)r   r   r   Ú	repo_hostrt   r   r   r   r!   -  s0   




ÿ
zRepoURL.post_validationN)r"   r#   r$   r8   r!   r   r   r   r   rr   %  s    rr   c                       s6   e Zd ZdZd	‡ fdd„	Zdd„ Z‡ fdd„Z‡  ZS )
ÚFilesystemObjectzB
    Base class for options that point to filesystem objects.
    Fc                    s&   t ƒ jddti|¤Ž || _d | _d S )NrF   r   )r;   r   rM   ÚexistsÚ
config_dir)r   rƒ   r-   r=   r   r   r   T  s   
zFilesystemObject.__init__c                 C   s$   |j rtj |j ¡| _d S d | _d S r   )Úconfig_file_pathÚosÚpathÚdirnamer„   r   r   r   r   r   Y  s   $zFilesystemObject.pre_validationc                    sp   t ƒ  |¡}| jrtj |¡stj | j|¡}| jr)|  |¡s)t	dj
|| jd�ƒ‚tj |¡}t|tƒs6J ‚|S )Nz)The path {path} isn't an existing {name}.©r‡   Úname)r;   r   r„   r†   r‡   ÚisabsÚjoinrƒ   Úexistence_testr	   r.   rŠ   Úabspathr3   rM   r   r=   r   r   r   \  s   ÿzFilesystemObject.run_validation)F)r"   r#   r$   r8   r   r   r   rA   r   r   r=   r   r‚   P  s
    r‚   c                   @   s(   e Zd ZdZeejjƒZdZ	dd„ Z
dS )ÚDirze
    Dir Config Option

    Validate a path to a directory, optionally verifying that it exists.
    Ú	directoryc                 C   s6   |j d u rd S tj |j ¡|| krtd |¡ƒ‚d S )Nz‘The '{0}' should not be the parent directory of the config file. Use a child directory instead so that the '{0}' is a sibling of the config file.)r…   r†   r‡   rˆ   r	   r.   r   r   r   r   r!   q  s   
ýÿzDir.post_validationN)r"   r#   r$   r8   Ústaticmethodr†   r‡   Úisdirr�   rŠ   r!   r   r   r   r   r�   h  s
    r�   c                   @   s    e Zd ZdZeejjƒZdZ	dS )ÚFileza
    File Config Option

    Validate a path to a file, optionally verifying that it exists.
    ÚfileN)
r"   r#   r$   r8   r‘   r†   r‡   Úisfiler�   rŠ   r   r   r   r   r“   }  s    r“   c                       s    e Zd ZdZ‡ fdd„Z‡  ZS )ÚSiteDirzo
    SiteDir Config Option

    Validates the site_dir and docs_dir directories do not contain each other.
    c                    sŽ   t ƒ  ||¡ |d tj  |d  tj¡tj ¡r&td |d |d ¡ƒ‚|d tj  |d  tj¡tj ¡rEtd |d |d ¡ƒ‚d S )NÚdocs_dirÚsite_dirzÎThe 'docs_dir' should not be within the 'site_dir' as this can mean the source files are overwritten by the output or it will be deleted if --clean is passed to mkdocs build.(site_dir: '{}', docs_dir: '{}')z¾The 'site_dir' should not be within the 'docs_dir' as this leads to the build directory being copied into itself and duplicate nested files in the 'site_dir'.(site_dir: '{}', docs_dir: '{}'))r;   r!   r†   Úsepr   Úrstripr	   r.   r   r=   r   r   r!   Ž  s   &û&ûÿzSiteDir.post_validation)r"   r#   r$   r8   r!   rA   r   r   r=   r   r–   ‡  s    r–   c                       s2   e Zd ZdZd	‡ fdd„	Zdd„ Zdd„ Z‡  ZS )
ÚThemez[
    Theme Config Option

    Validate that the theme exists and build Theme instance.
    Nc                    s   t ƒ  ¡  || _d S r   )r;   r   r   )r   r   r=   r   r   r   ¬  r(   zTheme.__init__c                 C   s˜   |d u r| j d urd| j i}t|tƒrd|i}t ¡ }t|tƒrCd|v r?|d d u s0|d |v r2|S td |d d |¡¡ƒ‚tdƒ‚td t	|ƒ¡ƒ‚)NrŠ   zEUnrecognised theme name: '{}'. The available installed themes are: {}z, zNo theme name set.z8Invalid type "{}". Expected a string or key/value pairs.)
r   r3   rM   r   Úget_theme_namesrW   r	   r.   rŒ   r4   )r   r   Úthemesr   r   r   r   °  s   


þzTheme.validatec                 C   s¢   || }|d sd|vrt dƒ‚d|v r.tj |d ¡s.tj |j¡}tj ||d ¡|d< d|v rEtj |d ¡sEt dj|d |d�ƒ‚t	j
di |¤Ž||< d S )NrŠ   Ú
custom_dirzCAt least one of 'theme.name' or 'theme.custom_dir' must be defined.z<The path set in {name}.custom_dir ('{path}') does not exist.r‰   r   )r	   r†   r‡   r‹   rˆ   r…   rŒ   r’   r.   r   r›   )r   r   r   Útheme_configr„   r   r   r   r!   Ç  s   
ÿzTheme.post_validationr   )r"   r#   r$   r8   r   r   r!   rA   r   r   r=   r   r›   ¥  s
    r›   c                       s0   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Z‡  ZS )ÚNavzh
    Nav Config Option

    Validate the Nav config. Automatically add all markdown files if empty.
    c                    s   t ƒ jdi |¤Ž tj| _d S rC   )r;   r   r   Úis_markdown_fileÚ
file_match©r   r-   r=   r   r   r   à  s   zNav.__init__c                 C   s`   t |tƒstd t|ƒ¡ƒ‚t|ƒdkrd S dd„ |D ƒ}| tth¡r&|S td |tth¡ƒ‚)NzExpected a list, got {}r   c                 S   s   h | ]}t |ƒ’qS r   )r4   )Ú.0r7   r   r   r   Ú	<setcomp>í  s    z%Nav.run_validation.<locals>.<setcomp>zInvalid pages config. {} {})	r3   Úlistr	   r.   r4   rG   ÚissubsetrM   rW   )r   r   Úconfig_typesr   r   r   r   ä  s   
ÿÿzNav.run_validationc                 C   sH   |dkr |d d ur"|d d u r|d |d< d}| j  |¡ d S d S d S )NÚpagesÚnavzzThe 'pages' configuration option has been deprecated and will be removed in a future release of MkDocs. Use 'nav' instead.)r   r5   )r   r   r   rY   r   r   r   r!   õ  s   úzNav.post_validation©r"   r#   r$   r8   r   r   r!   rA   r   r   r=   r   r    Ù  s
    r    c                   @   rq   )ÚPrivatezo
    Private Config Option

    A config option only for internal use. Raises an error if set by the user.
    c                 C   s   t dƒ‚)NzFor internal use only.)r	   r   r   r   r   r     s   zPrivate.run_validationN)r"   r#   r$   r8   r   r   r   r   r   r¬      s    r¬   c                       r9   )ÚMarkdownExtensionsak  
    Markdown Extensions Config Option

    A list of extensions. If a list item contains extension configs,
    those are set on the private  setting passed to `configkey`. The
    `builtins` keyword accepts a list of extensions which cannot be
    overriden by the user. However, builtins can be duplicated to define
    config options for them if desired.
    NÚmdx_configsc                    s,   t ƒ jdi |¤Ž |pg | _|| _i | _d S rC   )r;   r   ÚbuiltinsÚ	configkeyÚ
configdata)r   r¯   r°   r-   r=   r   r   r     s   

zMarkdownExtensions.__init__c              
   C   sð   t |ttfƒstdƒ‚g }|D ]A}t |tƒrBt|ƒdkr tdƒ‚| ¡ \}}| |¡ |d u r0qt |tƒs<td |¡ƒ‚|| j	|< qt |t
ƒrM| |¡ qtdƒ‚t | j| ¡}ztj|| j	d� W |S  tyw } zt|jd ƒ‚d }~ww )Nz)Invalid Markdown Extensions configurationrS   z3Invalid config options for Markdown Extension '{}'.)Ú
extensionsÚextension_configsr   )r3   r¦   Útupler	   rW   rG   Úpopitemr5   r.   r±   rM   r   Úreduce_listr¯   ÚmarkdownÚMarkdownrf   Úargs)r   r   r²   r7   ÚextÚcfgrj   r   r   r   r     s6   


ÿ
ý€ÿz!MarkdownExtensions.run_validationc                 C   s   | j || j< d S r   )r±   r°   r   r   r   r   r!   :  rd   z"MarkdownExtensions.post_validation)Nr®   r«   r   r   r=   r   r­     s
    	r­   c                       s8   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Zdd	„ Z‡  ZS )
ÚPluginsz’
    Plugins config option.

    A list of plugins. If a plugin defines config options those are used when
    initializing the plugin class.
    c                    s&   t ƒ jdi |¤Ž t ¡ | _d | _d S rC   )r;   r   r   Úget_pluginsÚinstalled_pluginsr…   r£   r=   r   r   r   F  s   

zPlugins.__init__c                 C   s   |j | _ d S r   )r…   r   r   r   r   r   K  s   zPlugins.pre_validationc                 C   s¢   t |ttfƒstdƒ‚t ¡ }|D ]=}t |tƒr;t|ƒdkr"tdƒ‚| ¡ \}}|p+i }t |tƒs8td 	|¡ƒ‚|}ni }t |t
ƒsFtdƒ‚|  ||¡||< q|S )Nz9Invalid Plugins configuration. Expected a list of pluginsrS   zInvalid Plugins configurationz+Invalid config options for the "{}" plugin.)r3   r¦   r´   r	   r   ÚPluginCollectionrW   rG   rµ   r.   rM   Úload_plugin)r   r   Úplginsr7   rŠ   r»   r   r   r   r   N  s&   

ÿ
zPlugins.run_validationc                 C   sš   || j vrtd |¡ƒ‚| j |  ¡ }t|tjƒs)td |j|jtjjtjj¡ƒ‚|ƒ }| 	|| j
¡\}}| j |¡ d dd„ |D ƒ¡}|rKt|ƒ‚|S )Nz The "{}" plugin is not installedz!{}.{} must be a subclass of {}.{}Ú
c                 s   s    � | ]\}}d   ||¡V  qdS )zPlugin value: '{}'. Error: {}N)r.   )r¤   ÚxÚyr   r   r   Ú	<genexpr>t  s
   € 
ÿ
ÿz&Plugins.load_plugin.<locals>.<genexpr>)r¾   r	   r.   ÚloadÚ
issubclassr   Ú
BasePluginr#   r"   Úload_configr…   r   ÚextendrŒ   )r   rŠ   r   ÚPluginÚpluginÚerrorsr   Úerrors_messager   r   r   rÀ   f  s"   
þ
þzPlugins.load_plugin)	r"   r#   r$   r8   r   r   r   rÀ   rA   r   r   r=   r   r¼   >  s    r¼   )#r†   Úcollectionsr   Úcollections.abcr   Úurllib.parser   rg   r·   Úmkdocsr   r   r   Úmkdocs.config.baser   r	   r
   r%   r)   r:   rB   rK   rP   r^   rl   rr   r‚   r�   r“   r–   r›   r    r¬   r­   r¼   r   r   r   r   Ú<module>   s6    '&"*+
4'3