3
^              +   @   s  d Z dZdddddddd	d
dddddgZyddlZW n   ddlmZ Y nX ye W n   eefZY nX ddlZddl	Z	ddl
Z
yddlmZ W n   ddlmZ Y nX yddlmZmZ W n   ddlmZmZ Y nX yddlZW n   ddlmZ Y nX G dd de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G dd deZG dd deZG dd	 d	eZG dd
 d
eZe	jdZdr\Z Z!G d!d" d"e"Z#d#d$ 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(G d-d. d.e"Z)G d/d0 d0e"Z*G d1d2 d2e*Z+G d3d4 d4e+Z,G d5d6 d6e*Z-G d7d8 d8e"Z.G d9d: d:e"Z/d;d< Z0d=d> Z1d?d@ Z2ee1e1dAdB dCdB eee0dDdB e2dddEZ3dFdG Z4dHdI Z5dJdK Z6dLdB dMdB e6dNZ7dOdP Z8i Z9dQdR Z:e;e<dS\Z=Z>Z?Z@ZAZBZCZDdTdU ZEdVdW ZFddXdYdZdB dZdB d[fd\dZGe	jd]ZHd^d_d`dagZIdbdB dfdcdZJdddB dfdedZKG dfd de"ZLdgdh ZMdidj ZNdkdl ZOdmdn ZPdodp ZQdqd ZRdS )sa  Python implementation of json-template.

JSON Template is a minimal and powerful templating language for transforming a
JSON dictionary to arbitrary text.

To use this module, you will typically use the Template constructor, and catch
various exceptions thrown.  You may also want to use the FromFile/FromString
methods, which allow Template constructor options to be embedded in the template
string itself.

Other functions are exposed for tools which may want to process templates.
zAndy ChuErrorCompilationErrorEvaluationErrorBadFormatterBadPredicateMissingFormatterConfigurationErrorTemplateSyntaxErrorUndefinedVariableCompileTemplate
FromStringFromFileTemplateexpand    N)StringIO)escape)	urlencode
quote_plus)urlparsec               @   s   e Zd ZdZdd ZdS )r   zBase class for all exceptions in this module.

  Thus you can "except jsontemplate.Error: to catch all exceptions thrown by
  this module.
  c             C   s2   t | dr$d| jd tj| jf S | jd S dS )zThis helps people debug their templates.

    If a variable isn't defined, then some context is shown in the traceback.
    TODO: Attach context for other errors.
    nearz%s

