Skip to content

MarkdownPlugin: serialize \n within a text child of a paragraph as line break#4835

Draft
dschoorl wants to merge 1 commit intoudecode:mainfrom
dschoorl:fix-markdown-linebreak-serialization
Draft

MarkdownPlugin: serialize \n within a text child of a paragraph as line break#4835
dschoorl wants to merge 1 commit intoudecode:mainfrom
dschoorl:fix-markdown-linebreak-serialization

Conversation

@dschoorl
Copy link
Copy Markdown

@dschoorl dschoorl commented Feb 6, 2026

See #4834 for background

Checklist

  • yarn typecheck
  • yarn lint:fix
  • yarn test
  • yarn brl
  • yarn changeset
  • ui changelog

@codesandbox
Copy link
Copy Markdown

codesandbox bot commented Feb 6, 2026

Review or Edit in CodeSandbox

Open the branch in Web EditorVS CodeInsiders

Open Preview

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Feb 6, 2026

🦋 Changeset detected

Latest commit: 281ca4d

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@platejs/markdown Patch
@platejs/ai Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link
Copy Markdown

vercel bot commented Feb 6, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
plate Ready Ready Preview, Comment Apr 10, 2026 10:09pm

Request Review

@dosubot dosubot bot added size:M This PR changes 30-99 lines, ignoring generated files. plugin:markdown Markdown deserializer labels Feb 6, 2026
@zbeyens
Copy link
Copy Markdown
Member

zbeyens commented Feb 6, 2026

Thanks for the PR. Looks like test is failing.

@dschoorl dschoorl force-pushed the fix-markdown-linebreak-serialization branch from ab23a04 to bce26b0 Compare February 6, 2026 19:57
@dschoorl
Copy link
Copy Markdown
Author

dschoorl commented Feb 6, 2026

Thanks for the PR. Looks like test is failing.

Yes, I noticed. Those tests pass on my local machine. I am looking into it.

@zbeyens zbeyens marked this pull request as draft March 6, 2026 08:31
Copy link
Copy Markdown

@JiwaniZakir JiwaniZakir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The handling of empty parts produced by consecutive or trailing \n characters has a subtle bug. When splitting 'text\n' (text ending with a newline), split('\n') produces ['text', ''], which causes the loop to emit [text:'text', break, break] — two break nodes instead of one — because the non-empty branch unconditionally appends a break before the empty trailing part, and then the empty-string branch appends another. A test covering a text node with a trailing \n would expose this.

The test description also has a minor mismatch: it says "two empty lines" but the input string 'Text followed by two empty lines\n\n\nFollowed by more text.' contains three \n characters, not two, and the expected output has three \\\n sequences. The test content itself is correct, but the description will mislead future readers.

Finally, the condition childParts.length !== index + 1 for "not last element" in defaultRules.ts is clearer as index < childParts.length - 1, which is the conventional idiom for this pattern in the codebase.

@dschoorl
Copy link
Copy Markdown
Author

Thanks for the review! See my comments below your feedback.

The handling of empty parts produced by consecutive or trailing \n characters has a subtle bug. When splitting 'text\n' (text ending with a newline), split('\n') produces ['text', ''], which causes the loop to emit [text:'text', break, break] — two break nodes instead of one — because the non-empty branch unconditionally appends a break before the empty trailing part, and then the empty-string branch appends another. A test covering a text node with a trailing \n would expose this.

Good catch. I fixed this and added some tests to verify that the mdast is now created as expected.

The test description also has a minor mismatch: it says "two empty lines" but the input string 'Text followed by two empty lines\n\n\nFollowed by more text.' contains three \n characters, not two, and the expected output has three \\\n sequences. The test content itself is correct, but the description will mislead future readers.

It takes three \n to create two empty lines, esp. when the first \n appears on a line with text, so that is not an empty line.

Finally, the condition childParts.length !== index + 1 for "not last element" in defaultRules.ts is clearer as index < childParts.length - 1, which is the conventional idiom for this pattern in the codebase.

Done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

plugin:markdown Markdown deserializer size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants