o
    ç&•a87  ã                   @   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é    NFc                 C   sL   |st  d| ¡} |  dd¡ d¡} t dd| ¡ ¡  ¡ } t d |¡|| ¡S )z, Slugify a string, to make it URL friendly. ÚNFKDÚasciiÚignorez[^\w\s-]Ú z[{}\s]+)	ÚunicodedataÚ	normalizeÚencodeÚdecodeÚreÚsubÚstripÚlowerÚformat)ÚvalueÚ	separatorÚunicode© r   ú9/usr/lib/python3/dist-packages/markdown/extensions/toc.pyÚslugify   s
   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]+)$c                 C   sb   | |v s| s*t  | ¡}|rd| d¡t| d¡ƒd f } nd| df } | |v s| r| | ¡ | 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)ÚidÚ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_name8   s   
r2   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 w t dd|¡}ˆr.t dd|¡}|S )z& Substitute raw html with plain text. r   r   z	(<[^>]+>)r   z(&[\#a-zA-Z0-9]+;))Ú	htmlStashÚrawHtmlBlocksr#   r"   Ú
IndexErrorÚ	TypeErrorr   r   )r'   ÚrawÚres©ÚmdÚstrip_entitiesr   r   Ú	_html_subF   s   ÿz#stashedHTML2text.<locals>._html_sub)r   r   )r0   r:   r;   r<   r   r9   r   ÚstashedHTML2textD   s   r=   c                 C   s   t ƒ }| | ¡S )z Unescape escaped text. )r
   Úrun)r0   r1   r   r   r   r-   U   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rG|d7 }q: |rX|d| … }|d| … }| |¡ ||d krq|rk|d d n| |¡ n|d  |¡ | |¡ | |¡ |}| s|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Úleveléÿÿÿÿr   N)ÚlenÚpopr+   Úreversed)	Útoc_listÚordered_listÚlastÚlevelsÚparentsÚtÚcurrent_levelÚto_popÚpr   r   r   Únest_toc_tokens[   s>   







Ü&rN   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 rA|d	 | _|d | _|d | _t d¡| _t|d tƒrpd|d v rpdd„ |d  d¡D ƒ\| _| _d S 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>¬   s    z-TocTreeprocessor.__init__.<locals>.<listcomp>)ÚsuperÚ__init__rP   rQ   r#   Ú
base_levelr   Úsepr   Úuse_anchorsrT   Úuse_permalinksrV   rW   r   ÚcompileÚ
header_rgxr*   ÚstrÚsplitÚtoc_topÚ
toc_bottom)Úselfr:   Úconfig©Ú	__class__r   r   r^   ›   s$   








$zTocTreeprocessor.__init__c                 c   sB   � |D ]}| 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. )ÚpreÚcodeN)rd   r!   ÚtagÚ
iterparent)ri   ÚnodeÚchildr   r   r   rp   ±   s   €
€ýzTocTreeprocessor.iterparentc                 C   s|   |   |¡D ]6\}}d | ¡ ¡ ¡ }|sq|jr;|j ¡ | jkr;t|ƒdkr;tt|ƒƒD ]}|| |kr:|||<  nq,qdS )z Replace marker with elem. r   r   N)rp   r.   r)   r   r0   rP   rB   Úrange)ri   ÚrootÚelemrM   r1   r0   Ú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. rA   é   zh%dN)r#   ro   r_   )ri   ru   r@   r   r   r   Ú	set_levelÑ   s   zTocTreeprocessor.set_levelc                 C   sr   t  d¡}|j|_d| |jd< | j|jd< d|_|D ]}| |¡ qt|ƒr2| |d ¡ t|ƒs'| |¡ d S )NÚaú#ÚhrefÚclassr   r   )ÚetreeÚElementr0   ÚattribrT   r+   rB   Úremove)ri   r1   Úelem_idÚanchorru   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r(| j|jd< | |¡ d S )Nrz   Tz%spara;r{   r|   r}   rQ   )	r~   r   rb   r   r0   r€   rV   rW   r+   )ri   r1   r‚   rU   r   r   r   Úadd_permalinkä   s   

ÿþzTocTreeprocessor.add_permalinkc                    sp   t  d¡}d|jd< | jrt  |d¡}d|jd< | j|_‡ fdd„‰ ˆ ||ƒ d| jjv r6| jjd  |¡ |S )	z' Return a string div given a toc list. ÚdivÚtocr}   ÚspanÚtoctitlec                    sl   t  |d¡}| D ]+}t  |d¡}t  |d¡}| dd¡|_d| dd¡ |jd< |d	 r3ˆ |d	 |ƒ q|S )
NÚulÚlirz   Únamer   r{   r%   r|   r?   )r~   Ú
SubElementÚgetr0   r€   )rE   ÚparentrŠ   Úitemr‹   Úlink©Úbuild_etree_ulr   r   r“   ú   s   €z6TocTreeprocessor.build_toc_div.<locals>.build_etree_ulÚprettify)	r~   r   r€   rQ   r�   r0   r:   Útreeprocessorsr>   )ri   rE   r†   Ú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rOt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%   rA   zdata-toc-labelF)r;   )r@   r%   rŒ   )FN)$ÚsetÚiterr€   r$   r*   ro   re   rd   r!   ry   r2   r-   r=   r:   r(   r   r`   r#   rg   rh   r+   r   rŽ   ra   r„   rb   r…   rN   r—   rP   rw   Ú
serializerÚpostprocessorsr>   Ú
toc_tokensr‡   )
ri   ÚdocÚused_idsr/   rœ   r0   Ú	innertextr†   r‡   Úppr   r   r   r>     sL   
€

(þý


€
zTocTreeprocessor.run)Ú__name__Ú
__module__Ú__qualname__r^   rp   rw   ry   r„   r…   r—   r>   Ú__classcell__r   r   rk   r   rO   š   s    rO   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d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 FalseÚ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 FalseÚ
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.rY   z Word separator. Defaults to "-".rx   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).)rP   rQ   rS   rT   rU   rV   rW   rR   r   r   rX   r   )r   rj   r]   r^   )ri   Úkwargsrk   r   r   r^   C  s>   ÿÿÿÿÿÿÿÿÿå$zTocExtension.__init__c                 C   s<   |  | ¡ || _|  ¡  |  ||  ¡ ¡}|j |dd¡ d S )Nr‡   é   )ÚregisterExtensionr:   ÚresetÚTreeProcessorClassÚ
getConfigsr•   Úregister)ri   r:   Útocextr   r   r   ÚextendMarkdownj  s
   
zTocExtension.extendMarkdownc                 C   s   d| j _g | j _d S )Nr   )r:   r‡   rœ   )ri   r   r   r   r¬   v  s   zTocExtension.reset)	r¡   r¢   r£   rO   r­   r^   r±   r¬   r¤   r   r   rk   r   r¥   ?  s
    'r¥   c                  K   s   t di | ¤ŽS )Nr   )r¥   )r©   r   r   r   ÚmakeExtension{  s   r²   )F)T)Ú__doc__r   r   r•   r   Úutilr   r   r   r   r	   r›   r
   r   r,   r   Úxml.etree.ElementTreer~   ÚElementTreer   r   rc   r    r(   r2   r=   r-   rN   rO   r¥   r²   r   r   r   r   Ú<module>   s*    



? &<