feature: first table implementation

This commit is contained in:
Prof. Dr. Matthias Jung DL9MJ
2025-05-14 14:53:31 +02:00
parent 0236f65bce
commit 4216ccce50
5 changed files with 115 additions and 5 deletions
+34 -1
View File
@@ -12,6 +12,7 @@ from .picture import Picture
from .question import Question from .question import Question
from .quote import Quote from .quote import Quote
from .references import References from .references import References
from .table import Table
from .tag import Tag from .tag import Tag
from .underline import Underline from .underline import Underline
from .unit import Unit from .unit import Unit
@@ -38,7 +39,8 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
References, References,
Question, Question,
Picture, Picture,
Photo Photo,
Table
) )
self.question_renderer = question_renderer self.question_renderer = question_renderer
@@ -196,3 +198,34 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
def render_photo(self, token) : def render_photo(self, token) :
return self.render_photo_helper(token.id, token.ref, token.text, token.number) return self.render_photo_helper(token.id, token.ref, token.text, token.number)
@staticmethod
def render_row_helper(row):
return f"""<tr>{row}</tr>"""
@staticmethod
def render_cell_helper(cell, alignment, type):
if alignment == "l":
return f"<{type} style='text-align: left;'>{cell}</{type}>"
elif alignment == "r":
return f"<{type} style='text-align: right;'>{cell}</{type}>"
elif alignment == "c":
return f"<{type} style='text-align: center;'>{cell}</{type}>"
else:
return f"<{type}>{cell}</{type}>"
def render_table(self, token):
data = token.table
alignment = token.alignment
table = "<table>"
for i, row in enumerate(data):
content = ""
for j, cell in enumerate(row[0]):
content += self.render_cell_helper(cell, alignment[j], ("th" if i==0 else "td"))
table += self.render_row_helper(content)
table += "</table>"
return table
+58
View File
@@ -0,0 +1,58 @@
from mistletoe.block_token import BlockToken
class Table(BlockToken):
@staticmethod
def start(line):
return '|' in line
@classmethod
def parseHeader(self, line):
line = line.strip().strip('|') # Remove leading/trailing whitespace and pipes
columns = [col.strip() for col in line.split('|')] # Split by pipe |
alignment = []
data = []
for column in columns:
attr, val = column.split(':')
alignment.append(attr)
data.append(val)
return data, alignment
@classmethod
def parseRow(self, line):
line = line.strip().strip('|')
columns = [col.strip() for col in line.split('|')]
data = []
for column in columns:
data.append(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")
+1 -1
View File
@@ -79,7 +79,7 @@ CQ CQ hier ist DL1PZ mit einem allgemeinen Anruf, hier ist DL1PZ und hört.
</indepth> </indepth>
<webmargin> <webmargin>
| c | l | c | l | c | l | | c: | l: | c: | l: | c: | l: |
| | | | | | | | | | | | | |
| A | [morse:a] | K | [morse:k] | U | [morse:u] | | A | [morse:a] | K | [morse:k] | U | [morse:u] |
| B | [morse:b] | L | [morse:l] | V | [morse:v] | | B | [morse:b] | L | [morse:l] | V | [morse:v] |
+2 -2
View File
@@ -7,7 +7,7 @@ from test.util import paragraph
@pytest.mark.html @pytest.mark.html
def test_comment_html(): def test_question_html():
assertions = { assertions = {
"[question:123]": "123\n", "[question:123]": "123\n",
"\n[question:123]\n": "123\n", "\n[question:123]\n": "123\n",
@@ -24,7 +24,7 @@ def test_comment_html():
@pytest.mark.latex @pytest.mark.latex
def test_comment_latex(): def test_question_latex():
assertions = { assertions = {
"[question:123]": "123", "[question:123]": "123",
"\n[question:123]\n": "123", "\n[question:123]\n": "123",
+19
View File
@@ -0,0 +1,19 @@
import pytest
from mistletoe import Document
from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
@pytest.mark.html
def test_question_html():
assertions = {
"| l: abc | r: abc | X: abc |\n| 123 | 456 | 789 | \n | 987 | 654 | 321 | ": "<table><tr><th style='text-align: left;'> abc</th><th style='text-align: right;'> abc</th><th> abc</th></tr><tr><td style='text-align: left;'>123</td><td style='text-align: right;'>456</td><td>789</td></tr><tr><td style='text-align: left;'>987</td><td style='text-align: right;'>654</td><td>321</td></tr></table>\n",
"text\n| l: abc | r: abc | X: abc |\n| 123 | 456 | 789 | \n | 987 | 654 | 321 |\ntext": "text\n<table><tr><th style='text-align: left;'> abc</th><th style='text-align: right;'> abc</th><th> abc</th></tr><tr><td style='text-align: left;'>123</td><td style='text-align: right;'>456</td><td>789</td></tr><tr><td style='text-align: left;'>987</td><td style='text-align: right;'>654</td><td>321</td></tr></table>\ntext\n",
}
def test_function(input):
return f"{input}"
with FiftyOhmHtmlRenderer(test_function) as renderer:
for assertion in assertions:
assert renderer.render(Document(assertion)) == assertions[assertion]