U
    \z/                     @   s   d Z ddlm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Zdd	lZd
d ZedZ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 )ao  
Table of Contents Extension for Python-Markdown
===============================================

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

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

All changes Copyright 2008-2014 The Python Markdown Project

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

    )absolute_import)unicode_literals   )	Extension   )Treeprocessor)etreeparseBoolValueAMP_SUBSTITUTEHTML_PLACEHOLDER_REstring_typeNc                 C   sB   t d| dd} tdd| d  } td| || S )z, Slugify a string, to make it URL friendly. ZNFKDasciiignorez[^\w\s-] z[%s\s]+)unicodedataZ	normalizeencoderesubdecodestriplower)value	separator r   9/usr/lib/python3/dist-packages/markdown/extensions/toc.pyslugify   s    r   z^(.*)_([0-9]+)$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)idZidsmr   r   r   unique#   s    
"
r#   c                    s    fdd}t || S )zN Extract raw HTML from stash, reduce to plain text and swap with placeholder. c              	      sL   z j jt| d }W n" ttfk
r<   | d Y S X tdd|S )z& Substitute raw html with plain text. r   r   z(<[^>]+>)|(&[\#a-zA-Z0-9]+;)r   )Z	htmlStashZrawHtmlBlocksr   r   
IndexError	TypeErrorr   r   )r"   rawmdr   r   	_html_sub1   s
    z#stashedHTML2text.<locals>._html_sub)r   r   )textr(   r)   r   r'   r   stashedHTML2text/   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popappendreversed)	toc_listZordered_listZlastZlevelsparentstZcurrent_levelZto_poppr   r   r   nest_toc_tokens=   sB    








r7   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 t| | |d | _|d | _t|d d | _|d | _|d | _t	|d | _
t	|d d	| _| jd kr||d | _td
| _t|d trd|d krdd |d dD \| _| _nd| _t|d | _d S )Nmarkertitle	baselevelr   r   r   
anchorlink	permalinkFz[Hh][123456]	toc_depth-c                 S   s   g | ]}t |qS r   )r   ).0xr   r   r   
<listcomp>   s     z-TocTreeprocessor.__init__.<locals>.<listcomp>)superr8   __init__r9   r:   r   
base_levelr   sepr	   use_anchorsuse_permalinksr   compile
header_rgx
isinstancer   splittoc_top
toc_bottom)selfr(   config	__class__r   r   rD   }   s    





"zTocTreeprocessor.__init__c                 c   sN   |D ]D}| j |js|jdkr||fV  | |D ]\}}||fV  q4qdS )z? Iterator wrapper to get allowed parent and child all at once. )ZprecodeN)rJ   r   tag
iterparent)rO   ZnodeZchildr6   cr   r   r   rU      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)rU   joinitertextr   r*   r9   ranger/   )rO   rootelemr6   rV   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   rT   rE   )rO   r[   r-   r   r   r   	set_level   s    zTocTreeprocessor.set_levelc                 C   sj   t d}|j|_d| |jd< d|jd< d|_|D ]}|| q4t|r\||d  qD|| d S )Na#hrefZtoclinkclassr   r   )r   Elementr*   attribr1   r/   remove)rO   rV   elem_idZanchorr[   r   r   r   
add_anchor   s    

zTocTreeprocessor.add_anchorc                 C   sT   t d}| jdkrdt n| j|_d| |jd< d|jd< d|jd	< || d S )
Nr`   Tz%spara;ra   rb   Z
headerlinkrc   zPermanent linkr:   )r   rd   rH   r
   r*   re   r1   )rO   rV   rg   r=   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krl| jjd | |S )	z' Return a string div given a toc list. divtocrc   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lir`   namer   ra   r!   rb   r,   )r   
SubElementgetr*   re   )r3   parentrm   itemrn   linkbuild_etree_ulr   r   rv      s    z6TocTreeprocessor.build_toc_div.<locals>.build_etree_ulZprettify)	r   rd   re   r:   rp   r*   r(   treeprocessorsrun)rO   r3   rj   headerr   ru   r   build_toc_div   s    



zTocTreeprocessor.build_toc_divc           
   	   C   s  t  }| D ]}d|jkr||jd  qg }| D ]}t|jtr:| j|jr:| 	| t
|jd | jk s:t
|jd | jkrq:d|  }d|jkrt|| j}t| || j||jd< |t
|jd |jd |jd|d d|jkr|jd= | jr*| ||jd  | jr:| ||jd  q:t|}| |}| jrj| || | j|}| jj D ]}	|	!|}q~|| j_"|| j_#d S )Nr!   r.   r   zdata-toc-label)r-   r!   ro   )$setiterre   r    rK   rT   r   rJ   r   r_   r   rM   rN   rW   rX   r   r+   r(   r#   r   rF   r1   rq   rG   rh   rH   ri   r7   rz   r9   r]   Z
serializerZpostprocessorsrx   
toc_tokensrk   )
rO   docZused_idsZelr}   r*   Z	innertextrj   rk   Zppr   r   r   rx      sD    

(

zTocTreeprocessor.run)__name__
__module____qualname__rD   rU   r]   r_   rh   ri   rz   rx   __classcell__r   r   rQ   r   r8   |   s   
r8   c                       s0   e Zd ZeZ fddZdd Zdd Z  ZS )TocExtensionc              	      sN   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t| jf | 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 Falser   zQTrue or link text if a Sphinx-style permalink should be added - Defaults to False1zBase level for headers.zdFunction to generate anchors based on header text - Defaults to the headerid ext's slugify function.r?   z Word separator. Defaults to "-".r^   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).)r9   r:   r<   r=   r;   r   r   r>   )r   rP   rC   r   rD   )rO   kwargsrQ   r   r   rD     s,    zTocExtension.__init__c                 C   s<   | |  || _|   | ||  }|j|dd d S )Nrk      )ZregisterExtensionr(   resetTreeProcessorClassZ
getConfigsrw   register)rO   r(   Ztocextr   r   r   extendMarkdown9  s
    
zTocExtension.extendMarkdownc                 C   s   d| j _g | j _d S )Nr   )r(   rk   r}   )rO   r   r   r   r   E  s    zTocExtension.reset)	r   r   r   r8   r   rD   r   r   r   r   r   rQ   r   r     s   r   c                  K   s
   t f | S )N)r   )r   r   r   r   makeExtensionJ  s    r   )__doc__Z
__future__r   r   r   r   rw   r   utilr   r	   r
   r   r   r   r   r   rI   r   r#   r+   r7   r8   r   r   r   r   r   r   <module>   s    
? 3