fix: decode repeated source layout escapes

This commit is contained in:
wuyang
2026-07-26 14:37:56 +08:00
parent 2dd308cf3b
commit 1216e96038
2 changed files with 25 additions and 8 deletions
+13 -8
View File
@@ -257,19 +257,22 @@ def decode_code_layout_escapes(content: str) -> str:
index += 1 index += 1
continue continue
if content.startswith("\\r\\n", index): escaped_crlf = re.match(r"\\+r\\+n", content[index:])
if escaped_crlf:
output.append("\n") output.append("\n")
index += 4 index += len(escaped_crlf.group(0))
line_comment = False line_comment = False
continue continue
if content.startswith("\\n", index): escaped_newline = re.match(r"\\+n", content[index:])
if escaped_newline:
output.append("\n") output.append("\n")
index += 2 index += len(escaped_newline.group(0))
line_comment = False line_comment = False
continue continue
if content.startswith("\\t", index): escaped_tab = re.match(r"\\+t", content[index:])
if escaped_tab:
output.append("\t") output.append("\t")
index += 2 index += len(escaped_tab.group(0))
continue continue
if line_comment: if line_comment:
if content[index] == "\n": if content[index] == "\n":
@@ -297,13 +300,15 @@ def decode_code_layout_escapes(content: str) -> str:
def normalize_write_file_content(path: str, content: str) -> str: def normalize_write_file_content(path: str, content: str) -> str:
literal_newlines = content.count("\\n") + content.count("\\r\\n") literal_newlines = content.count("\\n") + content.count("\\r\\n")
actual_newlines = content.count("\n") if literal_newlines < 2:
if literal_newlines < 2 or literal_newlines <= max(2, actual_newlines * 2):
return content return content
suffix = PurePosixPath(path).suffix.lower() suffix = PurePosixPath(path).suffix.lower()
if suffix in CODE_FILE_SUFFIXES: if suffix in CODE_FILE_SUFFIXES:
return decode_code_layout_escapes(content) return decode_code_layout_escapes(content)
if suffix in PLAIN_TEXT_FILE_SUFFIXES: if suffix in PLAIN_TEXT_FILE_SUFFIXES:
actual_newlines = content.count("\n")
if literal_newlines <= max(2, actual_newlines * 2):
return content
return content.replace("\\r\\n", "\n").replace("\\n", "\n").replace("\\t", "\t") return content.replace("\\r\\n", "\n").replace("\\n", "\n").replace("\\t", "\t")
return content return content
+12
View File
@@ -34,6 +34,18 @@ def test_write_file_normalizes_double_escaped_code_layout() -> None:
) )
def test_write_file_normalizes_mixed_code_layout_without_touching_strings() -> None:
escaped = 'import time\nvalue = "keep\\\\ninside"\\nprint(value)\\n'
assert normalize_write_file_content("benchmark.py", escaped) == (
'import time\nvalue = "keep\\\\ninside"\nprint(value)\n'
)
def test_write_file_consumes_multiple_layout_escape_layers() -> None:
escaped = r"import time\\n\\ndef main():\\n print('ok')\\n"
assert normalize_write_file_content("benchmark.py", escaped) == ("import time\n\ndef main():\n print('ok')\n")
def test_write_file_normalizes_double_escaped_plain_text() -> None: def test_write_file_normalizes_double_escaped_plain_text() -> None:
assert normalize_write_file_content("report.md", r"# Report\n\nMeasured: 1.2 s\n") == ( assert normalize_write_file_content("report.md", r"# Report\n\nMeasured: 1.2 s\n") == (
"# Report\n\nMeasured: 1.2 s\n" "# Report\n\nMeasured: 1.2 s\n"