fix(feishu): fix markdown rendering issues in headings and tables
- Fix double bold markers (****) when heading text already contains ** - Strip markdown formatting (**bold**, *italic*, ~~strike~~) from table cells since Feishu table elements do not support markdown rendering Fixes rendering issues where: 1. Headings like '**text**' were rendered as '****text****' 2. Table cells with '**bold**' showed raw markdown instead of plain text
This commit is contained in:
@@ -437,16 +437,36 @@ class FeishuChannel(BaseChannel):
|
|||||||
|
|
||||||
_CODE_BLOCK_RE = re.compile(r"(```[\s\S]*?```)", re.MULTILINE)
|
_CODE_BLOCK_RE = re.compile(r"(```[\s\S]*?```)", re.MULTILINE)
|
||||||
|
|
||||||
@staticmethod
|
# Markdown bold/italic patterns that need to be stripped for table cells
|
||||||
def _parse_md_table(table_text: str) -> dict | None:
|
_MD_BOLD_RE = re.compile(r"\*\*(.+?)\*\*")
|
||||||
|
_MD_ITALIC_RE = re.compile(r"(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)")
|
||||||
|
_MD_STRIKE_RE = re.compile(r"~~(.+?)~~")
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _strip_md_formatting(cls, text: str) -> str:
|
||||||
|
"""Strip markdown formatting markers from text for plain display.
|
||||||
|
|
||||||
|
Feishu table cells do not support markdown rendering, so we remove
|
||||||
|
the formatting markers to keep the text readable.
|
||||||
|
"""
|
||||||
|
# Remove bold markers
|
||||||
|
text = cls._MD_BOLD_RE.sub(r"\1", text)
|
||||||
|
# Remove italic markers
|
||||||
|
text = cls._MD_ITALIC_RE.sub(r"\1", text)
|
||||||
|
# Remove strikethrough markers
|
||||||
|
text = cls._MD_STRIKE_RE.sub(r"\1", text)
|
||||||
|
return text
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _parse_md_table(cls, table_text: str) -> dict | None:
|
||||||
"""Parse a markdown table into a Feishu table element."""
|
"""Parse a markdown table into a Feishu table element."""
|
||||||
lines = [_line.strip() for _line in table_text.strip().split("\n") if _line.strip()]
|
lines = [_line.strip() for _line in table_text.strip().split("\n") if _line.strip()]
|
||||||
if len(lines) < 3:
|
if len(lines) < 3:
|
||||||
return None
|
return None
|
||||||
def split(_line: str) -> list[str]:
|
def split(_line: str) -> list[str]:
|
||||||
return [c.strip() for c in _line.strip("|").split("|")]
|
return [c.strip() for c in _line.strip("|").split("|")]
|
||||||
headers = split(lines[0])
|
headers = [cls._strip_md_formatting(h) for h in split(lines[0])]
|
||||||
rows = [split(_line) for _line in lines[2:]]
|
rows = [[cls._strip_md_formatting(c) for c in split(_line)] for _line in lines[2:]]
|
||||||
columns = [{"tag": "column", "name": f"c{i}", "display_name": h, "width": "auto"}
|
columns = [{"tag": "column", "name": f"c{i}", "display_name": h, "width": "auto"}
|
||||||
for i, h in enumerate(headers)]
|
for i, h in enumerate(headers)]
|
||||||
return {
|
return {
|
||||||
@@ -513,11 +533,16 @@ class FeishuChannel(BaseChannel):
|
|||||||
if before:
|
if before:
|
||||||
elements.append({"tag": "markdown", "content": before})
|
elements.append({"tag": "markdown", "content": before})
|
||||||
text = m.group(2).strip()
|
text = m.group(2).strip()
|
||||||
|
# Avoid double bold markers if text already contains them
|
||||||
|
if text.startswith("**") and text.endswith("**"):
|
||||||
|
display_text = text
|
||||||
|
else:
|
||||||
|
display_text = f"**{text}**"
|
||||||
elements.append({
|
elements.append({
|
||||||
"tag": "div",
|
"tag": "div",
|
||||||
"text": {
|
"text": {
|
||||||
"tag": "lark_md",
|
"tag": "lark_md",
|
||||||
"content": f"**{text}**",
|
"content": display_text,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
last_end = m.end()
|
last_end = m.end()
|
||||||
|
|||||||
Reference in New Issue
Block a user