9d5e3e2710ab5d44fc246a334bd653411725f0f4
[tx] / tags.py
1 # -*- coding:utf-8 -*-
2
3 # Tags
4 # Copyright (C) 2005  Frédéric Jolliton <frederic@jolliton.com>
5
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
20 __all__ = [ 'Tags' , 'tags' ]
21
22 from nodes import *
23 from error import *
24
25 def decodeName( name ) :
26
27         '''
28         Decode python variable name.  If '_' is the first character, it's
29         discarded.  Other '_' are converted to '-', except for 2 '__' that
30         are converted to ':'.
31
32         '_class' -> 'class'
33         'xml__lang' -> 'xml:lang'
34         'http_equiv' -> 'http-equiv'
35         '''
36
37         if name.startswith( '_' ) and len( name ) > 1 :
38                 name = name[ 1 : ]
39         name = name.replace( '__' , ':' )
40         name = name.replace( '_' , '-' )
41         return name
42
43 def kws( kwargs ) :
44
45         '''Copy 'kwargs' dictionnary, rewriting keys using decodeName().'''
46
47         return dict( [ ( decodeName( key ) , value ) for key , value in kwargs.items() if value is not None ] )
48
49 def ensureNode( node ) :
50
51         if isinstance( node , Node ) :
52                 return node
53         elif isinstance( node , basestring ) :
54                 return Text( node )
55         else :
56                 raise Error( 'Invalid expression to build tree' )
57
58 class Tags :
59
60         def __getattr__( self , name ) :
61
62                 '''Create functions on the fly as needed.'''
63
64                 if name == '_doc_' :
65                         def fun( *contents ) :
66                                 children = [ ensureNode( child ) for child in contents if child ]
67                                 return Document( children )
68                 elif name == '_comment_' :
69                         def fun( contents ) :
70                                 return Comment( contents )
71                 elif name == '_pi_' :
72                         def fun( target , contents ) :
73                                 return ProcessingInstruction( target , contents )
74                 else :
75                         def fun( *contents , **kwargs ) :
76
77                                 '''If first item of contents is a dictionnary, then its items
78                                 take precedence on kwargs items.'''
79
80                                 if contents and isinstance( contents[ 0 ] , dict ) :
81                                         k , contents = contents[ 0 ] , contents[ 1 : ]
82                                         kwargs.update( k )
83                                 attributes = [ Attribute( n , v ) for n , v in kws( kwargs ).items() ]
84                                 children = [ ensureNode( child ) for child in contents if child ]
85                                 return Element( decodeName( name ) , attributes , children )
86
87                 self.__dict__[ name ] = fun
88
89                 return fun
90
91 tags = Tags()
92
93 # Local Variables:
94 # tab-width: 4
95 # python-indent: 4
96 # End: