o
    ⯪g                     @   sb  d Z ddlZddlmZ ddlZddlZddlZddlZddl	Z	ddl
mZ ddlmZ ddlmZmZmZ ddlmZmZmZmZmZmZmZmZ ddlZejrYddlmZmZ d	ZG d
d dZe Z de!de!de!f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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(Z0G d+d, d,e(Z1G d-d. d.e(Z2G d/d0 d0e2Z3G d1d2 d2e(Z4G d3d4 d4e5Z6G d5d6 d6e#Z7G d7d8 d8e#Z8d9e!de!fd:d;Z9		dBd<e8d=e$d>ee! d?ee! de*f
d@dAZ:dS )Ca  A simple template system that compiles templates to Python code.

Basic usage looks like::

    t = template.Template("<html>{{ myvalue }}</html>")
    print(t.generate(myvalue="XXX"))

`Loader` is a class that loads templates from a root directory and caches
the compiled templates::

    loader = template.Loader("/home/btaylor")
    print(loader.load("test.html").generate(myvalue="XXX"))

We compile all templates to raw Python. Error-reporting is currently... uh,
interesting. Syntax for the templates::

    ### base.html
    <html>
      <head>
        <title>{% block title %}Default title{% end %}</title>
      </head>
      <body>
        <ul>
          {% for student in students %}
            {% block student %}
              <li>{{ escape(student.name) }}</li>
            {% end %}
          {% end %}
        </ul>
      </body>
    </html>

    ### bold.html
    {% extends "base.html" %}

    {% block title %}A bolder title{% end %}

    {% block student %}
      <li><span style="bold">{{ escape(student.name) }}</span></li>
    {% end %}

Unlike most other template systems, we do not put any restrictions on the
expressions you can include in your statements. ``if`` and ``for`` blocks get
translated exactly into Python, so you can do complex expressions like::

   {% for student in [p for p in people if p.student and p.age > 23] %}
     <li>{{ escape(student.name) }}</li>
   {% end %}

Translating directly to Python means you can apply functions to expressions
easily, like the ``escape()`` function in the examples above. You can pass
functions in to your template just like any other variable
(In a `.RequestHandler`, override `.RequestHandler.get_template_namespace`)::

   ### Python code
   def add(x, y):
      return x + y
   template.execute(add=add)

   ### The template
   {{ add(1, 2) }}

We provide the functions `escape() <.xhtml_escape>`, `.url_escape()`,
`.json_encode()`, and `.squeeze()` to all templates by default.

Typical applications do not create `Template` or `Loader` instances by
hand, but instead use the `~.RequestHandler.render` and
`~.RequestHandler.render_string` methods of
`tornado.web.RequestHandler`, which load templates automatically based
on the ``template_path`` `.Application` setting.

Variable names beginning with ``_tt_`` are reserved by the template
system and should not be used by application code.

Syntax Reference
----------------

Template expressions are surrounded by double curly braces: ``{{ ... }}``.
The contents may be any python expression, which will be escaped according
to the current autoescape setting and inserted into the output.  Other
template directives use ``{% %}``.

To comment out a section so that it is omitted from the output, surround it
with ``{# ... #}``.


To include a literal ``{{``, ``{%``, or ``{#`` in the output, escape them as
``{{!``, ``{%!``, and ``{#!``, respectively.


``{% apply *function* %}...{% end %}``
    Applies a function to the output of all template code between ``apply``
    and ``end``::

        {% apply linkify %}{{name}} said: {{message}}{% end %}

    Note that as an implementation detail apply blocks are implemented
    as nested functions and thus may interact strangely with variables
    set via ``{% set %}``, or the use of ``{% break %}`` or ``{% continue %}``
    within loops.

``{% autoescape *function* %}``
    Sets the autoescape mode for the current file.  This does not affect
    other files, even those referenced by ``{% include %}``.  Note that
    autoescaping can also be configured globally, at the `.Application`
    or `Loader`.::

        {% autoescape xhtml_escape %}
        {% autoescape None %}

``{% block *name* %}...{% end %}``
    Indicates a named, replaceable block for use with ``{% extends %}``.
    Blocks in the parent template will be replaced with the contents of
    the same-named block in a child template.::

        <!-- base.html -->
        <title>{% block title %}Default title{% end %}</title>

        <!-- mypage.html -->
        {% extends "base.html" %}
        {% block title %}My page title{% end %}

``{% comment ... %}``
    A comment which will be removed from the template output.  Note that
    there is no ``{% end %}`` tag; the comment goes from the word ``comment``
    to the closing ``%}`` tag.

``{% extends *filename* %}``
    Inherit from another template.  Templates that use ``extends`` should
    contain one or more ``block`` tags to replace content from the parent
    template.  Anything in the child template not contained in a ``block``
    tag will be ignored.  For an example, see the ``{% block %}`` tag.

``{% for *var* in *expr* %}...{% end %}``
    Same as the python ``for`` statement.  ``{% break %}`` and
    ``{% continue %}`` may be used inside the loop.

``{% from *x* import *y* %}``
    Same as the python ``import`` statement.

``{% if *condition* %}...{% elif *condition* %}...{% else %}...{% end %}``
    Conditional statement - outputs the first section whose condition is
    true.  (The ``elif`` and ``else`` sections are optional)

``{% import *module* %}``
    Same as the python ``import`` statement.

``{% include *filename* %}``
    Includes another template file.  The included file can see all the local
    variables as if it were copied directly to the point of the ``include``
    directive (the ``{% autoescape %}`` directive is an exception).
    Alternately, ``{% module Template(filename, **kwargs) %}`` may be used
    to include another template with an isolated namespace.

``{% module *expr* %}``
    Renders a `~tornado.web.UIModule`.  The output of the ``UIModule`` is
    not escaped::

        {% module Template("foo.html", arg=42) %}

    ``UIModules`` are a feature of the `tornado.web.RequestHandler`
    class (and specifically its ``render`` method) and will not work
    when the template system is used on its own in other contexts.

``{% raw *expr* %}``
    Outputs the result of the given expression without autoescaping.

``{% set *x* = *y* %}``
    Sets a local variable.

``{% try %}...{% except %}...{% else %}...{% finally %}...{% end %}``
    Same as the python ``try`` statement.

``{% while *condition* %}... {% end %}``
    Same as the python ``while`` statement.  ``{% break %}`` and
    ``{% continue %}`` may be used inside the loop.

``{% whitespace *mode* %}``
    Sets the whitespace mode for the remainder of the current file
    (or until the next ``{% whitespace %}`` directive). See
    `filter_whitespace` for available options. New in Tornado 4.3.
    N)StringIO)escape)app_log)
ObjectDictexec_inunicode_type)AnyUnionCallableListDictIterableOptionalTextIO)TupleContextManagerxhtml_escapec                   @   s   e Zd ZdS )_UnsetMarkerN)__name__
__module____qualname__ r   r   L/var/www/html/chatdoc2/venv/lib/python3.10/site-packages/tornado/template.pyr      s    r   modetextreturnc                 C   sV   | dkr|S | dkrt dd|}t dd|}|S | dkr%t dd|S td	|  )
a  Transform whitespace in ``text`` according to ``mode``.

    Available modes are:

    * ``all``: Return all whitespace unmodified.
    * ``single``: Collapse consecutive whitespace with a single whitespace
      character, preserving newlines.
    * ``oneline``: Collapse all runs of whitespace into a single space
      character, removing all newlines in the process.

    .. versionadded:: 4.3
    allsinglez([\t ]+) z
