a
    ¶¯6`y<  ã                   @   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
 ddlmZ d	d
lmZ d	dlZd	dlZd	dlm  mZ ejd ej Zejd ej Ze d¡ZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ de
ƒZdd„ ZdS )a7  
Footnotes Extension for Python-Markdown
=======================================

Adds footnote handling to Python-Markdown.

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

Copyright The Python Markdown Project

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

é   )Ú	Extensioné   )ÚBlockProcessor)ÚInlineProcessor)ÚTreeprocessor)ÚPostprocessor)Úutilé    )ÚOrderedDictNZzz1337820767766393qqZqq3936677670287331zzz(fnref)(\d+)c                       sl   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Zdd	d
„Zdd„ Zdd„ Z	dd„ Z
dd„ Zddd„Zdd„ Z‡  ZS )ÚFootnoteExtensionz Footnote Extension. c                    sX   ddgddgddgddgd	d
gdœ| _ tƒ jf i |¤Ž d| _i | _tƒ | _|  ¡  dS )z Setup configs. z///Footnotes Go Here///z1The text string that marks where the footnotes goFz7Avoid name collisions across multiple calls to reset().z&#8617;zCThe text string that links from the footnote to the reader's place.z$Jump back to footnote %d in the textznThe text string used for the title HTML attribute of the backlink. %d will be replaced by the footnote number.ú:zFootnote separator.)ÚPLACE_MARKERÚ
UNIQUE_IDSÚBACKLINK_TEXTÚBACKLINK_TITLEÚ	SEPARATORr	   N)ZconfigÚsuperÚ__init__Úunique_prefixÚ
found_refsÚsetÚ	used_refsÚreset)ÚselfÚkwargs©Ú	__class__© ú?/usr/lib/python3/dist-packages/markdown/extensions/footnotes.pyr   #   s*    ÿÿÿÿÿîzFootnoteExtension.__init__c                 C   sˆ   |  | ¡ |j| _|| _|jj t| ƒdd¡ d}|j t|| ƒdd¡ |j t	| ƒdd¡ |j t
| ƒdd¡ |j t| ƒdd¡ d	S )
z Add pieces to Markdown. Úfootnoteé   z\[\^([^\]]*)\]é¯   é2   zfootnote-duplicateé   é   N)ZregisterExtensionÚparserÚmdÚblockprocessorsÚregisterÚFootnoteBlockProcessorZinlinePatternsÚFootnoteInlineProcessorÚtreeprocessorsÚFootnoteTreeprocessorÚFootnotePostTreeprocessorÚpostprocessorsÚFootnotePostprocessor)r   r&   ZFOOTNOTE_REr   r   r   ÚextendMarkdownD   s    
z FootnoteExtension.extendMarkdownc                 C   s(   t ƒ | _|  jd7  _i | _tƒ | _dS )z> Clear footnotes on reset, and prepare for distinct document. r   N)r
   Ú	footnotesr   r   r   r   ©r   r   r   r   r   ]   s    zFootnoteExtension.resetFc                 C   s°   |s|S |}|| j v rx| |  ¡ d¡\}}t |¡}|rbd| d¡t| d¡ƒd |  ¡ |f }qd|d|  ¡ |f }q| j  |¡ || jv r¢| j|  d7  < n
d| j|< |S )z1 Get a unique reference if there are duplicates. r   ú%s%d%s%sr   )	r   ÚsplitÚget_separatorÚ	RE_REF_IDÚmatchÚgroupÚintÚaddr   )r   Z	referenceÚfoundZoriginal_refÚrefÚrestÚmr   r   r   Ú
unique_refd   s    

*

zFootnoteExtension.unique_refc                    s   ‡ ‡fdd„‰ ˆ |ƒ}|S )z@ Return ElementTree Element that contains Footnote placeholder. c                    sz   | D ]p}|j r2|j  ˆ d¡¡dkr2|| df  S |jr\|j ˆ d¡¡dkr\|| df  S ˆ |ƒ}|d ur|  S qd S )Nr   éÿÿÿÿTF)ÚtextÚfindÚ	getConfigÚtail)ÚelementÚchildZ	child_res©Úfinderr   r   r   rH   {   s    
z:FootnoteExtension.findFootnotesPlaceholder.<locals>.finderr   )r   ÚrootÚresr   rG   r   ÚfindFootnotesPlaceholdery   s    z*FootnoteExtension.findFootnotesPlaceholderc                 C   s   || j |< dS )z' Store a footnote for later retrieval. N©r1   )r   ÚidrA   r   r   r   ÚsetFootnote‹   s    zFootnoteExtension.setFootnotec                 C   s
   |   d¡S )z Get the footnote separator. r   )rC   r2   r   r   r   r5      s    zFootnoteExtension.get_separatorc                 C   s2   |   d¡rd|  ¡ | j|f S d |  ¡ |¡S dS )z Return footnote link id. r   z	fn%s%d-%szfn{}{}N)rC   r5   r   Úformat)r   rM   r   r   r   ÚmakeFootnoteId“   s    
z FootnoteExtension.makeFootnoteIdc                 C   sB   |   d¡r&|  d|  ¡ | j|f |¡S |  d |  ¡ |¡|¡S dS )z Return footnote back-link id. r   zfnref%s%d-%sz	fnref{}{}N)rC   r?   r5   r   rO   )r   rM   r;   r   r   r   ÚmakeFootnoteRefIdš   s    
z#FootnoteExtension.makeFootnoteRefIdc                 C   sP  t | j ¡ ƒsdS t d¡}| dd¡ t |d¡ t |d¡}t d¡}t| j ¡ ddD ]î\}}t |d	¡}| d
|  |¡¡ | j	 
|| j| ¡ t |ƒD ]}| |¡ | |¡ qžt d¡}	|	 dd|  |¡ ¡ |	 dd¡ |	 d|  d¡| ¡ t|	_t|ƒr\|d }
|
jdkr4|
jt |
_|
 |	¡ q\t |d¡}| |	¡ q\|S )z( Return div of footnotes as et Element. NÚdivÚclassr   ZhrÚolr   )ÚstartÚlirM   ÚaÚhrefú#úfootnote-backrefÚtitler   r@   Úp)Úlistr1   ÚkeysÚetreeÚElementr   Ú
SubElementÚ	enumeraterP   r%   Z
parseChunkÚappendÚremoverQ   rC   ÚFN_BACKLINK_TEXTrA   ÚlenÚtagÚNBSP_PLACEHOLDER)r   rI   rR   rT   Zsurrogate_parentÚindexrM   rV   ÚelZbacklinkZnoder\   r   r   r   ÚmakeFootnotesDiv¡   s<    



þz"FootnoteExtension.makeFootnotesDiv)F)F)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r0   r   r?   rK   rN   r5   rP   rQ   rk   Ú__classcell__r   r   r   r   r       s   !

r   c                       sN   e Zd ZdZe dej¡Z‡ fdd„Zdd„ Z	dd„ Z
d	d
„ Zdd„ Z‡  ZS )r)   z7 Find all footnote references and store for later use. z!^[ ]{0,3}\[\^([^\]]*)\]:[ ]*(.*)$c                    s   t ƒ  |j¡ || _d S ©N)r   r   r%   r1   ©r   r1   r   r   r   r   Ð   s    zFootnoteBlockProcessor.__init__c                 C   s   dS )NTr   )r   ÚparentÚblockr   r   r   ÚtestÔ   s    zFootnoteBlockProcessor.testc                 C   s@  |  d¡}| j |¡}|r0| d¡}| d¡g}|| ¡ d…  d¡}| j |¡}|rª|d| ¡ …  d¡}	d |d |  	|	¡g¡ d¡|d< | 
d|| ¡ d… ¡ n2d |d |  	|¡g¡ d¡|d< | |  |¡¡ d |¡}
| j ||
 ¡ ¡ |d| ¡ …  ¡ r,| 
d|d| ¡ …  d¡¡ dS | 
d|¡ dS )	z- Find, set, and remove footnote definitions. r	   r   r   NÚ
z

TF)ÚpopÚREÚsearchr8   ÚendÚlstriprU   ÚrstripÚjoinÚdetabÚinsertÚstripÚextendÚdetectTabbedr1   rN   )r   rs   Úblocksrt   r>   rM   Ú	fn_blocksZtherestZm2Úbeforer   r   r   r   Úrun×   s(    

""
zFootnoteBlockProcessor.runc                 C   sŒ   g }|rˆ|d   d¡rˆ| d¡}| j |¡}|rr|d| ¡ …  d¡}| |  |¡¡ | d|| ¡ d… ¡ qˆq†| |  |¡¡ qqˆq|S )z† Find indented text and remove indent before further proccesing.

        Returns: a list of blocks with indentation removed.
        r	   ú    Nrv   )	Ú
startswithrw   rx   ry   rU   r|   rc   r~   r   )r   rƒ   r„   rt   r>   r…   r   r   r   r‚   û   s    
z#FootnoteBlockProcessor.detectTabbedc                 C   s@   |  d¡}t|ƒD ]"\}}| d¡r|dd… ||< qd |¡S )zˆ Remove one level of indent from a block.

        Preserve lazily indented blocks by only removing indent from indented lines.
        rv   r‡   é   N)r4   rb   rˆ   r}   )r   rt   ÚlinesÚiÚliner   r   r   r~     s
    

zFootnoteBlockProcessor.detab)rl   rm   rn   ro   ÚreÚcompileÚ	MULTILINErx   r   ru   r†   r‚   r~   rp   r   r   r   r   r)   Ë   s   $r)   c                       s(   e Zd ZdZ‡ fdd„Zdd„ Z‡  ZS )r*   z? InlinePattern for footnote markers in a document's body text. c                    s   t ƒ  |¡ || _d S rq   )r   r   r1   )r   Úpatternr1   r   r   r   r   &  s    z FootnoteInlineProcessor.__init__c                 C   sª   |  d¡}|| jj ¡ v r¢t d¡}t |d¡}| d| jj|dd¡ | dd| j |¡ ¡ | d	d
¡ t	t
| jj ¡ ƒ |¡d ƒ|_|| d¡| d¡fS dS d S )Nr   ÚsuprW   rM   T)r;   rX   rY   rS   zfootnote-refr	   )NNN)r8   r1   r^   r_   r`   ra   r   rQ   rP   Ústrr]   ri   rA   rU   rz   )r   r>   ÚdatarM   r‘   rW   r   r   r   ÚhandleMatch*  s    

 z#FootnoteInlineProcessor.handleMatch)rl   rm   rn   ro   r   r”   rp   r   r   r   r   r*   #  s   r*   c                   @   s8   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ ZdS )r-   z% Amend footnote div with duplicates. c                 C   s
   || _ d S rq   rL   rr   r   r   r   r   ;  s    z"FootnotePostTreeprocessor.__init__c           
      C   s¼   |  d¡D ]¬}|j dd¡dkr
