o
    v&i+,                     @  sp   d Z ddlmZ ddlZddl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NoReturn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   W/var/www/html/karishye-ai-python/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_section1   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   9      zCodeBuilder.indentc                 C  s   |  j | j8  _ dS )z0Decrease the current indent for following lines.Nr/   r$   r   r   r   dedent=   r1   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_globalsA   s
   
zCodeBuilder.get_globalsN)r   )r   r   r   r   )r   r   )r&   r   r   r   )r   r   r   r   )r   r3   )r
   r   r   r   r   r%   r*   r-   r0   r   r2   r7   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 %}

    if-else::

        {% if var %}...{% else %}...{% 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   contextsr3   r   r   c              
     s  i | _ |D ]}| j | qt | _t | _t d    }d d d d g  d7 fdd	}g }t	
d
|}d }}	|D ]O}
|
drd\}}|
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r| d|
 |r|d dkr| d|
   d   qR|d dkr*t|dks|d d kr| d!|
 |d | |d | j d"|d  d#| |d$  d%   qR|d d&kr9|d& d'}	qR|d d(r{t|dkrN| d)|
 |d d$d* }|s_| d+|
 | }||krn| d,| |d&krvd}	qR  qR| d-|d  qR|	rt	d.d/|
 }
n|r|
 }
|
r t|
 qR|r| d0|d  |  | j| j D ]}|d1| d2|d3 qd4   tttttf td5tf gtf  d6 | _d*S )8zConstruct 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   ifrC   zDon't understand ifzif %s:r<   elsezDon't understand elsezMismatched elsezelse:forr.   inzDon't understand forzfor c_z 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_functionr8   )contextupdatesetall_vars	loop_varsr   r*   r   r-   resplit
startswith
_expr_codestripr+   r>   _syntax_errorr2   	_variablepopsublstripreprr   r   dictr   r   r7   _render_function)r   r:   r;   rS   	vars_coderA   	ops_stacktokenssquash	in_joinedtokenstartrO   exprwordsend_what
start_whatvar_namer   r?   r   r   |   s   




















zTemplite.__init__rl   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   r<   NrP   ().r=   c                 s  r   r   )rb   )r   dr   r   r   r!     r"   z&Templite._expr_code.<locals>.<genexpr>zdo_dots(zc_%s)rY   r[   r^   rV   r#   )r   rl   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   rz   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)rX   matchr]   add)r   r|   r}   r   r   r   r^     s   zTemplite._variableNrS   dict[str, Any] | Nonec                 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.

        )rc   rS   rT   rd   _do_dots)r   rS   render_contextr   r   r   render$  s   

zTemplite.rendervaluerx   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 rt   N)getattrAttributeError	TypeErrorKeyErrorr   callable)r   r   rx   dotexcr   r   r   r   0  s(   zTemplite._do_dots)r:   r   r;   r3   r   r   )rl   r   r   r   )rz   r   r{   r   r   r   )r|   r   r}   r~   r   r   r   )rS   r   r   r   )r   r   rx   r   r   r   )
r
   r   r   r   r   r[   r]   r^   r   r   r   r   r   r   r9   M   s    
. 


r9   )r   
__future__r   rX   typingr   r   r   r   
ValueErrorr   r   r   r9   r   r   r   r   <module>   s   	.