o
    g*                     @  s   d Z ddlmZ ddlZddlmZmZmZmZm	Z	m
Z
mZmZmZ G dd deZG dd deZG d	d
 d
ZG dd dZdS )zA simple Python template renderer, for a nano-subset of Django syntax.

For a detailed discussion of this code, see this chapter from 500 Lines:
http://aosabook.org/en/500L/a-template-engine.html

    )annotationsN)	AnyCallableDictListNoReturnOptionalSetUnioncastc                   @     e Zd ZdZdS )TempliteSyntaxErrorz*Raised when a template has a syntax error.N__name__
__module____qualname____doc__ r   r   Q/var/www/html/bloggers_ems/venv/lib/python3.10/site-packages/coverage/templite.pyr          r   c                   @  r   )TempliteValueErrorz7Raised when an expression won't evaluate in a template.Nr   r   r   r   r   r      r   r   c                   @  s\   e Zd ZdZddddZdd
dZdddZdddZdZdddZ	dddZ
d ddZdS )!CodeBuilderzBuild source code conveniently.r   indentintreturnNonec                 C  s   g | _ || _d S N)codeindent_level)selfr   r   r   r   __init__#   s   
zCodeBuilder.__init__strc                 C  s   d dd | jD S )N c                 s      | ]}t |V  qd S r   )r!   ).0cr   r   r   	<genexpr>(       z&CodeBuilder.__str__.<locals>.<genexpr>)joinr   r   r   r   r   __str__'   s   zCodeBuilder.__str__linec                 C  s   | j d| j |dg dS )zwAdd a line of source to the code.

        Indentation and newline will be added for you, don't provide them.

         
N)r   extendr   )r   r+   r   r   r   add_line*   s   zCodeBuilder.add_linec                 C  s   t | j}| j| |S )z!Add a section, a sub-CodeBuilder.)r   r   r   append)r   sectionr   r   r   add_section2   s   
zCodeBuilder.add_section   c                 C  s   |  j | j7  _ dS )z0Increase the current indent for following lines.Nr   INDENT_STEPr)   r   r   r   r   :      zCodeBuilder.indentc                 C  s   |  j | j8  _ dS )z0Decrease the current indent for following lines.Nr4   r)   r   r   r   dedent>   r6   zCodeBuilder.dedentDict[str, Any]c                 C  s(   | j dksJ t| }i }t|| |S )z:Execute the code, and return a dict of globals it defines.r   )r   r!   exec)r   python_sourceglobal_namespacer   r   r   get_globalsB   s
   
zCodeBuilder.get_globalsN)r   )r   r   r   r   )r   r!   )r+   r!   r   r   )r   r   r   r   )r   r8   )r   r   r   r   r    r*   r/   r2   r5   r   r7   r<   r   r   r   r   r       s    




r   c                   @  sN   e Zd ZdZd!dd	Zd"ddZd#ddZd$ddZd%d&ddZd'dd Z	dS )(Templitea  A simple template renderer, for a nano-subset of Django syntax.

    Supported constructs are extended variable access::

        {{var.modifier.modifier|filter|filter}}

    loops::

        {% for var in list %}...{% endfor %}

    and ifs::

        {% if var %}...{% endif %}

    Comments are within curly-hash markers::

        {# This will be ignored #}

    Lines between `{% joined %}` and `{% endjoined %}` will have lines stripped
    and joined.  Be careful, this could join words together!

    Any of these constructs can have a hyphen at the end (`-}}`, `-%}`, `-#}`),
    which will collapse the white space following the tag.

    Construct a Templite with the template text, then use `render` against a
    dictionary context to create a finished string::

        templite = Templite('''
            <h1>Hello {{name|upper}}!</h1>
            {% for topic in topics %}
                <p>You are interested in {{topic}}.</p>
            {% endif %}
            ''',
            {"upper": str.upper},
        )
        text = templite.render({
            "name": "Ned",
            "topics": ["Python", "Geometry", "Juggling"],
        })

    textr!   contextsr8   r   r   c              
     sn  i | _ |D ]}| j | qt | _t | _t d    }d d d d g  d1 fdd	}g }t	
