o
    +eD                     @  s   d Z ddlmZ ddlZddlm  mZ ddlmZm	Z	 ddl
mZ ddl
mZ er1ddlmZ dddZdddZG dd dejZG dd deZG dd deZG dd deZdS ) z
Tree processors manipulate the tree created by block processors. They can even create an entirely
new `ElementTree` object. This is an excellent place for creating summaries, adding collected
references, or last minute adjustments.

    )annotationsN)TYPE_CHECKINGAny   )util)inlinepatterns)Markdownmdr   kwargsr   returnutil.Registry[Treeprocessor]c                 K  sB   t  }|t| dd |t| dd |t| dd |S )z3 Build the default  `treeprocessors` for Markdown. Zinline   Zprettify
   unescaper   )r   ZRegistryregisterInlineProcessorPrettifyTreeprocessorUnescapeTreeprocessor)r	   r
   Ztreeprocessors r   7lib/python3.10/site-packages/markdown/treeprocessors.pybuild_treeprocessors'   s
   r   sobjectboolc                 C  s   t | tjst | tS dS )z_ Return `True` if object is a string but not an  [`AtomicString`][markdown.util.AtomicString]. F)
isinstancer   AtomicStringstr)r   r   r   r   isString0   s   
r   c                   @  s   e Zd ZdZd	ddZdS )
Treeprocessora  
    `Treeprocessor`s are run on the `ElementTree` object before serialization.

    Each `Treeprocessor` implements a `run` method that takes a pointer to an
    `Element` and modifies it as necessary.

    `Treeprocessors` must extend `markdown.Treeprocessor`.

    rootetree.Elementr   etree.Element | Nonec                 C  s   dS )a  
        Subclasses of `Treeprocessor` should implement a `run` method, which
        takes a root `Element`. This method can return another `Element`
        object, and the existing root `Element` will be replaced, or it can
        modify the current tree and return `None`.
        Nr   )selfr   r   r   r   runA   s   zTreeprocessor.runN)r   r    r   r!   )__name__
__module____qualname____doc__r#   r   r   r   r   r   7   s    	r   c                   @  s   e Zd ZdZd8ddZd9d
dZd:ddZd;ddZd<d=ddZd>d?d d!Z		d>d@d%d&Z
	d<dAd+d,ZdBd0d1ZdCdDd6d7Zd2S )Er   zL
    A `Treeprocessor` that traverses a tree, applying inline patterns.
    r	   r   c                 C  sJ   t j| _t j| _dt| j t| j | _t j| _|| _	|j
| _
g | _d S )N   )r   ZINLINE_PLACEHOLDER_PREFIX$_InlineProcessor__placeholder_prefixETXZ$_InlineProcessor__placeholder_suffixlenZ$_InlineProcessor__placeholder_lengthZINLINE_PLACEHOLDER_RE _InlineProcessor__placeholder_rer	   inlinePatterns	ancestors)r"   r	   r   r   r   __init__P   s   
zInlineProcessor.__init__typer   r   tuple[str, str]c                 C  s    dt | j }tj| }||fS )z Generate a placeholder z%04d)r+   stashed_nodesr   ZINLINE_PLACEHOLDER)r"   r0   idhashr   r   r   Z__makePlaceholderZ   s   
z!InlineProcessor.__makePlaceholderdataindexinttuple[str | None, int]c                 C  s0   | j ||}|r|d| fS d|d fS )a  
        Extract id from data string, start from index.

        Arguments:
            data: String.
            index: Index, from which we start search.

        Returns:
            Placeholder id and string index, after the found placeholder.

        r   N)r,   searchgroupend)r"   r5   r6   mr   r   r   Z__findPlaceholder`   s   z!InlineProcessor.__findPlaceholdernodeetree.Element | strc                 C  s   |  |\}}|| j|< |S )z Add node to stash. )!_InlineProcessor__makePlaceholderr2   )r"   r=   r0   placeholderr3   r   r   r   Z__stashNoder   s   
zInlineProcessor.__stashNoder   patternIndexc                 C  sV   t |tjs)d}t| j}||k r)| | j| |||\}}}|s%|d7 }||k s|S )a  
        Process string with inline patterns and replace it with placeholders.

        Arguments:
            data: A line of Markdown text.
            patternIndex: The index of the `inlinePattern` to start with.

        Returns:
            String with placeholders.

        r   r   )r   r   r   r+   r-   _InlineProcessor__applyPattern)r"   r5   rA   
startIndexcountZmatchedr   r   r   Z__handleInlinex   s   