(\s*\n\s*)
onelinez(\s+)zinvalid whitespace mode %s)resub	Exception)r   r   r   r   r   filter_whitespace   s   r$   c                   @   s   e Zd ZdZddeedfdeeef deded dee	e
f d	eeee
f  d
ee ddfddZdedefddZded defddZded ded fddZdS )TemplatezA compiled template.

    We compile into Python from the given template_string. You can generate
    the template from variables with generate().
    z<string>Ntemplate_stringnameloader
BaseLoadercompress_whitespace
autoescape
whitespacer   c           	      C   sH  t || _|tur|durtd|rdnd}|du r4|r%|jr%|j}n|ds/|dr2d}nd}|dus:J t|d t|t	sH|| _
n
|rO|j
| _
nt| _
|rW|jni | _t|t ||}t| t|| | _| || _|| _ztt | jd| jd	d
 ddd| _W dS  ty   t| j }td| j|  w )a  Construct a Template.

        :arg str template_string: the contents of the template file.
        :arg str name: the filename from which the template was loaded
            (used for error message).
        :arg tornado.template.BaseLoader loader: the `~tornado.template.BaseLoader` responsible
            for this template, used to resolve ``{% include %}`` and ``{% extend %}`` directives.
        :arg bool compress_whitespace: Deprecated since Tornado 4.3.
            Equivalent to ``whitespace="single"`` if true and
            ``whitespace="all"`` if false.
        :arg str autoescape: The name of a function in the template
            namespace, or ``None`` to disable escaping by default.
        :arg str whitespace: A string specifying treatment of whitespace;
            see `filter_whitespace` for options.

        .. versionchanged:: 4.3
           Added ``whitespace`` parameter; deprecated ``compress_whitespace``.
        Nz2cannot set both whitespace and compress_whitespacer   r   z.htmlz.js z%s.generated.py._execT)dont_inheritz%s code:
