[Bug]: On 53.x, CRLF paragraph and blockquote text serializes with a lone `\r` and an extra hard break (fixed on `next` by #5152, not released)
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 70/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- typescript
- Ambito
- backend
Direzione di ricerca
Start with packages/markdown/src/lib/rules/defaultRules.ts:162-182 and the three reproduction inputs in the issue; compare the current line splitting with the paragraph handling described for PR #5152. Run the supplied bun reproduction and check serializeMd output for CRLF paragraph and blockquote text against the LF case. Done when CRLF output matches LF output and LF output stays unchanged.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Bug type
Regression (worked before, now fails)
Browser surface
No
Owner surface
Plate framework or plugin
Summary
On @platejs/markdown 53.x, paragraph and blockquote text with CRLF line endings serializes with a lone \r followed by a hard break (\). PR #5152 fixes this on next, but it is not in any 53.x release.
Public reproduction URL
https://gist.github.com/venmakli/97e3b7778ead568b96ac990fa3f760ee
Steps to reproduce
- Download the reproduction (
package.jsonandrepro.ts). - Run
bun install && bun repro.ts. line one\r\nline twoserializes toline one\r\\\nline two, and> q1\r\n> q2to> q1\r> \\\n> q2. The LF input serializes toline one\\\nline two.
Expected behavior
The CRLF input serializes like its LF version, which repro.ts prints next to it: line one\ + LF + line two, without a lone \r. On 53.1.5 the CRLF input did not produce a lone \r or an extra \ (see "Regression range").
Actual behavior
On @platejs/markdown 53.3.18 (output of repro.ts):
"line one\r\nline two\r\n"
value: [{"children":[{"text":"line one\r\nline two"}],"type":"p"}]
serialize: "line one\r\\\nline two\n"
"> q1\r\n> q2\r\n"
value: [{"children":[{"children":[{"text":"q1\r\nq2"}],"type":"p"}],"type":"blockquote"}]
serialize: "> q1\r> \\\n> q2\n"
"line one\nline two\n"
value: [{"children":[{"text":"line one\nline two"}],"type":"p"}]
serialize: "line one\\\nline two\n"
The output keeps a lone \r, which CommonMark reads as a line ending of its own. The blockquote output gets an extra > \ line. A second deserialize → serialize round trip keeps both.
Acceptance criteria
- On the 53.x line,
serializeMdoutput for CRLF paragraph and blockquote text has no lone\rand equals the output for the LF version of the same input. - Output for LF input is unchanged.
Question for maintainers: will #5152 (or its paragraph-text part) be backported to 53.x, or will the fix ship only with v54?
Regression range
last-known-good: "@platejs/markdown 53.1.5 (published 2026-06-14), with platejs 53.1.2"
first-known-bad: "@platejs/markdown 53.2.2 (published 2026-06-17), with platejs 53.2.1; still present in 53.3.18 and on main (170d73db6, 2026-10-23)"
evidence: >
Same script on both versions. 53.1.5: "line one\r\nline two\r\n" -> "line one\r\nline two\n" and "> q1\r\n> q2\r\n" -> "> q1\r\n> q2\n"
(no lone CR, no hard break). 53.2.2: "line one\r\\\nline two\n" and "> q1\r> \\\n> q2\n".
53.2.2 is the first release after PR #5026 (commit b99cebe3d "fix markdown text leaf line breaks", merged into main 2026-06-17T09:18Z).
It added normalizeParagraphLineBreaks, which splits text with text.split('\n')
(v53.3.18 packages/markdown/src/lib/rules/defaultRules.ts:169); the 53.1.5 dist has no normalizeParagraphLineBreaks.
PR #5152 (merged into next 2026-10-08T22:42Z) splits paragraph text with /\r?\n/ in encodeMarkdownParagraph
(next: packages/platejs/src/markdown/lib/internal/markdownIntrinsics.ts). 53.3.18 (2026-10-18) was released from main
without it; main's defaultRules.ts is identical to v53.3.18.
Reproducibility
Always
Plate / Plite / React versions
plate: "@platejs/markdown 53.3.18, platejs 53.3.18 (mdast-util-from-markdown 2.1.0, mdast-util-to-markdown 2.2.1)"
plite: not used
plite-react: not used
react: not used
Operating system
macOS 15 (Darwin 24.6.0)
Install method
bun 1.4.4: bun install && bun repro.ts
Framework / app setup
Headless createSlateEditor with MarkdownPlugin only, no React.
Affected packages or entry points
@platejs/markdown: editor.api.markdown.serialize / serializeMd (p rule via normalizeParagraphLineBreaks, blockquote), with values from deserializeMd for CRLF input.
Minimal code or config excerpt
import { MarkdownPlugin } from '@platejs/markdown';
import { createSlateEditor } from 'platejs';
const editor = createSlateEditor({ plugins: [MarkdownPlugin] });
for (const input of ['line one\r\nline two\r\n', '> q1\r\n> q2\r\n', 'line one\nline two\n']) {
const value = editor.api.markdown.deserialize(input);
editor.tf.setValue(value);
console.log(JSON.stringify(input));
console.log(' value: ', JSON.stringify(value));
console.log(' serialize:', JSON.stringify(editor.api.markdown.serialize()));
}
Logs, screenshots, and evidence
# @platejs/markdown 53.1.5 + platejs 53.1.2
"line one\r\nline two\r\n" serialize: "line one\r\nline two\n"
"> q1\r\n> q2\r\n" serialize: "> q1\r\n> q2\n"
"line one\nline two\n" serialize: "line one\nline two\n"
# @platejs/markdown 53.2.2 + platejs 53.2.1
"line one\r\nline two\r\n" serialize: "line one\r\\\nline two\n"
"> q1\r\n> q2\r\n" serialize: "> q1\r> \\\n> q2\n"
"line one\nline two\n" serialize: "line one\\\nline two\n"
# mdast from mdast-util-from-markdown 2.1.0: the text value keeps CRLF
[["text","line one\r\nline two"]]
Maintainer Codex context
route: N/A (headless)
local command: bun install && bun repro.ts
fixture/data: the three inputs in repro.ts
rule location: >
v53.3.18 and main (170d73db6): packages/markdown/src/lib/rules/defaultRules.ts:162-182 (normalizeParagraphLineBreaks,
split at :169, from b99cebe3d / PR #5026). next: packages/platejs/src/markdown/lib/internal/markdownIntrinsics.ts
(encodeMarkdownParagraph, split(/\r?\n/), PR #5152).
known blocker: none
Impact and severity
- Affected:
@platejs/markdown53.2.2 – 53.3.18 users who serialize values deserialized from CRLF Markdown with line breaks inside paragraphs or blockquotes. Observed on CRLF input bytes; the OS running the code does not matter. - Severity: data risk. The written Markdown gets a lone
\rand a hard break that the source did not have. - Frequency: always for CRLF input with a line break inside a paragraph or blockquote.
- Consequence: the serialized file renders differently from the source, and each line break inside a paragraph changes in diffs.
Additional information
Last known good: @platejs/markdown 53.1.5. First known bad: @platejs/markdown 53.2.2. Changing the LF soft break to \ is the intended effect of #5026 and is not reported here. Code-block lines under CRLF are a separate report.
- Lingua principale
- TypeScript
- Stelle
- 16.6k
- Fork
- 993
- Merge medio
- 15h 55m
- PR unite (30g)
- 63
Preparare l'ambiente
Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di udecode/plate
-
[Bug]: deserializeMd keeps `\r` at the end of code-block lines for CRLF input, and serializeMd writes mixed line endings inside the fenceForse di nuovo libera @yulman2207 l’ha presa 7 giorni fa e non c’è nessuna pull request aperta. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
udecode/plate#5322 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
[Bug]: Font colour toolbar component has fragile dropdown sizingForse di nuovo libera @Sawtone l’ha presa 59 giorni fa e non c’è nessuna pull request aperta. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
udecode/plate#5052 · 5 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Plate.js: our measured DOCX round-trip result, and an invitation to correct it in a pull requestAperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 18/100
udecode/plate#5327 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 85/100
udecode/plate#5324 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
[Bug]: deserializeMd drops a soft line break that follows an inline node, merging the words around itForse di nuovo libera @yulman2207 l’ha presa 7 giorni fa e non c’è nessuna pull request aperta. Aperta
Difficoltà 3/5 1-2 giorni Idoneità per principianti 76/100
udecode/plate#5321 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di udecode/plate
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 91/100
marimo-team/marimo#11768 ·
I maintainer di solito rispondono entro 1 giorno
-
enhancement good first issue priority: high size: XS
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
I maintainer di solito rispondono entro 1 giorno
-
clawsweeper:needs-maintainer-review clawsweeper:needs-product-decision clawsweeper:no-new-fix-pr clawsweeper:source-repro impact:ux-friction issue-rating: 🦞 diamond lobster P2
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
openclaw/openclaw#195577 · 1 commento · 1 reazione ·
I maintainer di solito rispondono entro 1 giorno
-
[Studio feedback] 对话内容向下滚动时执行过程吸顶时,由于背景色是透明的,导致执行过程标题与下面的具体执行内容重叠,导致了两行信息重叠显示;建议执行过程的背景色设置为会话界面的背景Apertabug from-studio
Difficoltà 2/5 1-3 ore Idoneità per principianti 66/100
esengine/DeepSeek-Reasonix#15044 ·
I maintainer di solito rispondono entro 1 giorno
-
Web wizard: "Launch without Sandbox" can switch a Structured create to Terminal in the same clickApertaarea:web bug needs-triage P3
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
agent-of-empires/agent-of-empires#5489 · 1 commento · 1 reazione ·
I maintainer di solito rispondono entro 1 giorno