U
    \>e                     @  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 dd	lmZmZ dd
lmZ ddlmZ ddlZddlmZmZmZ erddlmZ G dd deZG dd deZdd ZdS )z
This extension adds Fenced Code Blocks to Python-Markdown.

See the [documentation](https://Python-Markdown.github.io/extensions/fenced_code_blocks)
for details.
    )annotations)dedent   )	Extension   )Preprocessor)
CodeHiliteCodeHiliteExtensionparse_hl_lines)	get_attrsAttrListExtension)parseBoolValue_escape_attrib_htmlN)TYPE_CHECKINGAnyIterable)Markdownc                      s$   e Zd Z fddZdd Z  ZS )FencedCodeExtensionc                   s    dddgi| _ t jf | d S )Nlang_prefix	language-z6Prefix prepended to the language. Default: "language-")configsuper__init__)selfkwargs	__class__ C/tmp/pip-unpacked-wheel-wj0og6ym/markdown/extensions/fenced_code.pyr   '   s     zFencedCodeExtension.__init__c                 C  s(   | |  |jt||  dd dS )z9 Add `FencedBlockPreprocessor` to the Markdown instance. Zfenced_code_block   N)ZregisterExtensionpreprocessorsregisterFencedBlockPreprocessor
getConfigs)r   mdr   r   r   extendMarkdown.   s    
z"FencedCodeExtension.extendMarkdown)__name__
__module____qualname__r   r&   __classcell__r   r   r   r   r   &   s   r   c                      sv   e Zd ZdZeedejejB ej	B Z
ddd fddZddd	d
dZdddddZdddddZ  ZS )r#   z& Find and extract fenced code blocks. a}  
            (?P<fence>^(?:~{3,}|`{3,}))[ ]*                          # opening fence
            ((\{(?P<attrs>[^\}\n]*)\})|                              # (optional {attrs} or
            (\.?(?P<lang>[\w#.+-]*)[ ]*)?                            # optional (.)lang
            (hl_lines=(?P<quot>"|')(?P<hl_lines>.*?)(?P=quot)[ ]*)?) # optional hl_lines)
            \n                                                       # newline (end of opening fence)
            (?P<code>.*?)(?<=\n)                                     # the code block
            (?P=fence)[ ]*$                                          # closing fence
        r   zdict[str, Any])r%   r   c                   s6   t  | || _d| _i | _d| _ddddg| _d S )NFZlinenumsZ
guess_langZ	noclassesuse_pygments)r   r   r   checked_for_depscodehilite_confuse_attr_listbool_options)r   r%   r   r   r   r   r   E   s    z FencedBlockPreprocessor.__init__z	list[str])linesreturnc              	   C  sx  | j s>| jjD ](}t|tr&| | _t|trd| _qd| _ d	|}| j
|}|rnddg i f\}}}}|dr| t|d\}}}t|r|d}n0|dr|d}|drt|d|d< | jr^| jd	 r^|d	dr^| j }	|	| |r,d
d	||	d |	d< t|df||	ddd|	}
|
jdd}nd } } }}|r| jdd}d| t| d}|rdtd	| d}|rdt| d}| jr|r|d	dsd	dd | D }| |d}d| | d| | d| d	}| jj|}|d|   d| d|| d  }qHqnqH| dS )z8 Match and store Fenced Code Blocks in the `HtmlStash`. T
N attrsr   langhl_linesr+   z{} {} Z	css_classcodeZpygments_styledefault)r5   styleF)shebangr   r   z class=""z id="c                 s  s0   | ](\}}|d krd| dt | dV  qdS )r+   r7   z="r<   Nr   ).0kvr   r   r   	<genexpr>   s     z.FencedBlockPreprocessor.run.<locals>.<genexpr>z<prez><code>z</code></pre>)!r,   r%   ZregisteredExtensions
isinstancer	   r$   r-   r   r.   joinFENCED_BLOCK_REsearchgrouphandle_attrsr   lenpopr
   getcopyupdateformatr   Zhiliter   r   items_escapeZ	htmlStashstorestartendsplit)r   r0   exttextmr5   idclassesr   Zlocal_configZ	highliterr8   Zid_attrZ	lang_attrZ
class_attrZkv_pairsprefixplaceholderr   r   r   runS   sl    







"



 .zFencedBlockPreprocessor.runzIterable[tuple[str, str]]z%tuple[str, list[str], dict[str, Any]])r4   r1   c                 C  s   d}g }i }|D ]f\}}|dkr&|}q|dkr:| | q|dkrPt|||< q|| jkrnt|ddd||< q|||< q|||fS )z6 Return tuple: `(id, [list, of, classes], {configs})` r3   rW   .r6   FT)Zfail_on_errorsZpreserve_none)appendr
   r/   r   )r   r4   rW   rX   Zconfigsr>   r?   r   r   r   rG      s    

z$FencedBlockPreprocessor.handle_attrsstr)txtr1   c                 C  s4   | dd}| dd}| dd}| dd}|S )	z basic html escaping &z&amp;<z&lt;rA   z&gt;r<   z&quot;)replace)r   r_   r   r   r   rO      s
    zFencedBlockPreprocessor._escape)r'   r(   r)   __doc__recompiler   	MULTILINEDOTALLVERBOSErD   r   r[   rG   rO   r*   r   r   r   r   r#   5   s   	Kr#   c                  K  s
   t f | S )N)r   )r   r   r   r   makeExtension   s    ri   )rc   
__future__r   textwrapr   r3   r   r!   r   Z
codehiliter   r	   r
   	attr_listr   r   utilr   Zserializersr   rd   typingr   r   r   Zmarkdownr   r   r#   ri   r   r   r   r   <module>   s     