;ò
"h>c           @   s&  d  Z  d k Z d k Z d k l Z l Z l Z d k Z d Z e i	 d e e f ƒ Z
 e i	 d ƒ Z h  d d <d d	 <d
 d <Z e i ƒ  Z e i	 d ƒ Z e i	 d ƒ Z e i	 d ƒ Z d f  d „  ƒ  YZ d „  Z d „  Z d „  Z d f  d „  ƒ  YZ d f  d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d  „  ƒ  YZ d! e f d" „  ƒ  YZ d# e f d$ „  ƒ  YZ d% e f d& „  ƒ  YZ  d' e f d( „  ƒ  YZ! d) „  Z" d* „  Z# e$ d+ j o' d k% Z% e% i& e# e% i' ƒ d, ƒ n d S(-   sT  ezt.py -- easy templating

ezt templates are very similar to standard HTML files.  But additionally
they contain directives sprinkled in between.  With these directives
it is possible to generate the dynamic content from the ezt templates.

These directives are enclosed in square brackets.  If you are a 
C-programmer, you might be familar with the #ifdef directives of the
C preprocessor 'cpp'.  ezt provides a similar concept for HTML.  Additionally 
EZT has a 'for' directive, which allows to iterate (repeat) certain 
subsections of the template according to sequence of data items
provided by the application.

The HTML rendering is performed by the method generate() of the Template
class.  Building template instances can either be done using external
EZT files (convention: use the suffix .ezt for such files):

    >>> template = Template("../templates/log.ezt")

or by calling the parse() method of a template instance directly with 
a EZT template string:

    >>> template = Template()
    >>> template.parse('''<html><head>
    ... <title>[title_string]</title></head>
    ... <body><h1>[title_string]</h1>
    ...    [for a_sequence] <p>[a_sequence]</p>
    ...    [end] <hr>
    ...    The [person] is [if-any state]in[else]out[end].
    ... </body>
    ... </html>
    ... ''')

The application should build a dictionary 'data' and pass it together
with the output fileobject to the templates generate method:

    >>> data = {'title_string' : "A Dummy Page",
    ...         'a_sequence' : ['list item 1', 'list item 2', 'another element'],
    ...         'person': "doctor",
    ...         'state' : None }
    >>> import sys
    >>> template.generate(sys.stdout, data)
    <html><head>
    <title>A Dummy Page</title></head>
    <body><h1>A Dummy Page</h1>
     <p>list item 1</p>
     <p>list item 2</p>
     <p>another element</p>
     <hr>
    The doctor is out.
    </body>
    </html>

Template syntax error reporting should be improved.  Currently it is 
very sparse (template line numbers would be nice):

    >>> Template().parse("[if-any where] foo [else] bar [end unexpected args]")
    Traceback (innermost last):
      File "<stdin>", line 1, in ?
      File "ezt.py", line 220, in parse
        self.program = self._parse(text)
      File "ezt.py", line 275, in _parse
        raise ArgCountSyntaxError(str(args[1:]))
    ArgCountSyntaxError: ['unexpected', 'args']
    >>> Template().parse("[if unmatched_end]foo[end]")
    Traceback (innermost last):
      File "<stdin>", line 1, in ?
      File "ezt.py", line 206, in parse
        self.program = self._parse(text)
      File "ezt.py", line 266, in _parse
        raise UnmatchedEndError()
    UnmatchedEndError


