a
    =9`w5                     @   s   d 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
dZdd ZedZdd Zdd Zd!ddZdd Zdd ZG dd deZG dd deZdd ZdS )"an  
Table of Contents Extension for Python-Markdown
===============================================

See <https://Python-Markdown.github.io/extensions/toc>
for documentation.

Oringinal code Copyright 2008 [Jack Miller](https://codezen.org/)

All changes Copyright 2008-2014 The Python Markdown Project

License: [BSD](https://opensource.org/licenses/bsd-license.php)

   )	Extension   )Treeprocessor)code_escapeparseBoolValueAMP_SUBSTITUTEHTML_PLACEHOLDER_REAtomicString)UnescapePostprocessor    Nasciic                 C   sD   t d| |d} tdd| |  } td||| S )z, Slugify a string, to make it URL friendly. ZNFKDignorez[^\w\s-] z[{}\s]+)	unicodedataZ	normalizeencoderesubdecodestriplowerformat)value	separatorencoding r   6lib/python3.9/site-packages/markdown/extensions/toc.pyslugify   s    r   c                 C   s   t | |dS )zP Slugify a string, to make it URL friendly while preserving Unicode characters. zutf-8)r   )r   r   r   r   r   slugify_unicode!   s    r   z^(.*)_([0-9]+)$c                 C   sX   | |v 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)idZidsmr   r   r   unique)   s    
"
r%   c                 C   sF   g }|   D ]*}t|tr,|t| q|| qd| S )zGet title name.r   )itertext
isinstancer	   appendhtmlunescapejoinr   )eltextcr   r   r   get_name5   s    
r/   Tc                    s    fdd}t || S )zN Extract raw HTML from stash, reduce to plain text and swap with placeholder. c              	      s`   z j jt| d }W n  ttfy:   | d Y S 0 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mdstrip_entitiesr   r   	_html_subC   s    z#stashedHTML2text.<locals>._html_sub)r   r   )r-   r5   r6   r7   r   r4   r   stashedHTML2textA   s    r8   c                 C   s   t  }|| S )z Unescape escaped text. )r
   run)r-   r.   r   r   r   r*   R   s    r*   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 )a<  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popr(   reversed)	toc_listZordered_listZlastZlevelsparentstZcurrent_levelZto_poppr   r   r   nest_toc_tokensX   sB    








rD   c                       sT   e Zd Z fddZdd Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
  ZS )TocTreeprocessorc                    s   t  | |d | _|d | _t|d d | _|d | _|d | _t|d | _	|d | _
t|d	 d
| _| jd u r|d	 | _|d | _|d | _td| _t|d trd|d v rdd |d dD \| _| _nd| _t|d | _d S )Nmarkertitle	baselevelr   r   r   
anchorlinkanchorlink_class	permalinkFpermalink_classpermalink_titlez[Hh][123456]	toc_depth-c                 S   s   g | ]}t |qS r   )r!   ).0xr   r   r   
<listcomp>       z-TocTreeprocessor.__init__.<locals>.<listcomp>)super__init__rF   rG   r!   
base_levelr   sepr   use_anchorsrJ   use_permalinksrL   rM   r   compile
header_rgxr'   strsplittoc_top
toc_bottom)selfr5   config	__class__r   r   rU      s$    








"zTocTreeprocessor.__init__c                 c   s@   |D ]6}| j |js|jdvr||fV  | |E dH  qdS )z? Iterator wrapper to get allowed parent and child all at once. )ZprecodeN)r[   r   tag
iterparent)r`   Znodechildr   r   r   rf      s    
zTocTreeprocessor.iterparentc                 C   sp   |  |D ]`\}}d|  }|s*q
|jr
|j | jkr
tt|D ]}|| |krL|||<  q
qLq
dS )z Replace marker with elem. r   N)rf   r+   r&   r   r-   rF   ranger=   )r`   rootelemrC   r.   r-   ir   r   r   replace_marker   s    zTocTreeprocessor.replace_markerc                 C   s.   t |jd | j }|dkr d}d| |_dS )z. Adjust header level according to base level. r<      zh%dN)r!   re   rV   )r`   rj   r;   r   r   r   	set_level   s    zTocTreeprocessor.set_levelc                 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Elementr-   attribrJ   r(   r=   remove)r`   r.   elem_idZanchorrj   r   r   r   
add_anchor   s    
zTocTreeprocessor.add_anchorc                 C   s^   t d}| jdu rdt n| j|_d| |jd< | j|jd< | jrP| j|jd< || d S )Nro   Tz%spara;rp   rq   rr   rG   )	rs   rt   rY   r   r-   ru   rL   rM   r(   )r`   r.   rw   rK   r   r   r   add_permalink   s    

zTocTreeprocessor.add_permalinkc                    sp   t d}d|jd< | jr8t |d}d|jd< | j|_ fdd  || d| jjv rl| jjd | |S )	z' Return a string div given a toc list. divtocrr   spanZtoctitlec                    sl   t |d}| D ]V}t |d}t |d}|dd|_d|dd |jd< |d	 r |d	 | q|S )
Nulliro   namer   rp   r#   rq   r:   )rs   
SubElementgetr-   ru   )r@   parentr}   itemr~   linkbuild_etree_ulr   r   r      s    z6TocTreeprocessor.build_toc_div.<locals>.build_etree_ulZprettify)	rs   rt   ru   rG   r   r-   r5   treeprocessorsr9   )r`   r@   rz   headerr   r   r   build_toc_div   s    



zTocTreeprocessor.build_toc_divc           
      C   s  t  }| D ]}d|jv r||jd  qg }| D ]}t|jtr:| j|jr:| 	| t
|}d|jv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v r |jd= | jr:| ||jd  | jdvr:| ||jd  q:t|}| |}| jr~| || | j|}| jj D ]}	|	!|}q|| j_"|| j_#d S )Nr#   r<   zdata-toc-labelF)r6   )r;   r#   r   )FN)$setiterru   r"   r'   re   r\   r[   r   rn   r/   r*   r8   r5   r%   r   rW   r!   r^   r_   r(   r   r   rX   rx   rY   ry   rD   r   rF   rl   Z
serializerpostprocessorsr9   
toc_tokensr{   )
r`   docZused_idsr,   r   r-   Z	innertextrz   r{   Zppr   r   r   r9     sH    


,


zTocTreeprocessor.run)__name__
__module____qualname__rU   rf   rl   rn   rx   ry   r   r9   __classcell__r   r   rb   r   rE      s   rE   c                       s0   e Zd ZeZ fddZdd Zdd Z  ZS )TocExtensionc                    s`   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 i | d S )Nz[TOC]zhText to find and replace with Table of Contents - Set to an empty string to disable. Defaults to "[TOC]"r   z<Title to insert into TOC <div> - Defaults to an empty stringFz8True if header should be a self link - Defaults to FalseZtoclinkz6CSS class(es) used for the link. Defaults to "toclink"r   zQTrue or link text if a Sphinx-style permalink should be added - Defaults to FalseZ
headerlinkz9CSS class(es) used for the link. Defaults to "headerlink"zPermanent linkz?Title attribute of the permalink - Defaults to 'Permanent link'1zBase level for headers.zdFunction to generate anchors based on header text - Defaults to the headerid ext's slugify function.rO   z Word separator. Defaults to "-".rm   a%  Define the range of section levels to include inthe Table of Contents. A single integer (b) definesthe bottom section level (<h1>..<hb>) only.A string consisting of two digits separated by a hyphenin between ("2-5"), define the top (t) and thebottom (b) (<ht>..<hb>). Defaults to `6` (bottom).)rF   rG   rI   rJ   rK   rL   rM   rH   r   r   rN   )r   ra   rT   rU   )r`   kwargsrb   r   r   rU   ;  s>    $zTocExtension.__init__c                 C   s<   | |  || _|   | ||  }|j|dd d S )Nr{      )ZregisterExtensionr5   resetTreeProcessorClassZ
getConfigsr   register)r`   r5   Ztocextr   r   r   extendMarkdownb  s
    
zTocExtension.extendMarkdownc                 C   s   d| j _g | j _d S )Nr   )r5   r{   r   )r`   r   r   r   r   n  s    zTocExtension.reset)	r   r   r   rE   r   rU   r   r   r   r   r   rb   r   r   7  s   'r   c                  K   s   t f i | S )N)r   )r   r   r   r   makeExtensions  s    r   )r   )T)__doc__r   r   r   r   utilr   r   r   r   r	   r   r
   r   r)   r   Zxml.etree.ElementTreers   ZElementTreer   r   rZ   r   r%   r/   r8   r*   rD   rE   r   r   r   r   r   r   <module>   s(   


? !<