%s)r   
native_strr'   _UNSETr#   r,   endswithr$   
isinstancer   r+   _DEFAULT_AUTOESCAPE	namespace_TemplateReader_File_parsefile_generate_pythoncoder(   compile
to_unicodereplacecompiled_format_coderstripr   error)	selfr&   r'   r(   r*   r+   r,   readerformatted_coder   r   r   __init__  sF   




zTemplate.__init__kwargsc                    s   t jt jt jt jt jt jtt jtt	f j
ddt fdddd}| j || t j| ttg t	f |d }t  | S )z0Generate this template with the given arguments.r.   r/   c                    s    j S N)r=   r'   rE   r   r   <lambda>`  s    z#Template.generate.<locals>.<lambda>)
get_source)r   r   
url_escapejson_encodesqueezelinkifydatetime_tt_utf8_tt_string_typesr   
__loader___tt_execute)r   r   rO   rP   rQ   rR   rS   utf8r   bytesr'   r@   r   updater7   r   rA   typingcastr
   	linecache
clearcache)rE   rI   r7   executer   rL   r   generateQ  s$   
zTemplate.generatec                 C   sr   t  }z0i }| |}|  |D ]}||| qt||||d j}|d | | W |  S |  w Nr   )	r   _get_ancestorsreversefind_named_blocks_CodeWritertemplater`   getvalueclose)rE   r(   buffernamed_blocks	ancestorsancestorwriterr   r   r   r<   l  s   
zTemplate._generate_pythonr9   c                 C   sR   | j g}| j jjD ]}t|tr&|std||j| j}||	| q	|S )Nz1{% extends %} block found, but no template loader)
r;   bodychunksr5   _ExtendsBlock
ParseErrorloadr'   extendrb   )rE   r(   rk   chunkrf   r   r   r   rb   {  s   
zTemplate._get_ancestors)r   r   r   __doc__r3   r	   strrY   r   boolr   rH   r   r`   r<   r   rb   r   r   r   r   r%      s2    


Kr%   c                	   @   s   e Zd ZdZeddfdedeeeef  dee ddfddZ	dd	d
Z
ddedee defddZddedee defddZdedefddZdS )r)   zBase class for template loaders.

    You must use a template loader to use template constructs like
    ``{% extends %}`` and ``{% include %}``. The loader caches all
    templates after they are loaded the first time.
    Nr+   r7   r,   r   c                 C   s*   || _ |pi | _|| _i | _t | _dS )a  Construct a template loader.

        :arg str autoescape: The name of a function in the template
            namespace, such as "xhtml_escape", or ``None`` to disable
            autoescaping by default.
        :arg dict namespace: A dictionary to be added to the default template
            namespace, or ``None``.
        :arg str whitespace: A string specifying default behavior for
            whitespace in templates; see `filter_whitespace` for options.
            Default is "single" for files ending in ".html" and ".js" and
            "all" for other files.

        .. versionchanged:: 4.3
           Added ``whitespace`` parameter.
        N)r+   r7   r,   	templates	threadingRLocklock)rE   r+   r7   r,   r   r   r   rH     s
   