|jd  | j ¡ d¡\}}g }td|d ƒD ]B}t |¡}d||| j ¡ |f |jd< | 	|¡ |  j
d7  _
qNt|ƒd	 }	|D ]}|	 	|¡ q¢ q¸q
d
S )z@ Adjust current li and add the duplicates: fnref2, fnref3, etc. rW   rS   Ú rZ   rX   r   r   r3   r@   N)ÚiterÚattribÚgetr4   r1   r5   ÚrangeÚcopyÚdeepcopyrc   Úoffsetr]   )
r   rV   Ú
duplicatesÚlinkr<   r=   Zlinksri   Zsib_linkrj   r   r   r   Úadd_duplicates>  s    

z(FootnotePostTreeprocessor.add_duplicatesc                 C   sD   |j  dd¡ | j ¡ d¡\}}d || j ¡ |¡}| jj |d¡S )z3 Get the number of duplicate refs of the footnote. rM   r•   r   z	{}ref{}{}r	   )r—   r˜   r4   r1   r5   rO   r   )r   rV   Úfnr=   Zlink_idr   r   r   Úget_num_duplicatesR  s     z,FootnotePostTreeprocessor.get_num_duplicatesc                 C   s0   t |ƒD ]"}|  |¡}|dkr|  ||¡ qdS )z= Find duplicate footnotes and format and add the duplicates. r   N)r]   r¡   rŸ   )r   rs   rV   Úcountr   r   r   Úhandle_duplicatesX  s    
z+FootnotePostTreeprocessor.handle_duplicatesc                 C   sJ   d| _ | d¡D ]4}|j dd¡dkr| d¡D ]}|  |¡  qq0qdS )z= Crawl the footnote div and add missing duplicate footnotes. r	   rR   rS   r•   r   rT   N)rœ   r–   r—   r˜   r£   )r   rI   rR   rT   r   r   r   r†   a  s    
zFootnotePostTreeprocessor.runN)	rl   rm   rn   ro   r   rŸ   r¡   r£   r†   r   r   r   r   r-   8  s   	r-   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )r,   z3 Build and append footnote div to end of document. c                 C   s
   || _ d S rq   rL   rr   r   r   r   r   p  s    zFootnoteTreeprocessor.__init__c                 C   s~   | j  |¡}|d urz| j  |¡}|rp|\}}}t|ƒ |¡}|rX| |¡ | ||¡ qz| |d |¡ d |_n
