ó
…¾^Yc           @   s~   d  Z  d d l Z d d l m Z d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d	 „  ƒ  YZ d
 e f d „  ƒ  YZ	 d S(   sÅ   A 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

iÿÿÿÿN(   t   envt   TempliteSyntaxErrorc           B   s   e  Z d  Z RS(   s*   Raised when a template has a syntax error.(   t   __name__t
   __module__t   __doc__(    (    (    s3   /tmp/pip-build-hU8Cw8/coverage/coverage/templite.pyR      s   t   TempliteValueErrorc           B   s   e  Z d  Z RS(   s7   Raised when an expression won't evaluate in a template.(   R   R   R   (    (    (    s3   /tmp/pip-build-hU8Cw8/coverage/coverage/templite.pyR      s   t   CodeBuilderc           B   sV   e  Z d  Z d d „ Z d „  Z d „  Z d „  Z d Z d „  Z d „  Z	 d	 „  Z
 RS(
   s   Build source code conveniently.i    c         C   s   g  |  _  | |  _ d  S(   N(   t   codet   indent_level(   t   selft   indent(    (    s3   /tmp/pip-build-hU8Cw8/coverage/coverage/templite.pyt   __init__   s    	c         C   s   d j  d „  |  j Dƒ ƒ S(   Nt    c         s   s   |  ] } t  | ƒ Vq d  S(   N(   t   str(   t   .0t   c(    (    s3   /tmp/pip-build-hU8Cw8/coverage/coverage/templite.pys	   <genexpr>$   s    (   t   joinR   (   R	   (    (    s3   /tmp/pip-build-hU8Cw8/coverage/coverage/templite.pyt   __str__#   s    c         C   s$   |  j  j d |  j | d g ƒ d S(   sw   Add a line of source to the code.

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

        t    s   
N(   R   t   extendR   (   R	   t   line(    (    s3   /tmp/pip-build-hU8Cw8/coverage/coverage/templite.pyt   add_line&   s    c         C   s#   t  |  j ƒ } |  j j | ƒ | S(   s!   Add a section, a sub-CodeBuilder.(   R   R   R   t   append(   R	   t   section(    (    s3   /tmp/pip-build-hU8Cw8/coverage/coverage/templite.pyt   add_section.   s    i   c         C   s   |  j  |  j 7_  d S(   s0   Increase the current indent for following lines.N(   R   t   INDENT_STEP(   R	   (    (    s3   /tmp/pip-build-hU8Cw8/coverage/coverage/templite.pyR
   6   s    c         C   s   |  j  |  j 8_  d S(   s0   Decrease the current indent for following lines.N(   R   R   (   R	   (    (    s3   /tmp/pip-build-hU8Cw8/coverage/coverage/templite.pyt   dedent:   s    c         B   s3   |  j  d k s t ‚ e |  ƒ } i  } | | U| S(   s:   Execute the code, and return a dict of globals it defines.i    (   R   t   AssertionErrorR   (   R	   t   python_sourcet   global_namespace(    (    s3   /tmp/pip-build-hU8Cw8/coverage/coverage/templite.pyt   get_globals>   s
    (   R   R   R   R   R   R   R   R   R
   R   R   (    (    (    s3   /tmp/pip-build-hU8Cw8/coverage/coverage/templite.pyR      s   					t   Templitec           B   sG   e  Z d  Z d „  Z d „  Z d „  Z d „  Z d d „ Z d „  Z	 RS(   sü  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 #}

    Any of these constructs can have a hypen 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            s  i  |  _  x | D] } |  j  j | ƒ q Wt ƒ  |  _ t ƒ  |  _ t ƒ  ‰ ˆ j d ƒ ˆ j ƒ  ˆ j ƒ  } ˆ j d ƒ ˆ j d ƒ ˆ j d ƒ t	 j
 r® ˆ j d ƒ n ˆ j d ƒ g  ‰  ‡  ‡ f d †  } g  } t j d | ƒ } t } x¦| D]ž}	 |	 j d	 ƒ red' \ }
 } |	 d d k } | r8d } n  |	 j d ƒ rMqø q–|	 j d ƒ rŒ|  j |	 |
 | !j ƒ  ƒ } ˆ  j d | ƒ q–| ƒ  |	 |
 | !j ƒ  j ƒ  } | d d k rt | ƒ d
 k rá|  j d |	 ƒ n  | j d ƒ ˆ j d |  j | d ƒ ƒ ˆ j ƒ  q–| d d k r·t | ƒ d k sK| d
 d k r^|  j d |	 ƒ n  | j d ƒ |  j | d |  j ƒ ˆ j d | d |  j | d ƒ f ƒ ˆ j ƒ  q–| d j d ƒ rNt | ƒ d k rï|  j d |	 ƒ n  | d d } | s|  j d |	 ƒ n  | j ƒ  } | | k rA|  j d | ƒ n  ˆ j ƒ  q–|  j d  | d ƒ qø | rz|	 j ƒ  }	 n  |	 rø ˆ  j t |	 ƒ ƒ qø qø W| r·|  j d! | d" ƒ n  | ƒ  x/ |  j |  j D] } | j d# | | f ƒ qÏWˆ j d$ ƒ ˆ j ƒ  ˆ j ƒ  d% |  _ d& S((   s¸   Construct a Templite with the given `text`.

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

        s&   def render_function(context, do_dots):s   result = []s   append_result = result.appends   extend_result = result.extends   to_str = unicodes   to_str = strc              sa   t  ˆ  ƒ d k r* ˆ j d ˆ  d ƒ n/ t  ˆ  ƒ d k rY ˆ j d d j ˆ  ƒ ƒ n  ˆ  2d S(   s%   Force `buffered` to the code builder.i   s   append_result(%s)i    s   extend_result([%s])s   , N(   t   lenR   R   (    (   t   bufferedR   (    s3   /tmp/pip-build-hU8Cw8/coverage/coverage/templite.pyt   flush_output   s
    s   (?s)({{.*?}}|{%.*?%}|{#.*?#})t   {i   iþÿÿÿiýÿÿÿt   -s   {#s   {{s
   to_str(%s)i    t   ifs   Don't understand ifs   if %s:i   t   fori   t   ins   Don't understand fors   for c_%s in %s:i   t   ends   Don't understand ends   Too many endss   Mismatched end tags   Don't understand tags   Unmatched action tagiÿÿÿÿs   c_%s = context[%r]s   return "".join(result)t   render_functionN(   i   iþÿÿÿ(   t   contextt   updatet   sett   all_varst	   loop_varsR   R   R
   R   R    t   PY2t   ret   splitt   Falset
   startswitht
   _expr_codet   stripR   R    t   _syntax_errort	   _variablet   popR   t   lstript   reprR   t   _render_function(   R	   t   textt   contextsR*   t	   vars_codeR"   t	   ops_stackt   tokenst   squasht   tokent   startR(   t   exprt   wordst   end_whatt
   start_whatt   var_name(    (   R!   R   s3   /tmp/pip-build-hU8Cw8/coverage/coverage/templite.pyR   q   s    		
		"
c         C   sè   d | k ri | j  d ƒ } |  j | d ƒ } x³ | d D]) } |  j | |  j ƒ d | | f } q9 Wn{ d | k rÇ | j  d ƒ } |  j | d ƒ } d j d „  | d Dƒ ƒ } d | | f } n |  j | |  j ƒ d	 | } | S(
   s(   Generate a Python expression for `expr`.t   |i    i   s   c_%s(%s)t   .s   , c         s   s   |  ] } t  | ƒ Vq d  S(   N(   R:   (   R   t   d(    (    s3   /tmp/pip-build-hU8Cw8/coverage/coverage/templite.pys	   <genexpr>ò   s    s   do_dots(%s, %s)s   c_%s(   R1   R4   R7   R-   R   (   R	   RD   t   pipesR   t   funct   dotst   args(    (    s3   /tmp/pip-build-hU8Cw8/coverage/coverage/templite.pyR4   ç   s    
c         C   s   t  d | | f ƒ ‚ d S(   s6   Raise a syntax error using `msg`, and showing `thing`.s   %s: %rN(   R   (   R	   t   msgt   thing(    (    s3   /tmp/pip-build-hU8Cw8/coverage/coverage/templite.pyR6   ù   s    c         C   s6   t  j d | ƒ s% |  j d | ƒ n  | j | ƒ d S(   s°   Track 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.

        s   [_a-zA-Z][_a-zA-Z0-9]*$s   Not a valid nameN(   R0   t   matchR6   t   add(   R	   t   namet   vars_set(    (    s3   /tmp/pip-build-hU8Cw8/coverage/coverage/templite.pyR7   ý   s    c         C   s8   t  |  j ƒ } | r% | j | ƒ n  |  j | |  j ƒ S(   s‚   Render this template by applying it to `context`.

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

        (   t   dictR*   R+   R;   t   _do_dots(   R	   R*   t   render_context(    (    s3   /tmp/pip-build-hU8Cw8/coverage/coverage/templite.pyt   render	  s    c         G   s’   x‹ | D]ƒ } y t  | | ƒ } WnO t k
 rq y | | } Wqr t t f k
 rm t d | | f ƒ ‚ qr Xn Xt | ƒ r | ƒ  } q q W| S(   s(   Evaluate dotted expressions at run-time.s   Couldn't evaluate %r.%s(   t   getattrt   AttributeErrort	   TypeErrort   KeyErrorR   t   callable(   R	   t   valueRN   t   dot(    (    s3   /tmp/pip-build-hU8Cw8/coverage/coverage/templite.pyRW     s    N(
   R   R   R   R   R4   R6   R7   t   NoneRY   RW   (    (    (    s3   /tmp/pip-build-hU8Cw8/coverage/coverage/templite.pyR   J   s   &	v			(
   R   R0   t   coverageR    t
   ValueErrorR   R   t   objectR   R   (    (    (    s3   /tmp/pip-build-hU8Cw8/coverage/coverage/templite.pyt   <module>	   s   .