Directives
==========

 Several directives allow the use of dotted qualified names refering to objects
 or attributes of objects contained in the data dictionary given to the 
 .generate() method.

 Simple directives
 -----------------

   [QUAL_NAME]

   This directive is simply replaced by the value of identifier from the data 
   dictionary.  QUAL_NAME might be a dotted qualified name refering to some
   instance attribute of objects contained in the dats dictionary.
   Numbers are converted to string though.

   [include "filename"]  or [include QUAL_NAME]

   This directive is replaced by content of the named include file.

 Block directives
 ----------------

   [for QUAL_NAME] ... [end]
   
   The text within the [for ...] directive and the corresponding [end]
   is repeated for each element in the sequence referred to by the qualified
   name in the for directive.  Within the for block this identifiers now 
   refers to the actual item indexed by this loop iteration.

   [if-any QUAL_NAME [QUAL_NAME2 ...]] ... [else] ... [end]

   Test if any QUAL_NAME value is not None or an empty string or list.  
   The [else] clause is optional.  CAUTION: Numeric values are converted to
   string, so if QUAL_NAME refers to a numeric value 0, the then-clause is
   substituted!

   [if-index INDEX_FROM_FOR odd] ... [else] ... [end]
   [if-index INDEX_FROM_FOR even] ... [else] ... [end]
   [if-index INDEX_FROM_FOR first] ... [else] ... [end]
   [if-index INDEX_FROM_FOR last] ... [else] ... [end]
   [if-index INDEX_FROM_FOR NUMBER] ... [else] ... [end]

   These five directives work similar to [if-any], but are only useful 
   within a [for ...]-block (see above).  The odd/even directives are 
   for example useful to choose different background colors for adjacent rows 
   in a table.  Similar the first/last directives might be used to
   remove certain parts (for example "Diff to previous" doesn't make sense,
   if there is no previous).

   [is QUAL_NAME STRING] ... [else] ... [end]
   [is QUAL_NAME QUAL_NAME] ... [else] ... [end]

   The [is ...] directive is similar to the other conditional directives
   above.  But it allows to compare two value references or a value reference
   with some constant string.
 
