U
    \>e;                     @  sP  d Z ddlmZ ddlmZ ddlmZ ddlmZm	Z	m
Z
mZmZ ddlmZ dd	lZdd	lZdd	lZdd	lm  mZ dd
lmZmZmZmZ erddlmZ d.dddddddZddddddZedZddddddZdddddZ d/ddddd d!d"Z!ddd#d$d%Z"d&d' Z#G d(d) d)eZ$G d*d+ d+eZ%d,d- Z&d	S )0z
Add table of contents support to Python-Markdown.

See the [documentation](https://Python-Markdown.github.io/extensions/toc)
for details.
    )annotations   )	Extension   )Treeprocessor)code_escapeparseBoolValueAMP_SUBSTITUTEHTML_PLACEHOLDER_REAtomicString)UnescapeTreeprocessorN)TYPE_CHECKINGAnyIterator
MutableSet)MarkdownFstrbool)value	separatorunicodereturnc                 C  sL   |s"t d| } | ddd} tdd|   } td||| S )z, Slugify a string, to make it URL friendly. ZNFKDasciiignorez[^\w\s-] z[{}\s]+)	unicodedata	normalizeencodedecoderesubstriplowerformat)r   r   r    r$   ;/tmp/pip-unpacked-wheel-wj0og6ym/markdown/extensions/toc.pyslugify$   s
    r&   )r   r   r   c                 C  s   t | |ddS )zP Slugify a string, to make it URL friendly while preserving Unicode characters. T)r   )r&   )r   r   r$   r$   r%   slugify_unicode.   s    r'   z^(.*)_([0-9]+)$zMutableSet[str])ididsr   c                 C  sX   | |ks| sJt | }|r<d|dt|dd f } q d| df } q ||  | S )z@ Ensure id is unique in set of ids. Append '_1', '_2'... if not z%s_%dr   r   )
IDCOUNT_REmatchgroupintadd)r(   r)   mr$   r$   r%   unique6   s    
"
r0   etree.Element)elr   c                 C  sF   g }|   D ]*}t|tr,|t| q|| qd| S )zGet title name.r   )itertext
isinstancer   appendhtmlunescapejoinr!   )r2   textcr$   r$   r%   get_nameB   s    
r;   Tr   )r9   mdstrip_entitiesr   c                   s"   ddd fdd}t || S )zN Extract raw HTML from stash, reduce to plain text and swap with placeholder. zre.Match[str]r   )r/   r   c              	     sb   z j jt| d }W n" ttfk
r<   | d Y S X tdd|}r^tdd|}|S )z& Substitute raw html with plain text. r   r   z	(<[^>]+>)r   z(&[\#a-zA-Z0-9]+;))Z	htmlStashZrawHtmlBlocksr-   r,   
IndexError	TypeErrorr   r    )r/   rawresr<   r=   r$   r%   	_html_subP   s    z#stashedHTML2text.<locals>._html_sub)r
   r    )r9   r<   r=   rC   r$   rB   r%   stashedHTML2textN   s    rD   )r9   r   c                 C  s   t  }|| S )z Unescape escaped text. )r   r7   )r9   r:   r$   r$   r%   r7   _   s    r7   c           	      C  s  g }t | r| d}g |d< |d g}|| g }| r| d}|d }g |d< ||d k r|  d}t|D ]}||d kr|d7 }qx qqx|r|d|  }|d|  }|| ||d kr|r|d d n|| n"|d | || || |}q8|S )aV  Given an unsorted list with errors and skips, return a nested one.

        [{'level': 1}, {'level': 2}]
        =>
        [{'level': 1, 'children': [{'level': 2, 'children': []}]}]

    A wrong list is also converted:

        [{'level': 2}, {'level': 1}]
        =>
        [{'level': 2, 'children': []}, {'level': 1, 'children': []}]
    r   childrenlevelr   N)lenpopr5   reversed)	toc_listZordered_listlastlevelsparentstZcurrent_levelZto_poppr$   r$   r%   nest_toc_tokense   sB    








rQ   c                      s   e Zd ZdZddd fddZddd	d
dZddddddZdddddZddddddZddddddZ	dddddZ
dddddZ  ZS ) TocTreeprocessorz& Step through document and build TOC. r   zdict[str, Any])r<   configc                   s  t  | |d | _|d | _t|d d | _|d | _|d | _|d | _|d | _	t
|d	 | _|d
 | _t
|d d| _| jd kr|d | _|d | _|d | _t
|d d| _td| _t|d trd|d krdd |d dD \| _| _nd| _t|d | _d S )Nmarkertitle	baselevelr   r&   r   	toc_classtitle_class
anchorlinkanchorlink_class	permalinkFpermalink_classpermalink_titlepermalink_leadingz[Hh][123456]	toc_depth-c                 S  s   g | ]}t |qS r$   )r-   ).0xr$   r$   r%   
<listcomp>   s     z-TocTreeprocessor.__init__.<locals>.<listcomp>)super__init__rT   rU   r-   
base_levelr&   seprW   rX   r   use_anchorsrZ   use_permalinksr\   r]   r^   r   compile
header_rgxr4   r   splittoc_top
toc_bottom)selfr<   rS   	__class__r$   r%   re      s*    










"zTocTreeprocessor.__init__r1   z-Iterator[tuple[etree.Element, etree.Element]])noder   c                 c  s@   |D ]6}| j |js|jdkr||fV  | |E dH  qdS )z? Iterator wrapper to get allowed parent and child all at once. )precodeN)rk   r+   tag
iterparent)ro   rr   childr$   r$   r%   rv      s    
zTocTreeprocessor.iterparentNone)rootelemr   c                 C  s|   |  |D ]l\}}d|  }|s*q
|jr
|j | jkr
t|dkr
tt|D ]}|| |krX|||<  q
qXq
dS )z Replace marker with elem. r   r   N)rv   r8   r3   r!   r9   rT   rH   range)ro   ry   rz   rP   r:   r9   ir$   r$   r%   replace_marker   s    
"zTocTreeprocessor.replace_marker)rz   r   c                 C  s.   t |jd | j }|dkr d}d| |_dS )z. Adjust header level according to base level. rG      zh%dN)r-   ru   rf   )ro   rz   rF   r$   r$   r%   	set_level   s    zTocTreeprocessor.set_levelr   )r:   elem_idr   c                 C  sl   t d}|j|_d| |jd< | j|jd< d|_|D ]}|| q6t|r^||d  qF|| d S )Na#hrefclassr   r   )etreeElementr9   attribrZ   r5   rH   remove)ro   r:   r   anchorrz   r$   r$   r%   
add_anchor   s    
zTocTreeprocessor.add_anchorc                 C  s   t d}| jdkrdt n| j|_d| |jd< | j|jd< | jrP| j|jd< | jrr|j|_	d|_|
d	| n
|| d S )
Nr   Tz%spara;r   r   r   rU   r   r   )r   r   ri   r	   r9   r   r\   r]   r^   tailinsertr5   )ro   r:   r   r[   r$   r$   r%   add_permalink   s    

zTocTreeprocessor.add_permalinklist)rK   r   c                   s   t d}| j|jd< | jrBt |d}| jr:| j|jd< | j|_dddd fdd  || d	| jj	kr| jj	d	 
| |S )
z' Return a string div given a toc list. divr   spanr   r1   )rK   parentr   c                   sl   t |d}| D ]V}t |d}t |d}|dd|_d|dd |jd< |d	 r |d	 | q|S )
Nullir   namer   r   r(   r   rE   )r   
SubElementgetr9   r   )rK   r   r   itemr   linkbuild_etree_ulr$   r%   r     s    z6TocTreeprocessor.build_toc_div.<locals>.build_etree_ulZprettify)r   r   rW   r   rU   r   rX   r9   r<   treeprocessorsrun)ro   rK   r   headerr$   r   r%   build_toc_div  s    