zBaseLoader.__init__c                 C   s2   | j  i | _W d   dS 1 sw   Y  dS )z'Resets the cache of compiled templates.N)r{   rx   rL   r   r   r   reset  s   "zBaseLoader.resetr'   parent_pathc                 C      t  )z@Converts a possibly-relative path to absolute (used internally).NotImplementedErrorrE   r'   r}   r   r   r   resolve_path  s   zBaseLoader.resolve_pathc                 C   s\   | j ||d}| j || jvr| || j|< | j| W  d   S 1 s'w   Y  dS )zLoads a template.)r}   N)r   r{   rx   _create_templater   r   r   r   rr     s   
$zBaseLoader.loadc                 C   r~   rJ   r   rE   r'   r   r   r   r        zBaseLoader._create_template)r   NrJ   )r   r   r   ru   r6   rv   r   r   r   rH   r|   r   r%   rr   r   r   r   r   r   r)     s$    	

 r)   c                       s\   e Zd ZdZdededdf fddZdded	ee defd
dZdede	fddZ
  ZS )Loaderz:A template loader that loads from a single root directory.root_directoryrI   r   Nc                    s$   t  jdi | tj|| _d S Nr   )superrH   ospathabspathroot)rE   r   rI   	__class__r   r   rH     s   zLoader.__init__r'   r}   c                 C   s   |r?| ds?| ds?| ds?tj| j|}tjtj|}tjtj||}| | jr?|t| jd d  }|S )N</   )
startswithr   r   joinr   dirnamer   len)rE   r'   r}   current_pathfile_dirrelative_pathr   r   r   r     s   zLoader.resolve_pathc                 C   sT   t j| j|}t|d}t| || d}|W  d    S 1 s#w   Y  d S )Nrbr'   r(   )r   r   r   r   openr%   read)rE   r'   r   frf   r   r   r   r     s
   $zLoader._create_templaterJ   )r   r   r   ru   rv   r   rH   r   r   r%   r   __classcell__r   r   r   r   r     s
    r   c                       sd   e Zd ZdZdeeef deddf fddZdded	ee defd
dZ	dede
fddZ  ZS )
DictLoaderz/A template loader that loads from a dictionary.dictrI   r   Nc                    s   t  jdi | || _d S r   )r   rH   r   )rE   r   rI   r   r   r   rH     s   
zDictLoader.__init__r'   r}   c                 C   sB   |r| ds| ds| dst|}tt||}|S )Nr   r   )r   	posixpathr   normpathr   )rE   r'   r}   r   r   r   r   r     s   
zDictLoader.resolve_pathc                 C   s   t | j| || dS )Nr   )r%   r   r   r   r   r   r        zDictLoader._create_templaterJ   )r   r   r   ru   r   rv   r   rH   r   r   r%   r   r   r   r   r   r   r     s
    "r   c                   @   sJ   e Zd Zded  fddZdddZd	ee d
ee	df ddfddZ
dS )_Noder   c                 C   s   dS r   r   rL   r   r   r   
each_child     z_Node.each_childrm   re   Nc                 C   r~   rJ   r   rE   rm   r   r   r   r`     r   z_Node.generater(   rj   _NamedBlockc                 C   s   |   D ]}||| qd S rJ   )r   rd   )rE   r(   rj   childr   r   r   rd     s   z_Node.find_named_blocksrm   re   r   N)r   r   r   r   r   r`   r   r)   r   rv   rd   r   r   r   r   r     s    

