0
|
1 from cStringIO import StringIO
|
|
2
|
|
3 def HTMLmarkup(tag, text=None, **attributes):
|
|
4 """
|
|
5 markups the text with the tag and
|
|
6 attributes
|
|
7 """
|
|
8
|
|
9 # ideally, this woulod be cached for cascading calls
|
|
10 s = StringIO()
|
|
11
|
|
12 s.write('<%s' % tag)
|
|
13 for attribute, value in attributes.items():
|
|
14 if value is None:
|
|
15 s.write(' %s' % attribute)
|
|
16 else:
|
|
17 s.write(' %s="%s"' % (attribute, value))
|
|
18
|
|
19 if text:
|
|
20 if tag in block_level:
|
|
21 s.write('>\n%s\n</%s>' % (text, tag))
|
|
22 else:
|
|
23 s.write('>%s</%s>' % (text, tag))
|
|
24 else:
|
|
25 s.write('/>')
|
|
26 return s.getvalue()
|
|
27
|
|
28 tags = [ 'a',
|
|
29 'b', 'body', 'br',
|
|
30 'center',
|
|
31 'dd', 'div', 'dl', 'dt', 'em',
|
|
32 'form',
|
|
33 'h1', 'h2', 'h3', 'head', 'html',
|
|
34 'i', 'img', 'input',
|
|
35 'li', 'lh',
|
|
36 'ol', 'option',
|
|
37 'p',
|
|
38 'select', 'span', 'strong',
|
|
39 'table', 'td', 'textarea', 'th', 'title', 'tr',
|
|
40 'ul',
|
|
41 ]
|
|
42
|
|
43 for _i in tags:
|
|
44 globals()[_i] = lambda x=None, _i=_i, **y: HTMLmarkup(_i, x, **y)
|
|
45
|
|
46 # block-level elements
|
|
47 # from http://htmlhelp.com/reference/html40/block.html
|
|
48 block_level = set(['address',
|
|
49 'blockquote',
|
|
50 'center',
|
|
51 'dir', 'div', 'dl',
|
|
52 'fieldset', 'form',
|
|
53 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr',
|
|
54 'isindex',
|
|
55 'menu',
|
|
56 'noframes', 'noscript',
|
|
57 'ol',
|
|
58 'p', 'pre',
|
|
59 'table',
|
|
60 'ul',
|
|
61 # not really block level, but act like it is
|
|
62 'body',
|
|
63 'dd', 'dt',
|
|
64 'frameset',
|
|
65 'head', 'html',
|
|
66 'iframe',
|
|
67 'tbody', 'tfoot', 'th', 'thead', 'tr'])
|
|
68
|
|
69 ### front ends to tags to make our lives easier
|
|
70 ### these don't stomp on tags -- they're just front ends
|
|
71 ### (these should go in a separate file)
|
|
72
|
|
73 def image(src, **attributes):
|
|
74 attributes['src'] = src
|
|
75 return img(**attributes)
|
|
76
|
|
77 def link(location, description=None, **attributes):
|
|
78 if description is None:
|
|
79 description = location
|
|
80 attributes['href'] = location
|
|
81 return a(description, **attributes)
|
|
82
|
|
83 def listify(items, ordered=False, **attributes):
|
|
84 """
|
|
85 return a HTML list of iterable items
|
|
86 * ordered: whether the list is a <ol> (True) or an <ul> (False)
|
|
87 * item_attributes: attributes applied to each list item
|
|
88 """
|
|
89
|
|
90 # type of list
|
|
91 if ordered:
|
|
92 func = ol
|
|
93 else:
|
|
94 func = ul
|
|
95
|
|
96 item_attributes = attributes.pop('item_attributes', {})
|
|
97 listitems = [ li(item, **item_attributes) for item in items ]
|
|
98 return func('\n'.join(listitems), **attributes)
|
|
99
|
|
100 def definition_list(items, header=None, **attributes):
|
|
101 """definition list
|
|
102 items can be a dictionary or a list of 2-tuples"""
|
|
103 # XXX no attributes for header, dts, dds (yet)
|
|
104
|
|
105 if header is None:
|
|
106 header = '',
|
|
107 else:
|
|
108 header = '%s\n' % lh(header)
|
|
109
|
|
110 # convert dicts to lists of 2-tuples
|
|
111 if hasattr(items, 'items'):
|
|
112 items = items.items()
|
|
113
|
|
114 items = [ dt(term) + dd(definition) for term, definition in items ]
|
|
115 return dl(('\n%s%s\n' % ( header, '\n'.join(items))), **attributes)
|
|
116
|
|
117 def tablify(rows, header=False, item_attributes=None,
|
|
118 **attributes):
|
|
119 """return an HTML table from a iterable of iterable rows"""
|
|
120
|
|
121 if item_attributes is None:
|
|
122 item_attributes = {}
|
|
123
|
|
124 retval = []
|
|
125 if header:
|
|
126 markup = th
|
|
127 else:
|
|
128 markup = td
|
|
129
|
|
130 for row in rows:
|
|
131 retval.append('\n'.join([markup(str(item)) for item in row]))
|
|
132 markup = td
|
|
133
|
|
134 return table('\n\n'.join([tr(row) for row in retval]))
|
|
135
|
|
136 def wrap(string, pagetitle=None, stylesheets=(), icon=None, head_markup=()):
|
|
137 """wrap a string in a webpage"""
|
|
138
|
|
139 _head = ''
|
|
140 if pagetitle:
|
|
141 _head += title(pagetitle)
|
|
142 rel = 'stylesheet'
|
|
143 for i in stylesheets:
|
|
144 attributes = dict(rel=rel,
|
|
145 type='text/css')
|
|
146 if hasattr(i, '__iter__'):
|
|
147 # assume a 2-tuple
|
|
148 attributes['href'] = i[0]
|
|
149 attributes['title'] = i[1]
|
|
150 else:
|
|
151 attributes['href'] = i
|
|
152 _head += '\n' + HTMLmarkup('link', None, **attributes)
|
|
153 rel = 'alternate stylesheet' # first stylesheet is default
|
|
154 if icon:
|
|
155 _head += '\n' + HTMLmarkup('link', None, href=icon)
|
|
156
|
|
157 if head_markup:
|
|
158 # additional markup for <head>
|
|
159 if isinstance(head_markup, basestring):
|
|
160 _head += '\n' + head_markup
|
|
161 else:
|
|
162 for item in head_markup:
|
|
163 _head += '\n' + item
|
|
164 if _head:
|
|
165 _head = head(_head)
|
|
166
|
|
167 return html('%s\n\n%s' % ( _head, body(string) ) )
|