From 9a747dc8bf4b64f64248d131248e6d7b87312932 Mon Sep 17 00:00:00 2001 From: "Prof. Dr. Matthias Jung DL9MJ" Date: Wed, 14 May 2025 15:55:51 +0200 Subject: [PATCH] feature: html table implemented as envisioned by mistltoe developers --- renderer/fifty_ohm_html_renderer.py | 11 ++---- renderer/table.py | 57 ++++++++++++++++------------- test/test_table.py | 16 ++++---- 3 files changed, 44 insertions(+), 40 deletions(-) diff --git a/renderer/fifty_ohm_html_renderer.py b/renderer/fifty_ohm_html_renderer.py index cbc1a56..e8d03c8 100644 --- a/renderer/fifty_ohm_html_renderer.py +++ b/renderer/fifty_ohm_html_renderer.py @@ -215,17 +215,14 @@ class FiftyOhmHtmlRenderer(HtmlRenderer): return f"<{type}>{cell}" def render_table(self, token): - data = token.table alignment = token.alignment - table = "" - - for i, row in enumerate(data): + + for i, row in enumerate(token.children): content = "" - for j, cell in enumerate(row[0]): - content += self.render_cell_helper(cell, alignment[j], ("th" if i==0 else "td")) + for j, cell in enumerate(row.children): + content += self.render_cell_helper(self.render_inner(cell), alignment[j], ("th" if i==0 else "td")) table += self.render_row_helper(content) - table += "
" return table \ No newline at end of file diff --git a/renderer/table.py b/renderer/table.py index c95ff06..fae2fb4 100644 --- a/renderer/table.py +++ b/renderer/table.py @@ -1,4 +1,5 @@ +from mistletoe import span_token from mistletoe.block_token import BlockToken @@ -8,20 +9,40 @@ class Table(BlockToken): return '|' in line @classmethod - def parseHeader(self, line): + def parseHeader(cls, line): + # Parse header, extract alignment and make an ordinary row out of it line = line.strip().strip('|') # Remove leading/trailing whitespace and pipes columns = [col.strip() for col in line.split('|')] # Split by pipe | alignment = [] - data = [] + header = "| " for column in columns: attr, val = column.split(':') alignment.append(attr) - data.append(val) + header += val + " | " - return data, alignment + return header, alignment + @classmethod + def read(cls, lines): + header = next(lines) + header, alignment = cls.parseHeader(header) + rows = [TableRow(header)] + + for line in lines: + if "|" not in line : + break + else : + rows.append(TableRow(line)) + + return alignment, rows + + def __init__(self, match): + self.alignment, self.children = match + + +class TableRow(BlockToken): @classmethod def parseRow(self, line): line = line.strip().strip('|') @@ -30,29 +51,13 @@ class Table(BlockToken): data = [] for column in columns: - data.append(column) + data.append(TableCell(column)) return data - @classmethod - def read(self, lines): - - table = [] - - header = next(lines) - - data, alignment = self.parseHeader(header) - table.append([data]) - - for line in lines: - if "|" not in line: - break - data = self.parseRow(line) - table.append([data]) - - return [table, alignment] - def __init__(self, match): - self.table = match[0] - self.alignment = match[1] - print("init") + self.children = self.parseRow(match) + +class TableCell(BlockToken) : + def __init__(self, match): + super().__init__(match, span_token.tokenize_inner) diff --git a/test/test_table.py b/test/test_table.py index 6293444..46b96d2 100644 --- a/test/test_table.py +++ b/test/test_table.py @@ -5,15 +5,17 @@ from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer @pytest.mark.html -def test_question_html(): +def test_table_html(): assertions = { - "| l: abc | r: abc | X: abc |\n| 123 | 456 | 789 | \n | 987 | 654 | 321 | ": "
abc abc abc
123456789
987654321
\n", - "text\n| l: abc | r: abc | X: abc |\n| 123 | 456 | 789 | \n | 987 | 654 | 321 |\ntext": "text\n
abc abc abc
123456789
987654321
\ntext\n", + "| l: a |" : "
a
\n", + "| r: a |" : "
a
\n", + "| l: a |\n| *b* |" : "
a
b
\n", + "| l: *a* |" : "
a
\n", + "| l: a |\n| [morse:a] |" : "
a
\n\nā–„\n\nā–„ā–„ā–„\n\n
\n", + "| l: a |\n| b |" : "
a
b
\n", + "| l: abc | r: abc | X: abc |\n| 123 | 456 | 789 | \n | 987 | 654 | 321 | ": "
abcabcabc
123456789
987654321
\n", } - def test_function(input): - return f"{input}" - - with FiftyOhmHtmlRenderer(test_function) as renderer: + with FiftyOhmHtmlRenderer() as renderer: for assertion in assertions: assert renderer.render(Document(assertion)) == assertions[assertion]