-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathhtml_writer.py
162 lines (123 loc) · 4.22 KB
/
html_writer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#!/usr/bin/env python3
"""Quick and dirty HTML writer."""
import re
import sys
HTML_SCRIPT_CODE = 'garden.js'
LINK_RE = re.compile(r'https?://[a-zA-Z0-9./-]*')
class HTMLWriter(object):
SPACE = ' '
def __init__(self, out=sys.stdout):
self.out = out
self.in_row = False
def write(self, content):
self.out.write(content)
def nl(self):
self.out.write('<br/>')
def preamble(self, css):
self.write('<!DOCTYPE html>\n<html lang="en">')
self.write('<head>\n')
self.write('<meta charset="utf-8">\n')
if css:
self.write('<style>\n')
self.write(css)
self.write('</style>\n')
self.write('<script type="text/javascript" src="%s"></script>\n' % HTML_SCRIPT_CODE)
def done(self):
self.write('</html>\n')
@staticmethod
def B(content):
return ''.join(['<b>', content, '</b>'])
@staticmethod
def space(n):
return HTMLWriter.SPACE * n
@staticmethod
def Link(content, link):
return '<a href="%s" target=_none>%s</a>' % (link, content)
class Div(object):
def __init__(self, parent, css_class):
self.parent = parent
self.css_class = css_class
def __enter__(self):
self.parent.write('<div class="%s">' % self.css_class)
return self
def __exit__(self, unused_type, unused_value, unused_traceback):
self.parent.write('</div>')
def div(self, css_class):
return HTMLWriter.Div(self, css_class)
class TableRow(object):
def __init__(self, parent, heading=False):
self.parent = parent
self.heading = heading
def write(self, content):
self.parent.write(content)
def __enter__(self):
self.write('<tr>\n')
return self
def __exit__(self, unused_type, unused_value, unused_traceback):
self.write('</tr>\n')
def cell(self, content, rowspan=None, colspan=None, css_class=None,
make_links=False):
with HTMLWriter.TableCell(
self, rowspan=rowspan, colspan=colspan, css_class=css_class,
make_links=make_links) as c:
c.write(content)
class TableCell(object):
def __init__(self, parent, rowspan=None, colspan=None, css_class=None,
make_links=False):
self.parent = parent
self.rowspan = rowspan
self.colspan = colspan
self.css_class = css_class
self.make_links = make_links
def write(self, content, css_class=None):
if self.make_links and content.find('<a href') < 0:
pos = 0
while True:
m = LINK_RE.search(content, pos)
if not m:
break
txt = m.group(0)
if txt.startswith('https://github.com/bazelbuild'):
txt = txt[29:]
link = '<a href="%s" target=_none>%s</a>' % (m.group(0), txt)
content = content[0:m.start()] + link + content[m.end():]
pos = m.start() + len(link)
if css_class:
self.write('<div class="%s">' % self.css_class)
one_line = len(content) < 70
if not one_line:
self.write('\n ')
self.parent.write(content.replace('\r', '').replace('\n', '<br/>'))
if not one_line:
self.write('\n ')
if css_class:
self.write('</div>')
def __enter__(self):
tag = 'td' if not self.parent.heading else 'th'
if self.rowspan:
tag = tag + ' rowspan="%d"' % self.rowspan
if self.colspan:
tag = tag + ' colspan="%d"' % self.colspan
# write through parent to avoid link expand
self.parent.write(' <%s>' % tag)
if self.css_class:
self.write('<div class="%s">' % self.css_class)
return self
def __exit__(self, unused_type, unused_value, unused_traceback):
if self.css_class:
self.write('</div>')
self.parent.write('</td>\n' if not self.parent.heading else '</th>\n')
class Table(object):
def __init__(self, parent):
self.parent = parent
def write(self, content):
self.parent.write(content)
def __enter__(self):
self.write('<table>\n')
return self
def __exit__(self, unused_type, unused_value, unused_traceback):
self.write('</table>\n')
def row(self, heading=False):
return HTMLWriter.TableRow(self.parent, heading=heading)
def table(self):
return HTMLWriter.Table(self)