Near: %sr   N)hasattrargspprintpformatr   )self r   \/home/psgendb/BIRCHDEV/pkg/quast-5.2.0/quast_libs/site_packages/jsontemplate/jsontemplate.py__str__G   s    
zError.__str__N)__name__
__module____qualname____doc__r   r   r   r   r   r   @   s   c               @   s   e Zd ZdZdS )r   z?Base class for errors that happen during the compilation stage.N)r   r   r    r!   r   r   r   r   r   S   s   c               @   s   e Zd ZdZdddZdS )r   zBase class for errors that happen when expanding the template.

  This class of errors generally involve the data dictionary or the execution of
  the formatters.
  Nc             C   s   t j| | || _d S )N)r   __init__original_exception)r   msgr#   r   r   r   r"   ]   s    zEvaluationError.__init__)N)r   r   r    r!   r"   r   r   r   r   r   W   s   c               @   s   e Zd ZdZdS )r   z2A bad formatter was specified, e.g. {variable|BAD}N)r   r   r    r!   r   r   r   r   r   b   s   c               @   s   e Zd ZdZdS )r   z+A bad predicate was specified, e.g. {.BAD?}N)r   r   r    r!   r   r   r   r   r   e   s   c               @   s   e Zd ZdZdS )r   zQ
  Raised when formatters are required, and a variable is missing a formatter.
  N)r   r   r    r!   r   r   r   r   r   h   s   c               @   s   e Zd ZdZdS )r   zQ
  Raised when the Template options are invalid and it can't even be compiled.
  N)r   r   r    r!   r   r   r   r   r   m   s   c               @   s   e Zd ZdZdS )r   z"Syntax error in the template text.N)r   r   r    r!   r   r   r   r   r   r   s   c               @   s   e Zd ZdZdS )r	   zDThe template contains a variable not defined by the data dictionary.N)r   r   r    r!   r   r   r   r   r	   u   s   z(repeated)?\s*section\s+(\S+)   c               @   s    e Zd ZdZdd Zdd ZdS )FunctionRegistryzGAbstract class for looking up formatters or predicates at compile time.c             C   s   t dS )a  Lookup a function.

    Args:
      user_str: A raw string from the user, which may include uninterpreted
        arguments.  For example, 'pluralize person people' or 'test? admin'

    Returns:
      A 2-tuple of (function, args)
        function: Callable that formats data as a string
        args: Extra arguments to be passed to the function at expansion time
          Should be None to pass NO arguments, since it can pass a 0-tuple too.
    N)NotImplementedError)r   user_strr   r   r   Lookup   s    zFunctionRegistry.Lookupc             C   s   | j |\}}||tfS )N)r)   ENHANCED_FUNC)r   r(   funcr   r   r   r   LookupWithType   s    zFunctionRegistry.LookupWithTypeN)r   r   r    r!   r)   r,   r   r   r   r   r&      s   r&   c             C   s   | d j  rtS tS dS )z|
  By default, formatters/predicates which start with a non-lowercase letter take
  contexts rather than just the cursor.
  r   N)islowerSIMPLE_FUNCr*   )r(   r   r   r   _DecideFuncType   s    r/   c               @   s    e Zd ZdZdd Zdd ZdS )DictRegistryz)Look up functions in a simple dictionary.c             C   s
   || _ d S )N)	func_dict)r   r1   r   r   r   r"      s    zDictRegistry.__init__c             C   s   | j j|d t|fS )N)r1   getr/   )r   r(   r   r   r   r,      s    zDictRegistry.LookupWithTypeN)r   r   r    r!   r"   r,   r   r   r   r   r0      s   r0   c               @   s    e Zd ZdZdd Zdd ZdS )CallableRegistryz/Look up functions in a (higher-order) function.c             C   s
   || _ d S )N)r+   )r   r+   r   r   r   r"      s    zCallableRegistry.__init__c             C   s   | j |d t|fS )N)r+   r/   )r   r(   r   r   r   r,      s    zCallableRegistry.LookupWithTypeN)r   r   r    r!   r"   r,   r   r   r   r   r3      s   r3   c               @   s    e Zd ZdZdd Zdd ZdS )PrefixRegistryzLookup functions with arguments.
  
  The function name is identified by a prefix.  The character after the prefix,
  usually a space, is considered the argument delimiter (similar to sed/perl's
  s/foo/bar s|foo|bar syntax).
  c             C   s
   || _ dS )z
    Args:
      functions: List of 2-tuples (prefix, function), e.g.
      [('pluralize', _Pluralize), ('cycle', _Cycle)]
    N)	functions)r   r5   r   r   r   r"      s    zPrefixRegistry.__init__c             C   sn   xd| j D ]Z\}}|j|rt|}y|| }W n tk
rF   f }Y nX |j|dd  }||fS qW d f fS )Nr%   )r5   
startswithlen
IndexErrorsplit)r   r(   prefixr+   iZ	splitcharr   r   r   r   r)      s    

zPrefixRegistry.LookupN)r   r   r    r!   r"   r)   r   r   r   r   r4      s   r4   c               @   s    e Zd ZdZdd Zdd ZdS )ChainedRegistryz?Look up functions in chain of other FunctionRegistry instances.c             C   s
   || _ d S )N)
registries)r   r=   r   r   r   r"      s    zChainedRegistry.__init__c             C   s8   x,| j D ]"}|j|\}}}|r|||fS qW d d tfS )N)r=   r,   r.   )r   r(   registryr+   r   	func_typer   r   r   r,      s
    zChainedRegistry.LookupWithTypeN)r   r   r    r!   r"   r,   r   r   r   r   r<      s   r<   c               @   sp   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd ZdS )_ProgramBuilderz]
  Receives method calls from the parser, and constructs a tree of _Section()
  instances.
  c             C   s   t  | _| jg| _t|tr&t|}nt|r6t|}tdt	fdt
