mdx-editor / editor

A rich text editor React component for markdown
https://mdxeditor.dev
MIT License
1.57k stars 124 forks source link

[BUG] Fenced multiline code blocks inside lists are broken after switching to CodeMirror back and forth: {"type":"code","name":"N/A"} #463

Open makcyd opened 1 month ago

makcyd commented 1 month ago

Describe the bug

When using fenced code blocks with tripple backtick inside a list item, switching back and forth to CodeMirror breaks the structure, resulting in an error:

Parsing of the following markdown structure failed: {"type":"code","name":"N/A"}.
You can fix the errors in source mode and switch to rich text mode when you are ready.

It's not the same as https://github.com/mdx-editor/editor/issues/370, because code block language is set, but indentation and change of structure breaks it.

To Reproduce

Steps to reproduce the behavior:

  1. Go to https://mdxeditor.dev/editor/demo

  2. Switch to CodeMirror

  3. Replace the code content with the following Markdown:

    * List item one
        ```tsx
        line one
        line two
    • List item two
  4. Switch to MDX - for now everything is looking good

  5. Switch back to CodeMirror - it will show something like:

      * List item one```tsx
      line one
      line two
    • List item two
      
      Note, the line break and indentation before the fenced code block start got removed
  6. Now add anything else, e.g. another list item:

    * List item one```tsx
    line one
    line two
    • List item two
    • List item three
  7. Switch back to MDX and see the error:

Parsing of the following markdown structure failed: {"type":"code","name":"N/A"}.
You can fix the errors in source mode and switch to rich text mode when you are ready.

As a result, if you try to edit a markdown document like installation instructions with a step-by-step instructions (lists) with fenced code blocks inside those lists, you'd have to manually add the linebreak before the fence ``` and indent the line for each such code block after each edit, which is quite tiresome.

Expected behavior

  1. line break and indentation before the fenced block is not removed when switching back-and-forth to CodeMirror
  2. code blocks are not broken

Screenshots

Short video (0:20) with the reproducer:

https://www.youtube.com/watch?v=6PESBeDQC9c

petyosi commented 1 month ago

That's a legit problem, quite tricky to solve, Lexical itself is not happy with blocks nested inside list items. What you're observing is a byproduct of this line.

makcyd commented 1 month ago

That's a legit problem, quite tricky to solve, Lexical itself is not happy with blocks nested inside list items. What you're observing is a byproduct of this line.

Thanks for the insight, we'll probably try tackling the issue from our end too, so if we succeed - I'll open a PR :)

PS: Thanks for the project, it's really awesome (and we've tried a lot of alternatives too before we switched to MDX Editor).

petyosi commented 1 month ago

It might be a matter of a special casing multiple block elements inside the mdast list item node. The tricky part is that you have an inline node (text) next to a block node (the code block).

An alternative which might work is fixing this during the lexical -> markdown conversion, this might work, too.