o
    ç&•ay<  ã                   @   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é    )ÚOrderedDictNÚzz1337820767766393qqÚ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d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© )ÚconfigÚsuperÚ__init__Úunique_prefixÚ
found_refsÚsetÚ	used_refsÚreset)ÚselfÚkwargs©Ú	__class__r   ú?/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)ÚregisterExtensionÚparserÚmdÚblockprocessorsÚregisterÚFootnoteBlockProcessorÚinlinePatternsÚFootnoteInlineProcessorÚtreeprocessorsÚFootnoteTreeprocessorÚFootnotePostTreeprocessorÚpostprocessorsÚFootnotePostprocessor)r   r*   Ú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 r@| |  ¡ d¡\}}t |¡}|r1d| d¡t| d¡ƒd |  ¡ |f }n
d|d|  ¡ |f }|| j v s| j  |¡ || jv rV| j|  d7  < |S 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   Ú	referenceÚfoundÚ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 ]8}|j r|j  ˆ d¡¡dkr|| 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ÚchildÚ	child_res©Úfinderr   r   r!   rQ   {   s   ÿz:FootnoteExtension.findFootnotesPlaceholder.<locals>.finderr   )r   ÚrootÚresr   rP   r!   ÚfindFootnotesPlaceholdery   s   z*FootnoteExtension.findFootnotesPlaceholderc                 C   s   || j |< dS )z' Store a footnote for later retrieval. N©r7   )r   ÚidrI   r   r   r!   ÚsetFootnote‹   ó   zFootnoteExtension.setFootnotec                 C   s
   |   d¡S )z Get the footnote separator. r   )rK   r8   r   r   r!   r;   �   s   
zFootnoteExtension.get_separatorc                 C   s.   |   d¡rd|  ¡ | j|f S d |  ¡ |¡S )z Return footnote link id. r   z	fn%s%d-%szfn{}{})rK   r;   r   Úformat)r   rV   r   r   r!   ÚmakeFootnoteId“   s   
z FootnoteExtension.makeFootnoteIdc                 C   s>   |   d¡r|  d|  ¡ | j|f |¡S |  d |  ¡ |¡|¡S )z Return footnote back-link id. r   zfnref%s%d-%sz	fnref{}{})rK   rG   r;   r   rY   )r   rV   rB   r   r   r!   ÚmakeFootnoteRefIdš   s   
z#FootnoteExtension.makeFootnoteRefIdc                 C   sN  t | j ¡ ƒs	dS t d¡}| dd¡ t |d¡ t |d¡}t d¡}t| j ¡ dd�D ]v\}}t |d	¡}| d
|  |¡¡ | j	 
|| j| ¡ t |ƒD ]}| |¡ | |¡ qOt d¡}	|	 dd|  |¡ ¡ |	 dd¡ |	 d|  d¡| ¡ t|	_t|ƒr¤|d }
|
jdkr™|
jt |
_|
 |	¡ q.t |d¡}| |	¡ q.|S )z( Return div of footnotes as et Element. NÚdivÚclassr"   ÚhrÚolr   )ÚstartÚlirV   ÚaÚhrefú#úfootnote-backrefÚtitler   rH   Úp)Úlistr7   ÚkeysÚetreeÚElementr   Ú
SubElementÚ	enumeraterZ   r)   Ú
parseChunkÚappendÚremover[   rK   ÚFN_BACKLINK_TEXTrI   ÚlenÚtagÚNBSP_PLACEHOLDER)r   rR   r\   r_   Úsurrogate_parentÚindexrV   ra   ÚelÚbacklinkÚnoderg   r   r   r!   ÚmakeFootnotesDiv¡   s>   



þ

€z"FootnoteExtension.makeFootnotesDiv)F)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r6   r   rG   rT   rW   r;   rZ   r[   rz   Ú__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)   r7   ©r   r7   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 |¡}|r–| d¡}| d¡g}|| ¡ d…  d¡}| j |¡}|rT|d| ¡ …  d¡}	d |d |  	|	¡g¡ d¡|d< | 
d|| ¡ d… ¡ nd |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Úsearchr>   ÚendÚlstripr`   ÚrstripÚjoinÚdetabÚinsertÚstripÚextendÚdetectTabbedr7   rW   )r   r‚   Úblocksrƒ   rF   rV   Ú	fn_blocksÚtherestÚm2Úbeforer"   r   r   r!   Úrun×   s(   

""
zFootnoteBlockProcessor.runc                 C   s”   g }|rH|d   d¡rC| d¡}| j |¡}|r:|d| ¡ …  d¡}| |  |¡¡ | d|| ¡ d… ¡ 	 |S | |  |¡¡ n	 |S |s|S )z† Find indented text and remove indent before further proccesing.

        Returns: a list of blocks with indentation removed.
        r	   ú    Nr…   )	Ú
startswithr†   r‡   rˆ   r`   r‹   ro   r�   rŽ   )r   r’   r“   rƒ   rF   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.
        r…   r˜   é   N)r:   rm   r™   rŒ   )r   rƒ   ÚlinesÚiÚliner   r   r!   r�     s   

