From 70c3c2b4f6ca5a0a690ec82ed3a5abb8b2b5cfc9 Mon Sep 17 00:00:00 2001 From: it-education-md <128720033+it-education-md@users.noreply.github.com> Date: Fri, 6 Mar 2026 17:04:05 -0500 Subject: [PATCH] Fix markdown newline removal for CJK list-marker false positive (#18867) --- changelog_unreleased/markdown/18867.md | 20 +++++++++++++++++++ src/language-markdown/print/mdast.js | 14 ++++++++++++- .../__snapshots__/format.test.js.snap | 20 +++++++++++++++++++ tests/format/markdown/paragraph/cjk.md | 4 ++++ 4 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 changelog_unreleased/markdown/18867.md diff --git a/changelog_unreleased/markdown/18867.md b/changelog_unreleased/markdown/18867.md new file mode 100644 index 000000000..0e5943136 --- /dev/null +++ b/changelog_unreleased/markdown/18867.md @@ -0,0 +1,20 @@ +#### Fix CJK line break loss near list-like numbers (#18867 by @it-education-md) + +Avoid collapsing line breaks before list-like numbers followed by CJK characters (e.g. 3.中). + + +```markdown + +1.a +2.b +3.中 + + +1.a +2.b 3.中 + + +1.a +2.b +3.中 +``` diff --git a/src/language-markdown/print/mdast.js b/src/language-markdown/print/mdast.js index 059029545..01c6f785b 100644 --- a/src/language-markdown/print/mdast.js +++ b/src/language-markdown/print/mdast.js @@ -52,6 +52,15 @@ function prevOrNextWord(path) { return hasPrevOrNextWord; } +function hasFakeWhitespaceAfterNextToken(path) { + const { siblings, index } = path; + if (!siblings || typeof index !== "number") { + return false; + } + const afterNext = siblings[index + 2]; + return afterNext?.type === "whitespace" && afterNext.value === ""; +} + function printMdast(path, options, print) { const { node } = path; @@ -109,7 +118,10 @@ function printMdast(path, options, print) { const proseWrap = // leading char that may cause different syntax - next && /^>|^(?:[*+-]|#{1,6}|\d+[).])$/.test(next.value) + next && + /^>|^(?:[*+-]|#{1,6}|\d+[).])$/.test(next.value) && + // Avoid https://github.com/prettier/prettier/issues/18861 + !hasFakeWhitespaceAfterNextToken(path) ? "never" : options.proseWrap; diff --git a/tests/format/markdown/paragraph/__snapshots__/format.test.js.snap b/tests/format/markdown/paragraph/__snapshots__/format.test.js.snap index 8018a52a1..7b0d2fad6 100644 --- a/tests/format/markdown/paragraph/__snapshots__/format.test.js.snap +++ b/tests/format/markdown/paragraph/__snapshots__/format.test.js.snap @@ -26,6 +26,10 @@ IVS 麻󠄁羽󠄀‼️ ⿰あ⿱あ⿲あ⿳あ⿴あ⿵あ⿶あ⿷あ⿸あ⿹あ⿺あ⿻あ +1.a +2.b +3.中 + =====================================output===================================== 這是一段很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長的段落 @@ -45,6 +49,8 @@ IVS 麻󠄁羽󠄀‼️ ⿰あ⿱あ⿲あ⿳あ⿴あ⿵あ⿶あ⿷あ⿸あ⿹あ⿺あ⿻あ +1.a 2.b 3.中 + ================================================================================ `; @@ -74,6 +80,10 @@ IVS 麻󠄁羽󠄀‼️ ⿰あ⿱あ⿲あ⿳あ⿴あ⿵あ⿶あ⿷あ⿸あ⿹あ⿺あ⿻あ +1.a +2.b +3.中 + =====================================output===================================== 這是一段很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長的段落 @@ -93,6 +103,8 @@ IVS 麻󠄁羽󠄀‼️ ⿰あ⿱あ⿲あ⿳あ⿴あ⿵あ⿶あ⿷あ⿸あ⿹あ⿺あ⿻あ +1.a 2.b 3.中 + ================================================================================ `; @@ -122,6 +134,10 @@ IVS 麻󠄁羽󠄀‼️ ⿰あ⿱あ⿲あ⿳あ⿴あ⿵あ⿶あ⿷あ⿸あ⿹あ⿺あ⿻あ +1.a +2.b +3.中 + =====================================output===================================== 這是一段很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長的段落 @@ -143,6 +159,10 @@ IVS 麻󠄁羽󠄀‼️ ⿰あ⿱あ⿲あ⿳あ⿴あ⿵あ⿶あ⿷あ⿸あ⿹あ⿺あ⿻あ +1.a +2.b +3.中 + ================================================================================ `; diff --git a/tests/format/markdown/paragraph/cjk.md b/tests/format/markdown/paragraph/cjk.md index 5d7dc6d1f..d769ad5d2 100644 --- a/tests/format/markdown/paragraph/cjk.md +++ b/tests/format/markdown/paragraph/cjk.md @@ -17,3 +17,7 @@ This ia an english paragraph with a CJK quote “中文“. IVS 麻󠄁羽󠄀‼️ ⿰あ⿱あ⿲あ⿳あ⿴あ⿵あ⿶あ⿷あ⿸あ⿹あ⿺あ⿻あ + +1.a +2.b +3.中