r   c                   @   s>   e Zd ZdeddddfddZdd
dZded fddZdS )r9   rf   rn   
_ChunkListr   Nc                 C   s   || _ || _d| _d S ra   )rf   rn   line)rE   rf   rn   r   r   r   rH        
z_File.__init__rm   re   c                 C   sr   | d| j | $ | d| j | d| j | j| | d| j W d    d S 1 s2w   Y  d S )Nzdef _tt_execute():_tt_buffer = []_tt_append = _tt_buffer.append$return _tt_utf8('').join(_tt_buffer))
write_liner   indentrn   r`   r   r   r   r   r`     s   
"z_File.generater   c                 C      | j fS rJ   rn   rL   r   r   r   r        z_File.each_childr   )r   r   r   r%   rH   r`   r   r   r   r   r   r   r9     s    
r9   c                   @   s>   e Zd Zdee ddfddZddd	Zded
 fddZdS )r   ro   r   Nc                 C   
   || _ d S rJ   ro   )rE   ro   r   r   r   rH        
z_ChunkList.__init__rm   re   c                 C   s   | j D ]}|| qd S rJ   )ro   r`   )rE   rm   rt   r   r   r   r`     s   
z_ChunkList.generater   c                 C      | j S rJ   r   rL   r   r   r   r     r   z_ChunkList.each_childr   )	r   r   r   r   r   rH   r`   r   r   r   r   r   r   r     s    
r   c                
   @   sh   e Zd Zdededededdf
ddZded	 fd
dZ	dddZ
dee deed f ddfddZdS )r   r'   rn   rf   r   r   Nc                 C   s   || _ || _|| _|| _d S rJ   )r'   rn   rf   r   )rE   r'   rn   rf   r   r   r   r   rH   $  s   
z_NamedBlock.__init__r   c                 C   r   rJ   r   rL   r   r   r   r   *  r   z_NamedBlock.each_childrm   re   c                 C   sN   |j | j }||j| j |j| W d    d S 1 s w   Y  d S rJ   )rj   r'   includerf   r   rn   r`   )rE   rm   blockr   r   r   r`   -  s   "z_NamedBlock.generater(   rj   c                 C   s   | || j < t| || d S rJ   )r'   r   rd   )rE   r(   rj   r   r   r   rd   2  s   
z_NamedBlock.find_named_blocksr   )r   r   r   rv   r   r%   intrH   r   r   r`   r   r)   r   rd   r   r   r   r   r   #  s    

r   c                   @   s   e Zd ZdeddfddZdS )rp   r'   r   Nc                 C   r   rJ   rK   r   r   r   r   rH   :  r   z_ExtendsBlock.__init__)r   r   r   rv   rH   r   r   r   r   rp   9  s    rp   c                   @   sR   e Zd ZdedddeddfddZd	ee d
eee	f ddfddZ
dddZdS )_IncludeBlockr'   rF   r8   r   r   Nc                 C   s   || _ |j | _|| _d S rJ   )r'   template_namer   )rE   r'   rF   r   r   r   r   rH   ?  s   
z_IncludeBlock.__init__r(   rj   c                 C   s.   |d usJ | | j| j}|j|| d S rJ   )rr   r'   r   r;   rd   )rE   r(   rj   includedr   r   r   rd   D  s   z_IncludeBlock.find_named_blocksrm   re   c                 C   sb   |j d usJ |j | j| j}||| j |jj| W d    d S 1 s*w   Y  d S rJ   )	r(   rr   r'   r   r   r   r;   rn   r`   )rE   rm   r   r   r   r   r`   K  s
   "z_IncludeBlock.generater   )r   r   r   rv   r   rH   r   r)   r   r   rd   r`   r   r   r   r   r   >  s    

r   c                   @   sB   e Zd ZdedededdfddZded fd	d
ZdddZ	dS )_ApplyBlockmethodr   rn   r   Nc                 C      || _ || _|| _d S rJ   )r   r   rn   )rE   r   r   rn   r   r   r   rH   S  r   z_ApplyBlock.__init__r   c                 C   r   rJ   r   rL   r   r   r   r   X  r   z_ApplyBlock.each_childrm   re   c                 C   s   d|j  }| j d7  _ |d| | j | # |d| j |d| j | j| |d| j W d    n1 s?w   Y  |d| j|f | j d S )Nz_tt_apply%dr   z	def %s():r   r   r   z_tt_append(_tt_utf8(%s(%s()))))apply_counterr   r   r   rn   r`   r   )rE   rm   method_namer   r   r   r`   [  s   

z_ApplyBlock.generater   
r   r   r   rv   r   r   rH   r   r   r`   r   r   r   r   r   R      r   c                   @   sB   e Zd ZdedededdfddZdee fdd	ZdddZ	dS )_ControlBlock	statementr   rn   r   Nc                 C   r   rJ   )r   r   rn   )rE   r   r   rn   r   r   r   rH   j  r   z_ControlBlock.__init__c                 C   r   rJ   r   rL   r   r   r   r   o  r   z_ControlBlock.each_childrm   re   c                 C   s\   | d| j | j |  | j| | d| j W d    d S 1 s'w   Y  d S )N%s:pass)r   r   r   r   rn   r`   r   r   r   r   r`   r  s
   
"z_ControlBlock.generater   r   r   r   r   r   r   i  r   r   c                   @   ,   e Zd ZdededdfddZdd	d
ZdS )_IntermediateControlBlockr   r   r   Nc                 C      || _ || _d S rJ   r   r   rE   r   r   r   r   r   rH   {     
z"_IntermediateControlBlock.__init__rm   re   c                 C   s0   | d| j | d| j | j| d  d S )Nr   r   r   )r   r   r   indent_sizer   r   r   r   r`     s   "z"_IntermediateControlBlock.generater   r   r   r   rv   r   rH   r`   r   r   r   r   r   z      r   c                   @   r   )
_Statementr   r   r   Nc                 C   r   rJ   r   r   r   r   r   rH     r   z_Statement.__init__rm   re   c                 C   s   | | j| j d S rJ   )r   r   r   r   r   r   r   r`     r   z_Statement.generater   r   r   r   r   r   r     r   r   c                	   @   s2   e Zd ZddedededdfddZdddZdS )_ExpressionF
expressionr   rawr   Nc                 C   r   rJ   )r   r   r   )rE   r   r   r   r   r   r   rH     r   z_Expression.__init__rm   re   c                 C   sj   | d| j | j | d| j | d| j | js,|jjd ur,| d|jj | j | d| j d S )Nz_tt_tmp = %szEif isinstance(_tt_tmp, _tt_string_types): _tt_tmp = _tt_utf8(_tt_tmp)z&else: _tt_tmp = _tt_utf8(str(_tt_tmp))z_tt_tmp = _tt_utf8(%s(_tt_tmp))z_tt_append(_tt_tmp))r   r   r   r   current_templater+   r   r   r   r   r`     s   
z_Expression.generate)Fr   )r   r   r   rv   r   rw   rH   r`   r   r   r   r   r     s    r   c                       s*   e Zd Zdededdf fddZ  ZS )_Moduler   r   r   Nc                    s   t  jd| |dd d S )Nz_tt_modules.Tr   )r   rH   )rE   r   r   r   r   r   rH     s   z_Module.__init__)r   r   r   rv   r   rH   r   r   r   r   r   r     s    "r   c                   @   s0   e Zd ZdedededdfddZdd
dZdS )_Textvaluer   r,   r   Nc                 C   r   rJ   )r   r   r,   )rE   r   r   r,   r   r   r   rH     r   z_Text.__init__rm   re   c                 C   s>   | j }d|vrt| j|}|r|dt| | j d S d S )Nz<pre>z_tt_append(%r))r   r$   r,   r   r   rX   r   )rE   rm   r   r   r   r   r`     s   z_Text.generater   r   r   r   r   r   r     s    r   c                	   @   s@   e Zd ZdZ	ddedee deddfdd	Zdefd
dZdS )rq   zRaised for template syntax errors.

    ``ParseError`` instances have ``filename`` and ``lineno`` attributes
    indicating the position of the error.

    .. versionchanged:: 4.3
       Added ``filename`` and ``lineno`` attributes.
    Nr   messagefilenamelinenor   c                 C   r   rJ   r   r   r   )rE   r   r   r   r   r   r   rH     s   
zParseError.__init__c                 C   s   d| j | j| jf S )Nz%s at %s:%dr   rL   r   r   r   __str__  r   zParseError.__str__ra   )	r   r   r   ru   rv   r   r   rH   r   r   r   r   r   rq     s    

	rq   c                
   @   s   e Zd Zdedeeef dee de	ddf
ddZ
defd	d
ZdddZde	deddfddZ	ddededee ddfddZdS )re   r;   rj   r(   r   r   Nc                 C   s.   || _ || _|| _|| _d| _g | _d| _d S ra   )r;   rj   r(   r   r   include_stack_indent)rE   r;   rj   r(   r   r   r   r   rH     s   
z_CodeWriter.__init__c                 C   r   rJ   r   rL   r   r   r   r     r   z_CodeWriter.indent_sizer   c                    s   G  fdddt }| S )Nc                       0   e Zd Zd	 fddZdeddf fddZdS )
z$_CodeWriter.indent.<locals>.Indenterr   re   c                    s     j d7  _  S )Nr   r   r/   rL   r   r   	__enter__  s   z._CodeWriter.indent.<locals>.Indenter.__enter__argsNc                    s     j dksJ   j d8  _ d S )Nr   r   r   r/   r   rL   r   r   __exit__  s   z-_CodeWriter.indent.<locals>.Indenter.__exit__r   re   r   r   r   r   r   r   r   rL   r   r   Indenter  s    r   )object)rE   r   r   rL   r   r     s   	z_CodeWriter.indentrf   r   c                    s2    j  j|f | _G  fdddt}| S )Nc                       r   )
z,_CodeWriter.include.<locals>.IncludeTemplater   re   c                    s    S rJ   r   r   rL   r   r   r     r   z6_CodeWriter.include.<locals>.IncludeTemplate.__enter__r   Nc                    s    j  d  _d S ra   )r   popr   r   rL   r   r   r     r   z5_CodeWriter.include.<locals>.IncludeTemplate.__exit__r   r   r   rL   r   r   IncludeTemplate  s    r   )r   appendr   r   )rE   rf   r   r   r   rL   r   r     s   z_CodeWriter.includeline_numberr   c                 C   sh   |d u r| j }d| jj|f }| jr%dd | jD }|ddt| 7 }td| | | | jd d S )Nz	  # %s:%dc                 S   s   g | ]\}}d |j |f qS )z%s:%drK   ).0tmplr   r   r   r   
<listcomp>  s    z*_CodeWriter.write_line.<locals>.<listcomp>z	 (via %s)z, z    )r;   )r   r   r'   r   r   reversedprintr;   )rE   r   r   r   line_commentrk   r   r   r   r     s   z_CodeWriter.write_line)r   r   rJ   )r   r   r   r   r   rv   r   r   r)   r%   rH   r   r   r   r   r   r   r   r   r   re     s2    


re   c                	   @   s   e Zd ZdedededdfddZdd	ed
edee defddZddee defddZdefddZ	defddZ
deeef defddZdefddZdeddfddZdS )r8   r'   r   r,   r   Nc                 C   s"   || _ || _|| _d| _d| _d S )Nr   r   )r'   r   r,   r   pos)rE   r'   r   r,   r   r   r   rH     s
   
z_TemplateReader.__init__r   needlestartendc                 C   sn   |dksJ || j }||7 }|d u r| j||}n||7 }||ks%J | j|||}|dkr5||8 }|S )Nr   )r   r   find)rE   r   r   r   r   indexr   r   r   r     s   z_TemplateReader.findcountc                 C   sX   |d u rt | j| j }| j| }|  j| jd| j|7  _| j| j| }|| _|S )Nr   )r   r   r   r   r  )rE   r  newpossr   r   r   consume#  s   
z_TemplateReader.consumec                 C   s   t | j| j S rJ   )r   r   r   rL   r   r   r   	remaining,     z_TemplateReader.remainingc                 C   s   |   S rJ   )r  rL   r   r   r   __len__/  r   z_TemplateReader.__len__keyc                 C   s   t |tr0t| }||\}}}|d u r| j}n|| j7 }|d ur'|| j7 }| jt||| S |dk r9| j| S | j| j|  S ra   )r5   slicer   indicesr   r   )rE   r  sizer   stopstepr   r   r   __getitem__2  s   



z_TemplateReader.__getitem__c                 C   s   | j | jd  S rJ   )r   r   rL   r   r   r   r   B  r  z_TemplateReader.__str__msgc                 C   s   t || j| jrJ   )rq   r'   r   )rE   r  r   r   r   raise_parse_errorE  r  z!_TemplateReader.raise_parse_error)r   NrJ   )r   r   r   rv   rH   r   r   r   r  r  r  r	   r	  r  r   r  r   r   r   r   r8     s     	r8   r=   c                    s<   |   }dttt|d   d fddt|D S )Nz%%%dd  %%s
r   r-   c                    s    g | ]\}} |d  |f qS )r   r   )r   ir   formatr   r   r   L  s     z _format_code.<locals>.<listcomp>)
splitlinesr   reprr   	enumerate)r=   linesr   r  r   rB   I  s   rB   rF   rf   in_blockin_loopc                 C   s2  t g }	 d}	 | d|}|dks|d |  kr3|r#| d|  |jt|  | j| j	 |S | |d  dvr@|d7 }q|d |  k r]| |d  dkr]| |d  dkr]|d7 }q	 |dkrs| |}|jt|| j| j	 | d}| j}|  r| d d	kr| d |jt||| j	 q|d
kr| d}	|	dkr| d | |	
 }
| d q|dkr| d}	|	dkr| d | |	
 }
| d |
s| d |jt|
| q|dksJ || d}	|	dkr| d | |	
 }
| d |
s| d |
d\}}}|
 }tg dtdgtdgtdgd}||}|d ur\|sD| d||f  ||vrR| d||f  |jt|
| q|dkrk|si| d |S |dv r|dkrvq|d kr|
d!
d"}|s| d# t|}n|d$v r|s| d% t|
|}nl|d&kr|
d!
d"}|s| d' t|| |}nP|d(kr|s| d) t||}n=|d*kr|
 }|d+krd }||_q|d,kr|
 }t|d- || _	q|d.krt||dd/}n
|d0krt||}|j| q|d1v rr|d2v r(t| |||}n|d3kr5t| ||d }nt| |||}|d3krP|sI| d4 t|||}n|d5kre|s]| d6 t||||}nt|
||}|j| q|d7v r|s| d|td8d9gf  |jt|
| q| d:|  q);NTr   {r   r   z Missing {%% end %%} block for %s)r  %#   !z{#z#}zMissing end comment #}z{{z}}zMissing end expression }}zEmpty expressionz{%z%}zMissing end block %}zEmpty block tag ({% %})r   )ifforwhiletryr  r"  )elseelifexceptfinallyz%s outside %s blockz'%s block cannot be attached to %s blockr   zExtra {% end %} block)
extendsr   setimportfromcommentr+   r,   r   moduler+  r'  "'zextends missing file path)r)  r*  zimport missing statementr   zinclude missing file pathr(  zset missing statementr+   Noner,   r-   r   r   r,  )applyr   r"  r  r   r!  )r   r!  r0  zapply missing method namer   zblock missing name)breakcontinuer   r!  zunknown operator: %r)r   r   r  r  ro   r   r   r  r   r,   stripr   	partitionr(  getr   rp   r   r   r+   r$   r   r:   r   r   r   )rF   rf   r  r  rn   curlyconsstart_bracer   r   contentsoperatorspacesuffixintermediate_blocksallowed_parentsr   fnr   
block_bodyr   r   r   r:   O  s"  















































 r:   )NN);ru   rS   ior   r]   os.pathr   r   r!   ry   tornador   tornado.logr   tornado.utilr   r   r   r[   r   r	   r
   r   r   r   r   r   TYPE_CHECKINGr   r   r6   r   r3   rv   r$   r   r%   r)   r   r   r   r9   r   r   rp   r   r   r   r   r   r   r   r   r#   rq   re   r8   rB   r:   r   r   r   r   <module>   sn    8( =	:<	