From 97e6e905d472251d0a1b9ea2ce0d5799e1e03b9a Mon Sep 17 00:00:00 2001 From: Preet Mishra Date: Wed, 18 Mar 2020 18:17:14 +0530 Subject: [PATCH] boxes/helper: Add support for rendering tables. Added a helper function, render_table, to process a table and return its content as a list of strings which can then be rendered in the MessageBox. Tests amended. --- tests/ui/test_ui_tools.py | 12 +++++++++- zulipterminal/helper.py | 40 +++++++++++++++++++++++++++++++++ zulipterminal/ui_tools/boxes.py | 5 +++-- 3 files changed, 54 insertions(+), 3 deletions(-) diff --git a/tests/ui/test_ui_tools.py b/tests/ui/test_ui_tools.py index 7d003b3d52f..ed09d525701 100644 --- a/tests/ui/test_ui_tools.py +++ b/tests/ui/test_ui_tools.py @@ -1332,7 +1332,17 @@ def test_private_message_to_self(self, mocker): ('
', ['[RULER NOT RENDERED]']), ('', ['[IMAGE NOT RENDERED]']), ('', ['[IMAGE NOT RENDERED]']), - ('stuff
', ['[TABLE NOT RENDERED]']), + ('' + '
FirstnameLastname
JohnDoe
MaryMoe' + '
', [ + ('bold', '------------------------\n'), + ('bold', '| Firstname | Lastname |\n'), + ('bold', '------------------------\n'), + '| John | Doe |\n', + '------------------------\n', + '| Mary | Moe |\n', + '------------------------', + ]), ('some-math', ['some-math']), ('some-math', ['some-math']), ('', ['', ' * ', '', 'text']), diff --git a/zulipterminal/helper.py b/zulipterminal/helper.py index cf9093af4cd..5252bd55a9d 100644 --- a/zulipterminal/helper.py +++ b/zulipterminal/helper.py @@ -485,3 +485,43 @@ def notify(title: str, html_text: str) -> None: if command: res = subprocess.run(shlex.split(command), stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT) + + +def render_table(element: Any) -> List[Union[str, Tuple[str, str]]]: + """ + Renders table to be displayed in the MessageBox. + """ + # Header. + headers = element.find('thead').findChild().find_all('th') + # Cells store data column-wise. + cells = [[] for _ in headers] # type: List[List[str]] + for index, header in enumerate(headers): + cells[index].append(' ' + header.text + ' ') + + # Body. + rows = element.find('tbody').find_all('tr') + for row in rows: + for index, data in enumerate(row.find_all('td')): + cells[index].append(' ' + data.text + ' ') + + # Rendering. + col_width = [len(max(column, key=lambda s: len(s))) for column in cells] + dashes = ('-' * (sum(col_width) + len(headers) + 1)) + '\n' + contents = [] # type: List[Union[str, Tuple[str, str]]] + contents.append(('bold', dashes)) + rows_count = len(rows) + 1 # +1 to include header. + for index in range(rows_count): + row = '|' + '|'.join(col[index].ljust(col_width[col_index]) + for col_index, col in enumerate(cells)) + '|\n' + if index == 0: + # Make the headers bold. + contents.append(('bold', row)) + contents.append(('bold', dashes)) + else: + contents.append(row) + if index == rows_count - 1: + # Remove '\n' for the last row. + contents.append(dashes[:-1]) + else: + contents.append(dashes) + return contents diff --git a/zulipterminal/ui_tools/boxes.py b/zulipterminal/ui_tools/boxes.py index 6c3b317e273..4a88876d63d 100644 --- a/zulipterminal/ui_tools/boxes.py +++ b/zulipterminal/ui_tools/boxes.py @@ -13,7 +13,7 @@ from zulipterminal.config.keys import is_command_key, keys_for_command from zulipterminal.helper import ( - Message, match_groups, match_stream, match_user, + Message, match_groups, match_stream, match_user, render_table, ) from zulipterminal.urwid_types import urwid_Size @@ -386,7 +386,6 @@ def soup2markup(self, soup: Any) -> List[Any]: 'br': '', # No indicator of absence 'hr': 'RULER', 'img': 'IMAGE', - 'table': 'TABLE' } unrendered_div_classes = { # In pairs of 'div_class': 'text' # TODO: Support embedded content & twitter preview? @@ -482,6 +481,8 @@ def soup2markup(self, soup: Any) -> List[Any]: # TODO: Support nested lists markup.append(' * ') markup.extend(self.soup2markup(element)) + elif element.name == 'table': + markup.extend(render_table(element)) else: markup.extend(self.soup2markup(element)) return markup