N(   s
   StringTypes   IntTypes	   FloatTypes   (?:"(?:[^\\"]|\\.)*"|[-\w.]+)s&   \[(%s(?: +%s)*)\]|(\[\[\])|\[#[^\]]*\]s   "(?:[^\\"]|\\.)*"|[-\w.]+s   if-indexi   s   fori   s   iss   [ 	]*
\s*s   \s\s+s   %(%|[0-9]+)s   Templatec           B   s’   t  Z e d d „ Z d „  Z d „  Z d „  Z e f  d „ Z d „  Z d „  Z	 d	 „  Z
 d
 „  Z d „  Z d „  Z d „  Z d „  Z d „  Z RS(   Ni   c         C   s%   | |  _  | o |  i | ƒ n d  S(   N(   s   compress_whitespaces   selfs   fnames
   parse_file(   s   selfs   fnames   compress_whitespace(    (    s   build/generator/ezt.pys   __init__Ó   s    	c         C   s   |  i t | ƒ ƒ |  _ d S(   sH   fname -> a string object with pathname of file containg an EZT template.N(   s   selfs   _parses   _FileReaders   fnames   program(   s   selfs   fname(    (    s   build/generator/ezt.pys
   parse_fileØ   s     c         C   s7   t  | t ƒ o t | ƒ } n |  i | ƒ |  _ d S(   s¾   Parse the template specified by text_or_reader.

    The argument should be a string containing the template, or it should
    specify a subclass of ezt.Reader which can read templates.
    N(   s
   isinstances   text_or_readers   Readers   _TextReaders   selfs   _parses   program(   s   selfs   text_or_reader(    (    s   build/generator/ezt.pys   parseÝ   s     c         C   s5   t  ƒ  } | | _ h  | _ |  i |  i | | ƒ d  S(   N(   s   _contexts   ctxs   datas	   for_indexs   selfs   _executes   programs   fp(   s   selfs   fps   datas   ctx(    (    s   build/generator/ezt.pys   generateè   s    			c         C   s  t  i | i ƒ } g  } g  } | o
 g  } n xÉt t	 | ƒ ƒ D]µ} | | } | d } | d j oH | o= |  i o" t i d t i d | ƒ ƒ } n | i | ƒ qøqC | d j o | o | i d ƒ qøqC | ot i | ƒ }	 |	 d } | d j o^ t	 |	 ƒ d j o t t |	 d ƒ ƒ ‚ n | d	 d } | | } | | 3| | d	 d <qø| d
 j oÏ t	 |	 ƒ d j o t t |	 d ƒ ƒ ‚ n y | i ƒ  \ } } }	 } Wn t j
 o t ƒ  ‚ n X| | } t |  d t  i d d | ƒ ƒ }
 |
 |	 | | f f g | | )| d j o | i ƒ  qôqø| t" j oÇ t	 |	 ƒ t# | d j o t t |	 d ƒ ƒ ‚ n t$ |	 d | | ƒ |	 d <| d j o t$ |	 d | | ƒ |	 d <n' | d j o | i |	 d d ƒ n | i | t	 | ƒ |	 d t& g ƒ qø| d j oÜ |	 d d d j on |	 d d d	 !} g  } x+ |	 d D] } | i t$ | | | ƒ ƒ qZW| i* |  i+ | i, | ƒ | | ƒ ƒ qôt	 |	 ƒ d j o t t |	 ƒ ƒ ‚ n | i |  i- t$ |	 d | | ƒ | f f ƒ qø| d j oW g  } x+ |	 d D] } | i t$ | | | ƒ ƒ qW| i d t	 | ƒ | t& g ƒ qøt	 |	 ƒ d j oX g  } x' |	 D] } | i t$ | | | ƒ ƒ qƒW| i |  i. | d | d f f ƒ qø| i |  i/ t$ |	 d | | ƒ f ƒ qC qC W| o t0 ƒ  ‚ n | Sd S(   s\  text -> string object containing the HTML template.

    This is a private helper function doing the real work for method parse.
    It returns the parsed template as a 'program'.  This program is a sequence
    made out of strings or (function, argument) 2-tuples.

    Note: comment directives [# ...] are automatically dropped by _re_parse.
    i   i    s    s   
i   s   [s   elsei   iÿÿÿÿs   ends   _cmd_s   -s   _s   fors   iss   includes   "s   if-anyN(1   s	   _re_parses   splits   readers   texts   partss   programs   stacks	   for_namess   ranges   lens   is   pieces   whichs   selfs   compress_whitespaces   _re_whitespaces   subs   _re_newlines   appends   _re_argss   findalls   argss   cmds   ArgCountSyntaxErrors   strs   idxs   true_sections   pops
   IndexErrors   UnmatchedEndErrors   else_sections   getattrs   res   funcs   _block_cmdss   _block_cmd_specss   _prepare_refs	   file_argss   Nones   include_filenames   f_argss   args   extends   _parses
   read_others   _cmd_includes   _cmd_formats
   _cmd_prints   UnclosedBlocksError(   s   selfs   readers	   for_namess	   file_argss   args   programs   whichs   include_filenames   f_argss   argss   funcs   else_sections   stacks   idxs   true_sections   cmds   partss   is   piece(    (    s   build/generator/ezt.pys   _parseî   sœ     
 


"


"' 0 # (.c         C   sN   xG | D]? } t | t ƒ o | i | ƒ q | d | d | | ƒ q Wd S(   sË   This private helper function takes a 'program' sequence as created
    by the method '_parse' and executes it step by step.  strings are written
    to the file object 'fp' and functions are called.
    i    i   N(   s   programs   steps
   isinstances
   StringTypes   fps   writes   ctx(   s   selfs   programs   fps   ctxs   step(    (    s   build/generator/ezt.pys   _executeX  s      c         C   sl   t  | | ƒ } t | d ƒ o< xF n o- | i d ƒ } | o Pn | i | ƒ q) Wn | i | ƒ d  S(   Ns   readi   i @  (	   s
   _get_values   valrefs   ctxs   values   hasattrs   reads   chunks   fps   write(   s   selfs   valrefs   fps   ctxs   values   chunk(    (    s   build/generator/ezt.pys
   _cmd_printc  s     c         C   sÀ   | \ } } t | | ƒ }
 t i |
 ƒ } x t t	 | ƒ ƒ D]{ } | | }	 | d d j o
 |	 d j o@ t |	 ƒ } | t	 | ƒ j  o t | | | ƒ }	 q« d }	 n | i |	 ƒ q= Wd  S(   Ni   i   s   %s   <undef>(   s   valrefs   argss
   _get_values   ctxs   fmts	   _re_substs   splits   partss   ranges   lens   is   pieces   ints   idxs   fps   write(   s   selfs   .2s   fps   ctxs   valrefs   argss   idxs   is   partss   pieces   fmt(    (    s   build/generator/ezt.pys   _cmd_formatp  s    

c         C   sD   | \ } } t | | ƒ } |  i |  i | i | ƒ ƒ | | ƒ d  S(   N(
   s   valrefs   readers
   _get_values   ctxs   fnames   selfs   _executes   _parses
   read_others   fp(   s   selfs   .2s   fps   ctxs   valrefs   readers   fname(    (    s   build/generator/ezt.pys   _cmd_include}  s   c   	      C   s^   | \ } } } d } x) | D]! } t | | ƒ o d } Pq q W|  i	 | | | | | ƒ d S(   sD   If any value is a non-empty string or non-empty list, then T else F.i    i   N(   s   argss   valrefss	   t_sections	   f_sections   values   valrefs
   _get_values   ctxs   selfs   _do_ifs   fp(	   s   selfs   argss   fps   ctxs   valrefss   values	   t_sections   valrefs	   f_section(    (    s   build/generator/ezt.pys   _cmd_if_anyƒ  s      	c   
      C   sá   | \ \ } } } }	 | i | d \ } } | d j o | d d j } nx | d j o | d d j } nW | d j o | d j } n: | d j o | t	 | ƒ d j } n | t
 | ƒ j } |  i | | |	 | | ƒ d  S(   Ni    s   eveni   s   oddi   s   firsts   last(   s   argss   valrefs   values	   t_sections	   f_sections   ctxs	   for_indexs   lists   idxs   lens   ints   selfs   _do_ifs   fp(
   s   selfs   argss   fps   ctxs   idxs   lists   values	   t_sections   valrefs	   f_section(    (    s   build/generator/ezt.pys   _cmd_if_index  s    c   	      C   sh   | \ \ } } } } t | | ƒ } t i	 t | | ƒ ƒ t i	 | ƒ j } |  i | | | | | ƒ d  S(   N(   s   argss   left_refs	   right_refs	   t_sections	   f_sections
   _get_values   ctxs   values   strings   lowers   selfs   _do_ifs   fp(	   s   selfs   argss   fps   ctxs	   right_refs   left_refs   values	   t_sections	   f_section(    (    s   build/generator/ezt.pys   _cmd_isœ  s    'c         C   s\   | t j o | } t } n | o
 | } n | } | t j	 o |  i | | | ƒ n d  S(   N(	   s	   t_sections   Nones	   f_sections   values   sections   selfs   _executes   fps   ctx(   s   selfs   values	   t_sections	   f_sections   fps   ctxs   section(    (    s   build/generator/ezt.pys   _do_if¢  s    

c         C   s£   | \ \ }	 } }
 t |	 | ƒ } t | t ƒ o t	 ƒ  ‚ n |	 d } | d g | i | <} x3 | D]+ } |  i |
 | | ƒ | d d | d <qf W| i | =d  S(   Ni    i   (   s   argss   valrefs   unuseds   sections
   _get_values   ctxs   lists
   isinstances
   StringTypes   NeedSequenceErrors   refnames	   for_indexs   idxs   items   selfs   _executes   fp(   s   selfs   argss   fps   ctxs   idxs   lists   refnames   unuseds   items   valrefs   section(    (    s   build/generator/ezt.pys   _cmd_for­  s    
 (   s   __name__s
   __module__s   Nones   __init__s
   parse_files   parses   generates   _parses   _executes
   _cmd_prints   _cmd_formats   _cmd_includes   _cmd_if_anys   _cmd_if_indexs   _cmd_iss   _do_ifs   _cmd_for(    (    (    s   build/generator/ezt.pys   TemplateÑ   s   			j					
			c         C   s   |  o d Sn t Sd S(   sB   Return a value suitable for [if-any bool_var] usage in a template.s   yesN(   s   values   None(   s   value(    (    s   build/generator/ezt.pys   boolean¹  s     c         C   s  |  d d j o t |  d d !t f Sn |  d  d j oM y t |  d ƒ } Wn t j
 o q‡ X| t | ƒ j  o | | Sq‡ n t i |  d ƒ } | d } | d } xJ | o
 | | j o5 | d | d } | | j o | } | d =q° Pq° W|  | | f Sd S(	   sä   refname -> a string containing a dotted identifier. example:"foo.bar.bang"
  for_names -> a list of active for sequences.

  Returns a `value reference', a 3-Tupel made out of (refname, start, rest), 
  for fast access later.
  i    s   "i   iÿÿÿÿi   s   args   .N(   s   refnames   Nones   ints   idxs
   ValueErrors   lens	   file_argss   strings   splits   partss   starts   rests	   for_namess   name(   s   refnames	   for_namess	   file_argss   idxs   starts   partss   rests   name(    (    s   build/generator/ezt.pys   _prepare_refÀ  s*     

 c   	      C   s  |  \ } } } | t j o | Sn | i i | ƒ o! | i | \ } } | | } n1 | i
 i | ƒ o | i
 | } n t | ƒ ‚ xC | D]; } y t | | ƒ } Wq t j
 o t | ƒ ‚ q Xq Wt | t ƒ p t | t ƒ o t | ƒ Sn | t j o d Sn | Sd S(   s  (refname, start, rest) -> a prepared `value reference' (see above).
  ctx -> an execution context instance.

  Does a name space lookup within the template name space.  Active 
  for blocks take precedence over data dictionary members with the 
  same name.
  s    N(   s   refnames   starts   rests   Nones   ctxs	   for_indexs   has_keys   lists   idxs   obs   datas   UnknownReferences   attrs   getattrs   AttributeErrors
   isinstances   IntTypes	   FloatTypes   str(	   s   .0s   ctxs   refnames   starts   rests   attrs   idxs   lists   ob(    (    s   build/generator/ezt.pys
   _get_valueâ  s(      s   _contextc           B   s   t  Z d  Z RS(   s%   A container for the execution context(   s   __name__s
   __module__s   __doc__(    (    (    s   build/generator/ezt.pys   _context  s   s   Readerc           B   s   t  Z d  Z RS(   s9   Abstract class which allows EZT to detect Reader objects.(   s   __name__s
   __module__s   __doc__(    (    (    s   build/generator/ezt.pys   Reader
  s   s   _FileReaderc           B   s    t  Z d  Z d „  Z d „  Z RS(   s$   Reads templates from the filesystem.c         C   s1   t  | d ƒ i ƒ  |  _ t i i | ƒ |  _ d  S(   Ns   rb(	   s   opens   fnames   reads   selfs   texts   oss   paths   dirnames   _dir(   s   selfs   fname(    (    s   build/generator/ezt.pys   __init__  s    c         C   s    t  t i i |  i | ƒ ƒ Sd  S(   N(   s   _FileReaders   oss   paths   joins   selfs   _dirs   relative(   s   selfs   relative(    (    s   build/generator/ezt.pys
   read_other  s    (   s   __name__s
   __module__s   __doc__s   __init__s
   read_other(    (    (    s   build/generator/ezt.pys   _FileReader  s    	s   _TextReaderc           B   s    t  Z d  Z d „  Z d „  Z RS(   s&   'Reads' a template from provided text.c         C   s   | |  _  d  S(   N(   s   texts   self(   s   selfs   text(    (    s   build/generator/ezt.pys   __init__  s    c         C   s   t  ƒ  ‚ d  S(   N(   s   BaseUnavailableError(   s   selfs   relative(    (    s   build/generator/ezt.pys
   read_other  s    (   s   __name__s
   __module__s   __doc__s   __init__s
   read_other(    (    (    s   build/generator/ezt.pys   _TextReader  s    	s   EZTExceptionc           B   s   t  Z d  Z RS(   s#   Parent class of all EZT exceptions.(   s   __name__s
   __module__s   __doc__(    (    (    s   build/generator/ezt.pys   EZTException  s   s   ArgCountSyntaxErrorc           B   s   t  Z d  Z RS(   s6   A bracket directive got the wrong number of arguments.(   s   __name__s
   __module__s   __doc__(    (    (    s   build/generator/ezt.pys   ArgCountSyntaxError   s   s   UnknownReferencec           B   s   t  Z d  Z RS(   sG   The template references an object not contained in the data dictionary.(   s   __name__s
   __module__s   __doc__(    (    (    s   build/generator/ezt.pys   UnknownReference#  s   s   NeedSequenceErrorc           B   s   t  Z d  Z RS(   sG   The object dereferenced by the template is no sequence (tuple or list).(   s   __name__s
   __module__s   __doc__(    (    (    s   build/generator/ezt.pys   NeedSequenceError&  s   s   UnclosedBlocksErrorc           B   s   t  Z d  Z RS(   s)   This error may be simply a missing [end].(   s   __name__s
   __module__s   __doc__(    (    (    s   build/generator/ezt.pys   UnclosedBlocksError)  s   s   UnmatchedEndErrorc           B   s   t  Z d  Z RS(   s6   This error may be caused by a misspelled if directive.(   s   __name__s
   __module__s   __doc__(    (    (    s   build/generator/ezt.pys   UnmatchedEndError,  s   s   BaseUnavailableErrorc           B   s   t  Z d  Z RS(   s6   Base location is unavailable, which disables includes.(   s   __name__s
   __module__s   __doc__(    (    (    s   build/generator/ezt.pys   BaseUnavailableError/  s   c           C   s  t  i d ƒ d d t d g j p t ‚ t  i d ƒ d d t d d t d g j p t ‚ t  i d ƒ d d t d d t d g j p t ‚ t  i d ƒ d	 d t d
 d t d g j p t ‚ t  i d ƒ d d t d g j p t ‚ t  i d ƒ d d t d g j p t ‚ d  S(   Ns   [a]s    s   [a] [b]s    s   [b]s	   [a c] [b]s   [a c]s   x [a] y [b] zs   x s    y s    zs   [a "b" c "d"]s   ["a \"b[foo]" c.d f](   s	   _re_parses   splits   Nones   AssertionError(    (    (    s   build/generator/ezt.pys
   test_parse4  s    )222)c         C   s5   d  k  } d  k } d |  j } | i | d | ƒSd  S(   Ns   -vs   verbose(   s   doctests   ezts   argvs   verboses   testmod(   s   argvs   ezts   doctests   verbose(    (    s   build/generator/ezt.pys   _testA  s    s   __main__i    ((   s   __doc__s   strings   res   typess
   StringTypes   IntTypes	   FloatTypes   oss   _items   compiles	   _re_parses   _re_argss   _block_cmd_specss   keyss   _block_cmdss   _re_newlines   _re_whitespaces	   _re_substs   Templates   booleans   _prepare_refs
   _get_values   _contexts   Readers   _FileReaders   _TextReaders	   Exceptions   EZTExceptions   ArgCountSyntaxErrors   UnknownReferences   NeedSequenceErrors   UnclosedBlocksErrors   UnmatchedEndErrors   BaseUnavailableErrors
   test_parses   _tests   __name__s   syss   exits   argv(    s   _re_newlines   IntTypes   _tests   BaseUnavailableErrors   NeedSequenceErrors   booleans   UnknownReferences   Templates   Readers   _contexts
   StringTypes   _block_cmd_specss	   FloatTypes   _TextReaders   EZTExceptions   _re_whitespaces   ArgCountSyntaxErrors   res   UnclosedBlocksErrors   UnmatchedEndErrors	   _re_parses   _items
   _get_values   strings   _prepare_refs   syss   _re_argss	   _re_substs
   test_parses   _block_cmdss   _FileReaders   os(    (    s   build/generator/ezt.pys   ?†   s@   "			!è		"	$			