zInlineProcessor.__handleInlineTr    subnodeisTextr   Nonec                 C  sv   |r	|j }d|_ n|j}d|_| |||}|s&||ur&t||d }nd}|  |D ]
}|||d  q.dS )a'  
        Process placeholders in `Element.text` or `Element.tail`
        of Elements popped from `self.stashed_nodes`.

        Arguments:
            node: Parent node.
            subnode: Processing node.
            isText: Boolean variable, True - it's text, False - it's a tail.

        Nr   r   )texttail%_InlineProcessor__processPlaceholderslistr6   reverseinsert)r"   r=   rE   rF   rH   ZchildResultposnewChildr   r   r   Z__processElementText   s   z$InlineProcessor.__processElementText
str | Noneparent%list[tuple[etree.Element, list[str]]]c                   sV  d fdd}g d}|r| | j|}|dkr| ||\}}|| jv r~| j|}	|dkr;||| }
||
 t|	tsh|	gt|	 D ]}|jrX|j	 rX| 
|	|d	 |jrf|j	 rf| 
|| qGn||	 |}q|}|	| jd
d
 f n)|t| j }||||  |}n||d
 }
t|tjrt|
}
||
 d}|sS )a  
        Process string with placeholders and generate `ElementTree` tree.

        Arguments:
            data: String with placeholders instead of `ElementTree` elements.
            parent: Element, which contains processing inline data.
            isText: Boolean variable, True - it's text, False - it's a tail.

        Returns:
            List with `ElementTree` elements with applied inline patterns.

        rH   rP   r   rG   c                   s   | rEr!d d j rd d  j | 7  _ d S | d d _ d S  s4j r/ j | 7  _ d S | _ d S jr@ j| 7  _d S | _d S d S )Nr   )rI   rH   )rH   rF   rQ   resultr   r   linkText   s   

z7InlineProcessor.__processPlaceholders.<locals>.linkTextr   rS   FN )rH   rP   r   rG   )findr)   !_InlineProcessor__findPlaceholderr2   getr   r   rK   rI   strip$_InlineProcessor__processElementTextrH   appendr.   r+   r   r   )r"   r5   rQ   rF   rV   ZstrartIndexr6   r3   Z
phEndIndexr=   rH   childr;   r   rT   r   Z__processPlaceholders   sN   





*z%InlineProcessor.__processPlaceholderspatterninlinepatterns.PatternrC   tuple[str, bool, int]c                 C  s  t |tj}|jD ]}| | jv r|ddf  S q	|rEd}| ||D ]}|||\}}	}
|	du s9|
du rC||	d7 }d}q& n| 
||d }|d| }|s]|ddfS |sn||}|d}	|	d}
|du rw|d|
fS t |tst |jtjs|gt| D ],}t|s|jr| j|j  | |j|d |_| j  |jr| |j||_q| || }|rd|d|	 |||
d ddfS d||d|| d ddfS )	a  
        Check if the line fits the pattern, create the necessary
        elements, add it to `stashed_nodes`.

        Arguments:
            data: The text to be processed.
            pattern: The pattern to be checked.
            patternIndex: Index of current pattern.
            startIndex: String index, from which we start searching.

        Returns:
            String with placeholders instead of `ElementTree` elements.

        Fr   NTr   z{}{}{}z{}{}{}{}rS   )r   r   r   ZANCESTOR_EXCLUDESlowerr.   ZgetCompiledRegExpfinditerZhandleMatchr;   matchstartr   rH   r   r   rK   r   r]   tag_InlineProcessor__handleInlinepoprI   _InlineProcessor__stashNoder0   formatr:   groups)r"   r_   r5   rA   rC   Z	new_styleZexcluderd   r=   re   r;   ZleftDatar^   r@   r   r   r   Z__applyPattern   sj   








zInlineProcessor.__applyPatternr!   parents	list[str]c                 C  sN   g }|dur|dur| |j  | j|}|dus|  || dS )zBuild the ancestor list.N)r]   rf   rb   
parent_maprZ   rL   extend)r"   rQ   rl   r.   r   r   r   Z__build_ancestorsM  s   z!InlineProcessor.__build_ancestorsNtreer.   list[str] | Nonec                 C  s  i | _ |du r	g n|dd }dd | D | _||fg}|r| \}}|| _| || j g }|D ]}|jrtt|jtj	st| j
|j  |j}	d|_| | |	|}
|
D ]	}|| j|d < qZ||
7 }|
||
f | j  |jr| |j}td}d|_| ||d}|jr|j|_t||d }|  |D ]}|| j|d < |||d  qt|r|| j|< |
|| jdd f q4|D ]\}}
t|
D ]\}}|d }||| qq|s |S )a  Apply inline patterns to a parsed Markdown tree.

        Iterate over `Element`, find elements with inline tag, apply inline
        patterns and append newly created Elements to tree.  To avoid further
        processing of string with inline patterns, instead of normal string,
        use subclass [`AtomicString`][markdown.util.AtomicString]:

            node.text = markdown.util.AtomicString("This will not be processed.")

        Arguments:
            tree: `Element` object, representing Markdown tree.
            ancestors: List of parent tag names that precede the tree node (if needed).

        Returns:
            An element tree object with applied inline patterns.

        Nc                 S  s   i | ]
}|D ]}||qqS r   r   ).0pcr   r   r   
<dictcomp>o  s    z'InlineProcessor.run.<locals>.<dictcomp>r   dFr   )r2   iterrn   rh   r.   !_InlineProcessor__build_ancestorsrH   r   r   r   r]   rf   rb   rJ   rg   rI   etreeZElementrK   r6   rL   rM   r+   	enumerate)r"   rp   r.   Ztree_parentsstackZcurrElementrl   ZinsertQueuer^   rH   ZlstitemrI   ZdumbyZ
tailResultrN   rO   elementiobjr   r   r   r#   W  s^   




*zInlineProcessor.run)r	   r   )r0   r   r   r1   )r5   r   r6   r7   r   r8   )r=   r>   r0   r   r   r   )r   )r5   r   rA   r7   r   r   )T)r=   r    rE   r    rF   r   r   rG   )r5   rP   rQ   r    rF   r   r   rR   )
r_   r`   r5   r   rA   r7   rC   r7   r   ra   )rQ   r!   rl   rm   r   rG   N)rp   r    r.   rq   r   r    )r$   r%   r&   r'   r/   r?   rY   ri   rg   r\   rJ   rB   rx   r#   r   r   r   r   r   K   s    




!V
P
r   c                   @  s$   e Zd ZdZdddZdd	d
ZdS )r   z' Add line breaks to the html document. elemr    r   rG   c                 C  s   d}| j |jr7|jdvr7|jr|j s&t|r&| j |d jr&||_|D ]}| j |jr6| | q(|jr?|j sD||_dS dS )z8 Recursively add line breaks to `ElementTree` children. 
)codeprer   N)r	   Zis_block_levelrf   rH   r[   r+   _prettifyETreerI   )r"   r   r~   er   r   r   r     s   

z$PrettifyTreeprocessor._prettifyETreer   c                 C  s   |  | |d}|D ]}|jr|j sd|_qd|j |_q|d}|D ]%}t|rM|d jdkrM|d }t|sM|jdurMt|j	 d |_q(dS )z7 Add line breaks to `Element` object and its children. brr   z
%sr   r   r   N)
r   rw   rI   r[   r+   rf   rH   r   r   rstrip)r"   r   Zbrsr   Zpresr   r   r   r   r   r#     s   


zPrettifyTreeprocessor.runN)r   r    r   rG   r   r    r   rG   )r$   r%   r&   r'   r   r#   r   r   r   r   r     s    
r   c                   @  sD   e Zd ZdZedejej	Z
dddZdd
dZdddZdS )r   z Restore escaped chars z	{}(\d+){}r<   re.Match[str]r   r   c                 C  s   t t|dS )Nr   )chrr7   r:   )r"   r<   r   r   r   	_unescape  s   zUnescapeTreeprocessor._unescaperH   c                 C  s   | j | j|S r   )REsubr   )r"   rH   r   r   r   r     s   zUnescapeTreeprocessor.unescaper   r    rG   c                 C  sh   |  D ]-}|jr|jdks| |j|_|jr| |j|_| D ]\}}||| | q#qdS )z/ Loop over all elements and unescape all text. r   N)rw   rH   rf   r   rI   itemsset)r"   r   r   keyvaluer   r   r   r#     s   zUnescapeTreeprocessor.runN)r<   r   r   r   )rH   r   r   r   r   )r$   r%   r&   r'   recompilerj   r   ZSTXr*   r   r   r   r#   r   r   r   r   r     s    

r   )r	   r   r
   r   r   r   )r   r   r   r   )r'   Z
__future__r   r   Zxml.etree.ElementTreery   ZElementTreetypingr   r   rW   r   r   Zmarkdownr   r   r   Z	Processorr   r   r   r   r   r   r   r   <module>   s"   

	  V'