formatters.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. # coding=utf-8
  2. """
  3. 通知内容格式转换模块
  4. 提供不同推送平台间的格式转换功能
  5. """
  6. import re
  7. def strip_markdown(text: str) -> str:
  8. """去除文本中的 markdown 语法格式,用于个人微信推送
  9. Args:
  10. text: 包含 markdown 格式的文本
  11. Returns:
  12. 纯文本内容
  13. """
  14. # 转换链接 [text](url) -> text url(保留 URL)
  15. text = re.sub(r'\[([^\]]+)\]\(([^)]+)\)', r'\1 \2', text)
  16. # 先保护 URL,避免后续 markdown 清洗误伤链接中的下划线等字符
  17. protected_urls: list[str] = []
  18. def _protect_url(match: re.Match) -> str:
  19. protected_urls.append(match.group(0))
  20. return f"@@URLTOKEN{len(protected_urls) - 1}@@"
  21. text = re.sub(r'https?://[^\s<>\]]+', _protect_url, text)
  22. # 去除粗体 **text** 或 __text__
  23. text = re.sub(r'\*\*(.+?)\*\*', r'\1', text)
  24. text = re.sub(r'(?<!\w)__(?!\s)(.+?)(?<!\s)__(?!\w)', r'\1', text)
  25. # 去除斜体 *text* 或 _text_
  26. text = re.sub(r'\*(.+?)\*', r'\1', text)
  27. text = re.sub(r'(?<!\w)_(?!\s)(.+?)(?<!\s)_(?!\w)', r'\1', text)
  28. # 去除删除线 ~~text~~
  29. text = re.sub(r'~~(.+?)~~', r'\1', text)
  30. # 去除图片 ![alt](url) -> alt
  31. text = re.sub(r'!\[(.+?)\]\(.+?\)', r'\1', text)
  32. # 去除行内代码 `code`
  33. text = re.sub(r'`(.+?)`', r'\1', text)
  34. # 去除引用符号 >
  35. text = re.sub(r'^>\s*', '', text, flags=re.MULTILINE)
  36. # 去除标题符号 # ## ### 等
  37. text = re.sub(r'^#+\s*', '', text, flags=re.MULTILINE)
  38. # 去除水平分割线 --- 或 ***
  39. text = re.sub(r'^[\-\*]{3,}\s*$', '', text, flags=re.MULTILINE)
  40. # 去除 HTML 标签 <font color='xxx'>text</font> -> text
  41. text = re.sub(r'<font[^>]*>(.+?)</font>', r'\1', text)
  42. text = re.sub(r'<[^>]+>', '', text)
  43. # 清理多余的空行(保留最多两个连续空行)
  44. text = re.sub(r'\n{3,}', '\n\n', text)
  45. # 还原之前保护的 URL
  46. for idx, url in enumerate(protected_urls):
  47. text = text.replace(f"@@URLTOKEN{idx}@@", url)
  48. return text.strip()
  49. def convert_markdown_to_mrkdwn(content: str) -> str:
  50. """
  51. 将标准 Markdown 转换为 Slack 的 mrkdwn 格式
  52. 转换规则:
  53. - **粗体** → *粗体*
  54. - [文本](url) → <url|文本>
  55. - 保留其他格式(代码块、列表等)
  56. Args:
  57. content: Markdown 格式的内容
  58. Returns:
  59. Slack mrkdwn 格式的内容
  60. """
  61. # 1. 转换链接格式: [文本](url) → <url|文本>
  62. content = re.sub(r'\[([^\]]+)\]\(([^)]+)\)', r'<\2|\1>', content)
  63. # 2. 转换粗体: **文本** → *文本*
  64. content = re.sub(r'\*\*([^*]+)\*\*', r'*\1*', content)
  65. return content