diff --git a/modules/base/pymod/table.py b/modules/base/pymod/table.py index fc8ed05c8c8a157873b59a65a1fa4efbf6aad022..e5f46b260f01cc96d2d07457ffb6af04817d5124 100644 --- a/modules/base/pymod/table.py +++ b/modules/base/pymod/table.py @@ -1641,6 +1641,8 @@ class Table(object): ost ost-specific format (human readable) csv comma separated values (human readable) pickle pickled byte stream (binary) + html HTML table + context ConTeXt table ============= ======================================= :param stream_or_filename: filename or stream for writing output @@ -1658,6 +1660,10 @@ class Table(object): return self._SaveCSV(stream_or_filename, sep=sep) if format=='pickle': return self._SavePickle(stream_or_filename) + if format=='html': + return self._SaveHTML(stream_or_filename) + if format=='context': + return self._SaveContext(stream_or_filename) raise ValueError('unknown format "%s"' % format) def _SavePickle(self, stream): @@ -1665,6 +1671,79 @@ class Table(object): stream=open(stream, 'wb') cPickle.dump(self, stream, cPickle.HIGHEST_PROTOCOL) + def _SaveHTML(self, stream_or_filename): + def _escape(s): + return s.replace('&', '&').replace('>', '>').replace('<', '<') + + file_opened = False + if not hasattr(stream_or_filename, 'write'): + stream = open(stream_or_filename, 'w') + file_opened = True + else: + stream = stream_or_filename + stream.write('<table>') + stream.write('<tr>') + for col_name in self.col_names: + stream.write('<th>%s</th>' % _escape(col_name)) + stream.write('</tr>') + for row in self.rows: + stream.write('<tr>') + for i, col in enumerate(row): + val = '' + if col != None: + if self.col_types[i] == 'float': + val = '%.3f' % col + elif self.col_types[i] == 'int': + val = '%d' % col + elif self.col_types[i] == 'bool': + val = col and 'true' or 'false' + else: + val = str(col) + stream.write('<td>%s</td>' % _escape(val)) + stream.write('</tr>') + stream.write('</table>') + if file_opened: + stream.close() + def _SaveContext(self, stream_or_filename): + file_opened = False + if not hasattr(stream_or_filename, 'write'): + stream = open(stream_or_filename, 'w') + file_opened = True + else: + stream = stream_or_filename + stream.write('\\starttable[') + for col_type in self.col_types: + if col_type =='string': + stream.write('l|') + elif col_type=='int': + stream.write('r|') + elif col_type =='float': + stream.write('i3r|') + else: + stream.write('l|') + stream.write(']\n\\HL\n') + for col_name in self.col_names: + stream.write('\\NC \\bf %s' % col_name) + stream.write(' \\AR\\HL\n') + for row in self.rows: + for i, col in enumerate(row): + val = '---' + if col != None: + if self.col_types[i] == 'float': + val = '%.3f' % col + elif self.col_types[i] == 'int': + val = '%d' % col + elif self.col_types[i] == 'bool': + val = col and 'true' or 'false' + else: + val = str(col) + stream.write('\\NC %s' % val) + stream.write(' \\AR\n') + stream.write('\\HL\n') + stream.write('\\stoptable') + if file_opened: + stream.close() + def _SaveCSV(self, stream, sep): if not hasattr(stream, 'write'): stream=open(stream, 'wb') @@ -2400,4 +2479,3 @@ def Merge(table1, table2, by, only_matching=False): new_tab.AddRow(row) return new_tab - diff --git a/modules/base/tests/test_table.py b/modules/base/tests/test_table.py index 5e2e82824cad6963f3da7a5ce81e3ec70309a2ba..7a10f4ee131ac625e24d33a4cca634ca53d57803 100644 --- a/modules/base/tests/test_table.py +++ b/modules/base/tests/test_table.py @@ -853,6 +853,19 @@ class TestTable(unittest.TestCase): # read from disc tab_loaded_fname = Table.Load('saveloadtable_withspaces_filename_out.tab') self.CompareDataFromDict(tab_loaded_fname, {'first': ['x','foo',None,'hello spaces'], 'second': [3,None,9,10], 'third': [None,2.2,3.3,10.1]}) + def testSaveTableHTML(self): + import StringIO + tab = self.CreateTestTable() + stream = StringIO.StringIO() + tab.Save(stream, format='html') + self.assertEqual(stream.getvalue(), '<table><tr><th>first</th><th>second</th><th>third</th></tr><tr><td>x</td><td>3</td><td></td></tr><tr><td>foo</td><td></td><td>2.200</td></tr><tr><td></td><td>9</td><td>3.300</td></tr></table>') + def testSaveTableContext(self): + import StringIO + tab = self.CreateTestTable() + stream = StringIO.StringIO() + tab.Save(stream, format='context') + self.assertEqual(stream.getvalue(), + '\\starttable[l|r|i3r|]\n\\HL\n\\NC \\bf first\\NC \\bf second\\NC \\bf third \\AR\\HL\n\\NC x\\NC 3\\NC --- \\AR\n\\NC foo\NC ---\NC 2.200 \\AR\n\\NC ---\\NC 9\\NC 3.300 \\AR\n\\HL\n\\stoptable') def testSaveLoadTableCSV(self): tab = self.CreateTestTable()