zTocTreeprocessor.build_toc_div)docr   c           
      C  s  t  }| D ]}d|jkr||jd  qg }| D ]}t|jtr:| j|jr:| 	| t
|}d|jkrtt|| j}t| || j||jd< t|jd | jkrt|jd | jkr|t|jd |jd ttt|jd|| jddd d|jkr |jd= | jr:| ||jd  | jdkr:| ||jd  q:t|}| |}| jr~| || | j|}| jj D ]}	|	!|}q|| j_"|| j_#d S )Nr(   rG   zdata-toc-labelF)r=   )rF   r(   r   )FN)$setiterr   r.   r4   ru   r   rk   r+   r   r;   r7   rD   r<   r0   r&   rg   r-   rm   rn   r5   r   r   rh   r   ri   r   rQ   r   rT   r}   
serializerZpostprocessorsr   
toc_tokenstoc)
ro   r   Zused_idsr2   r   r9   Z	innertextr   r   ppr$   r$   r%   r   $  sJ    


, 


zTocTreeprocessor.run)__name__
__module____qualname____doc__re   rv   r}   r   r   r   r   r   __classcell__r$   r$   rp   r%   rR      s   rR   c                      s6   e Zd ZeZ fddZdd ZddddZ  ZS )	TocExtensionc                   sn   ddgddgddgddgd	d
gddgddgddgddgd	dgddgt dgddgddgd| _t jf | d S )Nz[TOC]zeText to find and replace with Table of Contents. Set to an empty string to disable. Default: `[TOC]`.r   z;Title to insert into TOC `<div>`. Default: an empty string.Ztoctitlez2CSS class used for the title. Default: `toctitle`.r   z4CSS class(es) used for the link. Default: `toclink`.Fz7True if header should be a self link. Default: `False`.Ztoclinkz5CSS class(es) used for the link. Defaults: `toclink`.r   zPTrue or link text if a Sphinx-style permalink should be added. Default: `False`.Z
headerlinkz7CSS class(es) used for the link. Default: `headerlink`.zPermanent linkz<Title attribute of the permalink. Default: `Permanent link`.z\True if permalinks should be placed at start of the header, rather than end. Default: False.1z%Base level for headers. Default: `1`.zFFunction to generate anchors based on header text. Default: `slugify`.r`   zWord separator. Default: `-`.r~   a'  Define the range of section levels to include in the Table of Contents. A single integer (b) defines the bottom section level (<h1>..<hb>) only. A string consisting of two digits separated by a hyphen in between (`2-5`) defines the top (t) and the bottom (b) (<ht>..<hb>). Default: `6` (bottom).)rT   rU   rX   rW   rY   rZ   r[   r\   r]   r^   rV   r&   r   r_   )r&   rS   rd   re   )ro   kwargsrp   r$   r%   re   Z  sP             1zTocExtension.__init__c                 C  s<   | |  || _|   | ||  }|j|dd dS )z% Add TOC tree processor to Markdown. r      N)ZregisterExtensionr<   resetTreeProcessorClassZ
getConfigsr   register)ro   r<   Ztocextr$   r$   r%   extendMarkdown  s
    
zTocExtension.extendMarkdownrx   )r   c                 C  s   d| j _g | j _d S )Nr   )r<   r   r   )ro   r$   r$   r%   r     s    zTocExtension.reset)	r   r   r   rR   r   re   r   r   r   r$   r$   rp   r%   r   V  s   4r   c                  K  s
   t f | S )N)r   )r   r$   r$   r%   makeExtension  s    r   )F)T)'r   
__future__r   r   r   r   r   utilr   r   r	   r
   r   r   r   r6   r   xml.etree.ElementTreer   ElementTreetypingr   r   r   r   Zmarkdownr   r&   r'   rj   r*   r0   r;   rD   r7   rQ   rR   r   r   r$   r$   r$   r%   <module>   s0   

A 1E