€
zFootnoteBlockProcessor.detab)r{   r|   r}   r~   ÚreÚcompileÚ	MULTILINEr‡   r   r„   r—   r‘   r�   r   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 r€   )r   r   r7   )r   Úpatternr7   r   r   r!   r   &  s   
z FootnoteInlineProcessor.__init__c                 C   s¦   |  d¡}|| jj ¡ v rQt d¡}t |d¡}| d| jj|dd�¡ | dd| j |¡ ¡ | d	d
¡ t	t
| jj ¡ ƒ |¡d ƒ|_|| d¡| d¡fS dS )Nr   Úsuprb   rV   T)rB   rc   rd   r]   zfootnote-refr	   )NNN)r>   r7   ri   rj   rk   rl   r   r[   rZ   Ústrrh   rv   rI   r`   r‰   )r   rF   ÚdatarV   r¢   rb   r   r   r!   ÚhandleMatch*  s   

 z#FootnoteInlineProcessor.handleMatch)r{   r|   r}   r~   r   r¥   r   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 )r2   z% Amend footnote div with duplicates. c                 C   ó
   || _ d S r€   rU   r�   r   r   r!   r   ;  ó   
z"FootnotePostTreeprocessor.__init__c           
      C   s¾   |  d¡D ]W}|j dd¡dkr\|jd  | j ¡ d¡\}}g }td|d ƒD ]!}t |¡}d||| j ¡ |f |jd< | 	|¡ |  j
d7  _
q't|ƒd	 }	|D ]}|	 	|¡ qQ d
S qd
S )z@ Adjust current li and add the duplicates: fnref2, fnref3, etc. rb   r]   Ú re   rc   r   r   r9   rH   N)ÚiterÚattribÚgetr:   r7   r;   ÚrangeÚcopyÚdeepcopyro   Úoffsetrh   )
r   ra   Ú
duplicatesÚlinkrD   rE   Úlinksrv   Úsib_linkrw   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. rV   r¨   r   z	{}ref{}{}r	   )rª   r«   r:   r7   r;   rY   r   )r   ra   ÚfnrE   Ú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)rh   r·   r´   )r   r‚   ra   Úcountr   r   r!   Úhandle_duplicatesX  s   
€ûz+FootnotePostTreeprocessor.handle_duplicatesc                 C   sF   d| _ | d¡D ]}|j dd¡dkr | d¡D ]}|  |¡  qdS )z= Crawl the footnote div and add missing duplicate footnotes. r	   r\   r]   r¨   r"   r_   N)r¯   r©   rª   r«   r¹   )r   rR   r\   r_   r   r   r!   r—   a  s   
€úzFootnotePostTreeprocessor.runN)	r{   r|   r}   r~   r   r´   r·   r¹   r—   r   r   r   r!   r2   8  s    	r2   c                   @   ó    e Zd ZdZdd„ Zdd„ ZdS )r1   z3 Build and append footnote div to end of document. c                 C   r¦   r€   rU   r�   r   r   r!   r   p  r§   zFootnoteTreeprocessor.__init__c                 C   s†   | j  |¡}|d urA| j  |¡}|r:|\}}}t|ƒ |¡}|r-| |¡ | ||¡ d S | |d |¡ d |_d S | |¡ d S d S )Nr   )	r7   rz   rT   rh   rv   rp   rŽ   rL   ro   )r   rR   ÚfootnotesDivÚresultrN   r‚   ÚisTextÚindr   r   r!   r—   s  s   


ôzFootnoteTreeprocessor.runN©r{   r|   r}   r~   r   r—   r   r   r   r!   r1   m  s    r1   c                   @   rº   )r4   z* Replace placeholders with html entities. c                 C   r¦   r€   rU   r�   r   r   r!   r   †  r§   zFootnotePostprocessor.__init__c                 C   s    |  t| j d¡¡}|  td¡S )Nr   z&#160;)Úreplacerq   r7   rK   rt   )r   rI   r   r   r!   r—   ‰  s   ÿzFootnotePostprocessor.runNr¿   r   r   r   r!   r4   „  s    r4   c                  K   s   t di | ¤ŽS )z- Return an instance of the FootnoteExtension Nr   )r   )r   r   r   r!   ÚmakeExtension�  rX   rÁ   ) r~   r¨   r   r+   r   Úinlinepatternsr   r0   r   r3   r   r   Úcollectionsr
   rž   r­   Úxml.etree.ElementTreerj   ÚElementTreeÚSTXÚETXrq   rt   rŸ   r<   r   r-   r/   r2   r1   r4   rÁ   r   r   r   r!   Ú<module>   s,    
 ,X5