B
    d                 @   s,  d Z ddl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dlmZ dd	lmZ e
rdd
lmZ yddlZdZW n ek
r   dZY nX dZeeee dddZeeeee dddZeeedddZeeedddZ G dd deZ!deeef dddZ"dS ) zHImplements the low-level algorithms Sphinx uses for versioning doctrees.    N)productzip_longest)
itemgetter)path)TYPE_CHECKINGAnyDictIterator)uuid4)Node)SphinxTransform)SphinxTFA   )doctree	conditionreturnc             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)findallr
   hexuid)r   r   node r   ^/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/sphinx/versioning.pyadd_uids   s    

r   )oldnewr   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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   sorteditemsr   VERSIONING_RATIO)r   r   r   Zold_iterZnew_iterZ	old_nodesZ	new_nodesratiosseenold_nodenew_noderatior   r   r   merge_doctrees)   sT    













r*   )r   r   r   c             C   sF   t | |gstS tr,t| |t| d  S t| |t| d  S dS )zReturn a "similarity 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    l   s
    r    )abr   c             C   s   | |krdS t | t |k r&||  } }| s2t |S ttt |d }xvt| D ]j\}}|d g}xRt|D ]F\}}||d  d }|| d }	|| ||k }
|t||	|
 qlW |}qPW |d S )zEReturn the Levenshtein edit distance between two strings *a* and *b*.r   r   )r.   listrange	enumerater   min)r0   r1   Zprevious_rowiZcolumn1Zcurrent_rowjZcolumn2
insertionsZ	deletionsZsubstitutionsr   r   r   r/   y   s     

r/   c               @   s$   e Zd ZdZdZeddddZdS )UIDTransformz#Add UIDs to doctree for versioning.ip  N)kwargsr   c          	   K   s   | j }d }|jsd S |jrhy8t|j|jd }t|d}t	|}W d Q R X W n t
k
rf   Y nX |jrv|d krtt| j|j ntt|| j|j d S )Nz.doctreerb)envZversioning_conditionZversioning_comparer   joinZ
doctreedirZdocnameopenpickleloadOSErrorr3   r   Zdocumentr*   )selfr;   r=   Zold_doctreefilenamefr   r   r   apply   s    zUIDTransform.apply)__name__
__module____qualname____doc__Zdefault_priorityr   rF   r   r   r   r   r:      s   r:   r   )appr   c             C   s   |  t ddddS )NbuiltinT)versionZparallel_read_safeZparallel_write_safe)Zadd_transformr:   )rK   r   r   r   setup   s    
rN   )#rJ   r@   	itertoolsr   r   operatorr   osr   typingr   r   r   r	   uuidr
   Zdocutils.nodesr   Zsphinx.transformsr   Zsphinx.applicationr   r-   r,   ImportErrorr$   r   r*   strfloatr    intr/   r:   rN   r   r   r   r   <module>   s,   
C