fg}t|tt|g| _t|trrt|}nt|rt|}t|ttg| _dS )zw
    Args:
      formatters: See docstring for CompileTemplate
      predicates: See docstring for CompileTemplate
    Z	pluralizecycleN)_Sectioncurrent_blockstack
isinstancedictr0   callabler3   r4   
_Pluralize_Cycler<   _DEFAULT_FORMATTERS
formatters_DEFAULT_PREDICATES
predicates)r   rK   rM   Zdefault_formattersr   r   r   r"      s     




z_ProgramBuilder.__init__c             C   s   | j j| dS )z1
    Args:
      statement: Append a literal
    N)rC   Append)r   	statementr   r   r   rN     s    z_ProgramBuilder.Appendc             C   s0   | j j|\}}}|r |||fS td| dS )zQ
    The user's formatters are consulted first, then the default formatters.
    z%r is not a valid formatterN)rK   r,   r   )r   Z
format_str	formatterr   r?   r   r   r   _GetFormatter  s    
z_ProgramBuilder._GetFormatterc             C   s0   | j j|\}}}|r |||fS td| dS )zQ
    The user's predicates are consulted first, then the default predicates.
    z%r is not a valid predicateN)rM   r,   r   )r   pred_str	predicater   r?   r   r   r   _GetPredicate#  s    
z_ProgramBuilder._GetPredicatec                s*    fdd|D } j jt||ff d S )Nc                s   g | ]} j |qS r   )rQ   ).0f)r   r   r   
<listcomp>.  s    z6_ProgramBuilder.AppendSubstitution.<locals>.<listcomp>)rC   rN   _DoSubstitute)r   namerK   r   )r   r   AppendSubstitution-  s    z"_ProgramBuilder.AppendSubstitutionc             C   s&   | j j||f | jj| || _ d S )N)rC   rN   rD   append)r   r+   	new_blockr   r   r   _NewSection1  s    z_ProgramBuilder._NewSectionc             C   sH   |t krt|}t}n"|tkr,t|}t}ntd| | j|| dS )z"For sections or repeated sections.zInvalid token type %sN)REPEATED_SECTION_TOKEN_RepeatedSection_DoRepeatedSectionSECTION_TOKENrB   
_DoSectionAssertionErrorr]   )r   
token_typesection_namer\   r+   r   r   r   
NewSection6  s    z_ProgramBuilder.NewSectionc             C   s$   |r| j |}nd}| jj| dS )zn
    {.or ...} Can appear inside predicate blocks or section blocks, with
    slightly different meaning.
    N)rT   rC   NewOrClause)r   rR   predr   r   r   rg   E  s    z_ProgramBuilder.NewOrClausec             C   s   | j j  d S )N)rC   AlternatesWith)r   r   r   r   ri   P  s    z_ProgramBuilder.AlternatesWithc             C   s*   | j |}t }|j| | jt| dS )z For chains of predicate clauses.N)rT   _PredicateSectionrg   r]   _DoPredicates)r   rR   rh   blockr   r   r   NewPredicateSectionS  s    

z#_ProgramBuilder.NewPredicateSectionc             C   s   | j j  | j d | _d S )Nr%   )rD   poprC   )r   r   r   r   
EndSection[  s    
z_ProgramBuilder.EndSectionc             C   s   | j S )N)rC   )r   r   r   r   Root_  s    z_ProgramBuilder.RootN)r   r   r    r!   r"   rN   rQ   rT   rZ   r]   rf   rg   ri   rm   rp   rq   r   r   r   r   r@      s   "

