feat(markdown): implement GFM table parser
This commit is contained in:
+42
-1
@@ -1,10 +1,51 @@
|
||||
import re
|
||||
from dataclasses import dataclass
|
||||
|
||||
_TABLE_SEPARATOR = re.compile(r"^\|?\s*:?-{2,}:?\s*(\|\s*:?-{2,}:?\s*)+\|?\s*$")
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class TableBlock:
|
||||
"""Frozen GFM table block.
|
||||
[C: src/markdown_helper.py:MarkdownRenderer.render]
|
||||
"""
|
||||
headers: list[str]
|
||||
rows: list[list[str]]
|
||||
span: tuple[int, int]
|
||||
|
||||
def _split_row(line: str) -> list[str]:
|
||||
line = line.strip()
|
||||
if line.startswith("|"): line = line[1:]
|
||||
if line.endswith("|"): line = line[:-1]
|
||||
return [c.strip() for c in line.split("|")]
|
||||
|
||||
def _is_table_at(lines: list[str], i: int) -> bool:
|
||||
if i + 1 >= len(lines): return False
|
||||
if "|" not in lines[i]: return False
|
||||
return bool(_TABLE_SEPARATOR.match(lines[i + 1]))
|
||||
|
||||
def parse_tables(text: str) -> list[TableBlock]:
|
||||
return []
|
||||
lines = text.splitlines()
|
||||
in_fence = False
|
||||
blocks: list[TableBlock] = []
|
||||
i = 0
|
||||
while i < len(lines):
|
||||
line = lines[i]
|
||||
if line.strip().startswith("```"):
|
||||
in_fence = not in_fence
|
||||
i += 1
|
||||
continue
|
||||
if in_fence:
|
||||
i += 1
|
||||
continue
|
||||
if _is_table_at(lines, i):
|
||||
headers = _split_row(lines[i])
|
||||
j = i + 2
|
||||
rows: list[list[str]] = []
|
||||
while j < len(lines) and "|" in lines[j] and not _TABLE_SEPARATOR.match(lines[j]):
|
||||
rows.append(_split_row(lines[j]))
|
||||
j += 1
|
||||
blocks.append(TableBlock(headers=headers, rows=rows, span=(i, j)))
|
||||
i = j
|
||||
continue
|
||||
i += 1
|
||||
return blocks
|
||||
|
||||
Reference in New Issue
Block a user