
}cAc           @   s  d  Z  y d d l Z Wn d d l Z n Xd d l Z d d l Z d d l Z d d l Z d d l Z d d l	 Z	 d d l
 Z
 d d l Z d d l Z e j Z y d d l m Z d Z Wn* e k
 r d Z d f  d     YZ n Xd d l Z d Z d	 Z d Z d
 Z d Z d Z d Z d Z d Z d Z d Z d Z d Z d Z  d Z! d Z" d Z# d Z$ e	 j% d  Z& e	 j% d  Z' e	 j% 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& f  d'     YZ. d( e/ f d)     YZ0 i d d* 6d d+ 6d d, 6d d- 6d d. 6d d/ 6d d0 6d d1 6d d2 6d d3 6d d4 6d d5 6d d6 6Z1 d7 e. e j2 f d8     YZ3 d9 e. e j4 j5 j6 e j4 j5 j7 e f d:     YZ8 d; d<  Z9 d=   Z: d S(>   s   simpleTAL Interpreter

		Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/)
		All rights reserved.
		
		Redistribution and use in source and binary forms, with or without
		modification, are permitted provided that the following conditions
		are met:
		1. Redistributions of source code must retain the above copyright
		   notice, this list of conditions and the following disclaimer.
		2. Redistributions in binary form must reproduce the above copyright
		   notice, this list of conditions and the following disclaimer in the
		   documentation and/or other materials provided with the distribution.
		3. The name of the author may not be used to endorse or promote products
		   derived from this software without specific prior written permission.
		
		THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
		IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
		OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
		IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
		INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
		NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
		DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
		THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
		(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
		THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
		
		If you make any bug fixes or feature enhancements please let me know!
		
		
		The classes in this module implement the TAL language, expanding
		both XML and HTML templates.
		
		Module Dependencies: logging, simpleTALES, simpleTALTemplates
iN(   t   LexicalHandleri   i    R    c           B   s   e  Z RS(    (   t   __name__t
   __module__(    (    (    s   lib/simpletal/simpleTAL.pyR    5   s   s$   http://xml.zope.org/namespaces/metals"   http://xml.zope.org/namespaces/tali   i   i   i   i   i   i   i	   i
   i   i   i   i   i   i   s   [a-zA-Z_][a-zA-Z0-9_]*s&   ^<[^\s/>]+(?:\s*[^=>]+="[^">]+")*\s*/>s   (?:.*?)(&.*?;)t   TemplateInterpreterc           B   s   e  Z d    Z d d  Z d   Z d   Z d   Z d   Z d d  Z d   Z	 d	   Z
 d
   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z RS(   c         C   s
  g  |  _  d  |  _ d  |  _ d |  _ i  |  _ i  |  _ |  j |  j t <|  j	 |  j t
 <|  j |  j t <|  j |  j t <|  j |  j t <|  j |  j t <|  j |  j t <|  j |  j t <|  j |  j t <|  j |  j t <|  j |  j t <|  j |  j t <|  j |  j t  <d  S(   Ni    (!   t   programStackt   Nonet   commandListt   symbolTablet   escapeAttributest   slotParameterst   commandHandlert	   cmdDefinet
   TAL_DEFINEt   cmdConditiont   TAL_CONDITIONt	   cmdRepeatt
   TAL_REPEATt
   cmdContentt   TAL_CONTENTt   cmdAttributest   TAL_ATTRIBUTESt
   cmdOmitTagt   TAL_OMITTAGt   cmdStartScopet   TAL_START_SCOPEt	   cmdOutputt
   TAL_OUTPUTt   cmdOutputStartTagt   TAL_STARTTAGt   cmdEndTagEndScopet   TAL_ENDTAG_ENDSCOPEt   cmdUseMacrot   METAL_USE_MACROt   cmdDefineSlott   METAL_DEFINE_SLOTt   cmdNoOpt   TAL_NOOP(   t   self(    (    s   lib/simpletal/simpleTAL.pyt   __init__h   s&    						i    c         C   s   | \ } } d g } | j  |  x | D]{ } | j  d  | j  | d  | j  d  |  j r | j  t j | d d d  n | j  | d  | j  d  q) W| r | j  d  n | j  d	  d
 j |  S(   sy    This returns a tag as text.
			If self.escapeAttributes is true then the value of the attributes will be 
			escaped.
		t   <t    i    s   ="i   t   quotet   "s    />t   >t    (   t   appendR   t   cgit   escapet   join(   R%   t   .1t   singletonFlagt   tagt   attst   resultt   att(    (    s   lib/simpletal/simpleTAL.pyt	   tagAsText}   s    			#c         C   s   | |  _  | |  _ d  S(   N(   t   contextt   file(   R%   R8   t
   outputFile(    (    s   lib/simpletal/simpleTAL.pyt
   initialise   s    	c         C   s   g  |  _  d |  _ d  |  _ d  |  _ d |  _ g  |  _ g  |  _ g  |  _ i  |  _	 d  |  _
 d |  _ d  |  _ d  |  _ d |  _ |  j |  _	 d  S(   Ni    i   (   t
   scopeStackt   programCounterR   t   movePCForwardt
   movePCBackt	   outputTagt   originalAttributest   currentAttributest   repeatAttributesCopyt   currentSlotst   repeatVariablet   repeatIndext   repeatSequencet
   tagContentt   localVarsDefinedR	   (   R%   (    (    s   lib/simpletal/simpleTAL.pyt
   cleanState   s    														c         C   s|   |  j  j   \ } |  _ |  _ | \ |  _ |  _ |  _ |  _ |  _ |  _	 |  _
 |  _ |  _ |  _ |  _ |  _ |  _ |  _ d  S(   N(   R   t   popR   R   R=   R<   R	   RD   R>   R?   R@   RA   RB   RE   RF   RG   RH   RI   (   R%   t   vars(    (    s   lib/simpletal/simpleTAL.pyt
   popProgram   s    c         C   s}   |  j  |  j |  j |  j |  j |  j |  j |  j |  j |  j	 |  j
 |  j |  j |  j f } |  j j | |  j |  j f  d  S(   N(   R=   R<   R	   RD   R>   R?   R@   RA   RB   RE   RF   RG   RH   RI   R   R-   R   R   (   R%   RL   (    (    s   lib/simpletal/simpleTAL.pyt   pushProgram   s    c         C   s   |  j  } | |  _  |  j   | j   \ |  _ |  _ } |  _ |  j } x@ |  j | k  r | |  j } |  j | d | d | d  qI W| |  _  d  S(   Ni    i   (   R   RJ   t
   getProgramR   R=   R   R
   (   R%   t   templateR   t   oldStatet   programLengtht   cmndListt   cmnd(    (    s   lib/simpletal/simpleTAL.pyt   execute   s    		
!	$c         C   s   d } xz | D]r \ } } } |  j  j | |  j  } | rl | sV d } |  j  j   n  |  j  j | |  q |  j  j | |  q W| |  _ |  j d 7_ d S(   sz    args: [(isLocalFlag (Y/n), variableName, variablePath),...]
				Define variables in either the local or global context
		i    i   N(   R8   t   evaluateRA   t
   pushLocalst   setLocalt	   addGlobalRI   R=   (   R%   t   commandt   argst   foundLocalst   isLocalt   varNamet   varPathR5   (    (    s   lib/simpletal/simpleTAL.pyR      s    	c         C   s   |  j  j | d |  j  } d } | d k r7 d } n> | sF d } n  y% t |  } | d k rj d } n  Wn n X| r d |  _ d |  _ |  j | d |  _ d S|  j d 7_ d S(   sq    args: expression, endTagSymbol
				Conditionally continues with execution of all content contained
				by it.
		i    i   N(	   R8   RV   RA   R   t   lenR@   RH   R   R=   (   R%   RZ   R[   R5   t   conditionFalset   temp(    (    s   lib/simpletal/simpleTAL.pyR      s$    	 	 		c         C   sU  |  j  d k	 r+|  j |  j k r9 t j |  j  |  _ n  d |  _ d |  _ d |  _ |  j d 7_ |  j t	 |  j
  k r d |  _  |  j j | d  |  j j   d |  _ d |  _ d |  _ |  j | d |  _ |  j j   |  _ d S|  j j | d |  j
 |  j  |  j  j   |  j d 7_ d S|  j j | d |  j  } | d k	 ru| t j k ru|  j d 7_ d Sy t	 |  } Wn d } n X| d k s| rd |  _ |  j | d |  _ d S| |  _
 |  j |  _ t j |  j
  |  _  |  j j | d |  j  |  j
 |  j  |  j j |  j  t j |  j  |  _ |  j d 7_ d S(   sR    args: (varName, expression, endTagSymbol)
				Repeats anything in the cmndList
		i   i    i   N(   RE   R   RB   RC   t   copyR@   RH   R>   RF   R`   RG   R8   t   removeRepeatt	   popLocalsR?   R   R=   R<   RK   RX   t	   incrementRV   RA   t   simpleTALESt   DEFAULTVALUEt   RepeatVariablet	   addRepeatR-   (   R%   RZ   R[   R5   t
   isSequence(    (    s   lib/simpletal/simpleTAL.pyR      sP    							!
		'c         C   s   |  j  j | d |  j  } | d k re | d r> d |  _ n  |  j | d |  _ |  j d 7_ d S| t j	 k s | d r d |  _ n  | d | f |  _
 |  j | d |  _ |  j d 7_ d S|  j d 7_ d Sd S(   sT    args: (replaceFlag, structureFlag, expression, endTagSymbol)
				Expands content
		i   i    i   i   N(   R8   RV   RA   R   R@   R   R>   R=   Rg   Rh   RH   (   R%   RZ   R[   R5   (    (    s   lib/simpletal/simpleTAL.pyR   2  s     

c   
      C   s  i  } g  } xO| D]G\ } } |  j  j | |  j  } | d k rP d | | <q | t j k s d | | <t |  t d  k r |  j s t j	 | d d } qD| } n t |  t d  k r |  j s t j	 t
 | d  d d } qDt
 | d  } nE |  j s/t j	 t
 t |  d  d d } n t
 t |  d  } | j | | f  q q Wx4 |  j D]) }	 | j |	 d  sh| j |	  qhqhW| |  _ |  j d 7_ d S(   sU   args: [(attributeName, expression)]
				Add, leave, or remove attributes from the start tag
				
			If self.escapeAttributes is true then the tag attributes will be escaped
			when they are output by cmdOutputStartTag (using tagAsText).  Hence
			we only escape the generated content here if they will *not* be when
			written out later!
		i   u    R)   R,   t   asciii    N(   R8   RV   RA   R   Rg   Rh   t   typeR   R.   R/   t   unicodet   strR-   RB   t   has_keyR=   (
   R%   RZ   R[   t   attsToRemovet   newAttst   attNamet   attExprt	   resultValt   escapedAttValt   oldAtt(    (    s   lib/simpletal/simpleTAL.pyR   L  s2    	
			!	'	c         C   sI   |  j  j | |  j  } | d k	 r6 | r6 d |  _ n  |  j d 7_ d S(   s:    args: expression
				Conditionally turn off tag output
		i    i   N(   R8   RV   RA   R   R@   R=   (   R%   RZ   R[   R5   (    (    s   lib/simpletal/simpleTAL.pyR     s    c         C   s   | \ } } |  j  rw |  j d  k rR | rR |  j j |  j | |  j f d   qw |  j j |  j | |  j f   n  |  j d  k	 r |  j |  _ d  S|  j d 7_ d  S(   Ni   (	   R@   RH   R   R9   t   writeR7   RB   R>   R=   (   R%   RZ   R[   t   tagNamet   singletonTag(    (    s   lib/simpletal/simpleTAL.pyR     s    	(%c         C   sn  |  j  d  k	 r|  j  \ } } | r t | t  rl |  j   | j |  j |  j |   |  j   i  |  _	 qt
 |  t
 d  k r |  j j |  qt
 |  t
 d  k r |  j j t | d   q|  j j t t |  d   qt
 |  t
 d  k r!|  j j t j |   qt
 |  t
 d  k r^|  j j t j t | d    q|  j j t j t t |  d    n  |  j r| d r| d o|  j  d  k s|  j j d | d d  qn  |  j d  k	 r|  j |  _ d  S|  j r|  j j   n  |  j j   \
 |  _ |  _ |  _ |  _ |  _ |  _ |  _ |  _ |  _  |  _ |  j d 7_ d  S(	   Nu    R,   Rl   i   i   s   </i    R+   (   RH   R   t
   isinstancet   TemplateRN   t   expandInlineR8   R9   RM   R	   Rm   Rx   Rn   Ro   R.   R/   R@   R?   R=   RI   Re   R<   RK   R>   RA   RB   RE   RF   RG   (   R%   RZ   R[   t   contentTypeRu   (    (    s   lib/simpletal/simpleTAL.pyR     s8    

"%+"	Kc         C   s#   |  j  j |  |  j d 7_ d  S(   Ni   (   R9   Rx   R=   (   R%   RZ   R[   (    (    s   lib/simpletal/simpleTAL.pyR     s    c         C   s   |  j  j |  j |  j |  j |  j |  j |  j |  j |  j	 |  j
 |  j f
  d |  _ d |  _ d |  _ | d |  _ | d |  _ d |  _ d |  _ d |  _	 d |  _
 d |  _ |  j d 7_ d S(   sx    args: (originalAttributes, currentAttributes)
				Pushes the current state onto the stack, and sets up the new state
		i   i    N(   R<   R-   R>   R?   R@   RA   RB   RE   RF   RG   RH   RI   R   R=   (   R%   RZ   R[   (    (    s   lib/simpletal/simpleTAL.pyR     s*    								c         C   s   |  j  d 7_  d  S(   Ni   (   R=   (   R%   RZ   R[   (    (    s   lib/simpletal/simpleTAL.pyR#     s    c         C   s   |  j  j | d |  j  } | d k rX d |  _ |  j | d |  _ |  j d 7_ d S| t j	 k r t
 | t  r d |  _ | d |  _ d | f |  _ |  j | d |  _ d S|  j d 7_ d Sd S(   s    args: (macroExpression, slotParams, endTagSymbol)
				Evaluates the expression, if it resolves to a SubTemplate it then places
				the slotParams into currentSlots and then jumps to the end tag
		i    i   i   N(   R8   RV   RA   R   R@   R   R>   R=   Rg   Rh   R{   t   SubTemplateR	   RH   (   R%   RZ   R[   t   value(    (    s   lib/simpletal/simpleTAL.pyR     s    		c         C   sd   |  j  j | d  rQ d |  _ d |  j  | d f |  _ |  j | d |  _ d S|  j d 7_ d S(   s~    args: (slotName, endTagSymbol)
				If the slotName is filled then that is used, otherwise the original conent
				is used.
		i    i   N(   RD   Rp   R@   RH   R   R=   (   R%   RZ   R[   (    (    s   lib/simpletal/simpleTAL.pyR!     s    	(   R   R   R&   R7   R;   RJ   RM   RN   RU   R   R   R   R   R   R   R   R   R   R   R#   R   R!   (    (    (    s   lib/simpletal/simpleTAL.pyR   g   s(   								;		7	
		4				R|   c           B   sA   e  Z d d   Z d d d  Z d d  Z d   Z d   Z RS(   c   
      C   s   | |  _  | |  _ | |  _ | |  _ x$ |  j j   D] } | j |   q4 WxT |  j  D]I \ } } | t k rU | d } x$ | j   D] }	 |	 j |   q WqU qU Wd  S(   Ni   (   R   t   macrosR   t   doctypet   valuest   setParentTemplateR    (
   R%   t   commandsR   t   symbolsR   t   macroRT   t   argt   slotMapt   slot(    (    s   lib/simpletal/simpleTAL.pyR&     s    				
c         C   s   |  j  | | |  d S(   s    This method will write to the outputFile, using the encoding specified,
				the expanded version of this template.  The context passed in is used to resolve
				all expressions with the template.
		N(   R}   (   R%   R8   R:   t   outputEncodingt   interpreter(    (    s   lib/simpletal/simpleTAL.pyt   expand1  s    c         C   su   | d k r( t   } | j | |  n | } y | j |   Wn/ t k
 rp } t j d  t j d   n Xd S(   sE    Internally used when expanding a template that is part of a context.sJ   UnicodeError caused by placing a non-Unicode string in the Context object.s$   Found non-unicode string in Context!N(	   R   R   R;   RU   t   UnicodeErrort   loggingt   errorRg   t   ContextContentException(   R%   R8   R:   R   t   ourInterpretert   unierror(    (    s   lib/simpletal/simpleTAL.pyR}   :  s    	c         C   s   |  j  d t |  j   |  j f S(   sE    Returns a tuple of (commandList, startPoint, endPoint, symbolTable) i    (   R   R`   R   (   R%   (    (    s   lib/simpletal/simpleTAL.pyRO   G  s    c         C   s  d } d } x |  j  D] } | d t k rO | d t |  t |  f } n | d t |  t | d  t | d d  f } xB | d d j   D], } | d | t | d d |  f } q W| d t | d d  } | d 7} q W| d	 } x` |  j j   D]O } | d
 t |  d t |  j |  d t |  j  |  j |  d } qW| d } x@ |  j j   D]/ } | d t |  d t |  j |  } qzW| S(   Ns
   Commands:
i    s   
[%s] %ss   
[%s] %s, (%s{i   s   %s: %ss   }, %s)i   s   

Symbols:
s   Symbol: s    points to: s   , which is command: s   
s
   

Macros:
s   Macro: s    value of: (   R   R    Ro   t   keysR   R   (   R%   R5   t   indext   cmdR   t   symbolR   (    (    s   lib/simpletal/simpleTAL.pyt   __str__K  s"    #5*
M
-N(   R   R   R   R&   R   R}   RO   R   (    (    (    s   lib/simpletal/simpleTAL.pyR|     s
   		R   c           B   s2   e  Z d  Z d   Z d   Z d   Z d   Z RS(   s   A SubTemplate is part of another template, and is used for the METAL implementation.
			The two uses for this class are:
				1 - metal:define-macro results in a SubTemplate that is the macro
				2 - metal:fill-slot results in a SubTemplate that is a parameter to metal:use-macro
	c         C   s,   t  j |  g  i  i   | |  _ | |  _ d S(   s    The parentTemplate is the template for which we are a sub-template.
				The startRange and endRange are indexes into the parent templates command list, 
				and defines the range of commands that we can execute
		N(   R|   R&   t
   startRanget   endRangeSymbol(   R%   R   R   (    (    s   lib/simpletal/simpleTAL.pyR&   f  s    	c         C   s%   | |  _  | j |  _ | j |  _ d  S(   N(   t   parentTemplateR   R   (   R%   R   (    (    s   lib/simpletal/simpleTAL.pyR   o  s    	c         C   s'   |  j  |  j |  j |  j d |  j f S(   sE    Returns a tuple of (commandList, startPoint, endPoint, symbolTable) i   (   R   R   R   R   (   R%   (    (    s   lib/simpletal/simpleTAL.pyRO   t  s    c         C   s3   |  j  |  j } d t |  j  t |  f } | S(   Ns   SubTemplate from %s to %s
(   R   R   Ro   R   (   R%   t   endRangeR5   (    (    s   lib/simpletal/simpleTAL.pyR   x  s    (   R   R   t   __doc__R&   R   RO   R   (    (    (    s   lib/simpletal/simpleTAL.pyR   `  s
   				t   HTMLTemplatec           B   s   e  Z d  Z d d d  Z RS(   s@   A specialised form of a template that knows how to output HTML
	s
   ISO-8859-1c         C   s3   t  j |  d | d  } |  j | | |  d S(   s    This method will write to the outputFile, using the encoding specified,
			the expanded version of this template.  The context passed in is used to resolve
			all expressions with the template.
		i   t   replaceN(   t   codecst   lookupR}   (   R%   R8   R:   R   R   t   encodingFile(    (    s   lib/simpletal/simpleTAL.pyR     s    N(   R   R   R   R   R   (    (    (    s   lib/simpletal/simpleTAL.pyR   }  s   t   XMLTemplatec           B   s;   e  Z d  Z d d  Z d d d d d  Z d d  Z RS(   s?   A specialised form of a template that knows how to output XML
	c         C   s#   t  j |  | | |  | |  _ d  S(   N(   R|   R&   R   (   R%   R   R   R   R   (    (    s   lib/simpletal/simpleTAL.pyR&     s    s
   iso-8859-1i    c         C   s   t  j |  d | d  } | s^ | j   d k rN | j d | j    q^ | j d  n  | rz |  j rz |  j } n  | r | j |  | j d  n  |  j | | |  d S(   s    This method will write to the outputFile, using the encoding specified,
			the expanded version of this template.  The context passed in is used to resolve
			all expressions with the template.
		i   R   s   utf-8s$   <?xml version="1.0" encoding="%s"?>
s   <?xml version="1.0"?>
s   
N(   R   R   t   lowerRx   R   R}   (   R%   R8   R:   R   t   docTypet   suppressXMLDeclarationR   R   (    (    s   lib/simpletal/simpleTAL.pyR     s    	c         C   s{   | d k r( t   } | j | |  n | } y | j |  d d Wn/ t k
 rv } t j d  t j d   n Xd S(   s    Internally used when expanding a template that is part of a context.
			This version replaces the default so that escapeAttributes can be passed.R   i   sJ   UnicodeError caused by placing a non-Unicode string in the Context object.s$   Found non-unicode string in Context!N(	   R   R   R;   RU   R   R   R   Rg   R   (   R%   R8   R:   R   R   R   (    (    s   lib/simpletal/simpleTAL.pyR}     s    	N(   R   R   R   R   R&   R   R}   (    (    (    s   lib/simpletal/simpleTAL.pyR     s   t   TemplateCompilerc           B   s   e  Z d  d  Z d   Z d   Z d   Z d   Z d  d  Z d   Z d   Z	 d	   Z
 i  d
  Z d  d  Z d  d  Z d   Z d   Z d   Z d   Z d   Z d  d  Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z RS(   i    c         C   sQ  g  |  _  g  |  _ i  |  _ i  |  _ d |  _ | |  _ i  |  _ |  j |  j t <|  j	 |  j t
 <|  j |  j t <|  j |  j t <|  j |  j t <|  j |  j t <|  j |  j t <|  j |  j t <|  j |  j t <|  j |  j t <|  j |  j t <|  j d  g  |  _ g  |  _ |  j j  d  |  j! d  |  j j  d  t" j# d  |  _$ d S(   s    Initialise a template compiler.  If attribute values are still in escaped
		form (e.g. &lt;) then set attributesEscaped to true.
		i   t   talt   metals   simpleTAL.TemplateCompilerN(%   R   t   tagStackt   symbolLocationTablet   macroMapt   endTagSymbolt   attributesEscapedR
   t   compileCmdDefineR   t   compileCmdConditionR   t   compileCmdRepeatR   t   compileCmdContentR   t   compileCmdReplacet   TAL_REPLACEt   compileCmdAttributesR   t   compileCmdOmitTagR   t   compileMetalUseMacroR    t   compileMetalDefineSlotR"   t   compileMetalFillSlott   METAL_FILL_SLOTt   compileMetalDefineMacrot   METAL_DEFINE_MACROt   setTALPrefixt   tal_namespace_prefix_stackt   metal_namespace_prefix_stackR-   t   setMETALPrefixR   t	   getLoggert   log(   R%   R   (    (    s   lib/simpletal/simpleTAL.pyR&     s2    									c         C   s   | |  _  i  |  _ t |  j d | <t |  j d | <t |  j d | <t |  j d | <t |  j d | <t |  j d | <t |  j d | <d  S(   Ns   %s:attributess
   %s:contents	   %s:defines
   %s:replaces   %s:omit-tags   %s:conditions	   %s:repeat(	   t   tal_namespace_prefixt   tal_attribute_mapR   R   R   R   R   R   R   (   R%   t   prefix(    (    s   lib/simpletal/simpleTAL.pyR     s    		c         C   sZ   | |  _  i  |  _ t |  j d | <t |  j d | <t |  j d | <t |  j d | <d  S(   Ns   %s:define-macros   %s:use-macros   %s:define-slots   %s:fill-slot(   t   metal_namespace_prefixt   metal_attribute_mapR   R    R"   R   (   R%   R   (    (    s   lib/simpletal/simpleTAL.pyR     s    		c         C   s    |  j  j   } |  j |  d  S(   N(   R   RK   R   (   R%   t	   newPrefix(    (    s   lib/simpletal/simpleTAL.pyt   popTALNamespace  s    c         C   s    |  j  j   } |  j |  d  S(   N(   R   RK   R   (   R%   R   (    (    s   lib/simpletal/simpleTAL.pyt   popMETALNamespace  s    c         C   s   | \ } } d g } | j  |  xW | D]O } | j  d  | j  | d  | j  d  | j  | d  | j  d  q) W| r | j  d  n | j  d  d	 j |  S(
   s    This returns a tag as text.
		R'   R(   i    s   ="i   R*   s    />R+   R,   (   R-   R0   (   R%   R1   R2   R3   R4   R5   R6   (    (    s   lib/simpletal/simpleTAL.pyR7     s    		c         C   s[  d } t  j |  } g  } x| d
 k	 r<| j d  } | j d  } | j | | | ! | } d
 } | | d | d !} t j j |  r t j | } | j	 d  r | d d !} d
 } q n  | d
 k r| j	 d  r d }	 | d }
 n d }	 | d }
 t
 t |
 |	   } n  | j |  t  j | |  } q W| j | |  d	 j |  S(   s    This function takes a string which contains escaped characters, and returns
			the expanded version of the string.  This is used to expand HTML attribute
			values so that TALES can function correctly.
		i    i   s   &#is   #xi   i   i
   u    N(   t   ESCAPED_ENTITIES_REGEXt   matchR   t   startt   endR-   t   htmlentitydefst
   entitydefsRp   t
   startswitht   unichrt   intR0   (   R%   t   theAttt   lastHTMLEntityR   R5   t   defStartt   defEndt   convertedDeft   theEntityDeft   baset	   theNumber(    (    s   lib/simpletal/simpleTAL.pyt
   convertAtt  s4    
c         C   s   t  |  j |  j |  j  } | S(   N(   R|   R   R   R   (   R%   RP   (    (    s   lib/simpletal/simpleTAL.pyt   getTemplate4  s    c         C   sy   | d t  k re t |  j  d k re |  j d d t  k re t  |  j d d | d f |  j d <n |  j j |  d  S(   Ni    ii   (   R   R`   R   R-   (   R%   RZ   (    (    s   lib/simpletal/simpleTAL.pyt
   addCommand8  s    <)c         C   s$  |  j  j d | d  | j d d  } | j d d  } | j d d  } | d k	 r | d t k r |  j j | | t |  j  d f  q |  j j | | d f  n |  j j | | d f  | d k	 r|  j	 t
 | | d f f  |  j	 |  n |  j	 t |  j | |  f  d S(   sQ   Used to add a tag to the stack.  Various properties can be passed in the dictionary
		    as being information required by the tag.
		    Currently supported properties are:
		    		'command'         - The (command,args) tuple associated with this command
		    		'originalAtts'    - The original attributes that include any metal/tal attributes
		    		'endTagSymbol'    - The symbol associated with the end tag for this element
		    		'popFunctionList' - A list of functions to execute when this tag is popped
					'singletonTag'    - A boolean to indicate that this is a singleton flag
		s   Adding tag %s to stacki    RZ   t   originalAttsRz   i   N(   R   t   debugt   getR   R    R   R-   R`   R   R   R   R   R7   (   R%   R3   t   tagPropertiesRZ   R   Rz   (    (    s   lib/simpletal/simpleTAL.pyt   addTag?  s    )c         C   s  xt  |  j  d k r|  j j   \ } } } | j d d  } | j d g   } | j d d  } x | D] }	 t |	 d  qm W|  j j d | d  | d | d k r8| d k	 r t  |  j  |  j	 | <|  j
 t | d | | f f  d S| d k r1| d k r1|  j
 t d | d d f  d Sd Sq | d k	 r d	 | d | d f }
 |  j j |
  t |  j |  |
   q q W|  j j d
 | d  t d | d d   d S(   s   omitTagFlag is used to control whether the end tag should be included in the
				output or not.  In HTML 4.01 there are several tags which should never have
				end tags, this flag allows the template compiler to specify that these
				should not be output.
		i    R   t   popFunctionListRz   s   Popped tag %s off stackNs   </R+   sE   TAL/METAL Elements must be balanced - found close tag %s expecting %ss2   Close tag %s found with no corresponding open tag.s   </%s>s5   Close tag encountered with no corresponding open tag.(    (   R`   R   RK   R   R   t   applyR   R   R   R   R   R   R   R   t   TemplateParseExceptionR7   (   R%   R3   t   omitTagFlagt   oldTagR   t   useMacroLocationR   t   popCommandListRz   t   funct   msg(    (    s   lib/simpletal/simpleTAL.pyt   popTag^  s.     c         C   s  | | f |  _  g  } g  } i  } g  } i  } g  }	 d }
 d } | | d <| j d  d k r | d | j d  !} | |  j k r d }
 |  j d } n% | |  j k r d }
 |  j d } n  |
 r | j t  d | t <q n  x| D]\ } } |
 r| j d  d k r| | } n | } |  j j d |  | d d !d k rT| d	 } | t k rt	 |  d k r|  j
 j |  j  |  j |  |	 j |  j  qQd
 } t |  j |  j   |   q| t k r>t	 |  d k r|  j j |  j  |  j |  |	 j |  j  qQd } t |  j |  j   |   q| j | | f  q |  j j |  r|  j | } | t k r|
 r|  j j d  q| | | <| j |  q |  j j |  r|  j | } | | | <| j |  q | j | | f  q W|	 | d <t	 |  t	 |  d k rB|  j | | f |  d  S|  j d 7_ |  j | d <| j   | j   | | } d } x | D] } |  j r|  j | |  } |  j | |  } n |  j | | |  } | d  k	 r| rd } | | d <| | d <|  j | | f |  q-|  j |  qqW| rp| | d <t | | f f | d <|  j | | f |  n |  j t | | f f  d  S(   Ni    R,   Rz   t   :i   s   Command name is now %si   t   xmlnsi   sC   Can not use METAL name space by default, a prefix must be provided.sA   Can not use TAL name space by default, a prefix must be provided.s;   Supressing omit-tag command present on TAL or METAL elementR   R   R   RZ   (    t   currentStartTagt   findR   R   R-   R   R   R   t   METAL_NAME_URIR`   R   R   R   R   R7   t   TAL_NAME_URIR   R   R   R   Rp   t   warnR   R   R   t   sortR   R   R
   R   R   R   (   R%   R3   t
   attributest   singletonElementt   foundTALAttst   foundMETALAttst   foundCommandsArgst   cleanAttributesR   t   popTagFuncListt   TALElementNameSpacet   prefixToAddt	   namespaceR6   R   t   commandAttNameR   R   RT   t   allCommandst   firstTagt   talAttt   safeAttribute(    (    s   lib/simpletal/simpleTAL.pyt   parseStartTag  s    







	


c         C   s   |  j  | d f  d S(   s6    Just pop the tag and related commands off the stack. N(   R   R   (   R%   R3   (    (    s   lib/simpletal/simpleTAL.pyt   parseEndTag  s    c         C   s   |  j  t | f  d  S(   N(   R   R   (   R%   t   data(    (    s   lib/simpletal/simpleTAL.pyt	   parseData  s    c   
      C   s{  g  } t  j d  } xY| j |  D]H} | j   j d d  } | j d  } d } t |  d k  r d | } |  j j |  t |  j	 |  j
  |   n  t |  d k r:| d d	 k r d } | d } d j | d  }	 qW| d d
 k r| d } d j | d  }	 qW| d } d j | d  }	 n | d } d j | d  }	 | j | | |	 f  q% Wt | f S(   Ns   (?<!;);(?!;)s   ;;t   ;R(   i   i   s   Badly formed define command '%s'.  Define commands must be of the form: '[local|global] varName expression[;[local|global] varName expression]'i    t   globalt   local(   t   ret   compilet   splitt   lstripR   R`   R   R   R   R7   R   R0   R-   R   (
   R%   t   argumentt   commandArgst   argumentSplittert
   defineStmtt   stmtBitsR]   R   R^   t
   expression(    (    s   lib/simpletal/simpleTAL.pyR     s0    




c         C   sY   t  |  d k rF d } |  j j |  t |  j |  j  |   n  t | |  j f f S(   Ni    sC   No argument passed!  condition commands must be of the form: 'path'(   R`   R   R   R   R7   R   R   R   (   R%   R  R   (    (    s   lib/simpletal/simpleTAL.pyR   ;  s
    c         C   s   | j  d  } t |  d k  rY d | } |  j j |  t |  j |  j  |   n  | d } d j | d  } t | | |  j	 f f S(   NR(   i   s\   Badly formed repeat command '%s'.  Repeat commands must be of the form: 'localVariable path'i    i   (
   R  R`   R   R   R   R7   R   R0   R   R   (   R%   R  t   attPropsR   R^   R  (    (    s   lib/simpletal/simpleTAL.pyR   G  s    

c         C   s   t  |  d k rF d } |  j j |  t |  j |  j  |   n  d } | j d  } t  |  d k r | d d k r d } d j | d  } q | d d k r d } d j | d  } q | } n | } t | | | |  j	 f f S(   Ni    sI   No argument passed!  content/replace commands must be of the form: 'path'R(   i   t	   structuret   text(
   R`   R   R   R   R7   R   R  R0   R   R   (   R%   R  t   replaceFlagR   t   structureFlagR  t   express(    (    s   lib/simpletal/simpleTAL.pyR   U  s     	c         C   s   |  j  | d d S(   NR  i   (   R   (   R%   R  (    (    s   lib/simpletal/simpleTAL.pyR   p  s    c   	      C   s   g  } t  j d  } x | j |  D] } | j   j d d  } | j d  } t |  d k  r d | } |  j j |  t |  j	 |  j
  |   n  | d } d j | d  } | j | | f  q% Wt | f S(	   Ns   (?<!;);(?!;)s   ;;R	  R(   i   ss   Badly formed attributes command '%s'.  Attributes commands must be of the form: 'name expression[;name expression]'i    i   (   R  R  R  R  R   R`   R   R   R   R7   R   R0   R-   R   (	   R%   R  R  R  t   attributeStmtR  R   Rs   Rt   (    (    s   lib/simpletal/simpleTAL.pyR   s  s    

c         C   s+   t  |  d k r d } n | } t | f S(   Ni    t   default(   R`   R   (   R%   R  R  (    (    s   lib/simpletal/simpleTAL.pyR     s    	c         C   s|   t  |  d k rF d } |  j j |  t |  j |  j  |   n  t | i  |  j f f } |  j j d t	 |   | S(   Ni    sN   No argument passed!  use-macro commands must be of the form: 'use-macro: path's   Returning METAL_USE_MACRO: %s(
   R`   R   R   R   R7   R   R    R   R   Ro   (   R%   R  R   RT   (    (    s   lib/simpletal/simpleTAL.pyR     s    c         C   s  t  |  d k rF d } |  j j |  t |  j |  j  |   n  t j |  j   t  |  k r d | } |  j j |  t |  j |  j  |   n  |  j	 j
 |  r d | } |  j j |  t |  j |  j  |   n  t t  |  j  |  j  } | |  j	 | <d  S(   Ni    sT   No argument passed!  define-macro commands must be of the form: 'define-macro: name's   Macro name %s is invalid.s!   Macro name %s is already defined!(   R`   R   R   R   R7   R   t   METAL_NAME_REGEXR   R   R   Rp   R   R   R   R   (   R%   R  R   R   (    (    s   lib/simpletal/simpleTAL.pyR     s    !

c         C   s\  t  |  d k rF d } |  j j |  t |  j |  j  |   n  t j |  j   t  |  k r d | } |  j j |  t |  j |  j  |   n  d  } t  |  j
  d } x | d  k r:|  j
 | d } | d  k	 r | } q | d 8} | d k  r d } |  j j |  t |  j |  j  |   q q W|  j | \ } } |  j j d t |   | \ } }	 }
 t j |  j   t  |  k rd | } |  j j |  t |  j |  j  |   n  |	 j |  rd | } |  j j |  t |  j |  j  |   n  t t  |  j  |  j  } | |	 | <| | |	 |
 f f |  j | <d  S(	   Ni    sN   No argument passed!  fill-slot commands must be of the form: 'fill-slot: name's   Slot name %s is invalid.i   i   s:   metal:fill-slot must be used inside a metal:use-macro calls   Use macro argument: %ss    Slot %s has already been filled!(   R`   R   R   R   R7   R   R  R   R   R   R   R   R   Ro   Rp   R   R   (   R%   R  R   t   ourMacroLocationt   locationt   macroLocationRT   R[   t	   macroNameR   t	   endSymbolR   (    (    s   lib/simpletal/simpleTAL.pyR     sD    !
	
"!


c         C   s   t  |  d k rF d } |  j j |  t |  j |  j  |   n  t j |  j   t  |  k r d | } |  j j |  t |  j |  j  |   n  t	 | |  j
 f f S(   Ni    sE   No argument passed!  define-slot commands must be of the form: 'name's   Slot name %s is invalid.(   R`   R   R   R   R7   R   R  R   R   R"   R   (   R%   R  R   (    (    s   lib/simpletal/simpleTAL.pyR     s    !
(   R   R   R&   R   R   R   R   R7   R   R   R   R   R   R  R  R  R   R   R   R   R   R   R   R   R   R   R   (    (    (    s   lib/simpletal/simpleTAL.pyR     s2   %					(		,			'								3R   c           B   s   e  Z d    Z d   Z RS(   c         C   s   | |  _  | |  _ d  S(   N(   R   t   errorDescription(   R%   R   R$  (    (    s   lib/simpletal/simpleTAL.pyR&     s    	c         C   s   d |  j  d |  j S(   Nt   [s   ] (   R   R$  (   R%   (    (    s   lib/simpletal/simpleTAL.pyR     s    (   R   R   R&   R   (    (    (    s   lib/simpletal/simpleTAL.pyR     s   	t   AREAt   BASEt   BASEFONTt   BRt   COLt   FRAMEt   HRt   IMGt   INPUTt   ISINDEXt   LINKt   METAt   PARAMt   HTMLTemplateCompilerc           B   sn   e  Z d    Z d d  Z d   Z d   Z d   Z d   Z d   Z d   Z	 d	   Z
 d
   Z d   Z RS(   c         C   s9   t  j |  d d t j j |   t j d  |  _ d  S(   NR   i   s   simpleTAL.HTMLTemplateCompiler(   R   R&   t   sgmllibt
   SGMLParserR   R   R   (   R%   (    (    s   lib/simpletal/simpleTAL.pyR&     s    s
   iso-8859-1c         C   sF   t  j |  d | d  } | |  _ |  j | j    |  j   d  S(   Ni   R   (   R   R   t   encodingt   feedt   readt   close(   R%   R9   R6  t   encodedFile(    (    s   lib/simpletal/simpleTAL.pyt   parseTemplate  s    	c         C   s  |  j  j d | d t |   g  } x{ | D]s } | d | d k rs |  j  j d  | j | d d f  q/ |  j  j d | d | d f  | j |  q/ Wt j | j    r |  j | |  |  j  j d  |  j | d  f d	 d n |  j | |  d  S(
   Ns   Recieved Start Tag: s    Attributes: i    i   sD   The attribute value is the same as the name, setting to empty stringR,   s   HTML Attribute %s has value %ss7   End tag forbidden, generating close tag with no output.R   (
   R   R   Ro   R-   t   HTML_FORBIDDEN_ENDTAGRp   t   upperR  R   R   (   R%   R3   R   R4   R6   (    (    s   lib/simpletal/simpleTAL.pyt   unknown_starttag  s    ""c         C   sW   |  j  j d |  t j | j    r@ |  j  j d |  n |  j | d  f  d  S(   Ns   Recieved End Tag: s-   HTML 4.01 forbids end tags for the %s element(   R   R   R<  Rp   R=  R   R   R   (   R%   R3   (    (    s   lib/simpletal/simpleTAL.pyt   unknown_endtag$  s    c         C   s.   |  j  j d |  |  j t j |   d  S(   Ns   Recieved Real Data: (   R   R   R  R.   R/   (   R%   R  (    (    s   lib/simpletal/simpleTAL.pyt   handle_data,  s    c         C   s   |  j  d |  d  S(   Nu   &#%s;(   R  (   R%   t   ref(    (    s   lib/simpletal/simpleTAL.pyt   handle_charref2  s    c         C   s   |  j  d |  d  S(   Nu   &%s;(   R  (   R%   RA  (    (    s   lib/simpletal/simpleTAL.pyt   handle_entityref5  s    c         C   s   |  j  d |  d  S(   Nu   <!%s>(   R  (   R%   R  (    (    s   lib/simpletal/simpleTAL.pyt   handle_decl9  s    c         C   s   |  j  d |  d  S(   Nu	   <!--%s-->(   R  (   R%   R  (    (    s   lib/simpletal/simpleTAL.pyt   handle_comment=  s    c         C   s   |  j  j d  d  S(   Ns2   End tag %s present with no corresponding open tag.(   R   R   (   R%   R3   (    (    s   lib/simpletal/simpleTAL.pyt   report_unbalanced@  s    c         C   s   t  |  j |  j |  j  } | S(   N(   R   R   R   R   (   R%   RP   (    (    s   lib/simpletal/simpleTAL.pyR   C  s    (   R   R   R&   R;  R>  R?  R@  RB  RC  RD  RE  RF  R   (    (    (    s   lib/simpletal/simpleTAL.pyR3    s   									t   XMLTemplateCompilerc           B   se   e  Z d    Z d d  Z d   Z d   Z d   Z d   Z d   Z d   Z	 d	   Z
 d
   Z RS(   c         C   sK   t  j |   t j j j j |   d  |  _ t j	 d  |  _
 d |  _ d  S(   Ns   simpleTAL.XMLTemplateCompileri    (   R   R&   t   xmlt   saxt   handlert   ContentHandlerR   R   R   R   R   R   (   R%   (    (    s   lib/simpletal/simpleTAL.pyR&   H  s
    	i    c         C   s   | \ } } d g } | j  |  xf | D]^ } | j  d  | j  | d  | j  d  | j  t j | d d d  | j  d  q) W| r | j  d  n | j  d	  d
 j |  S(   sG   This escapes the attribute values - used because SAX expands the valuesR'   R(   i    s   ="i   R)   R*   s    />R+   R,   (   R-   R.   R/   R0   (   R%   R1   R2   R3   R4   R5   R6   (    (    s   lib/simpletal/simpleTAL.pyR7   O  s    		 c         C   s   t  j j   |  _ |  j j d  |  j j t  j j j d  t	 rc |  j j
 t  j j j |   n  |  j j |   |  j j |   |  j j |  d  S(   Ns   Setting features of parseri    (   RH  RI  t   make_parsert	   ourParserR   R   t
   setFeatureRJ  t   feature_external_gest   use_lexical_handlert   setPropertyt   property_lexical_handlert   setContentHandlert   setDTDHandlert   parse(   R%   R9   (    (    s   lib/simpletal/simpleTAL.pyR;  _  s    c         C   sZ   |  j  j d | d | d |  | rC d | | | f |  _ n d | | f |  _ d  S(   Ns   Recieved DOCTYPE: s    public_id: s    system_id: s   <!DOCTYPE %s PUBLIC "%s" "%s">s   <!DOCTYPE %s SYSTEM "%s">(   R   R   R   (   R%   t   namet	   public_idt	   system_id(    (    s   lib/simpletal/simpleTAL.pyt   startDTDk  s    $c         C   s   |  j  j d | d t |   y: |  j j t j j j  } t	 j
 |  r[ d |  _ n  Wn t j j k
 rw } n Xg  } xI | j   D]; } |  j  j d | | | f  | j | | | f  q W|  j | | d |  j d  S(   Ns   Recieved Real Start Tag: s    Attributes: i   s   Attribute name %s has value %sR   (   R   R   Ro   RM  t   getPropertyRH  RI  RJ  t   property_xml_stringt   SINGLETON_XML_REGEXR   R   t   SAXExceptiont   getNamesR-   R  (   R%   R3   R   t   xmlTextt   eR4   R6   (    (    s   lib/simpletal/simpleTAL.pyt   startElementr  s    "c         C   s.   |  j  j d |  |  j |  d |  _ d  S(   Ns   Recieved Real End Tag: i    (   R   R   R  R   (   R%   R3   (    (    s   lib/simpletal/simpleTAL.pyt
   endElement  s    c         C   s   |  j  t j |   d  S(   N(   R  R.   R/   (   R%   R  (    (    s   lib/simpletal/simpleTAL.pyt
   characters  s    c         C   s+   |  j  j d  |  j d | | f  d  S(   Ns    Recieved processing instruction.u	   <?%s %s?>(   R   R   R  (   R%   t   targetR  (    (    s   lib/simpletal/simpleTAL.pyt   processingInstruction  s    c         C   s   |  j  d |  d  S(   Nu	   <!--%s-->(   R  (   R%   R  (    (    s   lib/simpletal/simpleTAL.pyt   comment  s    c         C   s%   t  |  j |  j |  j |  j  } | S(   N(   R   R   R   R   R   (   R%   RP   (    (    s   lib/simpletal/simpleTAL.pyR     s    !(   R   R   R&   R7   R;  RY  Ra  Rb  Rc  Re  Rf  R   (    (    (    s   lib/simpletal/simpleTAL.pyRG  G  s   								s
   ISO-8859-1c         C   se   t  |  t d   s* t  |  t d   r< t j |   } n |  } t   } | j | |  | j   S(   s    Reads the templateFile and produces a compiled template.
			To use the resulting template object call:
				template.expand (context, outputFile)
	R,   u    (   R{   Rm   t   StringIOR3  R;  R   (   RP   t   inputEncodingt   templateFilet   compiler(    (    s   lib/simpletal/simpleTAL.pyt   compileHTMLTemplate  s    *	c         C   sM   t  |  t d   r' t j |   } n |  } t   } | j |  | j   S(   s    Reads the templateFile and produces a compiled template.
			To use the resulting template object call:
				template.expand (context, outputFile)
	R,   (   R{   Rm   Rg  RG  R;  R   (   RP   Ri  Rj  (    (    s   lib/simpletal/simpleTAL.pyt   compileXMLTemplate  s    	(;   R   R   t   DummyLoggerR4  t   xml.saxRH  R.   Rg  R   R  R   t	   simpletalRc   t   __version__t   xml.sax.saxlibR    RP  t   ImportErrorRg   R   R   R   R   R   R   R   R   R   R   R   R   R   R$   R    R"   R   R   R  R  R\  R   R   R|   R   R   R   R   t	   ExceptionR   R<  R5  R3  RI  RJ  RK  t
   DTDHandlerRG  Rk  Rl  (    (    (    s   lib/simpletal/simpleTAL.pyt   <module>#   sh   T	
 B-  @
&#B1R