d
|}d }}	|D ]}
|
drQd\}}|
d dk}|rid}|
droqR|
dr| |
||  } d|  qR|  |
||  
 }|d dkrt|dkr| d|
 |d d| |d     qR|d dkrt|dks|d dkr| d|
 |d | |d | j d|d | |d    qR|d dkr|d d }	qR|d d!rHt|dkr| d"|
 |d dd# }|s,| d$|
 | }||kr;| d%| |dkrCd}	qR  qR| d&|d  qR|	r^t	d'd(|
 }
n|re|
 }
|
ro t|
 qR|r{| d)|d*  |  | j| j D ]}|d+| d,|d- qd.   tttttf td/tf gtf  d0 | _d#S )2zConstruct a Templite with the given `text`.

        `contexts` are dictionaries of values to use for future renderings.
        These are good for filters and global values.

        z&def render_function(context, do_dots):zresult = []zappend_result = result.appendzextend_result = result.extendzto_str = strr   r   c                     sN   t  dkrd d   nt  dkr dd    dd= dS )z%Force `buffered` to the code builder.   zappend_result(%s)r   zextend_result([%s]), N)lenr/   r(   r   bufferedr   r   r   flush_output   s
   z'Templite.__init__.<locals>.flush_outputz(?s)({{.*?}}|{%.*?%}|{#.*?#})F{)   -z{#z{{z
to_str(%s)r   ifrH   zDon't understand ifzif %s:rA   forr3   inzDon't understand forzfor c_{} in {}:   joinedTendzDon't understand endNzToo many endszMismatched end tagzDon't understand tagz\s*\n\s*r"   zUnmatched action tagc_z = context[]zreturn ''.join(result).render_functionr=   )contextupdatesetall_vars	loop_varsr   r/   r   r2   resplit
startswith
_expr_codestripr0   rC   _syntax_error	_variableformatpopr7   sublstripreprr   r   r   r!   r   r<   _render_function)r   r?   r@   rV   	vars_coderF   	ops_stacktokenssquash	in_joinedtokenstartrQ   exprwordsend_what
start_whatvar_namer   rD   r   r    x   s   


















zTemplite.__init__ro   c                 C  s   d|v r+| d}| |d }|dd D ]}| || j d| d| d}q|S d|v rT| d}| |d }d	d
d |dd D }d| d	| d}|S | || j d| }|S )z(Generate a Python expression for `expr`.|r   rA   NrS   ().rB   c                 s  r#   r   )rf   )r$   dr   r   r   r&     r'   z&Templite._expr_code.<locals>.<genexpr>zdo_dots(zc_%s)r\   r^   ra   rY   r(   )r   ro   pipesr   funcdotsargsr   r   r   r^      s    
	
zTemplite._expr_codemsgthingr   r   c                 C  s   t | d|)z6Raise a syntax error using `msg`, and showing `thing`.z: )r   )r   r}   r~   r   r   r   r`     s   zTemplite._syntax_errornamevars_setSet[str]c                 C  s&   t d|s| d| || dS )zTrack that `name` is used as a variable.

        Adds the name to `vars_set`, a set of variable names.

        Raises an syntax error if `name` is not a valid name.

        z[_a-zA-Z][_a-zA-Z0-9]*$zNot a valid nameN)r[   matchr`   add)r   r   r   r   r   r   ra     s   zTemplite._variableNrV   Optional[Dict[str, Any]]c                 C  s&   t | j}|r|| | || jS )zRender this template by applying it to `context`.

        `context` is a dictionary of values to use in this rendering.

        )dictrV   rW   rg   _do_dots)r   rV   render_contextr   r   r   render  s   

zTemplite.rendervaluer{   c                 G  s~   |D ]:}zt ||}W n) ty4   z|| }W n ttfy1 } ztd|d| |d}~ww Y nw t|r<| }q|S )z(Evaluate dotted expressions at run-time.zCouldn't evaluate rw   N)getattrAttributeError	TypeErrorKeyErrorr   callable)r   r   r{   dotexcr   r   r   r   '  s(   zTemplite._do_dots)r?   r!   r@   r8   r   r   )ro   r!   r   r!   )r}   r!   r~   r   r   r   )r   r!   r   r   r   r   r   )rV   r   r   r!   )r   r   r{   r!   r   r   )
r   r   r   r   r    r^   r`   ra   r   r   r   r   r   r   r>   N   s    
) 


r>   )r   
__future__r   r[   typingr   r   r   r   r   r   r	   r
   r   
ValueErrorr   r   r   r>   r   r   r   r   <module>   s   	,.