o
    Nif                     @  s  d Z ddlm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 ddlmZ dd	lmZ erPdd
lmZmZ ddlmZ ddlmZ ddlmZ zddlZdZW n eyc   dZY nw dZd-ddZd.ddZ d/dd Z!d0d$d%Z"G d&d' d'eZ#d1d+d,Z$dS )2zHImplements the low-level algorithms Sphinx uses for versioning doctrees.    )annotationsN)productzip_longest)
itemgetter)path)TYPE_CHECKINGAny)uuid4)SphinxTransform)CallableIterator)Node)Sphinx)ExtensionMetadataTFA   doctreer   	conditionCallable[[Node], bool]returnIterator[Node]c                 c  s&    |  |D ]
}t j|_|V  q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   E/home/ubuntu/.local/lib/python3.10/site-packages/sphinx/versioning.pyadd_uids!   s
   

r   oldnewc                 c  s   |  |}| |}g }g }i }t }t||D ]H\}	}
|	du r'||
 qt|	dds2t j|	_|
du r<||	 qt|	j	|
j	}|dkrQ|	j|
_|
|
 q|||	|
f< ||	 ||
 qt||D ]*\}	}
|
|v su|	|
f|v rvqgt|	j	|
j	}|dkr|	j|
_|
|
 qg|||	|
f< qgt| tddD ]!\\}	}
}|
|v rq|
|
 |tk r|	j|
_qt j|
_|
V  qt|| D ]
}
t j|
_|
V  qd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_ratio	rawsourceaddr   sorteditemsr   VERSIONING_RATIO)r   r   r   old_iternew_iter	old_nodes	new_nodesratiosseenold_nodenew_noderatior   r   r   merge_doctrees0   sV   





 



r3   strfloatc                 C  sB   t | |gstS trt| |t| d  S t| |t| 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@)allr)   
IS_SPEEDUPLevenshteindistancelenlevenshtein_distance)r   r   r   r   r   r$   t   s
   r$   abintc                 C  s   | |krdS t | t |k r|| } }| st |S ttt |d }t| D ]3\}}|d g}t|D ]#\}}||d  d }|| d }	|| ||k }
|t||	|
 q4|}q'|d S )zEReturn the Levenshtein edit distance between two strings *a* and *b*.r   r   )r:   listrange	enumerater"   min)r<   r=   previous_rowicolumn1current_rowjcolumn2
insertions	deletionssubstitutionsr   r   r   r;      s    

r;   c                   @  s   e Zd ZdZdZd
ddZd	S )UIDTransformz#Add UIDs to doctree for versioning.ip  kwargsr   r   Nonec                 K  s   | j }d }|j}|sd S |jr?z&t|j|jd }t|d}t	|}W d    n1 s/w   Y  W n	 t
y>   Y nw |jrF|d u rPtt| j| d S tt|| j| d S )Nz.doctreerb)envversioning_conditionversioning_comparer   join
doctreedirdocnameopenpickleloadOSErrorr@   r   documentr3   )selfrN   rQ   old_doctreerR   filenamefr   r   r   apply   s$   zUIDTransform.applyN)rN   r   r   rO   )__name__
__module____qualname____doc__default_priorityr`   r   r   r   r   rM      s    rM   appr   r   c                 C  s   |  t ddddS )NbuiltinT)versionparallel_read_safeparallel_write_safe)add_transformrM   )rf   r   r   r   setup   s
   
rl   )r   r   r   r   r   r   )r   r   r   r   r   r   r   r   )r   r4   r   r4   r   r5   )r<   r4   r=   r4   r   r>   )rf   r   r   r   )%rd   
__future__r   rX   	itertoolsr   r   operatorr   osr   typingr   r   uuidr	   sphinx.transformsr
   collections.abcr   r   docutils.nodesr   sphinx.applicationr   sphinx.util.typingr   r8   r7   ImportErrorr)   r   r3   r$   r;   rM   rl   r   r   r   r   <module>   s6    


D
