fix(turnreply): 围栏闭合串不得短于开启串(复审 p2 收口)
复审 review-m19-r1 的 p2:`codeProtectedEnd` 的围栏分支只判「下一个 ≥3 反引号
的串」,没判「闭合不短于开启」。CommonMark 要求闭合串**至少与开启串等长**,
因此 ```` 开启的围栏不能被内层 ``` 关闭。复现形态(````markdown 里嵌 ```go,
示例里写 `print("a\nb")`):旧实现把内层 ``` 当闭合 ⇒ 之后的示例正文被当普通
正文渲染,代码里的 `\n` 变成真换行;而这一步跑在**落库之前**,改坏的代码会永久进
历史 —— 反向踩了本文件「宁可少渲染也不改坏代码」的自己的红线。
- literal_breaks.go:围栏分支改为 findBacktickRun(text, body, n, unboundedRun)
(closing ≥ opening);注释写明 CommonMark 口径与「改了会落库」的后果。
- 新增 TestRenderLiteralLineBreaks_NestedFenceRespectsOpeningRun:嵌套围栏逐字保留、
围栏外仍照常渲染(保护不得溢出)。摘掉这一行 ⇒ 该用例红,还原即绿。
- 新增 TestTurnReply_DoubleLiteralBreakBecomesParagraphBreak:钉住 `\n\n` ⇒ 空行 ⇒
两段 <p> ⇒ 两端各 2 条气泡(复审观察②,语义对但此前无用例覆盖)。
- 措辞收口:样本 455 字符 / 907 字节;IM 侧主动推送的注释补明「Web 活跃客户端那条
主动推送不经 NormalizeParagraphs,另计」。
行内代码那条等长分支未动。全树 go build ./... + go vet ./... + go test -count=1 ./...
全绿(73 包,RC 0)。
This commit is contained in:
1 parent
fa573663c1
commit
6b0af81136
3 files changed
+68
-11
No files matched your search
@@ -79,8 +79,30 @@ func TestRenderLiteralLineBreaks_CodeFenceProtected(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestRenderLiteralLineBreaks_NestedFenceRespectsOpeningRun 钉住 CommonMark 的围栏闭合
|
||||
// 口径:**闭合串不得短于开启串**。四个反引号开启的围栏里嵌着三反引号的示例时,内层
|
||||
// ``` 只是**代码内容**,不能把外层围栏闭合 —— 否则示例里的 `print("a\nb")` 会被渲染成
|
||||
// 真换行,而这段文本紧接着就落库(改坏的代码会永久进历史)。
|
||||
func TestRenderLiteralLineBreaks_NestedFenceRespectsOpeningRun(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
const nested = "````markdown\n```go\nfmt.Println(\"a" + literalEscapeSample + "b\")\n```\n````"
|
||||
in := "教你怎么写围栏代码块:\n\n" + nested + "\n\n围栏之后这句" + literalEscapeSample + "也换行。"
|
||||
got := RenderLiteralLineBreaks(in)
|
||||
|
||||
if !strings.Contains(got, nested) {
|
||||
t.Fatalf("嵌套围栏没有被逐字保留(内层 ``` 提前闭合了外层 ````):\n got %q\nwant 含 %q", got, nested)
|
||||
}
|
||||
if strings.Contains(got, "fmt.Println(\"a\nb\")") {
|
||||
t.Fatalf("嵌套围栏里的字面 `\\n` 被渲染成真换行 —— 代码内容被改坏:\n%q", got)
|
||||
}
|
||||
if !strings.HasSuffix(got, "围栏之后这句\n也换行。") {
|
||||
t.Fatalf("围栏之外的正文没被渲染(保护不得溢出):\n%q", got)
|
||||
}
|
||||
}
|
||||
|
||||
// TestRenderLiteralLineBreaks_InlineCodeProtected 是必测②的另一半:行内代码
|
||||
// (“ `…` “ 与等长的 “ “…“ “)里的 `\n` 也不动。
|
||||
// (单个反引号与两个反引号两种定界符)里的 `\n` 也不动。
|
||||
func TestRenderLiteralLineBreaks_InlineCodeProtected(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
Reference in new issue
Block a user