blob: 2f115b5577974872e50f8339e9c58ac2786e4e89 [file] [log] [blame]
David Spickett82c94b22023-06-12 16:18:33 +01001# This file contains a basic "builder" style API for making HTML tables
2# and writing them to a file once finished.
3#
4# Use it as follows:
5# with Table(outfile) as table:
6# table.AddRow().AddCell("foo")
7#
8# To get:
9# <table>
10# <td>foo</td>
11# </table>
12#
13# Methods return a reference to self, or to the new thing you added.
14# This means you can keep chaining calls to build what you want.
15#
16# table.AddRow().AddCell("foo").Colspan(1).Style("mystyle")
17
18
19class TableCell(object):
20 def __init__(self, name, content=None):
21 self.name = name
22 self.content = content
23 self.style = None
24 self.colspan = None
25
26 def Style(self, style):
27 self.style = style
28 return self
29
30 def Colspan(self, colspan):
31 self.colspan = colspan
32 return self
33
34 def Content(self, content):
35 self.content = content
36 return self
37
38 def __str__(self):
39 return " <{}{}{}>{}</{}>".format(
40 self.name,
41 "" if self.style is None else ' style="{}"'.format(self.style),
42 "" if self.colspan is None else " colspan={}".format(self.colspan),
43 "&nbsp;" if self.content is None else self.content,
44 self.name,
45 )
46
47
48class Cell(TableCell):
49 def __init__(self, content=None):
50 super(Cell, self).__init__("td", content)
51
52
53class Header(TableCell):
54 def __init__(self, content=None):
55 super(Header, self).__init__("th", content)
56
57
58class Row(object):
59 def __init__(self):
60 self.cells = []
61
62 def AddCell(self, content=None):
63 self.cells.append(Cell(content))
64 return self.cells[-1]
65
66 def AddHeader(self, content=None):
67 self.cells.append(Header(content))
68 return self.cells[-1]
69
70 def __str__(self):
71 return "\n".join([" <tr>", *map(str, self.cells), " </tr>"])
72
73
74class TableBody(object):
75 def __init__(self, close=False):
76 self.close = close
77
78 def __str__(self):
79 return "<{}tbody>".format("/" if self.close else "")
80
81
82class Table(object):
83 def __init__(self, out):
84 self.out = out
85 self.rows = []
86 self.border = None
87 self.cellspacing = None
88 self.cellpadding = None
89 self.body_begins = None
90
91 def __enter__(self):
92 return self
93
94 def __exit__(self, *args):
95 self.out.write("\n" + str(self))
96
97 def __str__(self):
98 open_tag = "<table{}{}{}>".format(
99 "" if self.border is None else " border={}".format(self.border),
100 ""
101 if self.cellspacing is None
102 else " cellspacing={}".format(self.cellspacing),
103 ""
104 if self.cellpadding is None
105 else " cellpadding={}".format(self.cellpadding),
106 )
107 rows = map(str, self.rows)
108 close_tag = "</table>"
109
110 return "\n".join([open_tag, *rows, close_tag])
111
112 def AddRow(self):
113 self.rows.append(Row())
114 return self.rows[-1]
115
116 def Border(self, border):
117 self.border = border
118 return self
119
120 def Cellspacing(self, cellspacing):
121 self.cellspacing = cellspacing
122 return self
123
124 def Cellpadding(self, cellpadding):
125 self.cellpadding = cellpadding
126 return self
127
128 def BeginBody(self):
129 self.rows.append(TableBody())
130
131 def EndBody(self):
132 self.rows.append(TableBody(close=True))