from quixote.html import value_quote def render_attr (attr, val): if attr == 'klass': attr = 'class' if val is None: return ' %s' % attr return ' %s=%s' % (attr, value_quote(val)) def render_attrs (attrs): render = '' for (attr, val) in attrs.items(): render += render_attr(attr, val) return render class Table: def __init__ (self, **attrs): self.table_attrs = attrs self.rows = [] def set_table_attr (self, attr, val): self.table_attrs[attr] = val def set_tr_attr (self, row, col, attr, val): self.rows[row][1][attr] = val def set_cell_attr (self, row, col, attr, val): self.rows[row][0][col][2][attr] = val def tr (self, row=None, **attrs): if row is None: self.rows.append(([], attrs)) else: self.rows.insert(row, ([], attrs)) def th (self, text, row=None, col=None, **attrs): th = ('th', text, attrs) if row is None: row = self.rows[-1] else: row = self.rows[row] if col is None: row[0].append(th) else: row[0].insert(col, th) def td (self, text, row=None, col=None, **attrs): td = ('td', text, attrs) if row is None: row = self.rows[-1] else: row = self.rows[row] if col is None: row[0].append(td) else: row[0].insert(col, td) def render (self): if not self.rows: return '' output = '\n' % render_attrs(self.table_attrs) for row in self.rows: output += '\n' % render_attrs(row[1]) for cell in row[0]: output += '\n<%s%s>%s' % (cell[0], render_attrs(cell[2]), cell[1], cell[0]) output += '\n' output += '\n' return output template table_example (): example = Table(style='border: thin solid black; padding: 2px') example.tr() example.th('Example Header') example.tr() example.th('Header span 2 columns', colspan=2) example.tr(style='background-color: #ffff66') example.td('Stuff span 2 columns', colspan=2) example.tr(row=0, style='background-color: #f6f6f6') example.th('Inserted Header', row=0, style='background-color: #f666f6') example.td('Inserted Stuff', row=0, col=0) example.render()