Skip to content

markdown editor formatting problems #1254

Closed

Description

@nedtwigg

Our built-in markdown editors makes some unacceptable changes on save:

## [Unreleased]

## [1.3.0] - 2026-10-20

becomes

## \[Unreleased]

## \[1.3.0] - 2026-10-20

There is some issue around text like <your relay> That was causing rendering problems, I changed it to &lt;your relay&gt;, but I think the editor then changed it back into brackets and broke itself.

When a markdown file has parsing problems (such as <your relay>) it will open in plain-text only, but it's impossible to save. It's fine to open in plaintext only, show the error, that's a great flow. But if the user fixes the parse error and saves, it should then be possible to view in WYSIWYG mode.

Unnecessarily changing newlines after headers: A markdown file that was like this:

## header
body

gets changed to this after save

## header

body

This isn't a massive problem, but it would be better to preserve the formatting of the existing file pre-edit as much as is easily possible. Don't add too much complexity fixing this though...

Activity

  1. dormouse-bot commented on Oct 20, 2026

    @dormouse-bot
    Collaborator

    #1255 fixes the save problem, and its CI is green; it has not landed yet. After a parse error, MDXEditor never clears its "initial normalization" flag, so the viewer treated every source edit as normalization and the document never became dirty. Edits now count until the next load, so you can fix the file, save it, and switch to rich text. I couldn't run the page in the triage sandbox, so the fix has not been tried by hand.

    The other three come from mdast-util-to-markdown's serializer, and the PR leaves them alone:

    • \[Unreleased]: it escapes every [ in running text. Keeping a bare bracket is only safe when it can't become a link or reference, for example when no (, [, or matching definition follows.
    • <your relay>: unescaped, it parses as an unclosed JSX element and triggers the source-only fallback. Stored as text, the serializer writes the < back escaped (\< before a letter), not as the &lt; you typed. I couldn't confirm the exact round trip that broke it again without running the editor.
    • Blank line after headings: the serializer always puts a blank line between blocks. Once Lexical holds the document, the original spacing is gone, so preserving it would mean diffing against the loaded source. That is more complexity than you wanted. The cheap alternative is a join rule that never adds the blank line after a heading, but it would also remove blank lines files already have.

    The bracket escape seems worth fixing first: it appears in every changelog. It needs a decision on how conservative the unescape should be.

  2. added a commit that references this issue on Oct 21, 2026
    d33522b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions