B
    \                 @   s   d 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mZ dd	lmZ dd
lmZ yddlZdZW n ek
r   dZY nX dZdd Zdd Zdd Zdd ZG dd deZdd ZdS )z
    sphinx.versioning
    ~~~~~~~~~~~~~~~~~

    Implements the low-level algorithms Sphinx uses for the versioning of
    doctrees.

    :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
    :license: BSD, see LICENSE for details.
    N)product)
itemgetter)uuid4)	iteritems)cPickle)rangezip_longest)RemovedInSphinx30Warning)SphinxTransformTFA   c             c   s(   x"|  |D ]}t j|_|V  qW dS )a  Add a unique id to every node in the `doctree` which matches the
    condition and yield the nodes.

    :param doctree:
        A :class:`docutils.nodes.document` instance.

    :param condition:
        A callable which returns either ``True`` or ``False`` for a given node.
    N)traverser   hexuid)Zdoctree	conditionZnode r   0lib/python3.7/site-packages/sphinx/versioning.pyadd_uids'   s    
r   c             c   s  |  |}| |}g }g }i }t }xt||D ]\}	}
|	dkrN||
 q2t|	ddsdt j|	_|
dkrx||	 q2t|	j	|
j	}|dkr|	j|
_|
|
 q2|||	|
f< ||	 ||
 q2W xdt||D ]V\}	}
|
|ks|	|
f|krqt|	j	|
j	}|dkr|	j|
_|
|
 q|||	|
f< qW tt|tdd}xT|D ]L\\}	}
}|
|krbqFn
|
|
 |tk r|	j|
_nt j|
_|
V  qFW x&t|| D ]}
t j|
_|
V  qW dS )a1  Merge the `old` doctree with the `new` one while looking at nodes
    matching the `condition`.

    Each node which replaces another one or has been added to the `new` doctree
    will be yielded.

    :param condition:
        A callable which returns either ``True`` or ``False`` for a given node.
    Nr   r      )key)r   setr   appendgetattrr   r   r   	get_ratioZ	rawsourceaddr   sortedr   r   VERSIONING_RATIO)oldnewr   Zold_iterZnew_iterZ	old_nodesZ	new_nodesZratiosseenZold_nodeZnew_nodeZratior   r   r   merge_doctrees7   sT    












r   c             C   sF   t | |gstS tr,t| |t| d  S t| |t| d  S dS )zReturn a "similiarity ratio" (in percent) representing the similarity
    between the two strings where 0 is equal and anything above less than equal.
    g      Y@N)allr   
IS_SPEEDUPLevenshteinZdistancelenlevenshtein_distance)r   r   r   r   r   r   {   s
    r   c             C   s   | |krdS t | t |k r&||  } }| s2t |S tt |d }xvt| D ]j\}}|d g}xRt|D ]F\}}||d  d }|| d }	|| ||k }
|t||	|
 qhW |}qLW |d S )zEReturn the Levenshtein edit distance between two strings *a* and *b*.r   r   )r#   r   	enumerater   min)abZprevious_rowiZcolumn1Zcurrent_rowjZcolumn2Z
insertionsZ	deletionsZsubstitutionsr   r   r   r$      s     

r$   c               @   s   e Zd ZdZdZdd ZdS )UIDTransformz#Add UIDs to doctree for versioning.ip  c          	   C   s   | j }d }|jsd S |jrfy6||j|jd}t|d}t|}W d Q R X W n t	k
rd   Y nX |jrt|d krt
t| j|j nt
t|| j|j d S )Nz.doctreerb)envZversioning_conditionZversioning_compareZdoc2pathZdocnameZ
doctreediropenpickleloadEnvironmentErrorlistr   documentr   )selfr.   Zold_doctreefilenamefr   r   r   apply   s    zUIDTransform.applyN)__name__
__module____qualname____doc__Zdefault_priorityr8   r   r   r   r   r,      s   r,   c             C   s$   t jdtdd t| }|  dS )z Simple wrapper for UIDTransform.z=versioning.prepare() is deprecated. Use UIDTransform instead.   )
stacklevelN)warningswarnr	   r,   r8   )r4   Z	transformr   r   r   prepare   s    
rA   )r<   r?   	itertoolsr   operatorr   Zuuidr   Zsixr   Z	six.movesr   r0   r   r   Zsphinx.deprecationr	   Zsphinx.transformsr
   r"   r!   ImportErrorr   r   r   r   r$   r,   rA   r   r   r   r   <module>   s*   
D