B
    `)                 @   s\   d Z ddlZddlmZ G dd deZG dd deZG dd	 d	eZG d
d de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

    N)envc               @   s   e Zd ZdZdS )TempliteSyntaxErrorz*Raised when a template has a syntax error.N)__name__
__module____qualname____doc__ r   r   Y/home/kop/projects/devel/pgwui/test_venv/lib/python3.7/site-packages/coverage/templite.pyr      s   r   c               @   s   e Zd ZdZdS )TempliteValueErrorz7Raised when an expression won't evaluate in a template.N)r   r   r   r   r   r   r   r	   r
      s   r
   c               @   sN   e Zd ZdZdddZdd Zdd Zd	d
 ZdZdd Z	dd Z
dd ZdS )CodeBuilderzBuild source code conveniently.r   c             C   s   g | _ || _d S )N)codeindent_level)selfindentr   r   r	   __init__   s    zCodeBuilder.__init__c             C   s   d dd | jD S )N c             s   s   | ]}t |V  qd S )N)str).0cr   r   r	   	<genexpr>$   s    z&CodeBuilder.__str__.<locals>.<genexpr>)joinr   )r   r   r   r	   __str__#   s    zCodeBuilder.__str__c             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   liner   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_section.   s    
zCodeBuilder.add_section   c             C   s   |  j | j7  _ dS )z0Increase the current indent for following lines.N)r   INDENT_STEP)r   r   r   r	   r   6   s    zCodeBuilder.indentc             C   s   |  j | j8  _ dS )z0Decrease the current indent for following lines.N)r   r!   )r   r   r   r	   dedent:   s    zCodeBuilder.dedentc             C   s(   | j dkstt| }i }t|| |S )z:Execute the code, and return a dict of globals it defines.r   )r   AssertionErrorr   exec)r   Zpython_sourceZglobal_namespacer   r   r	   get_globals>   s
    
zCodeBuilder.get_globalsN)r   )r   r   r   r   r   r   r   r   r!   r   r"   r%   r   r   r   r	   r      s   
r   c               @   sB   e Zd ZdZdd Zdd Zdd Zdd	 ZdddZ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 whitespace 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'],
        })

    c          	      sv  i | _ x|D ]}| j | qW t | _t | _t d    }d d d t	j
rd n
d g   fdd}g }td	|}d
 }}	xT|D ]J}
|
drd\}}|
d dk}|rd}|
drqq|
dr.| |
||  } d|  q|  |
||   }|d dkrt|dkrp| d|
 |d d| |d     q|d dkrt|dks|d dkr| d|
 |d | |d | j d|d | |d f    n|d dkr8|d d}	n|d d rt|dkrb| d!|
 |d dd" }|s| d#|
 | }||kr| d$| |dkrd
}	n  n| d%|d  q|	rtd&d'|
 }
n|r|
 }
|
r t|
 qW |r"| d(|d)  |  x(| j| j D ]}|d*||f  q6W d+    d, | _d"S )-zConstruct 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 = unicodezto_str = strc                  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])z, 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   ifr,   zDon't understand ifzif %s:r'   forr    inzDon't understand forzfor c_%s in %s:   ZjoinedTendzDon't understand endNzToo many endszMismatched end tagzDon't understand tagz\s*\n\s*r   zUnmatched action tagzc_%s = context[%r]zreturn "".join(result)Zrender_function)contextupdatesetall_varsZ	loop_varsr   r   r   r   r   PY2resplit
startswith
_expr_codestripr   r(   _syntax_error	_variablepopr"   sublstripreprr%   _render_function)r   textZcontextsr6   Z	vars_coder*   Z	ops_stacktokensZsquashZ	in_joinedtokenstartr4   exprwordsZend_whatZ
start_whatvar_namer   )r)   r   r	   r   t   s    














zTemplite.__init__c             C   s   d|krR| d}| |d }x|dd D ]}| || j d||f }q.W n`d|kr| d}| |d }ddd	 |dd D }d
||f }n| || j d| }|S )z(Generate a Python expression for `expr`.|r   r'   Nzc_%s(%s).z, c             s   s   | ]}t |V  qd S )N)rE   )r   dr   r   r	   r      s    z&Templite._expr_code.<locals>.<genexpr>zdo_dots(%s, %s)zc_%s)r<   r>   rA   r9   r   )r   rK   Zpipesr   funcdotsargsr   r   r	   r>      s    

zTemplite._expr_codec             C   s   t d||f dS )z6Raise a syntax error using `msg`, and showing `thing`.z%s: %rN)r   )r   msgthingr   r   r	   r@     s    zTemplite._syntax_errorc             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   nameZvars_setr   r   r	   rA     s    zTemplite._variableNc             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.

        )dictr6   r7   rF   _do_dots)r   r6   Zrender_contextr   r   r	   render  s    

zTemplite.renderc             G   sz   xt|D ]l}yt ||}W nJ tk
rb   y|| }W n( ttfk
r\   td||f Y nX Y nX t|r| }qW |S )z(Evaluate dotted expressions at run-time.zCouldn't evaluate %r.%s)getattrAttributeError	TypeErrorKeyErrorr
   callable)r   valuerR   dotr   r   r	   rZ      s    

zTemplite._do_dots)N)
r   r   r   r   r   r>   r@   rA   r[   rZ   r   r   r   r	   r&   J   s   )~
r&   )
r   r;   Zcoverager   
ValueErrorr   r
   objectr   r&   r   r   r   r	   <module>	   s   .