feat: parse table captions

This commit is contained in:
Tim Grelka
2025-05-14 23:24:33 +02:00
parent 1a8656428d
commit 60e8d65e04
2 changed files with 37 additions and 19 deletions
+8 -5
View File
@@ -210,13 +210,16 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
def render_table(self, token): def render_table(self, token):
alignment = token.alignment alignment = token.alignment
table = "<table>" table = "<table>\n"
for i, row in enumerate(token.children): for i, row in enumerate(token.children):
content = "" content = ""
for j, cell in enumerate(row.children): for j, cell in enumerate(row.children):
content += self.render_cell_helper(self.render_inner(cell), alignment[j], ("th" if i==0 else "td")) content += self.render_cell_helper(self.render_inner(cell), alignment[j], ("th" if i == 0 else "td"))
table += f"<tr>{content}</tr>" table += f"<tr>\n{content}</tr>\n"
if token.caption != "":
table += f"<caption>{token.caption}</caption>"
table += "</table>" table += "</table>"
return table return table
+29 -14
View File
@@ -1,3 +1,4 @@
import re
from mistletoe import span_token from mistletoe import span_token
from mistletoe.block_token import BlockToken from mistletoe.block_token import BlockToken
@@ -6,13 +7,13 @@ from mistletoe.block_token import BlockToken
class Table(BlockToken): class Table(BlockToken):
@staticmethod @staticmethod
def start(line): def start(line):
return '|' in line return "|" in line
@classmethod @classmethod
def parse_header(cls, line): def parse_header(cls, line):
# Parse header, extract alignment and make an ordinary row out of it # Parse header, extract alignment and make an ordinary row out of it
line = line.strip().strip('|') # Remove leading/trailing whitespace and pipes line = line.strip().strip("|") # Remove leading/trailing whitespace and pipes
columns = [col.strip() for col in line.split('|')] # Split by pipe | columns = [col.strip() for col in line.split("|")] # Split by pipe |
alignment = [] alignment = []
header = "| " header = "| "
@@ -21,32 +22,45 @@ class Table(BlockToken):
attr, val = re.match(r"^ ?(?:([lcrX]):)?(.*)", column).group(1, 2) attr, val = re.match(r"^ ?(?:([lcrX]):)?(.*)", column).group(1, 2)
alignment.append(attr) alignment.append(attr)
header += val + " | " header += val + " | "
return header, alignment return header, alignment
@classmethod @classmethod
def read(cls, lines): def read(cls, lines):
header = next(lines) header = next(lines)
header, alignment = cls.parse_header(header) header, alignment = cls.parse_header(header)
name = ""
caption = ""
rows = [TableRow(header)] rows = [TableRow(header)]
for line in lines: # Read table until the end: No more column definitions, caption, or empty line.
if "|" not in line : line_buffer = []
next_line = lines.peek()
while next_line is not None and next_line.strip() != "":
maybe_caption = re.match(r"\[table:([^:\]]+):([^:\]]+)\]", next_line)
if maybe_caption is not None:
name, caption = maybe_caption.group(1, 2)
next(lines)
break break
else : elif "|" not in next_line:
rows.append(TableRow(line)) break
else:
line_buffer.append(next(lines))
next_line = lines.peek()
return alignment, rows rows.extend([TableRow(line) for line in line_buffer])
return alignment, rows, name, caption
def __init__(self, match): def __init__(self, match):
self.alignment, self.children = match self.alignment, self.children, self.name, self.caption = match
class TableRow(BlockToken): class TableRow(BlockToken):
@classmethod @classmethod
def parse_row(cls, line): def parse_row(cls, line):
line = line.strip().strip('|') line = line.strip().strip("|")
columns = [col.strip() for col in line.split('|')] columns = [col.strip() for col in line.split("|")]
data = [] data = []
@@ -58,6 +72,7 @@ class TableRow(BlockToken):
def __init__(self, match): def __init__(self, match):
self.children = self.parse_row(match) self.children = self.parse_row(match)
class TableCell(BlockToken) :
class TableCell(BlockToken):
def __init__(self, match): def __init__(self, match):
super().__init__(match, span_token.tokenize_inner) super().__init__(match, span_token.tokenize_inner)