| |¡ d S )Nr   )	r1   rk   rK   r]   ri   rd   r   rD   rc   )r   rI   ZfootnotesDivÚresultrF   rs   ZisTextZindr   r   r   r†   s  s    

zFootnoteTreeprocessor.runN©rl   rm   rn   ro   r   r†   r   r   r   r   r,   m  s   r,   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )r/   z* Replace placeholders with html entities. c                 C   s
   || _ d S rq   rL   rr   r   r   r   r   †  s    zFootnotePostprocessor.__init__c                 C   s    |  t| j d¡¡}|  td¡S )Nr   z&#160;)Úreplacere   r1   rC   rh   )r   rA   r   r   r   r†   ‰  s    ÿzFootnotePostprocessor.runNr¥   r   r   r   r   r/   „  s   r/   c                  K   s   t f i | ¤ŽS )z- Return an instance of the FootnoteExtension )r   )r   r   r   r   ÚmakeExtension  s    r§   ) ro   r•   r   r'   r   Zinlinepatternsr   r+   r   r.   r   r   Úcollectionsr
   r   rš   Zxml.etree.ElementTreer_   ZElementTreeZSTXZETXre   rh   rŽ   r6   r   r)   r*   r-   r,   r/   r§   r   r   r   r   Ú<module>   s*   
 ,X5