1 ##############################################################################
2 # Copyright (c) 2015 Huawei Technologies Co.,Ltd and others.
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
11 from sys import stdout, modules
13 doc_type = '<!DOCTYPE HTML>\n'
14 default_title = "Html Page"
15 charset = '<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />\n'
17 html4_tags = {'a', 'abbr', 'acronym', 'address', 'area', 'b', 'base', 'bdo', 'big',
18 'blockquote', 'body', 'br', 'button', 'caption', 'cite', 'code', 'col',
19 'colgroup', 'dd', 'del', 'div', 'dfn', 'dl', 'dt', 'em', 'fieldset',
20 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head',
21 'hr', 'html', 'i', 'iframe', 'img', 'input', 'ins', 'kbd',
22 'label', 'legend', 'li', 'link', 'map', 'menu', 'menuitem', 'meta',
23 'noframes', 'noscript', 'object', 'ol', 'optgroup', 'option', 'p',
24 'param', 'pre', 'q', 'samp', 'script', 'select', 'small', 'span', 'strong',
25 'style', 'sub', 'sup', 'table', 'tbody', 'td', 'textarea', 'tfoot', 'th',
26 'thead', 'title', 'tr', 'tt', 'ul', 'var'}
27 disused_tags = {'isindex', 'font', 'dir', 's', 'strike',
28 'u', 'center', 'basefont', 'applet', 'xmp'}
29 html5_tags = {'article', 'aside', 'audio', 'bdi', 'canvas', 'command', 'datalist', 'details',
30 'dialog', 'embed', 'figcaption', 'figure', 'footer', 'header',
31 'keygen', 'mark', 'meter', 'nav', 'output', 'progress', 'rp', 'rt', 'ruby',
32 'section', 'source', 'summary', 'details', 'time', 'track', 'video', 'wbr'}
35 tags = html4_tags | disused_tags | html5_tags
37 __all__ = [x.title() for x in tags] + ['PyHtml', 'space']
39 self_close = {'input', 'img', 'link', 'br'}
49 def __init__(self, *args, **kwargs):
50 self.attributes = kwargs
57 self._id = kwargs.get('id', name)
61 def __iadd__(self, obj):
62 if isinstance(obj, Tag) and obj.is_seq:
69 def add_obj(self, obj):
70 if not isinstance(obj, Tag):
72 _id = self.set_id(obj)
73 setattr(self, _id, obj)
76 def set_id(self, obj):
77 if isinstance(obj, Tag):
79 obj_lst = filter(lambda t: isinstance(
80 t, Tag) and t._id.startswith(_id), self)
83 obj_lst = filter(lambda t: not isinstance(t, Tag), self)
86 _id = '%s_%03i' % (_id, length)
87 if isinstance(obj, Tag):
91 def __add__(self, obj):
97 def __lshift__(self, obj):
98 if isinstance(obj, Tag):
101 print "unknown obj: %s " % obj
107 result += '<%s%s%s>' % (self.tag_name,
108 self._render_attr(), self._self_close() * ' /')
109 if not self._self_close():
112 if isinstance(c, Tag):
119 result += '</%s>' % self.tag_name
123 def _render_attr(self):
125 for key, value in self.attributes.iteritems():
126 if key != 'txt' and key != 'open':
129 result += ' %s="%s"' % (key, value)
132 def _self_close(self):
133 return self.tag_name in self_close
136 def tag_factory(tag):
140 F.__name__ = tag.title()
144 THIS = modules[__name__]
147 setattr(THIS, t.title(), tag_factory(t))
149 THIS = modules[__name__]
151 obj = type(t.title(), (Tag, ), {'tag_name': t})
152 setattr(THIS, t.title(), obj)
155 def _render_style(style):
161 for key, value in values.iteritems():
162 result += " %s: %s;\n" % (key, value)
165 result = '\n' + result
172 def __init__(self, title=default_title):
176 self.attributes = dict(xmlns='http://www.w3.org/1999/xhtml', lang='en')
177 self.head += Title(title)
179 def __iadd__(self, obj):
180 if isinstance(obj, Head) or isinstance(obj, Body):
182 elif isinstance(obj, Meta) or isinstance(obj, Link):
186 _id = self.set_id(obj)
187 setattr(self, _id, obj)
190 def add_js(self, *arg):
192 self.head += Script(type='text/javascript', src=f)
194 def add_css(self, *arg):
196 self.head += Link(rel='stylesheet', type='text/css', href=f)
198 def output(self, name=''):
200 fil = open(name, 'w')
203 fil.write(self.as_string())
209 return doc_type + self.render()
211 def add_style(self, style):
212 self.head += Style(_render_style(style))
214 def add_table(self, data):
215 table = self << Table()
217 cols = len(zip(*data))
219 for i in range(rows):
222 for j in range(1, cols):