o
    i ebC                     @  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	m
Z
 ddlmZ ddlmZ er3d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SequenceAny   )util)inlinepatterns)Markdownmdr	   kwargsr   returnutil.Registryc                 K  sB   t  }|t| dd |t| dd |t| dd |S )z3 Build the default  `treeprocessors` for Markdown. inline   prettify
   unescaper   )r   RegistryregisterInlineProcessorPrettifyTreeprocessorUnescapeTreeprocessor)r
   r   treeprocessors r   F/var/www/myenv/lib/python3.10/site-packages/markdown/treeprocessors.pybuild_treeprocessors'   s
   r   s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                   @  sv   e Zd ZdZdd Zdd Zd-ddZdd Zd.d/ddZd0d1ddZ	d0d2ddZ
d.d3d#d$Zd%d& Zd4d5d+d,Zd'S )6r   zL
    A `Treeprocessor` that traverses a tree, applying inline patterns.
    c                 C  sJ   t j| _t j| _dt| j t| j | _t j| _|| _	|j
| _
g | _d S )N   )r   INLINE_PLACEHOLDER_PREFIX$_InlineProcessor__placeholder_prefixETX$_InlineProcessor__placeholder_suffixlen$_InlineProcessor__placeholder_lengthINLINE_PLACEHOLDER_RE _InlineProcessor__placeholder_rer
   inlinePatterns	ancestors)r&   r
   r   r   r   __init__P   s   
zInlineProcessor.__init__c                 C  s    dt | j }tj| }||fS )z Generate a placeholder z%04d)r1   stashed_nodesr   INLINE_PLACEHOLDER)r&   typeidhashr   r   r   __makePlaceholderZ   s   
z!InlineProcessor.__makePlaceholderdatar    indexintr   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)r4   searchgroupend)r&   r>   r?   mr   r   r   __findPlaceholder`   s   z!InlineProcessor.__findPlaceholderc                 C  s   |  |\}}|| j|< |S )z Add node to stash. )!_InlineProcessor__makePlaceholderr8   )r&   noder:   placeholderr;   r   r   r   __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   r1   r5   _InlineProcessor__applyPattern)r&   r>   rK   
startIndexcountmatchedr   r   r   __handleInlinex   s   

zInlineProcessor.__handleInlineTrH   r$   subnodeisTextr   c                 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listr?   reverseinsert)r&   rH   rQ   rR   rS   childResultposnewChildr   r   r   __processElementText   s   z$InlineProcessor.__processElementTextparentlist[etree.ElementTree]c                   sR   fdd}g d}|r| | j|}|dkr| ||\}}|| jv r|| j|}	|dkr:||| }
||
 t|	sf|	gt|	 D ]}|jrV|j rV| 	|	|d |j
rd|j
 rd| 	|| qEn||	 |}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.

        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   )rT   rS   )rS   rR   r]   resultr   r   linkText   s   

z7InlineProcessor.__processPlaceholders.<locals>.linkTextr   r_   FN )findr.   !_InlineProcessor__findPlaceholderr8   getr!   rV   rT   strip$_InlineProcessor__processElementTextrS   appendr6   r1   r   r   r   )r&   r>   r]   rR   rb   strartIndexr?   r;   
phEndIndexrH   rS   childrD   r   r`   r   __processPlaceholders   sN   




*z%InlineProcessor.__processPlaceholderspatternrM   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|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{}{}{}{}r_   )r   r   r   ANCESTOR_EXCLUDESlowerr6   getCompiledRegExpfinditerhandleMatchrD   matchstartr!   rS   r   r   rV   ri   tag_InlineProcessor__handleInlinepoprT   _InlineProcessor__stashNoder:   formatrC   groups)r&   rn   r>   rK   rM   	new_styleexcluderu   rH   rv   rD   leftDatarl   rI   r   r   r   __applyPattern   sj   







zInlineProcessor.__applyPatternc                 C  sN   g }|dur|dur| |j  | j|}|dus|  || dS )zBuild the ancestor list.N)ri   rw   rq   
parent_maprf   rW   extend)r&   r]   parentsr6   r   r   r   __build_ancestorsB  s   z!InlineProcessor.__build_ancestorsNtreer6   Sequence[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>d  s    z'InlineProcessor.run.<locals>.<dictcomp>r   dFr   )r8   iterr   ry   r6   !_InlineProcessor__build_ancestorsrS   r   r   r   ri   rw   rq   rU   rx   rT   etreeElementrV   r?   rW   rX   r1   	enumerate)r&   r   r6   tree_parentsstackcurrElementr   insertQueuerl   rS   lstitemrT   dumby
tailResultrZ   r[   elementiobjr   r   r   r'   L  s^   




*zInlineProcessor.run)r>   r    r?   r@   r   rA   )r   )r>   r    rK   r@   r   r    )T)rH   r$   rQ   r$   rR   r   )r>   r    r]   r$   rR   r   r   r^   )
rn   r    r>   r    rK   r@   rM   r@   r   ro   N)r   r$   r6   r   r   r$   )r(   r)   r*   r+   r7   rG   re   rz   rx   rh   rU   rL   r   r'   r   r   r   r   r   K   s    

LJ
r   c                   @  s"   e Zd ZdZdd Zddd	Zd
S )r   z' Add line breaks to the html document. 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
   is_block_levelrw   rS   rg   r1   _prettifyETreerT   )r&   elemr   er   r   r   r     s   

z$PrettifyTreeprocessor._prettifyETreer#   r$   r   Nonec                 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   r   rT   rg   r1   rw   rS   r   r   rstrip)r&   r#   brsr   presr   r   r   r   r   r'     s   


zPrettifyTreeprocessor.runN)r#   r$   r   r   )r(   r)   r*   r+   r   r'   r   r   r   r   r     s    r   c                   @  s>   e Zd ZdZedejej	Z
dd Zdd Zdd Zd	S )
r   z Restore escaped chars z	{}(\d+){}c                 C  s   t t|dS )Nr   )chrr@   rC   )r&   rE   r   r   r   	_unescape  s   zUnescapeTreeprocessor._unescapec                 C  s   | j | j|S r   )REsubr   )r&   rS   r   r   r   r     s   zUnescapeTreeprocessor.unescapec                 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)r   rS   rw   r   rT   itemsset)r&   r#   r   keyvaluer   r   r   r'     s   zUnescapeTreeprocessor.runN)r(   r)   r*   r+   recompiler{   r   STXr/   r   r   r   r'   r   r   r   r   r     s    r   )r
   r	   r   r   r   r   )r   r   r   r   )r+   
__future__r   r   xml.etree.ElementTreer   ElementTreetypingr   r   r   rc   r   r   markdownr	   r   r!   	Processorr"   r   r   r   r   r   r   r   <module>   s"   

	  K'