r@   c               @   s,   e Zd Zdd Zdd Zdd Zdd Zd	S )
_AbstractSectionc             C   s
   g | _ d S )N)current_clause)r   r   r   r   r"   f  s    z_AbstractSection.__init__c             C   s   | j j| dS )z!Append a statement to this block.N)rs   r[   )r   rO   r   r   r   rN   j  s    z_AbstractSection.Appendc             C   s   t dd S )NzB{.alternates with} can only appear with in {.repeated section ...})r   )r   r   r   r   ri   n  s    z_AbstractSection.AlternatesWithc             C   s   t d S )N)r'   )r   r   r   r   rg   r  s    z_AbstractSection.NewOrClauseN)r   r   r    r"   rN   ri   rg   r   r   r   r   rr   d  s   rr   c               @   s4   e Zd ZdZdddZdd Zddd	Zd
d ZdS )rB   z Represents a (repeated) section.Nc             C   s    t j|  || _d| ji| _dS )z
    Args:
      section_name: name given as an argument to the section
      token_type: The token type that created this section (e.g.
          PREDICATE_TOKEN)
    defaultN)rr   r"   re   rs   
statements)r   re   r   r   r   r"   y  s    
z_Section.__init__c             C   s
   d| j  S )Nz<Section %s>)re   )r   r   r   r   __repr__  s    z_Section.__repr__rt   c             C   s   | j j|g S )N)ru   r2   )r   Zclauser   r   r   
Statements  s    z_Section.Statementsc             C   s"   |rt dg | _| j| jd< d S )Nz;{.or} clause only takes a predicate inside predicate blocksor)r   rs   ru   )r   rh   r   r   r   rg     s
    z_Section.NewOrClause)N)rt   )r   r   r    r!   r"   rv   rw   rg   r   r   r   r   rB   v  s
   

rB   c               @   s   e Zd ZdZdd ZdS )r_   zDRepeated section is like section, but it supports {.alternates with}c             C   s   g | _ | j | jd< d S )Nzalternates with)rs   ru   )r   r   r   r   ri     s    z_RepeatedSection.AlternatesWithN)r   r   r    r!   ri   r   r   r   r   r_     s   r_   c               @   s    e Zd ZdZdd Zdd ZdS )rj   z+Represents a sequence of predicate clauses.c             C   s   t j|  g | _d S )N)rr   r"   clauses)r   r   r   r   r"     s    
z_PredicateSection.__init__c             C   s.   |pdd d t f}g | _| jj|| jf d S )Nc             S   s   dS )NTr   )xr   r   r   <lambda>  s    z/_PredicateSection.NewOrClause.<locals>.<lambda>)r.   rs   ry   r[   )r   rh   r   r   r   rg     s    z_PredicateSection.NewOrClauseN)r   r   r    r!   r"   rg   r   r   r   r   rj     s   rj   c               @   s"   e Zd ZdZd	ddZdd ZdS )
_FramezA stack frame.r%   c             C   s   || _ || _d S )N)contextindex)r   r}   r~   r   r   r   r"     s    z_Frame.__init__c             C   s   d| j | jf S )NzFrame %s (%s))r}   r~   )r   r   r   r   r     s    z_Frame.__str__Nrn   )rn   )r   r   r    r!   r"   r   r   r   r   r   r|     s   
r|   c               @   sH   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dS )_ScopedContextzsAllows scoped lookup of variables.

  If the variable isn't in the current context, then we search up the stack.
  c             C   s   t |g| _|| _dS )z`
    Args:
      context: The root context
      undefined_str: See Template() constructor.
    N)r|   rD   undefined_str)r   r}   r   r   r   r   r"     s    z_ScopedContext.__init__c             C   s<   |dkr| j d j}n| j d jj|}| j jt| |S )zGiven a section name, push it on the top of the stack.

    Returns:
      The new section, or None if there is no such section.
    @r%   rn   rn   )rD   r}   r2   r[   r|   )r   rY   Znew_contextr   r   r   PushSection  s
    z_ScopedContext.PushSectionc             C   s   | j j  d S )N)rD   ro   )r   r   r   r   Pop  s    z_ScopedContext.Popc             C   sr   | j d }|jdkr,tddd}| j j| | j d	 j}|jt|krT| j j  t||j |_| jd7  _dS )
zsAdvance to the next item in a repeated section.

    Raises:
      StopIteration if there are no more elements
    r%   Nr   )r~      Trn   rn   )rD   r~   r|   r[   r}   r7   ro   StopIteration)r   ZstacktopZcontext_arrayr   r   r   Next  s    


z_ScopedContext.Nextc             C   s"   | j d krtd| n| j S d S )Nz%r is not defined)r   r	   )r   rY   r   r   r   
_Undefined  s    
z_ScopedContext._Undefinedc             C   s   t | jd }xp| j| }|dkr4|jdkrb|jS n.|j}t|drby|| S  tk
r`   Y nX |d8 }|dkr| j|S qW dS )z%Look up the stack for the given name.r%   z@indexr2   Nrn   rn   )r7   rD   r~   r}   r   KeyErrorr   )r   rY   r;   framer}   r   r   r   _LookUpStack  s    


