fix(weixin): wrap long copy-unfriendly lines

This commit is contained in:
LeonSGP43 2026-05-03 21:23:43 +08:00 committed by Teknium
parent a494a614d0
commit 7244a1f0d3
2 changed files with 66 additions and 1 deletions

View file

@ -23,6 +23,7 @@ import re
import secrets
import struct
import tempfile
import textwrap
import time
import uuid
from datetime import datetime
@ -32,6 +33,8 @@ from urllib.parse import quote, urlparse
logger = logging.getLogger(__name__)
WEIXIN_COPY_LINE_WIDTH = 120
try:
import aiohttp
@ -731,6 +734,46 @@ def _normalize_markdown_blocks(content: str) -> str:
return "\n".join(result).strip()
def _wrap_copy_friendly_lines_for_weixin(content: str) -> str:
"""Wrap long display lines that are hard to copy in WeChat clients."""
if not content:
return content
wrapped: List[str] = []
in_code_block = False
for raw_line in content.splitlines():
line = raw_line.rstrip()
stripped = line.strip()
if _FENCE_RE.match(stripped):
in_code_block = not in_code_block
wrapped.append(line)
continue
if (
in_code_block
or len(line) <= WEIXIN_COPY_LINE_WIDTH
or not stripped
or stripped.startswith("|")
or _TABLE_RULE_RE.match(stripped)
):
wrapped.append(line)
continue
wrapped_lines = textwrap.wrap(
line,
width=WEIXIN_COPY_LINE_WIDTH,
break_long_words=False,
break_on_hyphens=False,
replace_whitespace=False,
drop_whitespace=True,
)
wrapped.extend(wrapped_lines or [line])
return "\n".join(wrapped).strip()
def _split_markdown_blocks(content: str) -> List[str]:
if not content:
return []
@ -2022,7 +2065,7 @@ class WeixinAdapter(BasePlatformAdapter):
def format_message(self, content: Optional[str]) -> str:
if content is None:
return ""
return _normalize_markdown_blocks(content)
return _wrap_copy_friendly_lines_for_weixin(_normalize_markdown_blocks(content))
async def send_weixin_direct(

View file

@ -54,6 +54,28 @@ class TestWeixinFormatting:
assert adapter.format_message(content) == content
def test_format_message_wraps_long_plain_lines_for_copying(self):
adapter = _make_adapter()
content = (
"Here is a long issue template line with many copyable fields "
+ " ".join(f"field_{idx}=value_{idx}" for idx in range(24))
)
formatted = adapter.format_message(content)
assert "\n" in formatted
assert all(len(line) <= weixin.WEIXIN_COPY_LINE_WIDTH for line in formatted.splitlines())
assert " ".join(formatted.split()) == " ".join(content.split())
def test_format_message_does_not_wrap_long_code_block_lines(self):
adapter = _make_adapter()
command = "hermes " + " ".join(f"--option-{idx}=value" for idx in range(30))
content = f"```bash\n{command}\n```"
assert adapter.format_message(content) == content
def test_format_message_returns_empty_string_for_none(self):
adapter = _make_adapter()