1 #@file: pyh.py
2 #@purpose: a HTML tag generator
3 #@author: Emmanuel Turlay
4
5 __doc__ = """The pyh.py module is the core of the PyH package. PyH lets you6 generate HTML tags from within your python code.7 See http://code.google.com/p/pyh/ for documentation.8 """
9 __author__ = "Emmanuel Turlay "
10 __version__ = '$Revision: 43 $'
11 __date__ = '$Date$'
12
13 from sys import_getframe, stdout, modules, version14 nOpen={}15
16 nl = '\n'
17 doctype = '\n'
18 charset = '\n'
19
20 tags = ['html', 'body', 'head', 'link', 'meta', 'div', 'p', 'form', 'legend',21 'input', 'select', 'span', 'b', 'i', 'option', 'img', 'script',22 'table', 'tr', 'td', 'th', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',23 'fieldset', 'a', 'title', 'body', 'head', 'title', 'script', 'br', 'table']24
25 selfClose = ['input', 'img', 'link', 'br']26
27 classTag(list):28 tagname = ''
29
30 def __init__(self, *arg, **kw):31 self.attributes =kw32 ifself.tagname :33 name =self.tagname34 self.isSeq =False35 else:36 name = 'sequence'
37 self.isSeq =True38 self.id = kw.get('id', name)39 #self.extend(arg)
40 for a inarg: self.addObj(a)41
42 def __iadd__(self, obj):43 if isinstance(obj, Tag) andobj.isSeq:44 for o inobj: self.addObj(o)45 else: self.addObj(obj)46 returnself47
48 defaddObj(self, obj):49 if not isinstance(obj, Tag): obj =str(obj)50 id=self.setID(obj)51 setattr(self, id, obj)52 self.append(obj)53
54 defsetID(self, obj):55 ifisinstance(obj, Tag):56 id =obj.id57 n = len([t for t in self if isinstance(t, Tag) andt.id.startswith(id)])58 else:59 id = 'content'
60 n = len([t for t in self if notisinstance(t, Tag)])61 if n: id = '%s_%03i' %(id, n)62 if isinstance(obj, Tag): obj.id =id63 returnid64
65 def __add__(self, obj):66 if self.tagname: returnTag(self, obj)67 self.addObj(obj)68 returnself69
70 def __lshift__(self, obj):71 self +=obj72 returnobj73
74 defrender(self):75 result = ''
76 ifself.tagname:77 result = '' % (self.tagname, self.renderAtt(), self.selfClose()*'/')78 if notself.selfClose():79 for c inself:80 ifisinstance(c, Tag):81 result +=c.render()82 else: result +=c83 ifself.tagname:84 result += '%s>' %self.tagname85 result += '\n'
86 returnresult87
88 defrenderAtt(self):89 result = ''
90 for n, v inself.attributes.items():91 if n != 'txt' and n != 'open':92 if n == 'cl': n = 'class'
93 result += '%s="%s"' %(n, v)94 returnresult95
96 defselfClose(self):97 return self.tagname inselfClose98
99 defTagFactory(name):100 classf(Tag):101 tagname =name102 f.__name__ =name103 returnf104
105 thisModule = modules[__name__]106
107 for t intags: setattr(thisModule, t, TagFactory(t))108
109 defValidW3C():110 out = a(img(src='http://www.w3.org/Icons/valid-xhtml10', alt='Valid XHTML 1.0 Strict'), href='http://validator.w3.org/check?uri=referer')111 returnout112
113 classPyH(Tag):114 tagname = 'html'
115
116 def __init__(self, name='MyPyHPage'):117 self +=head()118 self +=body()119 self.attributes = dict(xmlns='http://www.w3.org/1999/xhtml', lang='en')120 self.head +=title(name)121
122 def __iadd__(self, obj):123 if isinstance(obj, head) orisinstance(obj, body): self.addObj(obj)124 elif isinstance(obj, meta) or isinstance(obj, link): self.head +=obj125 else:126 self.body +=obj127 id=self.setID(obj)128 setattr(self, id, obj)129 returnself130
131 def addJS(self, *arg):132 for f in arg: self.head += script(type='text/javascript', src=f)133
134 def addCSS(self, *arg):135 for f in arg: self.head += link(rel='stylesheet', type='text/css', href=f)136
137 def printOut(self,file=''):138 if file: f = open(file, 'w')139 else: f =stdout140 f.write(doctype)141 f.write(self.render())142 f.flush()143 iffile: f.close()144
145 classTagCounter:146 _count ={}147 _lastOpen =[]148 for t in tags: _count[t] =0149 def __init__(self, name):150 self._name =name151 defopen(self, tag):152 ifisLegal(tag):153 self._count[tag] += 1
154 self._lastOpen +=[tag]155 defclose(self, tag):156 if isLegal(tag) and self._lastOpen[-1] ==tag:157 self._count[tag] -= 1
158 self._lastOpen.pop()159 else:160 print('Cross tagging is wrong')161 defisAllowed(self, tag, open):162 if not open andself.isClosed(tag):163 print('TRYING TO CLOSE NON-OPEN TAG: %s' %tag)164 returnFalse165 returnTrue166 defisOpen(self, tag):167 if isLegal(tag): returnself._count[tag]168 defisClosed(self, tag):169 if isLegal(tag): return notself._count[tag]170
171
172 defisLegal(tag):173 if tag in tags: returnTrue174 else:175 print('ILLEGAL TAG: %s' %tag)176 return False