z_ScopedContext._LookUpStackc             C   sr   |dkr| j d jS |jd}| j|d }x@|dd D ]0}y|| }W q: ttfk
rh   | j|S X q:W |S )a^  Get the value associated with a name in the current context.

    The current context could be an dictionary in a list, or a dictionary
    outside a list.

    Args:
      name: name to lookup, e.g. 'foo' or 'foo.bar.baz'

    Returns:
      The value, or self.undefined_str

    Raises:
      UndefinedVariable if self.undefined_str is not set
    r   r%   .r   Nrn   )rD   r}   r9   r   r   	TypeErrorr   )r   rY   partsvaluepartr   r   r   r)     s    
z_ScopedContext.LookupN)r   r   r    r!   r"   r   r   r   r   r   r)   r   r   r   r   r     s   	r   c             C   s$   | d krdS t | tr| S tj| S )Nnull)rE   
basestringr   r   )rz   r   r   r   	_ToString'  s
    
r   c             C   s   t | ddS )NT)quote)escape_html)rz   r   r   r   _HtmlAttrValue0  s    r   c             C   s   t j|jd| S )a  Returns an absolute URL, given the current node as a relative URL.

  Assumes that the context has a value named 'base-url'.  This is a little like
  the HTML <base> tag, but implemented with HTML generation.

  Raises:
    UndefinedVariable if 'base-url' doesn't exist
  zbase-url)r   urljoinr)   )Zrelative_urlr}   unused_argsr   r   r   _AbsUrl4  s    r   c             C   s   | S )Nr   )rz   r   r   r   r{   S  s    r{   c             C   s   t t| S )N)strr7   )r   r   r   r   r{   V  s    c             C   s   dt | ddt | f S )Nz<a href="%s">%s</a>T)r   )r   )rz   r   r   r   r{   d  s   )htmlzhtml-attr-valueZhtmltagrawsizez
url-paramszurl-param-valuer   z	plain-urlZAbsUrljsonz	js-stringc             C   s`   t |dkrd\}}n6t |dkr2d|d  }}nt |dkrH|\}}nt| dkrX|S |S dS )zFormatter to pluralize words.r    sr%   r   N)r   r   )r7   rc   )r   unused_contextr   r   pr   r   r   rH   w  s    

rH   c             C   s   || d t |  S )z5Cycle between various values on consecutive integers.r%   )r7   )r   r   r   r   r   r   rI     s    rI   c             C   s(   yt |jdS  tk
r"   dS X d S )NdebugF)boolr)   r	   )Zunused_valuer}   r   r   r   r   _IsDebugMode  s    r   c             C   s   | dkS )Nr%   r   )rz   r   r   r   r{     s    c             C   s   | dkS )Nr%   r   )rz   r   r   r   r{     s    )z	singular?zplural?zDebug?c             C   s@   t | }|d dkr td|  | d|d  | |d d fS )zSplit and validate metacharacters.

  Example: '{}' -> ('{', '}')

  This is public so the syntax highlighter and other tools can use it.
  r   r%   z&%r has an odd number of metacharactersN)r7   r   )metanr   r   r   	SplitMeta  s
    
r   c             C   sB   | |f}|t kr:tjdtj|  d tj| d t |< t | S )zReturn a (compiled) regular expression for tokenization.

  Args:
    meta_left, meta_right: e.g. '{' and '}'

  - The regular expressions are memoized.
  - This function is public so the syntax highlighter can use it.
  (z.+?))_token_re_cacherecompiler   )	meta_left
meta_rightkeyr   r   r   MakeTokenRegex  s    	r      c             C   s   | j dr| dd } ndS | dkr,t| fS | j drb| j dkrJtdfS | dd j }t|fS | dkrrtdfS tj| }|r|j \}}|rt|fS t	|fS | j drt
| d	d j fS | jd
rt
| fS dS )z0Helper function for matching certain directives.r   r%   Nzalternates withrx   r   endzif    ?)NN)NN)r6   ALTERNATES_TOKENstripOR_TOKEN	END_TOKEN_SECTION_REmatchgroupsr^   ra   PREDICATE_TOKENendswith)tokenrR   r   Zrepeatedre   r   r   r   _MatchDirective  s.    




r   c             c   s  t |}t||}xn| jdD ]^}|j|}t |dkr|d j sR|d  r|d j sh|d  r|d ||  }|jdrq t|\}}|dk	r||fV  q xt|D ]\}	}|	d dkrt|fV  q|j|st	t
||j|st	t
||||  }|jdrq|jdrr||d	d
ddj|}
|
dk	rPt|
fV  qt|\}}|dk	r|||fV  qt|fV  qW q W dS )z=Yields tokens, which are 2-tuples (TOKEN_TYPE, token_string).Tr   r   r   r%   #Nr    	
)z
.meta-leftz.meta-rightz.spacez.tabz.newline)r7   r   
splitlinesr9   isspacer6   r   	enumerateLITERAL_TOKENrc   reprr   r2   SUBSTITUTION_TOKEN)template_strr   r   ZtrimlenZtoken_relinetokensr   rd   r;   literalr   r   r   	_Tokenize  sH    






r   z{}|c             C   s   d S )Nr   )rz   r   r   r   r{   ?  s    r   c             C   s~  |pt ||}t|\}}|d
kr.td| d}	x&t| ||D ]\}
}|
tkrd|rB|j| qB|
ttfkr|j|
| |	d7 }	qB|
t	kr|j
|}|	d7 }	qB|
tkr|j| qB|
tkr|j  qB|
tkr|	d8 }	|	dk rtd||f |j  qB|
tkrB|j|}t|dkr8|dkr,td|}|g}n|d }|dd }|j|| qBW |	dkrvtd	||f |j S )a  Compile the template string, calling methods on the 'program builder'.

  Args:
    template_str: The template string.  It should not have any compilation
        options in the header -- those are parsed by FromString/FromFile

    builder: The interface of _ProgramBuilder isn't fixed.  Use at your own
        risk.

    meta: The metacharacters to use, e.g. '{}', '[]'.

    more_formatters:
        Something that can map format strings to formatter functions.  One of:
          - A plain dictionary of names -> functions  e.g. {'html': html.escape}
          - A higher-order function which takes format strings and returns
            formatter functions.  Useful for when formatters have parsed
            arguments.
          - A FunctionRegistry instance for the most control.  This allows
            formatters which takes contexts as well.

    more_predicates:
        Like more_formatters, but for predicates.

    default_formatter: The formatter to use for substitutions that are missing a
        formatter.  The 'str' formatter the "default default" -- it just tries
        to convert the context value to a string in some unspecified manner.

  Returns:
    The compiled program (obtained from the builder)

  Raises:
    The various subclasses of CompilationError.  For example, if
    default_formatter=None, and a variable is missing a formatter, then
    MissingFormatter is raised.

  This function is public so it can be used by other tools, e.g. a syntax
  checking tool run before submitting a template to source control.
  :r   z4Only format characters : and | are accepted (got %r)r   r%   zmGot too many %send%s statements.  You may have mistyped an earlier 'section' or 'repeated section' directive.Nz+This template requires explicit formatters.zGot too few %send%s statements)r   r   )r@   r   r   r   r   rN   ra   r^   rf   r   rm   r   rg   r   ri   r   r   rp   r   r9   r7   r   rZ   rq   )r   builderr   Zformat_charmore_formattersZmore_predicatesdefault_formatterr   r   Zbalance_counterrd   r   Z
block_mader   rY   rK   r   r   r   r
   =  s^    *






z^([a-zA-Z\-]+):\s*(.*)r   zformat-charzdefault-formatterzundefined-strc             C   s   d S )Nr   )rz   r   r   r   r{     s    c             C   s   t j | }t|||dS )z"Like FromFile, but takes a string.)r   _constructor)r   r   )r   r   r   rV   r   r   r   r     s    
c             C   s   d S )Nr   )rz   r   r   r   r{     s    c       	      C   s   |pt }i }x|| j }tj|}|r|jd|jd }}|j }|tkr|jdd}|j }|dkrv|j dkrvd}|||< qP qP qW |r|j rt	d| | j
 }n|| j
  }||fd	|i|S )
at  Parse a template from a file, using a simple file format.

  This is useful when you want to include template options in a data file,
  rather than in the source code.

  The format is similar to HTTP or E-mail headers.  The first lines of the file
  can specify template options, such as the metacharacters to use.  One blank
  line must separate the options from the template body.

  Example:

    default-formatter: none
    meta: {{}}
    format-char: :
    <blank line required>
    Template goes here: {{variable:html}}

  Args:
    f: A file handle to read from.  Caller is responsible for opening and
    closing it.
  r%   r   -_r   noneNzAMust be one blank line between template options and body (got %r)r   )r   readline
_OPTION_REr   grouplower_OPTION_NAMESreplacer   r   read)	rV   r   r   optionsr   r   rY   r   bodyr   r   r   r     s0    


c               @   s2   e Zd ZdZdddZdd Zdd Zd	d
 ZdS )r   aU  Represents a compiled template.

  Like many template systems, the template string is compiled into a program,
  and then it can be expanded any number of times.  For example, in a web app,
  you can compile the templates once at server startup, and use the expand()
  method at request handling time.  expand() uses the compiled representation.

  There are various options for controlling parsing -- see CompileTemplate.
  Don't go crazy with metacharacters.  {}, [], {{}} or <> should cover nearly
  any circumstance, e.g. generating HTML, CSS XML, JavaScript, C programs, text
  files, etc.
  Nc             K   s    t |fd|i|| _|| _dS )a  
    Args:
      template_str: The template string.
      undefined_str: A string to appear in the output when a variable to be
          substituted is missing.  If None, UndefinedVariable is raised.
          (Note: This is not really a compilation option, because affects
          template expansion rather than compilation.  Nonetheless we make it a
          constructor argument rather than an .expand() argument for
          simplicity.)

    It also accepts all the compile options that CompileTemplate does.
    r   N)r
   _programr   )r   r   r   r   Zcompile_optionsr   r   r   r"     s    zTemplate.__init__c             C   s"   t || j}t| jj || dS )a  Low level method to expands the template piece by piece.

    Args:
      data_dict: The JSON data dictionary.
      callback: A callback which should be called with each expanded token.

    Example: You can pass 'f.write' as the callback to write directly to a file
    handle.
    N)r   r   _Executer   rw   )r   	data_dictcallbackr}   r   r   r   render  s    
zTemplate.renderc             O   sH   |r(t |dkr|d }q,td| n|}g }| j||j dj|S )a'  Expands the template with the given data dictionary, returning a string.

    This is a small wrapper around render(), and is the most convenient
    interface.

    Args:
      The JSON data dictionary.  Like the builtin dict() constructor, it can
      take a single dictionary as a positional argument, or arbitrary keyword
      arguments.

    Returns:
      The return value could be a str() or unicode() instance, depending on the
      the type of the template string passed in, and what the types the strings
      in the dictionary are.
    r%   r   z2expand() only takes 1 positional argument (got %s)r   )r7   r   r   r[   join)r   r   kwargsr   r   r   r   r   r   +  s    
zTemplate.expandc             c   s*   g }| j ||j x|D ]
}|V  qW dS )a  Yields a list of tokens resulting from expansion.

    This may be useful for WSGI apps.  NOTE: In the current implementation, the
    entire expanded template must be stored memory.

    NOTE: This is a generator, but JavaScript doesn't have generators.
    N)r   r[   )r   r   r   r   r   r   r   tokenstreamH  s    
zTemplate.tokenstream)NN)r   r   r    r!   r"   r   r   r   r   r   r   r   r     s
   
c       	      C   s   | }|j |j}|rt|ts.tdt| t|d }|j }|jd}y>d}x4|j  t	||| ||kr|t	||| |d7 }qTW W q t
k
r   Y qX nt	|jd|| |j  dS )z{repeated section foo}zExpected a list; got %sr%   zalternates withr   rx   N)r   re   rE   listr   typer7   rw   r   r   r   r   )	r   r}   r   rl   items
last_indexru   Zalt_statementsr;   r   r   r   r`   V  s(    

r`   c             C   sH   | }|j |jr*t|j || |j  n|j  t|jd|| dS )z{section foo}rx   N)r   re   r   rw   r   )r   r}   r   rl   r   r   r   rb   y  s    
rb   c       	      C   s\   | }|j d}xH|jD ]>\\}} }}|tkr:|||| }n||}|rt||| P qW dS )z[{.predicate?}

  Here we execute the first clause that evaluates to true, and then stop.
  r   N)r)   ry   r*   r   )	r   r}   r   rl   r   rS   r?   ru   Z	do_clauser   r   r   rk     s    
rk   c             C   s  | \}}|dkr|j d}nDy|j |}W n4 tk
r^   tj \}}}td|||f Y nX x|D ]z\}	} }
y"|
tkr|	||| }n|	|}W qf tk
r    Y qf tk
r   tj \}}}td|||f |dY qfX qfW |dkrtd| || dS )z!Variable substitution, e.g. {foo}r   z%Error evaluating %r in context %r: %rz:Formatting value %r with formatter %s raised exception: %r)r#   NzEvaluating %r gave None value)r)   r   sysexc_infor   r*   KeyboardInterrupt	Exception)r   r}   r   rY   rK   r   exc_type	exc_valuer   r+   r?   r   r   r   rX     s0    rX   c             C   s   xt | D ]~\}}t|tr&|| q
y|\}}|||| W q
 tk
r   tj \}}}	td|d }
|d }| |
| |_ Y q
X q
W dS )zExecute a bunch of template statements in a ScopedContext.

  Args:
    callback: Strings are "written" to this callback function.

  This is called in a mutually recursive fashion.
  r   r   N)r   rE   r   r	   r   r   maxr   )ru   r}   r   r;   rO   r+   r   r   r   r   startr   r   r   r   r     s    	

r   c             K   s   t | f|}|j|S )zFree function to expands a template string with a data dictionary.

  This is useful for cases where you don't care about saving the result of
  compilation (similar to re.match('.*', s) vs DOT_STAR.match(s))
  )r   r   )r   Z
dictionaryr   tr   r   r   r     s    )r   r%   )Sr!   
__author____all__r   ior   r   bytesr   r   r   r   r   r   Zcgiurllibr   r   urllib.parser   r   r   r   r   r   r   r   r   r   r	   r   r   r.   r*   objectr&   r/   r0   r3   r4   r<   r@   rr   rB   r_   rj   r|   r   r   r   r   rJ   rH   rI   r   rL   r   r   r   r   ranger   r   ra   r^   r   r   r   r   r   r   r
   r   r   r   r   r   r`   rb   rk   rX   r   r   r   r   r   r   <module>   s   



!zp	
!'Dq
=\#%